commit ca040bc2b96fac033ca8e8205b53250effdb06c1 Author: Kaxi <1042864399@qq.com> Date: Wed Sep 24 00:54:08 2025 +0800 初版提交 diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..db8dae8 --- /dev/null +++ b/config.yaml @@ -0,0 +1,29 @@ +# 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 new file mode 100644 index 0000000..bcbd7d9 --- /dev/null +++ b/config/erlang_gen_cfg.go @@ -0,0 +1,43 @@ +package config + +type ErlangGeneratorCfg struct { + TemplateDir string `yaml:"template_dir" json:"template_dir"` // 模板文件存放地址 + Keywords []ErlangTemKey `yaml:"keywords" json:"keywords"` +} + +type ErlangTemKey struct { + 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"` // 默认模板参数 +} + +type DefaultArg struct { + Key string `yaml:"key" json:"key"` + Value string `yaml:"val" json:"Value"` +} + +func DefaultErlConfig() *ErlangGeneratorCfg { + return &ErlangGeneratorCfg{ + TemplateDir: "./templates", + Keywords: []ErlangTemKey{ + { + MainTemplate: "port.tpl", + Filename: "*_port.erl", + OutputDir: "output", + OutFileExt: ".cfg", + DefaultArgs: []DefaultArg{ + { + Key: "template", + Value: "_Z_SESSION", + }, + { + Key: "project", + Value: "Project", + }, + }, + }, + }, + } +} diff --git a/config/generator_config.go b/config/generator_config.go new file mode 100644 index 0000000..f135201 --- /dev/null +++ b/config/generator_config.go @@ -0,0 +1,42 @@ +// 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 new file mode 100644 index 0000000..60d2456 --- /dev/null +++ b/examples/peak_arena_port.erl @@ -0,0 +1,518 @@ +%%%------------------------------------------------------------------- +%%% @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 new file mode 100644 index 0000000..419a63b --- /dev/null +++ b/examples/sample.erl @@ -0,0 +1,13 @@ +%% 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 new file mode 100644 index 0000000..aa3b7b5 --- /dev/null +++ b/examples/templates/config_template.tplerl @@ -0,0 +1,36 @@ +%% 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 new file mode 100644 index 0000000..15a117b --- /dev/null +++ b/examples/templates/game_port.tpl @@ -0,0 +1,11 @@ +%% ---------------------------------------------------------------------------------- +{{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 new file mode 100644 index 0000000..3362e61 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module complie-erlang + +go 1.23.4 + +require gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..7534661 --- /dev/null +++ b/go.sum @@ -0,0 +1,3 @@ +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= diff --git a/main.go b/main.go new file mode 100644 index 0000000..a7c367c --- /dev/null +++ b/main.go @@ -0,0 +1,74 @@ +// main.go +package main + +import ( + "complie-erlang/config" + "complie-erlang/parser" + tm "complie-erlang/template" + "fmt" + "log" + "os" + "strings" + "text/template" +) + +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] +} diff --git a/parser/erlang_function.go b/parser/erlang_function.go new file mode 100644 index 0000000..89b7bea --- /dev/null +++ b/parser/erlang_function.go @@ -0,0 +1,58 @@ +package parser + +import ( + "regexp" + "strings" +) + +// ErlangFunction 表示 Erlang 函数 +type ErlangFunction struct { + Name string // 函数名 + Arity int // 参数个数 + Parameters []string // 参数列表 + Comments []string // 函数注释 + StartLine int // 函数起始行号 + EndLine int // 函数结束行号 + Export bool // 是否被导出 + KeyMap map[string]map[string][]string // 注解 +} + +func (function *ErlangFunction) ParseComments() ErlangFunction { + var keyMap = make(map[string]map[string][]string) + //var parameters = make(map[string]string) + + for _, comment := range function.Comments { + // 匹配注解格式: @keyword(param1=value1, param2=value2) + re := regexp.MustCompile(`@(\w+)(?:\s*\((.*)\))?`) + matches := re.FindStringSubmatch(comment) + + if len(matches) < 2 { + continue + } + + keyword := matches[1] + parameters, is := keyMap[keyword] + if !is { + parameters = make(map[string][]string) + } + + // 解析参数 + if len(matches) > 2 && matches[2] != "" { + paramsStr := matches[2] + paramRe := regexp.MustCompile(`(\w+)\s*=\s*('[^']*'|"[^"]*"|[^,]+)`) + paramMatches := paramRe.FindAllStringSubmatch(paramsStr, -1) + + for _, match := range paramMatches { + if len(match) >= 3 { + value := strings.TrimSpace(match[2]) + // 移除引号 + value = strings.Trim(value, `'"`) + parameters[strings.TrimSpace(match[1])] = append(parameters[strings.TrimSpace(match[1])], value) + } + } + } + keyMap[keyword] = parameters + } + function.KeyMap = keyMap + return *function +} diff --git a/parser/erlang_module.go b/parser/erlang_module.go new file mode 100644 index 0000000..367ddf7 --- /dev/null +++ b/parser/erlang_module.go @@ -0,0 +1,175 @@ +package parser + +import ( + "fmt" + "os" + "regexp" + "strings" +) + +// ModuleInfo 表示 Erlang 模块信息 +type ModuleInfo struct { + ModuleName string + Functions []ErlangFunction + FilePath string +} + +// ParseErlangFile 解析 Erlang 文件 +func ParseErlangFile(filePath string) (*ModuleInfo, error) { + content, err := os.ReadFile(filePath) + if err != nil { + return nil, fmt.Errorf("读取文件失败: %v", err) + } + + lines := strings.Split(string(content), "\n") + moduleInfo := &ModuleInfo{ + FilePath: filePath, + } + + // 提取模块名 + moduleInfo.ModuleName = extractModuleName(lines) + + // 提取导出函数列表 + exportedFunctions := extractExportedFunctions(lines) + + // 解析函数 + moduleInfo.Functions = parseFunctions(lines, exportedFunctions) + + return moduleInfo, nil +} + +// 提取模块名 +func extractModuleName(lines []string) string { + moduleRegex := regexp.MustCompile(`^-module\(([^)]+)\)\.`) + for _, line := range lines { + matches := moduleRegex.FindStringSubmatch(line) + if len(matches) > 1 { + return strings.Trim(matches[1], " '\"") + } + } + return "" +} + +// 提取导出函数列表 +func extractExportedFunctions(lines []string) map[string]bool { + exported := make(map[string]bool) + + // 匹配 -export([...]) 格式 + exportRegex := regexp.MustCompile(`-export\(\[([^]]+)]\)`) + functionRegex := regexp.MustCompile(`(\w+)/(\d+)`) + + for _, line := range lines { + if matches := exportRegex.FindStringSubmatch(line); len(matches) > 1 { + exports := strings.Split(matches[1], ",") + for _, export := range exports { + export = strings.TrimSpace(export) + if funcMatches := functionRegex.FindStringSubmatch(export); len(funcMatches) > 2 { + functionKey := fmt.Sprintf("%s/%s", funcMatches[1], funcMatches[2]) + exported[functionKey] = true + } + } + } + } + return exported +} + +// 解析所有函数 +func parseFunctions(lines []string, exportedFunctions map[string]bool) []ErlangFunction { + var functions []ErlangFunction + var currentComments []string + inFunction := false + var currentFunction ErlangFunction + braceCount := 0 + parenCount := 0 + + for i, line := range lines { + trimmedLine := strings.TrimSpace(line) + + // 收集注释 + if strings.HasPrefix(trimmedLine, "%") { + comment := strings.TrimPrefix(trimmedLine, "%") + comment = strings.TrimSpace(comment) + currentComments = append(currentComments, comment) + continue + } + + // 检测函数开始 + if !inFunction && isFunctionStart(trimmedLine) { + if funcInfo := parseFunctionSignature(trimmedLine); funcInfo != nil { + inFunction = true + currentFunction = *funcInfo + currentFunction.Comments = append([]string(nil), currentComments...) + currentFunction.StartLine = i + 1 + currentFunction.Export = isExported(currentFunction, exportedFunctions) + + // 重置注释收集 + currentComments = nil + braceCount = 0 + parenCount = 0 + } + } + + if inFunction { + // 统计括号和花括号来检测函数结束 + braceCount += strings.Count(line, "{") - strings.Count(line, "}") + parenCount += strings.Count(line, "(") - strings.Count(line, ")") + + // 函数结束条件:行以 . 结束,且括号和花括号匹配 + if strings.HasSuffix(trimmedLine, ".") && braceCount == 0 && parenCount == 0 { + currentFunction.EndLine = i + 1 + functions = append(functions, currentFunction.ParseComments()) + inFunction = false + currentFunction = ErlangFunction{} + } + } else { + // 不在函数中时,遇到非注释行就清空注释缓存 + if trimmedLine != "" && !strings.HasPrefix(trimmedLine, "%") { + currentComments = nil + } + } + } + + return functions +} + +// 检测是否为函数开始行 +func isFunctionStart(line string) bool { + // 匹配函数定义模式: 函数名(参数) -> 或 函数名(参数) when ... -> + functionPattern := `^(\w+)\([^)]*\)\s*(when\s+[^>]*)?->` + matched, _ := regexp.MatchString(functionPattern, line) + return matched +} + +// 解析函数签名 +func parseFunctionSignature(line string) *ErlangFunction { + // 匹配函数名和参数 + pattern := `^(\w+)\(([^)]*)\)\s*(when\s+[^>]*)?->` + regex := regexp.MustCompile(pattern) + matches := regex.FindStringSubmatch(line) + + if len(matches) < 3 { + return nil + } + + function := &ErlangFunction{ + Name: matches[1], + } + + // 解析参数 + params := strings.Split(matches[2], ",") + for _, param := range params { + param = strings.TrimSpace(param) + if param != "" { + function.Parameters = append(function.Parameters, param) + } + } + function.Arity = len(function.Parameters) + + return function +} + +// 检查函数是否被导出 +func isExported(function ErlangFunction, exportedFunctions map[string]bool) bool { + key := fmt.Sprintf("%s/%d", function.Name, function.Arity) + return exportedFunctions[key] +} diff --git a/run/run.go b/run/run.go new file mode 100644 index 0000000..8bca287 --- /dev/null +++ b/run/run.go @@ -0,0 +1,56 @@ +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 new file mode 100644 index 0000000..be7fb77 --- /dev/null +++ b/template/template_engine.go @@ -0,0 +1,55 @@ +package template + +import ( + "os" + "path/filepath" + "strings" + "text/template" +) + +type Template struct { + Templates map[string]*template.Template +} + +var DefaultFuncMap = template.FuncMap{ + "hd": hd, + "title": strings.Title, + "join": strings.Join, + "list": func(strs []string) string { return strings.Join(strs, ",") }, +} + +func hd(str []string) string { + return str[0] +} + +func NewTemplate() *Template { + return &Template{ + Templates: make(map[string]*template.Template), + } +} + +func (t *Template) Load(dir string) error { + files, err := os.ReadDir(dir) + 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 + } + } + return nil +} diff --git a/templates/port.tpl b/templates/port.tpl new file mode 100644 index 0000000..5caafb2 --- /dev/null +++ b/templates/port.tpl @@ -0,0 +1,11 @@ +%% ---------------------------------------------------------------------------------- +{{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}} +]}}. +%% -----------------------------------------------------------------------------------