From 7cbb4b2cf9d89a57dcc952f6d4c1d3b27dfa731c Mon Sep 17 00:00:00 2001 From: shine <1042864399@qq.com> Date: Thu, 25 Sep 2025 02:49:27 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=E5=AE=8C=E6=88=90=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/root.go | 28 ++ cmd/single_dir.go | 91 ++++ cmd/singlefile.go | 92 ++++ config.yaml | 29 -- config/erlang_gen_cfg.go | 28 +- config/generator_config.go | 42 -- examples/peak_arena_port.erl | 518 ---------------------- examples/sample.erl | 13 - examples/templates/config_template.tplerl | 36 -- examples/templates/game_port.tpl | 11 - go.mod | 7 +- go.sum | 9 + main.go | 70 +-- run/run.go | 56 --- template/template_engine.go | 41 +- templates/port.tpl | 11 - worker/single_file.go | 134 ++++++ 17 files changed, 394 insertions(+), 822 deletions(-) create mode 100644 cmd/root.go create mode 100644 cmd/single_dir.go create mode 100644 cmd/singlefile.go delete mode 100644 config.yaml delete mode 100644 config/generator_config.go delete mode 100644 examples/peak_arena_port.erl delete mode 100644 examples/sample.erl delete mode 100644 examples/templates/config_template.tplerl delete mode 100644 examples/templates/game_port.tpl delete mode 100644 run/run.go delete mode 100644 templates/port.tpl create mode 100644 worker/single_file.go diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 0000000..d452803 --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,28 @@ +package cmd + +import ( + "fmt" + "github.com/spf13/cobra" + "os" +) + +var rootCmd = &cobra.Command{ + Use: "", + Short: "erlang注解生成配置模版工具", + Long: ` +erlang注解生成配置模版工具 +- 专注于将接口,事件,定时器等需要定义模版配置的方法,方便的注入生成模版配置文件`, + Run: func(cmd *cobra.Command, args []string) { + if len(args) == 0 { + args = []string{"config.yaml"} + } + ExecuteSingleDir(args) + }, +} + +func Execute() { + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} diff --git a/cmd/single_dir.go b/cmd/single_dir.go new file mode 100644 index 0000000..7a1adbd --- /dev/null +++ b/cmd/single_dir.go @@ -0,0 +1,91 @@ +package cmd + +import ( + "complie-erlang/config" + tm "complie-erlang/template" + "complie-erlang/worker" + "fmt" + "gopkg.in/yaml.v2" + "log" + "os" + "path/filepath" + "strings" +) + +func ExecuteSingleDir(args []string) { + cfgFileName := args[0] + + cfg := config.DefaultErlConfig() + + templates := tm.NewTemplate() + worker1 := worker.NewSingleFile(templates) + + xmlPath, err := worker1.FindConfigXMLPath(cfgFileName) + if err != nil { + fmt.Printf("Err 获取可执行文件路径失败: %v", err) + return + } + + bytes, err := os.ReadFile(xmlPath) + if err != nil { + fmt.Printf("Err 读取配置文件失败: %v", err) + return + } + + if err = yaml.Unmarshal(bytes, cfg); err != nil { + fmt.Printf("Err 解析配置文件 %s 失败: %v", xmlPath, err) + return + } + + // 获取可执行文件所在目录 + exePath, err := os.Executable() + if err != nil { + log.Fatalf("获取可执行文件路径失败: %v", err) + return + } + + // 加载模版报错 + if err := templates.ParseGlob(filepath.Join(filepath.Dir(exePath), cfg.TemplateDirPattern)); err != nil { + log.Fatalf("Err 加载模版报错: %v", err) + return + } + + for _, cfgPublic := range cfg.Keywords { + // 查询目标文件 + erlFiles, err := worker1.FindPatternErlFiles(cfgPublic.Filename) + if err != nil { + log.Fatalf("Err FindPatternErlFiles: %v", err) + return + } + if len(erlFiles) == 0 { + log.Printf("Info 未检索到文件: %v", cfgPublic.Filename) + continue + } + + for _, filename := range erlFiles { + parseTemKey, err := worker1.ParseTemKey(filename, cfgPublic) + if err != nil { + log.Fatalf("loading templates: %v", err) + return + } + + // 输出文件夹 + outDir, err := worker1.FindPluginCfgFiles(cfgPublic.OutputSep, cfgPublic.OutDirName, filename) + if err != nil { + log.Fatalf("Err 查找输出文件夹: %v", err) + return + } + + baseName := strings.Replace(filepath.Base(filename), cfgPublic.InFileExt, cfgPublic.OutFileExt, 1) + outFileNema := filepath.Join(outDir, baseName) + + if len(parseTemKey) == 0 { + continue + } + + err = os.WriteFile(outFileNema, []byte(strings.Join(parseTemKey, "\n\n")), os.ModePerm) + fmt.Println(err) + } + } + +} diff --git a/cmd/singlefile.go b/cmd/singlefile.go new file mode 100644 index 0000000..66033ac --- /dev/null +++ b/cmd/singlefile.go @@ -0,0 +1,92 @@ +package cmd + +import ( + "complie-erlang/config" + tm "complie-erlang/template" + "complie-erlang/worker" + "fmt" + "github.com/spf13/cobra" + "gopkg.in/yaml.v2" + "log" + "os" + "path/filepath" + "strings" +) + +type SingleFile struct { + CheckFile string + OutFile string + Cfg string +} + +func (s *SingleFile) run(_ *cobra.Command, _ []string) { + + cfg := config.DefaultErlConfig() + templates := tm.NewTemplate() + worker1 := worker.NewSingleFile(templates) + + xmlPath, err := worker1.FindConfigXMLPath(s.Cfg) + if err != nil { + fmt.Printf("Err 获取可执行文件路径失败: %v", err) + return + } + + bytes, err := os.ReadFile(xmlPath) + if err != nil { + fmt.Printf("Err 读取配置文件失败: %v", err) + return + } + + if err = yaml.Unmarshal(bytes, cfg); err != nil { + fmt.Printf("Err 解析配置文件 %s 失败: %v", xmlPath, err) + return + } + + // 获取可执行文件所在目录 + exePath, err := os.Executable() + if err != nil { + log.Fatalf("获取可执行文件路径失败: %v", err) + return + } + + // 加载模版报错 + if err := templates.ParseGlob(filepath.Join(filepath.Dir(exePath), cfg.TemplateDirPattern)); err != nil { + log.Fatalf("Err 加载模版报错: %v", err) + return + } + + var parseTemKeys []string + for _, cfgPublic := range cfg.Keywords { + // 查询目标文件 + parseTemKey, err := worker1.ParseTemKey(s.CheckFile, cfgPublic) + if err != nil { + log.Fatalf("loading templates: %v", err) + return + } + + if len(parseTemKey) == 0 { + continue + } + parseTemKeys = append(parseTemKeys, parseTemKey...) + } + if err = os.WriteFile(s.OutFile, []byte(strings.Join(parseTemKeys, "\n\n")), os.ModePerm); err != nil { + fmt.Println("Err WriteFile:", err) + return + } + fmt.Println("ok") +} + +func init() { + var singleSet = new(SingleFile) + var logsCmd = &cobra.Command{ + Use: "single", + Short: "single 单文件生成", + Long: `这是一个文件监视器工具集合`, + Run: singleSet.run, + } + logsCmd.PersistentFlags().StringVar(&singleSet.CheckFile, "file", "", "读取文件") + logsCmd.PersistentFlags().StringVar(&singleSet.OutFile, "out", "", "输出文件") + logsCmd.PersistentFlags().StringVar(&singleSet.Cfg, "cfg", "config.yaml", "配置地址") + + rootCmd.AddCommand(logsCmd) +} diff --git a/config.yaml b/config.yaml deleted file mode 100644 index db8dae8..0000000 --- a/config.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# config.yaml -template_dir: "./examples" -file_patterns: - - "*.erl" - - "*.hrl" -output_file: "./generated/app.config" -template_file: "./examples/templates/config_template.tplerl" -ignore_dirs: - - ".git" - - "_build" - - "deps" - - "node_modules" - -keywords: - - name: "config" - description: "配置项定义" - required: true - - name: "module" - description: "模块配置" - required: false - - name: "function" - description: "函数配置" - required: false - - name: "param" - description: "参数配置" - required: false - - name: "type" - description: "类型配置" - required: false \ No newline at end of file diff --git a/config/erlang_gen_cfg.go b/config/erlang_gen_cfg.go index bcbd7d9..e7d4b06 100644 --- a/config/erlang_gen_cfg.go +++ b/config/erlang_gen_cfg.go @@ -1,32 +1,38 @@ package config type ErlangGeneratorCfg struct { - TemplateDir string `yaml:"template_dir" json:"template_dir"` // 模板文件存放地址 - Keywords []ErlangTemKey `yaml:"keywords" json:"keywords"` + TemplateDirPattern string `yaml:"template_dir_pattern" json:"template_dir_pattern"` + Keywords []ErlangTemKey `yaml:"keywords" json:"keywords"` } type ErlangTemKey struct { + Name string `yaml:"name" json:"name"` // 关键key MainTemplate string `yaml:"main_template" json:"main_template"` // 主模板 - Filename string `yaml:"filename" json:"filename"` // _port.erl - OutputDir string `yaml:"output_dir" json:"output_dir"` // 输出地址 - OutFileExt string `yaml:"out_file_ext" json:"out_file_ext"` // .cfg - DefaultArgs []DefaultArg `yaml:"default_args" json:"default_args"` // 默认模板参数 + Filename string `yaml:"filename" json:"filename"` // *_port.erl + OutputSep string `yaml:"output_sep" json:"output_sep"` // 输出地址 + OutDirName string `yaml:"out_dir_name" json:"out_dir_name"` + InFileExt string `yaml:"in_file_ext" json:"in_file_ext"` + OutFileExt string `yaml:"out_file_ext" json:"out_file_ext"` // .cfg + DefaultArgs []DefaultArg `yaml:"default_args" json:"default_args"` // 默认模板参数 } type DefaultArg struct { Key string `yaml:"key" json:"key"` - Value string `yaml:"val" json:"Value"` + Value string `yaml:"value" json:"value"` } func DefaultErlConfig() *ErlangGeneratorCfg { return &ErlangGeneratorCfg{ - TemplateDir: "./templates", + TemplateDirPattern: "./templates/*.tpl", Keywords: []ErlangTemKey{ { - MainTemplate: "port.tpl", + Name: "GamePort", + MainTemplate: "PublicPort", Filename: "*_port.erl", - OutputDir: "output", - OutFileExt: ".cfg", + OutputSep: "plugin\\game", + OutDirName: ".cfg", + InFileExt: ".erl", + OutFileExt: "_gen.cfg", DefaultArgs: []DefaultArg{ { Key: "template", diff --git a/config/generator_config.go b/config/generator_config.go deleted file mode 100644 index f135201..0000000 --- a/config/generator_config.go +++ /dev/null @@ -1,42 +0,0 @@ -// config/generator_config.go -package config - -type GeneratorConfig struct { - // 扫描配置 - ScanDir string `yaml:"scan_dir" json:"scan_dir"` - FilePatterns []string `yaml:"file_patterns" json:"file_patterns"` - OutputFile string `yaml:"output_file" json:"output_file"` - - // 注解关键词配置 - Keywords []KeywordConfig `yaml:"keywords" json:"keywords"` - - // 模板配置 - TemplateFile string `yaml:"template_file" json:"template_file"` - - // 忽略的目录 - IgnoreDirs []string `yaml:"ignore_dirs" json:"ignore_dirs"` -} - -type KeywordConfig struct { - Name string `yaml:"name" json:"name"` - Description string `yaml:"description" json:"description"` - Required bool `yaml:"required" json:"required"` -} - -// 默认配置 -func DefaultConfig() *GeneratorConfig { - return &GeneratorConfig{ - ScanDir: "./", - FilePatterns: []string{"*.erl", "*.hrl"}, - OutputFile: "./generated/app.config", - TemplateFile: "./templates/config_template.tplerl", - IgnoreDirs: []string{".git", "node_modules", "_build", "deps"}, - Keywords: []KeywordConfig{ - {Name: "config", Description: "配置项定义", Required: true}, - {Name: "module", Description: "模块配置", Required: false}, - {Name: "function", Description: "函数配置", Required: false}, - {Name: "param", Description: "参数配置", Required: false}, - {Name: "type", Description: "类型配置", Required: false}, - }, - } -} diff --git a/examples/peak_arena_port.erl b/examples/peak_arena_port.erl deleted file mode 100644 index 60d2456..0000000 --- a/examples/peak_arena_port.erl +++ /dev/null @@ -1,518 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author Administrator -%%% @copyright (C) 2022, -%%% @doc -%%% 巅峰擂台 接口 -%%% @end -%%% Created : 27. 9月 2022 10:09 -%%%------------------------------------------------------------------- --module(peak_arena_port). --decription("peak_arena_port"). --copyright('youkia,www.youkia.net'). --author("yyh,yangyuhang@youkia.net"). --vsn(1). - -%%%========================EXPORT======================== --export([get_info/5, update_state/5, get_last_show/5, get_stage_info/5, get_preliminaries_group_info/5, get_group_info/5, - get_guess_info/5, get_preliminaries_p_log/5, get_p_log/5, get_simulated_fight_info/5, join/5, fight/5, guess/5, - redistribution/5, simulated_fight/5, get_index_garray/5, get_fail_info/5, - get_preliminaries_follow_info/5, fight_follow/5, get_logs/5]). -%%%========================INCLUDE======================= --include("cross.hrl"). --include("peak_arena.hrl"). --include("../../game/include/error_lib.hrl"). --include("../../game/include/array.hrl"). --include("fight_type.hrl"). --include("table.hrl"). -%%%========================DEFINE======================== --define(IS_FAIL_0, 0). %%成功晋级 --define(IS_FAIL_1, 1). %%淘汰 -%%%========================RECORD======================== -%%%=================EXPORTED FUNCTIONS=================== -%% ---------------------------------------------------- -%% @GamePort(cmd=\game\peak_arena\get_info, desc=获取信息, reconnect=1) -%% @FunOpenCheck(fun_id=93) -%% @PrePort(proto=pub_proto, message=single_int) -%% ---------------------------------------------------- -get_info(_, _Session, Attr, Info, _Msg) -> - Src = z_lib:get_value(Info, 'src', 'none'), - ServerId = role_lib:get_server_id(Attr), - RoleUid = role_lib:get_uid(Attr), - PABase = peak_arena_db:get_base(Src, ServerId), - Term = peak_arena_base:get_term(PABase), - ActivityTime = peak_arena_db:get_active_time(ServerId), - ActivityTime == none andalso ?ThrowErr("fun_open_limit"), - AlPlayer = peak_arena_db:refresh_player(Src, RoleUid, ServerId, Term), - Reply = peak_arena_pb_lib:format_player_info({Src, RoleUid, ServerId, PABase, ActivityTime, AlPlayer, Term}), - {ok, [], Info, [{gpb, pro_peak_arena, Reply}]}. - -%% ---------------------------------------------------- -%% Description: 获取玩家自己的淘汰信息 -%% ---------------------------------------------------- -get_fail_info(_, _Session, Attr, Info, _Msg) -> - Src = z_lib:get_value(Info, 'src', 'none'), - ServerId = role_lib:get_server_id(Attr), - RoleUid = role_lib:get_uid(Attr), - PABase = peak_arena_db:get_base(Src, ServerId), - PlayerInfo = peak_arena_db:get_player_info(Src, RoleUid, ServerId), - FinalId = player_peak_arena:get_final_id(PlayerInfo), - {WinList, _FailList} = peak_arena_base:get_final_info(PABase), - IsFail = case lists:keyfind(FinalId, 1, WinList) of - false -> - ?IS_FAIL_1; - _ -> - ?IS_FAIL_0 - end, - {ok, [], Info, [{gpb, pro_peak_arena, pro_peak_arena:init_s2c_role_fail_info(IsFail)}]}. - -%% ---------------------------------------------------- -%% Description: 报名 -%% ---------------------------------------------------- -join(_, _Session, Attr, Info, _Msg) -> - Src = z_lib:get_value(Info, 'src', 'none'), - ServerId = role_lib:get_server_id(Attr), - RoleUid = role_lib:get_uid(Attr), - Reply = peak_arena_db:join(Src, RoleUid, ServerId), - {ok, [], Info, Reply}. -%% ---------------------------------------------------- -%% Description: 获取海选赛分组信息 -%% @GamePort(cmd=\game\peak_arena\get_preliminaries_group_info, desc=获取海选赛分组信息, pre_proto=pub_proto, pre_message=single_int) -%% ---------------------------------------------------- -get_preliminaries_group_info(_, _Session, Attr, Info, Msg) -> - Src = z_lib:get_value(Info, 'src', 'none'), - RoleUid = role_lib:get_uid(Attr), - ServerId = role_lib:get_server_id(Attr), - PB = z_lib:get_value(Msg, de_gpb, none), - GroupId = pub_proto:get_single_int_item(PB), - PABase = peak_arena_db:get_base(Src, ServerId), - Reply = peak_arena_pb_lib:format_preliminaries_group_info({Src, PABase, GroupId, RoleUid, ServerId}), - {ok, [], Info, [{gpb, pro_peak_arena, Reply}]}. - -%% ---------------------------------------------------- -%% Description: 获取海选赛分组追随者信息 -%% ---------------------------------------------------- -get_preliminaries_follow_info(_, _Session, Attr, Info, Msg) -> - Src = z_lib:get_value(Info, 'src', 'none'), - RoleUid = role_lib:get_uid(Attr), - ServerId = role_lib:get_server_id(Attr), - PB = z_lib:get_value(Msg, de_gpb, none), - GroupId = pub_proto:get_kv_int_k(PB), - ChampionId = pub_proto:get_kv_int_v(PB), - [?ThrowErr("args_err") || (not lists:member(GroupId, ?PEAK_GROUPS_2) orelse (not lists:member(ChampionId, ?ALL_INDEX)))], - FollowList = peak_arena_db:get_follow_info(ServerId, GroupId, ChampionId), - LanguageType = language_lib:get_language_by_type(RoleUid, ServerId), - %% 追随者数据 - F = fun - (Index, Acc) -> - FollowUid = case lists:keyfind(Index, 1, FollowList) of - {Index, ItemRoleUid} -> ItemRoleUid; - _ -> 0 - end, - case peak_arena_pb_lib:format_i_arena_follow_show(Src, ServerId, FollowUid, LanguageType, Index, GroupId, ChampionId) of - none -> Acc; - ItemPb -> [ItemPb | Acc] - end - end, - {_, FollowSum} = zm_config:get(peak_arena_info, follow_sum), - Reply = lists:foldl(F, [], lists:seq(1, FollowSum)), - %% 获取擂主数据 - PABase = peak_arena_db:get_base(Src, ServerId), - Winner = peak_arena_base:get_preliminaries_winner(PABase), - {_, WinnerPlayerL} = lists:keyfind(GroupId, 1, Winner), - {_, ChampionRoleUid, _ServerId} = lists:keyfind(ChampionId, 1, WinnerPlayerL), - ChampionPb = peak_arena_pb_lib:format_i_arena_champion_show(Src, ChampionRoleUid, ServerId, ChampionId), - {ok, [], Info, [{gpb, pro_peak_arena, pro_peak_arena:init_s2c_peak_arena_group_follow_info(ChampionPb, Reply)}]}. - - -%% ---------------------------------------------------- -%% @Cmd(cmd=/game/peak_arena/fight_follow, desc=追随者战斗) -%% @Decode(mod=pro_peak_arena, message=c2s_peak_arena_fight_follow) -%% @FunOpenCheck(open_id=72) -%% ---------------------------------------------------- -fight_follow(_, _Session, Attr, Info, Msg) -> - Src = z_lib:get_value(Info, 'src', 'none'), - ServerId = role_lib:get_server_id(Attr), - RoleUid = role_lib:get_uid(Attr), - PB = z_lib:get_value(Msg, de_gpb, none), - GroupId = pro_peak_arena:get_c2s_peak_arena_fight_follow_group_id(PB), - Index = pro_peak_arena:get_c2s_peak_arena_fight_follow_index(PB), - FollowId = pro_peak_arena:get_c2s_peak_arena_fight_follow_follow_id(PB), - FightScene = pro_peak_arena:get_c2s_peak_arena_fight_follow_fight_scene(PB), - {_, FollowSum} = zm_config:get(peak_arena_info, follow_sum), - [?ThrowErr("args_err") || (not lists:member(Index, ?ALL_INDEX) orelse (FollowId > FollowSum) orelse FollowId < 0)], - Reply = peak_arena_db:fight_follow(Src, RoleUid, ServerId, GroupId, Index, FollowId, FightScene), - {ok, [], Info, [{gpb, pro_peak_arena, Reply}]}. - -%% ---------------------------------------------------- -%% @Cmd(cmd=/game/peak_arena/get_logs, desc=日志) -%% ---------------------------------------------------- -get_logs(_, _Session, Attr, Info, _Msg) -> -%% Src = z_lib:get_value(Info, 'src', 'none'), -%% ServerId = role_lib:get_server_id(Attr), - RoleUid = role_lib:get_uid(Attr), - Logs = peak_arena_db:get_logs(RoleUid), - Reply = peak_arena_pb_lib:format_log(Logs), - {ok, [], Info, [{gpb, pro_peak_arena, pro_peak_arena:init_s2c_peak_arena_logs(Reply)}]}. - -%% ---------------------------------------------------- -%% Description: 获取海选赛位置阵容数据 -%% ---------------------------------------------------- -get_index_garray(_, _Session, Attr, Info, Msg) -> - Src = z_lib:get_value(Info, 'src', 'none'), - ServerId = role_lib:get_server_id(Attr), - PB = z_lib:get_value(Msg, de_gpb, none), - RoleUid = role_lib:get_uid(Attr), - Index = pub_proto:get_single_int_item(PB), - PABase = peak_arena_db:get_base(Src, ServerId), - Reply = peak_arena_pb_lib:format_index_garray({Src, ServerId, RoleUid, PABase, Index, ServerId}), - {ok, [], Info, [{gpb, pro_peak_arena, Reply}]}. -%% ---------------------------------------------------- -%% Description: 获取晋级赛分组信息 -%% ---------------------------------------------------- -get_group_info(_, _Session, Attr, Info, Msg) -> - Src = z_lib:get_value(Info, 'src', 'none'), - RoleUid = role_lib:get_uid(Attr), - ServerId = role_lib:get_server_id(Attr), - PB = z_lib:get_value(Msg, de_gpb, none), - GroupId = pub_proto:get_single_int_item(PB), - PABase = peak_arena_db:get_base(Src, ServerId), - ActivityTime = peak_arena_db:get_active_time(ServerId), - Stage = time_peak_arena:get_stage(ActivityTime), - FightIds = - if - GroupId >= 1 andalso GroupId =< 8 -> - F = fun(R, I) -> - List = peak_arena_lib:get_fight_ids({I, GroupId}), - List ++ R - end, - z_lib:for(F, [], 1, Stage + 2);%%多取一场,因为下一阶段的战斗已被生成,则也需要显示 - GroupId =:= 9 -> - [?ThrowErr("pa_stage_err") || Stage < ?Legend_Stage5], - F = fun(R, I) -> - List = peak_arena_lib:get_fight_ids({I, GroupId}), - List ++ R - end, - z_lib:for(F, [], 1, Stage + 2); - true -> - ?ThrowErr("pa_group_id_err") - end, - FinalIds = - case GroupId of - ?PEAK_GROUP_9 ->%%冠军组的finalId为8强 - {StartId, EndId} = peak_arena_lib:stage_2_fight_id(?Legend_Stage5), - FightIng = peak_arena_base:get_fight_ing(PABase), - FightEd = peak_arena_base:get_fight_ed(PABase), - F2 = fun(FightItem, Acc) -> - FightId = fight_peak_arena:get_fight_id(FightItem), - if - FightId >= StartId andalso FightId =< EndId -> - FightId1 = fight_peak_arena:get_final_id1(FightItem), - FightId2 = fight_peak_arena:get_final_id2(FightItem), - [FightId1, FightId2 | Acc]; - true -> - Acc - end - end, - lists:foldl(F2, [], FightIng ++ FightEd); - _ -> - {_, FinalIds0} = lists:keyfind(GroupId, 1, ?PEAK_ARENA_GROUP), - FinalIds0 - end, - MyGroup = player_peak_arena:get_group(peak_arena_db:get_player_info(Src, RoleUid, ServerId)), - {Index, FollowId} = peak_arena_db:get_player_follow_monster_index(ServerId, MyGroup, RoleUid), - PreLiminar = peak_arena_base:get_preliminaries_winner(PABase), - %% 取出跟随数据 - FollowRoleUid = if - Index =/= 0 -> - {_, IndexL} = lists:keyfind(MyGroup, 1, PreLiminar), - {_, ItemRoleUid, _} = lists:keyfind(Index, 1, IndexL), - ItemRoleUid; - true -> - 0 - end, - - Reply = peak_arena_pb_lib:format_group_info({Src, FightIds, FinalIds, PABase, FollowRoleUid, FollowId}), - %% io:format("(st@~p)~p>Re:~p~n", [?MODULE, ?LINE, {MyGroup, Reply}]), - {ok, [], Info, [{gpb, pro_peak_arena, Reply}]}. -%% ---------------------------------------------------- -%% Description: 挑战对手/登擂 -%% ---------------------------------------------------- -fight(_, _Session, Attr, Info, Msg) -> - Src = z_lib:get_value(Info, 'src', 'none'), - ServerId = role_lib:get_server_id(Attr), - RoleUid = role_lib:get_uid(Attr), - PB = z_lib:get_value(Msg, de_gpb, none), - Index = pub_proto:get_kv_int_k(PB), - BattleSceneModel = pub_proto:get_kv_int_v(PB), - peak_arena_db:fight(Src, RoleUid, ServerId, Index, BattleSceneModel), - {ok, [], Info, game_lib:pb_str("ok")}. -%% ---------------------------------------------------- -%% Description: 获取阶段 -%% ---------------------------------------------------- -get_stage_info(_, _Session, Attr, Info, _Msg) -> - ServerId = role_lib:get_server_id(Attr), - ActivityTime = peak_arena_db:get_active_time(ServerId), - Stage = time_peak_arena:get_stage(ActivityTime), - {ok, [], Info, game_lib:pb_int(Stage)}. -%% ---------------------------------------------------- -%% Description: 换组 -%% ---------------------------------------------------- -redistribution(_, _Session, Attr, Info, _Msg) -> - Src = z_lib:get_value(Info, 'src', 'none'), - ServerId = role_lib:get_server_id(Attr), - RoleUid = role_lib:get_uid(Attr), - NewGroup = peak_arena_db:redistribution(Src, RoleUid, ServerId), - {ok, [], Info, game_lib:pb_int(NewGroup)}. - -%% ---------------------------------------------------- -%% Description: 获取个人初赛战报 -%% ---------------------------------------------------- -get_preliminaries_p_log(_, _Session, Attr, Info, _Msg) -> - Src = z_lib:get_value(Info, 'src', 'none'), - ServerId = role_lib:get_server_id(Attr), - RoleUid = role_lib:get_uid(Attr), - PlayerLogList = peak_arena_db:get_player_log(Src, RoleUid, ServerId), - Reply = peak_arena_pb_lib:format_player_log(PlayerLogList), - {ok, [], Info, [{gpb, pro_peak_arena, Reply}]}. -%% ---------------------------------------------------- -%% Description: 修改状态 -%% ---------------------------------------------------- -update_state(_, _Session, Attr, Info, Msg) -> - Src = z_lib:get_value(Info, 'src', 'none'), - ServerId = role_lib:get_server_id(Attr), - RoleUid = role_lib:get_uid(Attr), - PB = z_lib:get_value(Msg, de_gpb, none), - Type = pub_proto:get_single_int_item(PB),%% 1修改守擂, 2修改结算 3修改决赛弹窗 - peak_arena_db:update_state(Src, RoleUid, ServerId, Type), - {ok, [], Info, game_lib:pb_str("ok")}. -%% ---------------------------------------------------- -%% Description: 竞猜 -%% ---------------------------------------------------- -guess(_, _Session, Attr, Info, Msg) -> - Src = z_lib:get_value(Info, 'src', 'none'), - ServerId = role_lib:get_server_id(Attr), - RoleUid = role_lib:get_uid(Attr), - PB = z_lib:get_value(Msg, de_gpb, none), - GuessFinalId = pub_proto:get_kv_int_k(PB), - Type = pub_proto:get_kv_int_v(PB), - Consume = - case zm_config:get(peak_arena_scuffle_guess, Type) of - {_, {Consume0, _, _}} -> Consume0; - _ -> ?ThrowErr("arg_err") - end, - Tables = consume_lib:get_consume_table(Src, RoleUid, ServerId, Consume, [{?PEAK_ARENA_GUESS_TABLE, ServerId, peak_arena_guess:init()}, - {?PLAYER_PEAK_ARENA_TABLE, RoleUid, player_peak_arena:init()}]), - Args = {RoleUid, ServerId, GuessFinalId, Type, Consume}, - case z_db_lib:dynamic(ServerId, fun peak_arena_db:guess/2, Args, Tables) of - {ok, ConsumeLog} -> - zm_event:notify(Src, 'war_token2_normal', {RoleUid, ServerId, war_token2_lib:convert(peak_arena, 1)}), - %%参与巅峰擂台收集事件 - zm_event:notify(Src, fun_ok, {RoleUid, ServerId, [{peak_arena_action, 1}]}), - zm_event:notify(Src, consumes_awards_ok, [{role_uid, RoleUid}, {server_id, ServerId}, {consumes, ConsumeLog}, {act_method, peak_arena_guess}]), - BiList = [begin - BiMethod = {act_method, {peak_arena_guess, Type, GuessFinalId}}, - bi_lib:init(consume_logs, ServerId, [{role_uid, RoleUid}, {logs, ConsumeLog}, BiMethod]) - end || not consume_lib:log_is_empty(ConsumeLog)], - zm_event:notify(Src, bi_event, [bi_lib:init(sky_throne_guess, ServerId, [{role_uid, RoleUid}, - {final_id, GuessFinalId}, - {guess_type, Type}]) | BiList]), - Replay = data_pb_lib:format_log(none, ConsumeLog), - {ok, [], Info, [{gpb, pro_prop, Replay}]}; - Err -> - throw(Err) - end. -%% ---------------------------------------------------- -%% Description:获取竞猜信息 -%% ---------------------------------------------------- -get_guess_info(_, _Session, Attr, Info, _Msg) -> - Src = z_lib:get_value(Info, 'src', 'none'), - ServerId = role_lib:get_server_id(Attr), - RoleUid = role_lib:get_uid(Attr), - PABase = peak_arena_db:get_base(Src, ServerId), - PAPlayer = peak_arena_db:get_player_info(Src, RoleUid, ServerId), - GuessL = peak_arena_db:get_guess_info(Src, ServerId), - PATime = z_db_lib:get(z_db_lib:get_table(?PEAK_ARENA_TIME_TABLE), {?PA_Time_Key, ServerId}, 'none'), - Reply = peak_arena_pb_lib:format_guess_info({Src, PAPlayer, PABase, GuessL, PATime}), - {ok, [], Info, [{gpb, pro_peak_arena, Reply}]}. -%% ---------------------------------------------------- -%% Description: 获取模拟赛对手信息 -%% ---------------------------------------------------- -get_simulated_fight_info(_, _Session, Attr, Info, _Msg) -> - Src = z_lib:get_value(Info, 'src', 'none'), - ServerId = role_lib:get_server_id(Attr), - RoleUid = role_lib:get_uid(Attr), - PABase = peak_arena_db:get_base(Src, ServerId), - PAPlayer = peak_arena_db:get_player_info(Src, RoleUid, ServerId), - FinalId = player_peak_arena:get_final_id(PAPlayer), - FightPAL = peak_arena_base:get_fight_ing(PABase), - {WinList, LoseList} = peak_arena_base:get_final_info(PABase), - AllList = WinList ++ LoseList, - F = fun(R, Item) -> - FinalId1 = fight_peak_arena:get_final_id1(Item), - FinalId2 = fight_peak_arena:get_final_id2(Item), - case FinalId1 =:= FinalId orelse FinalId2 =:= FinalId of - true -> {break, Item}; - false -> R - end - end, - R = - case z_lib:foreach(F, none, FightPAL) of - none ->%%没有模拟战对手 - pro_peak_arena:init_i_simulated_fight_show("", 0, []); - FightPA -> - case fight_peak_arena:get_final_id1(FightPA) of - FinalId ->%%一号位,对手是二号 - Id2 = fight_peak_arena:get_final_id2(FightPA), - Id2 =:= 0 andalso ?ThrowErr("peak_arena_tar_final_id_err"), - {_, RoleUid2, ServerId2} = lists:keyfind(Id2, 1, AllList), - Power2 = power_db:get_array_power(Src, RoleUid2, ServerId2, ?ARRAY_8), - {_, [Array2], _} = array_db:get_array(Src, RoleUid2, ServerId2, ?ARRAY_8, 1), - ArrayList = array_item:get_array(Array2), - CardStorage = card_db:get_card(Src, RoleUid2, ServerId2), - Role = role_db:get_role(Src, RoleUid2, ServerId2), - CardShow2 = [begin - CardProp = storage_lib:find_by_sid(CardStorage, CardSid), - CardRecord = prop_kit_lib:get_prop_record(CardProp), - LittleStar = card:get_little_star(CardRecord), - RoleLevel = role:get_level(Role), - Level = card_lib:get_level(CardRecord, RoleLevel), - LQ = card:get_quality_cultivate(CardRecord), - AwakenLv = card:get_awaken_lv(CardRecord), - Stage = card:get_stage(CardRecord), - pro_arena_legend:init_i_card_show(CardSid, LittleStar, Level, LQ, AwakenLv, Stage) - end || {_, {_, CardSid}} <- ArrayList], - Role2 = role_db:get_role(Src, RoleUid2, ServerId2), - Name2 = role:get_name(Role2), - pro_peak_arena:init_i_simulated_fight_show(Name2, Power2, CardShow2); - OtherFinalId ->%%对手是一号 - OtherFinalId =:= 0 andalso ?ThrowErr("peak_arena_tar_final_id_err"), - {_, RoleUid1, ServerId1} = lists:keyfind(OtherFinalId, 1, AllList), - Power1 = power_db:get_array_power(Src, RoleUid1, ServerId1, ?ARRAY_8), - {_, [Array1], _} = array_db:get_array(Src, RoleUid1, ServerId1, ?ARRAY_8, 1), - ArrayList = array_item:get_array(Array1), - CardStorage = card_db:get_card(Src, RoleUid1, ServerId1), - Role = role_db:get_role(Src, RoleUid1, ServerId1), - CardShow1 = [begin - CardProp = storage_lib:find_by_sid(CardStorage, CardSid), - CardRecord = prop_kit_lib:get_prop_record(CardProp), - LittleStar = card:get_little_star(CardRecord), - RoleLevel = role:get_level(Role), - Level = card_lib:get_level(CardRecord, RoleLevel), - LQ = card:get_quality_cultivate(CardRecord), - AwakenLv = card:get_awaken_lv(CardRecord), - Stage = card:get_stage(CardRecord), - pro_arena_legend:init_i_card_show(CardSid, LittleStar, Level, LQ, AwakenLv, Stage) - end || {_, {_, CardSid}} <- ArrayList], - Role1 = role_db:get_role(Src, RoleUid1, ServerId1), - Name1 = role:get_name(Role1), - pro_peak_arena:init_i_simulated_fight_show(Name1, Power1, CardShow1) - end - end, - {ok, [], Info, [{gpb, pro_peak_arena, R}]}. -%% ---------------------------------------------------- -%% Description: 获取4强 -%% ---------------------------------------------------- -get_last_show(_, _Session, Attr, Info, _Msg) -> - Src = z_lib:get_value(Info, 'src', 'none'), - ServerId = role_lib:get_server_id(Attr), - LastInfo = peak_arena_db:get_last_info(Src, ServerId), - Replay = peak_arena_pb_lib:format_last_show(LastInfo), - {ok, [], Info, [{gpb, pro_peak_arena, Replay}]}. -%% ---------------------------------------------------- -%% Description: 获取决赛战报 -%% ---------------------------------------------------- -get_p_log(_, _Session, Attr, Info, Msg) -> - Src = z_lib:get_value(Info, 'src', 'none'), - ServerId = role_lib:get_server_id(Attr), - PB = z_lib:get_value(Msg, de_gpb, none), - Stage = pub_proto:get_single_int_item(PB), - {StartId, EndId} = peak_arena_lib:stage_2_fight_id(Stage), - PABase = peak_arena_db:get_base(Src, ServerId), - FightEd = peak_arena_base:get_fight_ed(PABase), - FightIng = peak_arena_base:get_fight_ing(PABase), - F = fun(FightPAInfo, Acc) -> - FightId = fight_peak_arena:get_fight_id(FightPAInfo), - if - FightId >= StartId andalso FightId =< EndId -> - FinalId1 = fight_peak_arena:get_final_id1(FightPAInfo), - FinalId2 = fight_peak_arena:get_final_id2(FightPAInfo), - if - FinalId1 =:= 0 andalso FinalId2 =:= 0 -> - Acc; - true -> - LogUid = - case fight_peak_arena:get_log_uids(FightPAInfo) of - [] -> 0; - [LogUid0] -> LogUid0 - end, - Group = peak_arena_lib:fight_id_2_group(FightId), - {WinList, LoseList} = peak_arena_base:get_final_info(PABase), - RoleFun = fun - (FinalId) -> - case lists:keyfind(FinalId, 1, WinList ++ LoseList) of - false -> - []; - {_, RoleUid, ServerId} -> - Role1 = role_db:get_role(Src, RoleUid, ServerId), - Name1 = role:get_name(Role1), - Level1 = role:get_level(Role1), - Style = role:get_style(Role1), - Skin = role:get_skin(Role1), - Sex = role:get_sex(Role1), - AvatarBorder1 = role:get_avatar_border(Role1), - Player = pro_peak_arena:init_i_player_show(Style, AvatarBorder1, Level1, Name1, FinalId, RoleUid, Skin, Sex), - [Player] - end - end, - WinFinalId = - case fight_peak_arena:get_win_uids(FightPAInfo) of - [] -> 0; - [WinFinalId0] -> WinFinalId0 - end, - Acc ++ [pro_peak_arena:init_i_pa_log(LogUid, Group, WinFinalId, RoleFun(FinalId1) ++ RoleFun(FinalId2))] - end; - true -> - Acc - end - end, - LogList = lists:foldl(F, [], FightIng ++ FightEd), - R = pro_peak_arena:init_s2c_pa_l_log(LogList), - {ok, [], Info, [{gpb, pro_peak_arena, R}]}. -%% ---------------------------------------------------- -%% Description: 模拟战斗 -%% ---------------------------------------------------- -simulated_fight(_, _Session, Attr, Info, _Msg) -> - Src = z_lib:get_value(Info, 'src', 'none'), - ServerId = role_lib:get_server_id(Attr), - RoleUid = role_lib:get_uid(Attr), - [?ThrowErr("pa_fight_ing") || fs_server:api_check_fighting({role_uid, ServerId, RoleUid}, [{role_uid, RoleUid}])], - {_, BattleSceneModel} = zm_config:get(peak_arena_info, battle_scene), - PABase = peak_arena_db:get_base(Src, ServerId), - PlayerInfo = peak_arena_db:get_player_info(Src, RoleUid, ServerId), - FinalId = player_peak_arena:get_final_id(PlayerInfo), - [?ThrowErr("peak_arena_not_join_err") || FinalId =:= 0],%%没有参赛 - FightIng = peak_arena_base:get_fight_ing(PABase), - F = fun(R, FightItem) -> - FinalId1 = fight_peak_arena:get_final_id1(FightItem), - FinalId2 = fight_peak_arena:get_final_id2(FightItem), - if - FinalId1 =:= FinalId -> {break, FinalId2}; - FinalId2 =:= FinalId -> {break, FinalId1}; - true -> R - end - end, - TarFinalId = z_lib:foreach(F, 0, FightIng), - [?ThrowErr("peak_arena_tar_final_id_err") || TarFinalId =:= 0],%%没有对手 - {WinList, _} = peak_arena_base:get_final_info(PABase), - F2 = fun(R, {WinFinalId, WinRoleUid, WinServerId}) -> - if - WinFinalId =:= TarFinalId -> - {break, {WinRoleUid, WinServerId}}; - true -> - R - end - end, - {TarUid, TarServerId} = z_lib:foreach(F2, {0, 0}, WinList), - [?ThrowErr("peak_arena_tar_final_id_err") || TarUid =:= 0 orelse TarServerId =:= 0],%%对手错误 - peak_arena_db:pa_test_fight(Src, RoleUid, ServerId, TarUid, TarServerId, PABase, ?PEAK_ARENA_TYPE3, BattleSceneModel), - {ok, [], Info, game_lib:pb_str("ok")}. \ No newline at end of file diff --git a/examples/sample.erl b/examples/sample.erl deleted file mode 100644 index 419a63b..0000000 --- a/examples/sample.erl +++ /dev/null @@ -1,13 +0,0 @@ -%% examples/sample.erl --module(sample). --export([start/0, process/1]). - -%% @function(type="init", timeout=5000) -%% @param(name="data", type="binary") -start() -> - ok. - -%% @function(type="worker", concurrency=10) -%% @param(name="input", type="list") -process(Input) -> - {ok, processed}. \ No newline at end of file diff --git a/examples/templates/config_template.tplerl b/examples/templates/config_template.tplerl deleted file mode 100644 index aa3b7b5..0000000 --- a/examples/templates/config_template.tplerl +++ /dev/null @@ -1,36 +0,0 @@ -%% Generated Erlang Configuration -%% DO NOT EDIT MANUALLY - Generated by annotation generator -%%%------------------------------------获取基本信息------------------------------ -{ template, _Z_SESSION, {Project, "/game/peak_arena/get_info", [ - {peak_arena_port, get_info, []} -]}}. - -%%%------------------------------------修改状态------------------------------ -{ template, _Z_SESSION, {Project, "/game/peak_arena/update_state", [ - {reconnect_db, msg_start, []}, - {fun_open_check, check, [98]}, - {pre_port, decode, [pub_proto, single_int]}, - {peak_arena_port, update_state, []}, - {reconnect_db, msg_end, []} -]}}. - - -%%%---------------------------------成就start--------------------------------- -{local, Achieve, z_lib, to_atom, [Project, "/achieve"]}. -{template, _FILE_TABLE_GAME_GLOBAL, {achieve, Achieve}}. -%%%---------------------------------成就end--------------------------------- - -%%%---------------------------------成就点start--------------------------------- -{local, AchievePoint, z_lib, to_atom, [Project, "/achieve_point"]}. -{template, _FILE_TABLE_GAME_GLOBAL, {achieve_point, AchievePoint}}. -%%%---------------------------------成就点end--------------------------------- - -%%%---------------------------------成就点背包start--------------------------------- -{local, AchieveStorage, z_lib, to_atom, [Project, "/achieve_storage"]}. -{template, _FILE_TABLE_GAME_GLOBAL, {achieve_storage, AchieveStorage}}. -%%%---------------------------------成就点背包end--------------------------------- - -%%%---------------------------------成就点start--------------------------------- -{local, AchieveInfo, z_lib, to_atom, [Project, "/achieve_info"]}. -{template, _FILE_TABLE_GAME_GLOBAL, {achieve_info, AchieveInfo}}. -%%%---------------------------------成就点end--------------------------------- \ No newline at end of file diff --git a/examples/templates/game_port.tpl b/examples/templates/game_port.tpl deleted file mode 100644 index 15a117b..0000000 --- a/examples/templates/game_port.tpl +++ /dev/null @@ -1,11 +0,0 @@ -%% ---------------------------------------------------------------------------------- -{{if .desc}}%% {{hd .desc}} {{end}} -{template, _Z_SESSION, {Project, "{{hd .cmd}}", [ - {{if .reconnect}} { reconnect_db, msg_start, [] }, - {{end}} {{if .fun_id}}{ fun_open_check, check, [{{hd .fun_id}}] }, {{end}} - {{if .pre_message}} { pre_port, decode, [{{hd .pre_proto }}, {{hd .pre_message}}] }, {{end}} - {{if .reconnect}} { {{hd .module}}, {{hd .func}}, [{{join .args ","}}] }, - { reconnect_db, msg_end, [] } {{else}} { {{hd .module}}, {{hd .func}}, [] } -{{end}} -]}}. -%% ----------------------------------------------------------------------------------- diff --git a/go.mod b/go.mod index 3362e61..2da4073 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,9 @@ module complie-erlang go 1.23.4 -require gopkg.in/yaml.v2 v2.4.0 // indirect +require ( + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/spf13/cobra v1.10.1 // indirect + github.com/spf13/pflag v1.0.9 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) diff --git a/go.sum b/go.sum index 7534661..584657f 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,12 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= +github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index a7c367c..c5b6a81 100644 --- a/main.go +++ b/main.go @@ -1,74 +1,8 @@ // main.go package main -import ( - "complie-erlang/config" - "complie-erlang/parser" - tm "complie-erlang/template" - "fmt" - "log" - "os" - "strings" - "text/template" -) +import "complie-erlang/cmd" func main() { - cfg := config.DefaultErlConfig() - - templates := tm.NewTemplate() - - if err := templates.Load(cfg.TemplateDir); err != nil { - log.Fatalf("loading templates: %v", err) - return - } - - erlangFile, _ := parser.ParseErlangFile("E:\\gopackage2\\2025.7\\complie-erl\\examples\\peak_arena_port.erl") - // fmt.Printf("ParseErlangFile: %v, %v\n", erlangFile, err) - for _, function := range erlangFile.Functions { - if len(function.KeyMap) > 0 { - fmt.Printf("Function: %v %v \n", function.Name, function.KeyMap) - } - - } - -} - -func main1() { - - erlangFile, _ := parser.ParseErlangFile("E:\\gopackage2\\2025.7\\complie-erl\\examples\\peak_arena_port.erl") - // fmt.Printf("ParseErlangFile: %v, %v\n", erlangFile, err) - for _, function := range erlangFile.Functions { - if len(function.KeyMap) > 0 { - fmt.Printf("Function: %v %v \n", function.Name, function.KeyMap) - } - - } - - bytes, _ := os.ReadFile("E:\\gopackage2\\2025.7\\complie-erl\\examples\\templates\\port.tpl") - // 解析模板 - t := template.Must(template.New("test").Funcs(template.FuncMap{ - "hd": hd, - "title": strings.Title, - "join": strings.Join, - "list": func(strs []string) string { return strings.Join(strs, ",") }, - }).Parse(string(bytes))) - - // 执行模板,填充数据 - var args = map[string]interface{}{ - "cmd": []string{"\\game\\role_port\\get_info"}, - "desc": []string{"获取数据1", "获取数据2"}, - "module": []string{"peak_arena_port"}, - "func": []string{"get_info"}, - //"args": []string{"game", "1", "2"}, - "reconnect": []string{"1"}, - "fun_id": []string{"98"}, - "pre_proto": []string{"pub_proto"}, - "pre_message": []string{"single_int"}, - } - err := t.Execute(os.Stdout, args) - fmt.Println(err) -} - -func hd(str []string) string { - return str[0] + cmd.Execute() } diff --git a/run/run.go b/run/run.go deleted file mode 100644 index 8bca287..0000000 --- a/run/run.go +++ /dev/null @@ -1,56 +0,0 @@ -package run - -import ( - "complie-erlang/config" - "gopkg.in/yaml.v2" - "log" - "os" -) - -type ConfigGenerator struct { - config *config.GeneratorConfig -} - -func NewConfigGenerator(cfg *config.GeneratorConfig) *ConfigGenerator { - return &ConfigGenerator{config: cfg} -} - -func (g *ConfigGenerator) Generate() error { - return nil -} - -func Run1() { - // 加载配置 - cfg := loadConfig() - - generator := NewConfigGenerator(cfg) - if err := generator.Generate(); err != nil { - log.Fatalf("Error generating config: %v", err) - } -} - -func loadConfig() *config.GeneratorConfig { - configFile := "config.yaml" - if len(os.Args) > 1 { - configFile = os.Args[1] - } - - if _, err := os.Stat(configFile); os.IsNotExist(err) { - log.Printf("Config file not found, using default config") - return config.DefaultConfig() - } - - data, err := os.ReadFile(configFile) - if err != nil { - log.Printf("Failed to read config file, using default: %v", err) - return config.DefaultConfig() - } - - var cfg config.GeneratorConfig - if err := yaml.Unmarshal(data, &cfg); err != nil { - log.Printf("Failed to parse config file, using default: %v", err) - return config.DefaultConfig() - } - - return &cfg -} diff --git a/template/template_engine.go b/template/template_engine.go index be7fb77..cdfc85d 100644 --- a/template/template_engine.go +++ b/template/template_engine.go @@ -1,14 +1,12 @@ package template import ( - "os" - "path/filepath" "strings" "text/template" ) type Template struct { - Templates map[string]*template.Template + GlobTemplate *template.Template } var DefaultFuncMap = template.FuncMap{ @@ -23,33 +21,24 @@ func hd(str []string) string { } func NewTemplate() *Template { - return &Template{ - Templates: make(map[string]*template.Template), - } + return &Template{} } -func (t *Template) Load(dir string) error { - files, err := os.ReadDir(dir) +func (t *Template) ParseGlob(pattern string) error { + parse, err := template.New(""). + Funcs(DefaultFuncMap).ParseGlob(pattern) if err != nil { return err } - for _, file := range files { - if file.IsDir() { - continue - } - if strings.HasSuffix(file.Name(), ".tpl") { - templateName := strings.TrimSuffix(file.Name(), ".tpl") - path := filepath.Join(dir, file.Name()) - bytes, err := os.ReadFile(path) - if err != nil { - return err - } - parse, err := template.New(templateName).Funcs(DefaultFuncMap).Parse(string(bytes)) - if err != nil { - return err - } - t.Templates[templateName] = parse - } - } + t.GlobTemplate = template.Must(parse, nil) return nil } + +func (t *Template) ExecuteTemplate(templateName2 string, data interface{}) (string, error) { + var buf strings.Builder + err := t.GlobTemplate.ExecuteTemplate(&buf, templateName2, data) + if err != nil { + return "", err + } + return buf.String(), nil +} diff --git a/templates/port.tpl b/templates/port.tpl deleted file mode 100644 index 5caafb2..0000000 --- a/templates/port.tpl +++ /dev/null @@ -1,11 +0,0 @@ -%% ---------------------------------------------------------------------------------- -{{if .desc}}%% {{hd .desc}} {{end}} -{template, {{.template}}, { {{.project}}, "{{hd .cmd}}", [ - {{if .reconnect}} { reconnect_db, msg_start, [] }, - {{end}} {{if .fun_id}}{ fun_open_check, check, [{{hd .fun_id}}] }, {{end}} - {{if .pre_message}} { pre_port, decode, [{{hd .pre_proto }}, {{hd .pre_message}}] }, {{end}} - {{if .reconnect}} { {{hd .module}}, {{hd .func}}, [{{join .args ","}}] }, - { reconnect_db, msg_end, [] } {{else}} { {{hd .module}}, {{hd .func}}, [] } -{{end}} -]}}. -%% ----------------------------------------------------------------------------------- diff --git a/worker/single_file.go b/worker/single_file.go new file mode 100644 index 0000000..1ad8769 --- /dev/null +++ b/worker/single_file.go @@ -0,0 +1,134 @@ +package worker + +import ( + "bufio" + "complie-erlang/config" + "complie-erlang/parser" + "complie-erlang/template" + "fmt" + "os" + "path/filepath" + "strings" +) + +type SingleFile struct { + templater *template.Template +} + +func NewSingleFile(templater *template.Template) *SingleFile { + return &SingleFile{ + templater: templater, + } +} + +func (s *SingleFile) ParseTemKey(filename string, Keyword config.ErlangTemKey) ([]string, error) { + + erlangFile, err := parser.ParseErlangFile(filename) + if err != nil { + return nil, err + } + + var result []string + for _, function := range erlangFile.Functions { + if len(function.KeyMap[Keyword.Name]) == 0 { + continue + } + var argsMap = map[string]any{ + "module": []string{erlangFile.ModuleName}, + "func": []string{function.Name}, + } + + for key, arg := range function.KeyMap { + if key == Keyword.Name { + for key1, arg1 := range arg { + argsMap[key1] = arg1 + } + continue + } + if len(arg) == 0 { + arg["is"] = []string{"1"} + argsMap[key] = arg + continue + } + argsMap[key] = arg + } + + for _, cfgPublicArg := range Keyword.DefaultArgs { + argsMap[cfgPublicArg.Key] = cfgPublicArg.Value + } + executeTemplate, err := s.templater.ExecuteTemplate(Keyword.MainTemplate, argsMap) + if err != nil { + return nil, err + } + result = append(result, strings.TrimSpace(removeEmptyLinesUniversal(executeTemplate))) + } + return result, nil +} +func removeEmptyLinesUniversal(text string) string { + var result strings.Builder + scanner := bufio.NewScanner(strings.NewReader(text)) + + for scanner.Scan() { + line := scanner.Text() + if strings.TrimSpace(line) != "" { + result.WriteString(line) + result.WriteString("\n") + } + } + + return strings.TrimSpace(result.String()) +} + +// FindConfigXMLPath 1. 打印当前 exe 文件夹内的 config.xml 文件的绝对路径 +func (s *SingleFile) FindConfigXMLPath(cfgFile string) (string, error) { + // 获取可执行文件所在目录 + exePath, err := os.Executable() + if err != nil { + return "", fmt.Errorf("获取可执行文件路径失败: %v", err) + } + exeDir := filepath.Dir(exePath) + + configPath := filepath.Join(exeDir, cfgFile) + + // 检查文件是否存在 + if _, err := os.Stat(configPath); err == nil { + absPath, err := filepath.Abs(configPath) + if err != nil { + return "", fmt.Errorf("获取绝对路径失败: %v", err) + } + return absPath, nil + } else { + return "", fmt.Errorf("%s 文件不存在于: %s\n", cfgFile, exeDir) + } +} + +// FindPatternErlFiles 2. 打印当前目录下符合 "*_port.erl" 的全部文件的文件名 +func (s *SingleFile) FindPatternErlFiles(patternFile string) ([]string, error) { + currentDir, err := os.Getwd() + if err != nil { + return nil, err + } + + pattern := filepath.Join(currentDir, patternFile) + files, err := filepath.Glob(pattern) + if err != nil { + return nil, err + } + return files, nil +} + +// FindPluginCfgFiles 3. 打印当前目录的绝对路径中最近的 plugin 文件夹下第一级与当前目录同名的文件夹中的 .cfg 文件的绝对路径 +func (s *SingleFile) FindPluginCfgFiles(sep string, dir, currentFile string) (string, error) { + //sep := "plugin\\game" + + // 使用系统路径分隔符进行分割 + pathParts := strings.Split(currentFile, sep) + + if len(pathParts) < 2 { + return "", fmt.Errorf("未找到插件目录") + } + + // 查找目标路径下的所有 .cfg 文件 + pattern := filepath.Join(pathParts[0], sep, dir) + return pattern, nil +}