/*
文件名:誉名录.nut
路径:_DPS_/_BuiltProject/誉名录/誉名录.nut
创建日期:2026-02-01	02:19
文件用途:
*/

class NewTitleC {


    MysqlObject = null;


    //数据
    data = null;

    constructor() {

        //创建数据库
        MysqlObject = Mysql(Str_Ptr("127.0.0.1"), 3306, Str_Ptr("taiwan_cain"), Str_Ptr("game"), Str_Ptr("uu5!^%jg"));
        MysqlObject.Exec_Sql(format("SET NAMES %s", "latin1"));

        local check_table_sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'newtitle';"
        local Ret = MysqlObject.Select(check_table_sql, ["int"]);
        if (Ret.len() == 0 || Ret[0][0] == 0) {
            local sql = "CREATE TABLE `taiwan_cain`.`newtitle` (`cid` int(11) NOT NULL,`data` text NULL,PRIMARY KEY (`cid`));";
            MysqlObject.Exec_Sql(sql);
        }


        //读取数据库数据到缓存
        InitMysqlData();
        //固化缓存数据到数据库
        SaveCacheData();



        //注册客户端收包
        RegisterClient();

        //注册GM命令
        Gm_InputFunc_Handle["Title"] <- function(SUser, CmdString) {
            local count = -1;
            local pos = 0;
            local handler = [];
            do {
                local start = pos;
                pos = CmdString.find(" ", pos + 1);
                if (pos != null) {
                    handler.append(CmdString.slice(start + 1, pos));
                } else
                    handler.append(CmdString.slice(start + 1));
                count = count + 1
            } while (pos != null)

            //得到空格数量
            if (count == 1) {
                AddTitle(SUser, handler[1]);
            }
        }.bindenv(this);

        //注册区域移动添加角色的Hook
        Cb_Area_insert_user_Leave.rawset("NewTitleC", function(args) {
            local UserList = World.GetAreaUserList(args[0]);
            if (UserList) {
                local ShowList = GenerateDrawInfo(UserList);
                foreach(AreaUser in UserList) {
                    AreaUser.SendJso({
                        op = 21012004,
                        ShowData = ShowList
                    });
                }
            }
        }.bindenv(this));

        //上线时 下发自己的渲染信息
        Cb_reach_game_world_Func.rawset("NewTitleC", function(SUser) {
            local ShowCidList = [SUser];
            local ShowList = GenerateDrawInfo(ShowCidList);
            SUser.SendJso({
                op = 21012004,
                ShowData = ShowList
            });
        }.bindenv(this));
    }

    function RegisterClient() {
        //查询自身称号簿数据
        ClientSocketPackFuncMap.rawset(21012001, function(SUser, Jso) {
            local SendInfo = {};
            local Cid = SUser.GetCID().tostring();
            if (data.rawin(Cid)) {
                SendInfo = data.rawget(Cid);
            }
            SUser.SendJso({
                op = 21012002,
                Info = SendInfo
            })
        }.bindenv(this));

        //保存称号簿配置
        ClientSocketPackFuncMap.rawset(21012003, function(SUser, Jso) {
            local SaveInfo = Jso.SendInfo;
            local SaveId = Jso.Id;
            local Cid = SUser.GetCID().tostring();
            //因为json传输过程会导致INT key变成string 所以这里的缓存里一律要使用string 的编号
            data[Cid].rawset(SaveId.tostring(), SaveInfo);
            RefreshAreaDrawInfo(SUser);
        }.bindenv(this));
    }


    //给玩家添加称号
    function AddTitle(SUser, TitleId) {
        local Cid = SUser.GetCID().tostring();
        if (!data.rawin(Cid)) {
            data.rawset(Cid, {});
        }
        data[Cid].rawset(TitleId, {
            IsDisplay = false,
            Scale = 1.0,
            XOffset = 0,
            YOffset = 0,
            ZOrder = 1
        })
    }

    //给玩家移除称号
    function RemoveTitle(SUser, TitleId) {
        local Cid = SUser.GetCID().tostring();
        if (!data.rawin(Cid)) {
            data.rawset(Cid, {});
        }
        data[Cid].rawdelete(TitleId);
    }

    //刷新角色区域内的渲染信息
    function RefreshAreaDrawInfo(SUser) {
        local Location = SUser.GetLocation();
        local Area = World.GetArea(Location.Town, Location.Area);
        local UserList = World.GetAreaUserList(Area);
        if (UserList) {
            local ShowList = GenerateDrawInfo(UserList);
            foreach(AreaUser in UserList) {
                AreaUser.SendJso({
                    op = 21012004,
                    ShowData = ShowList
                });
            }
        }
    }

    //生成指定List的渲染信息
    function GenerateDrawInfo(ShowCidList) {
        local ShowList = {};
        foreach(SUserObj in ShowCidList) {
            local Cid = SUserObj.GetCID().tostring();
            local ShowData = null;
            if (data.rawin(Cid)) {
                ShowData = data.rawget(Cid);
            }
            local Data = [];
            if (ShowData) {
                foreach(TitleId, RealData in ShowData) {
                    if (!RealData.IsDisplay) continue;
                    RealData.Id <- TitleId;
                    Data.push(RealData);
                }
            }
            Data.sort(function(a, b) {
                return a.ZOrder <=> b.ZOrder;
            });
            ShowList.rawset(SUserObj.GetUniqueId(), Data);
        }
        return ShowList.len() > 0 ? ShowList : null;
    }

    function InitMysqlData() {
        data = {};
        local Sql = "SELECT * FROM newtitle"
        local Ret = MysqlObject.Select(Sql, ["int", "string"]);
        foreach(Row in Ret) {
            local uid = Row[0];
            local jso = Json.Decode(Row[1]);
            data.rawset(uid, jso);
        }
    }

    function SaveCacheData() {
        //每5分钟固化一次数据到数据库
        Timer.RemoveCronTask("NewTitleC");
        Timer.SetCronTask(function() {
            local DataList = [];
            foreach(cid, value in data) {
                local str = format("(%s,'%s'),", cid.tostring(), Json.Encode(value));
                DataList.push(str);
            }
            local sql = "REPLACE INTO newtitle (cid, data) VALUES";
            foreach(value in DataList) {
                sql += value;
            }
            //去除最后一个,
            sql = sql.slice(0, -1);
            sql += ";";
            MysqlObject.Exec_Sql(sql);
        }.bindenv(this), {
            Cron = "* */5 * * * *",
            Name = "NewTitleC"
        });
    }
}


Timer.SetTimeOut(function() {

    getroottable()._NewTitle_ <- NewTitleC();
    print("誉名录 - 已加载");
}, 1);