%%% ----------------------------------------------------
%%% 协议映射
%%% @author huangyongxing@yeah.net
%%% ----------------------------------------------------
-module(protocol_routing).
-export([
        conn_routing/4
        ,do_routing/5
        ,map/1
    ]).
-include("conn.hrl").
-include("common.hrl").
-include("errcode.hrl").
-include("def_fun.hrl").

-compile({
        inline,
        [proto_mod/1]
    }).

proto_mod(CmdType) when CmdType >= 100 andalso CmdType =< 655 ->
    list_to_atom( lists:concat(["pt_", CmdType]) );
proto_mod(_) ->
    error.

-spec map(CmdType :: integer()) -> Result when
    Result :: {Processer :: role | conn, ProtoMod :: atom(), Mod :: atom()} | error.
map(CmdType) ->
    case sub_map(CmdType) of
        {Processer, CallMod} ->
            ProtoMod = proto_mod(CmdType),
            {Processer, ProtoMod, CallMod};
        _ ->
            error
    end.

sub_map(100) -> {conn, pp_login};               %% 登录
sub_map(102) -> {role, pp_game};                %% 游戏控制
sub_map(103) -> {role, pp_czone};               %% 跨服分区
sub_map(104) -> {role, pp_treasure_house};      %% 珍宝阁
sub_map(110) -> {role, pp_chat};                %% 聊天
sub_map(111) -> {role, pp_gm};                  %% GM命令
sub_map(112) -> {role, pp_dress_up};            %% 装扮
sub_map(113) -> {role, pp_offline_hosting};     %% 离线托管
sub_map(114) -> {role, pp_newer};               %% 新手引导
sub_map(120) -> {role, pp_scene};               %% 场景
sub_map(121) -> {role, pp_npc};                 %% NPC
sub_map(130) -> {role, pp_player};              %% 玩家信息
sub_map(132) -> {role, pp_onhook};              %% 离线挂机设置
sub_map(137) -> {role, pp_drum};                %% 钻石大战
sub_map(138) -> {role, pp_journey};             %% 征途活动
sub_map(139) -> {role, pp_nucleon};             %% 灵能装甲
sub_map(140) -> {role, pp_relationship};        %% 好友
sub_map(141) -> {role, pp_unite_buff};          %% 联合buff
sub_map(142) -> {role, pp_glamour};             %% 跑马
sub_map(143) -> {role, pp_warsoul};             %% 战魂
sub_map(144) -> {role, pp_uranium};             %% 魂力
sub_map(145) -> {role, pp_equipment_check};     %% 装备考核
sub_map(146) -> {role, pp_foster};              %% 进阶系统
sub_map(147) -> {role, pp_visus};               %% 幻光系统
sub_map(148) -> {role, pp_galaxy};              %% 星辰系统
sub_map(149) -> {role, pp_mate};                %% 羁绊系统
sub_map(150) -> {role, pp_goods};               %% 物品
sub_map(151) -> {role, pp_compose};             %% 物品合成
sub_map(152) -> {role, pp_equipment};           %% 装备系统
sub_map(153) -> {role, pp_shop};                %% 商城
sub_map(154) -> {role, pp_auction};             %% 拍卖
sub_map(155) -> {role, pp_market};              %% 交易市场
sub_map(157) -> {role, pp_activitycalen};       %% 活动日历
sub_map(158) -> {role, pp_recharge};            %% 充值界面
sub_map(159) -> {role, pp_recharge_act};        %% 充值活动
sub_map(160) -> {role, pp_welfare};             %% 福利大厅
sub_map(163) -> {role, pp_pet};                 %% 宠物
sub_map(165) -> {role, pp_child};               %% 孩子
sub_map(166) -> {role, pp_degree};              %% 学位
sub_map(170) -> {role, pp_capsule_egg};         %% 扭蛋
sub_map(173) -> {role, pp_god};                 %% 唤神
sub_map(175) -> {role, pp_login_reward};        %% 七天登录
sub_map(176) -> {role, pp_seven_days_goal};     %% 七日目标
sub_map(177) -> {role, pp_fishing};             %% 钓鱼
sub_map(182) -> {role, pp_module_advance};      %% 功能预告
sub_map(190) -> {role, pp_mail};                %% 邮件
sub_map(200) -> {role, pp_battle};              %% 战斗
sub_map(210) -> {role, pp_skill};               %% 技能
sub_map(215) -> {role, pp_dun_multi};           %% 跨服多人组队
sub_map(240) -> {role, pp_team};                %% 队伍
sub_map(221) -> {role, pp_common_rank};         %% 榜单
sub_map(223) -> {role, pp_flower};              %% 鲜花
sub_map(224) -> {role, pp_flower_act};          %% 鲜花结婚榜活动
sub_map(225) -> {role, pp_rush_rank};           %% 开服冲榜活动
sub_map(280) -> {role, pp_arena};                 %% 竞技
sub_map(281) -> {role, pp_top_pk};              %% 巅峰竞技
sub_map(282) -> {role, pp_role_view};           %% 查看角色信息
sub_map(300) -> {role, pp_task};                %% 任务
sub_map(331) -> {role, pp_custom_act};          %% 定制活动
sub_map(332) -> {role, pp_custom_act};          %% 定制活动
sub_map(333) -> {role, pp_race_rank};           %% 跨服竞榜活动
sub_map(334) -> {role, pp_sakura_gift};         %% 源樱之礼
sub_map(335) -> {role, pp_act_turntable};       %% 源能转盘
sub_map(336) -> {role, pp_custom_act};          %% 定制活动
sub_map(339) -> {role, pp_red_envelopes};       %% 红包
sub_map(340) -> {role, pp_currencywish};        %% 货币祈愿
sub_map(400) -> {role, pp_guild};               %% 帮派
sub_map(404) -> {role, pp_guild_labor};         %% 社团劳务
sub_map(405) -> {role, pp_guild_war};           %% 本服公会战
sub_map(406) -> {role, pp_guild_boss};          %% 社团BOSS
sub_map(407) -> {role, pp_guild_race_rank};     %% 社团竞速
sub_map(408) -> {role, pp_guild_collect};       %% 社团午间采集
sub_map(409) -> {role, pp_achievement};         %% 成就
sub_map(410) -> {role, pp_camp_war};            %% 跨服团战
sub_map(411) -> {role, pp_designation};         %% 称号
sub_map(413) -> {role, pp_fashion};             %% 时装
sub_map(414) -> {role, pp_marble};              %% 附能寻宝
sub_map(415) -> {role, pp_madness_land};        %% 狂战领域
sub_map(416) -> {role, pp_beauty_contest};      %% 靓丽大赛
sub_map(417) -> {role, pp_guild_run_assist};    %% 跑环协助
sub_map(418) -> {role, pp_charm_beach};         %% 魅力海滩
sub_map(419) -> {role, pp_resource_back};       %% 回归
sub_map(420) -> {role, pp_investment};          %% 投资活动
sub_map(421) -> {role, pp_workroom};            %% 时装工坊
sub_map(422) -> {role, pp_wardrobe};            %% 衣橱
sub_map(424) -> {role, pp_treasure_map};        %% 藏宝图
sub_map(425) -> {role, pp_dance};               %% 舞姿
sub_map(426) -> {role, pp_rename};              %% 重命名
sub_map(435) -> {role, pp_live_skill};          %% 生活技能系统
sub_map(450) -> {role, pp_vip};                 %% vip
sub_map(451) -> {role, pp_sup_vip};             %% 贵族
sub_map(452) -> {role, pp_elite_assessment};    %% 精英考核
sub_map(459) -> {role, pp_jump_act};            %% 跳一跳
sub_map(460) -> {role, pp_local_boss};          %% 本服BOSS
sub_map(461) -> {role, pp_local_boss};          %% 废都BOSS
sub_map(462) -> {role, pp_local_boss};          %% 幻魔之家
sub_map(463) -> {role, pp_exp_sea};             %% 经验海
sub_map(500) -> {role, pp_convoy};              %% 护送
sub_map(501) -> {role, pp_limit_goal};          %% 限时目标
sub_map(600) -> {role, pp_void_fam};            %% 无尽领域
sub_map(601) -> {role, pp_cross_guild_war};     %% 跨服帮战
sub_map(602) -> {role, pp_wasteland_war};       %% 废土战场(饥饿游戏)
sub_map(603) -> {role, pp_legion};              %% 跨服战团
sub_map(604) -> {role, pp_cross_point_fight};   %% 跨服沙盘
sub_map(610) -> {role, pp_dungeon};             %% 副本
sub_map(611) -> {role, pp_dungeon};             %% 副本
sub_map(621) -> {role, pp_kf_1vn};              %% 1vN
sub_map(650) -> {role, pp_3v3};                 %% 跨服3v3
sub_map(_)   -> error.

%% 客户端SOCKET连接进程协议分发处理
conn_routing(_ClientType, Cmd, Bin, ConnState = #conn{pid_msg_handler = Pid}) ->
    case check_cmd_cd(Cmd) of
        true ->
            CmdType = Cmd div 100,
            case map(CmdType) of
                {conn, ProtoMod, Mod} ->
                    do_routing(ProtoMod, Mod, Cmd, Bin, ConnState);
                {role, ProtoMod, Mod} when is_pid(Pid) ->
                    gen_server:cast(Pid, {'SOCKET_EVENT', self(), ProtoMod, Mod, Cmd, Bin}),
                    wait;
                {role, _, _} ->
                    ?ERR_TTY("Access Denied, Request invalid! [~w]", [Cmd]),
                    error;
                _Error ->
                    ?ERR_TTY("cmd error, invalid protocol! [~w]", [Cmd]),
                    _Error
            end;
        {false, RestCdTime} ->
            %% TODO ERR110_CD_LIMIT 暂时先借用这边类似的编号，有可能要再改
            {Code, CodeArgs} = util:parse_error_code({?ERRCODE(err102_too_frequent), [util:ceil(RestCdTime/1000)]}),
            {ok, BinData} = pt_102:write(10205, [Code, CodeArgs]),
            gen_server:cast(Pid, {send_cmd_msg, BinData}),
            ?DEBUG_TTY("cmd cd error ! in cooling [~w]", [Cmd]),
            ignore
    end.

do_routing(ProtoMod, Mod, Cmd, Bin, State) ->
    case ProtoMod:read(Cmd, Bin) of
        {ok, Data} ->
            % pp_tracer:trace(Mod, Cmd, Data),
            Mod:handle(Cmd, State, Data);
        _Other ->
            ?ERR_TTY("[~w][~p]read unmatch:[~w]", [Cmd, ProtoMod, _Other]),
            unmatch_cmd
    end.

check_cmd_cd(Cmd) ->
    CdTime = cmd_cd_time(Cmd),
    case CdTime > 0 of
        false -> true;
        true  ->
            NowTime  = utime:unixtime(ms),
            LastTime =
            case get({cmd_request_time, Cmd}) of
                undefined -> 0;
                Time -> Time
            end,
            case NowTime - LastTime >= CdTime of
                true  ->
                    put({cmd_request_time, Cmd}, NowTime),
                    true;
                false ->
                    RestCdTime = max(round((CdTime - (NowTime - LastTime)) / 1000), 0),
                    {false, RestCdTime}
            end
    end.

%% 特定协议请求间隔时间（单位:ms）
cmd_cd_time(10300) -> 5000;         % 跨服分区状态
cmd_cd_time(10301) -> 5000;         % 跨服分区预告
cmd_cd_time(10302) -> 5000;         % 跨服分区进度
cmd_cd_time(12033) -> 200;          % 小飞鞋使用
cmd_cd_time(13004) -> 100;          % 查询玩家信息
cmd_cd_time(14013) -> 10000;        % 好友推荐
cmd_cd_time(14021) -> 100;          % 好友状态
cmd_cd_time(14024) -> 1500;         % 查询好友形象
cmd_cd_time(15004) -> 5000;         % 整理背包
cmd_cd_time(15501) -> 100;
cmd_cd_time(17719) -> 2000;
cmd_cd_time(19006) -> 15000;        % 公会邮件
cmd_cd_time(24006) -> 300;          % 邀请入队
cmd_cd_time(24020) -> 3000;         % 发起投票
cmd_cd_time(28002) -> 1000;         % 竞技随机对手
cmd_cd_time(28003) -> 1000;         % 竞技挑战
cmd_cd_time(40003) -> 60000;        % 公会申请
cmd_cd_time(40401) -> 8000;         % 弹珠寻宝
cmd_cd_time(33245) -> 300;          % 刮刮卡
cmd_cd_time(22301) -> 100;          % 赠送鲜花
cmd_cd_time(28110) -> 2000;         % 决战之巅匹配
cmd_cd_time(28114) -> 2000;         % 决战之巅取消匹配
cmd_cd_time(40241) -> 10000;        % 公会争霸快捷信息
cmd_cd_time(40313) -> 5000;         % 篝火召集
cmd_cd_time(41401) -> 3000;         % 器灵寻宝
cmd_cd_time(41715) -> 3000;         % 领取礼包卡奖励
cmd_cd_time(60200) -> 100;          % 废土查询活动状态(防协议频发)
cmd_cd_time(60205) -> 100;          % 废土查询排行榜(防协议频发)
cmd_cd_time(60410) -> 1000;         % 退出勾玉
cmd_cd_time(40317) -> 10000;        % 公会争霸-使用技能
cmd_cd_time(40319) -> 5000;         % 公会争霸-发出召集
cmd_cd_time(60903) -> 1000;         % 跨服入侵
cmd_cd_time(62118) -> 3000;         % 1vN押注
cmd_cd_time(62126) -> 5000;         % 1vN拍卖
cmd_cd_time(60510) -> 5000;         % 荣耀战神召集
cmd_cd_time(60012) -> 8000;         % 号令CD
cmd_cd_time(_)     -> 0.

