// 排行榜前三名数组 默认数据 local Ranklist = { "1": { "rank": 100, "characname": "帝尊天穹", "job": 0, "lev": 60, "Grow": 4, "Guilkey": 0, "GuildName": "诸神之荣丶", "str": "", "equip": [0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0] }, "2": { "rank": 90, "characname": "圣皇极境", "job": 1, "lev": 60, "Grow": 4, "Guilkey": 0, "GuildName": "诸神之荣丶", "str": "", "equip": [0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0] }, "3": { "rank": 80, "characname": "神王之巅", "job": 2, "lev": 60, "Grow": 4, "Guilkey": 0, "GuildName": "诸神之荣丶", "str": "", "equip": [0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0] } }; /** * 获得rank分(排名分数) * 根据配置选择不同的数据库获取战力值 * @param {string} charac_no * @returns 返回对应的战力值 */ function GetRankNumberBynangua(charac_no) { local Config = GlobalConfig.Get("战力榜配置_南瓜.json"); local currentDB = Config["战力榜配置"]["当前选择"]; local dbConfig = Config["战力榜配置"]["数据库选择"][currentDB]; local SqlObj = MysqlPool.GetInstance().GetConnect(); // 构建查询语句 - 直接使用角色ID查询 local insertQuery = "SELECT " + dbConfig["字段名"] + " FROM " + dbConfig["数据库名"] + "." + dbConfig["表名"] + " WHERE " + dbConfig["条件字段"] + "=" + charac_no; local column_type_list = ["string"]; local result = SqlObj.Select(insertQuery, column_type_list); MysqlPool.GetInstance().PutConnect(SqlObj); if (result.len() > 0) { return result[0][0].tointeger(); } return 0; } //获取个人信息 function GetMyEquInfo(SUser) { local MyRanklist = { "rank": 0, "characname": "", "job": 0, "lev": 0, "Grow": 0, "Guilkey": 0, "GuildName": "", "str": "", "equip": [] }; local Config = GlobalConfig.Get("战力榜配置_南瓜.json"); // 检查CID是否在排除列表中 if ("角色CID" in Config["战力榜配置"]["排除名单"]) { foreach(excludedCID in Config["战力榜配置"]["排除名单"]["角色CID"]) { if (SUser.GetCID() == excludedCID) { return MyRanklist; } } } MyRanklist.rank = GetRankNumberBynangua(SUser.GetCID()); MyRanklist.characname = SUser.GetCharacName(); MyRanklist.job = SUser.GetCharacJob(); MyRanklist.lev = SUser.GetCharacLevel(); MyRanklist.Grow = Sq_CallFunc(S_Ptr("0x815741C"), "int", ["pointer"], SUser.C_Object); MyRanklist.Guilkey = Sq_CallFunc(S_Ptr("0x822F46C"), "int", ["pointer"], SUser.C_Object); MyRanklist.GuildName = SUser.GetGuildName(); if (MyRanklist.GuildName.len() == 0) { MyRanklist.GuildName = "天地会"; //当公会不存在时,设置默认公会名字 } local InvenObj = SUser.GetInven(); if (!InvenObj) { return; } if (InvenObj) { for (local i = 0; i <= 10; i++) { if (i != 9) { local clearAvatar = Sq_CallFunc(S_Ptr("0x0850D374"), "int", ["pointer", "int"], InvenObj.C_Object, i); local ItemObj = InvenObj.GetSlot(0, i); local item_id = clearAvatar > 0 ? clearAvatar : ItemObj.GetIndex(); MyRanklist.equip.push(item_id); } else { MyRanklist.equip.push(-1); } } } return MyRanklist; } // 玩家下线时,保存自身信息并且和排行榜进行排名 function SetRankingBynangua(SUser) { local IP = Rank_nangua.api_CUser_get_public_ip_address(SUser); if (IP == "10.0.0.1") { return; } local MyRanklist = GetMyEquInfo(SUser); local existingIndex = -1; foreach(index, rankInfo in Ranklist) { if (rankInfo.characname == MyRanklist.characname) { existingIndex = index; break; } } if (MyRanklist.rank > 0) { if (existingIndex != -1) { Ranklist[existingIndex] = MyRanklist; } else { if (!Ranklist.rawin("4")) { Ranklist["4"] <- {}; } Ranklist["4"] = MyRanklist; } local rankArray = []; foreach(key, value in Ranklist) { rankArray.append(value); } rankArray.sort(function(a, b) { return b.rank - a.rank; }); // 获取前三名玩家的信息 local topThree = rankArray.slice(0, 3); if (Ranklist.rawin("4")) { Ranklist.rawdelete("4"); } Ranklist = { "1": topThree[0], "2": topThree[1], "3": topThree[2] }; } } //清除排名的自定义留言信息 function DeleteSpecificMessage() { local G_CGameManager = Sq_CallFunc(S_Ptr("0x080cc18e"), "pointer", []); local Message = Sq_CallFunc(S_Ptr("0x08298EEC"), "pointer", ["pointer"], G_CGameManager); Sq_CallFunc(S_Ptr("0x08600D0C"), "char", ["pointer", "int"], Message, 1); Sq_CallFunc(S_Ptr("0x08600D0C"), "char", ["pointer", "int"], Message, 2); Sq_CallFunc(S_Ptr("0x08600D0C"), "char", ["pointer", "int"], Message, 3); } //发送留言信息 function UpdateServerMessageByBroadcast(SUser, Ranking, msg) { DeleteSpecificMessage() local Pack = Packet(); Pack.Put_Header(0, 192); Pack.Put_Byte(1); Pack.Put_Byte(1); Pack.Put_Byte(Ranking); Rank_nangua.api_InterfacePacketBuf_put_string(Pack, msg); Pack.Finalize(true); SUser.Send(Pack); Pack.Delete(); } function SendRanklistPacket(SUser, Ranklist, bool) { local Pack = Packet(); Pack.Put_Header(0, 182); local rankArray = [Ranklist["1"], Ranklist["2"], Ranklist["3"]]; Pack.Put_Byte(rankArray.len()); foreach(index, value in rankArray) { Rank_nangua.api_InterfacePacketBuf_put_string(Pack, value.characname); Pack.Put_Byte(value.lev); Pack.Put_Byte(value.job); Pack.Put_Byte(value.Grow); Rank_nangua.api_InterfacePacketBuf_put_string(Pack, value.GuildName + ""); Pack.Put_Int(value.Guilkey); for (local i = 0; i < value.equip.len(); i++) { Pack.Put_Int((i != 9) ? value.equip[i] : -1); } } Pack.Finalize(true); if (bool) { World.SendAll(Pack); } else { SUser.Send(Pack); } Pack.Delete(); } //因客户端原因,只有名称有变动或排名有变动时才会刷新外观,所以发送一次加空格的名字,然后删除空格再发送一次 function SendRankLists(SUser, bool) { local ip = Rank_nangua.api_CUser_get_public_ip_address(SUser); if (ip == "10.0.0.1") { return; } local Config = GlobalConfig.Get("战力榜配置_南瓜.json"); foreach(key, value in Ranklist) { value["characname"] = value["characname"] + " "; } SendRanklistPacket(SUser, Ranklist, bool); foreach(key, value in Ranklist) { value["characname"] = value["characname"].slice(0, value["characname"].find(" ")) + value["characname"].slice(value["characname"].find(" ") + 1); } //发送排名留言信息 UpdateServerMessageByBroadcast(SUser, 1, Config["战力榜配置"]["留言信息"]["第一名"]); UpdateServerMessageByBroadcast(SUser, 2, Config["战力榜配置"]["留言信息"]["第二名"]); UpdateServerMessageByBroadcast(SUser, 3, Config["战力榜配置"]["留言信息"]["第三名"]); SendRanklistPacket(SUser, Ranklist, bool); } class Rank_nangua { function api_InterfacePacketBuf_put_string(Pack, s) { local p = Memory.allocUtf8String(s); local len = s.len(); Pack.Put_Int(len); Pack.Put_BinaryEx(p.C_Object, len); } function api_CUser_get_public_ip_address(SUser){ local s_addr = Sq_CallFunc(S_Ptr("0x084EC90A"), "int", ["pointer"], SUser.C_Object); if(s_addr){ local inet_ntoa = Sq_CallFunc(S_Ptr("0x0807DDC0"), "pointer", ["int"], s_addr); return NativePointer(inet_ntoa).readUtf8String(); } return null; } } // 创建数据库和表 function createRankEventTable() { local CreateSql1 = "create database if not exists DP_S default charset utf8;"; local CreateSql2 = "CREATE TABLE IF NOT EXISTS DP_S.event (" + "event_id varchar(30) NOT NULL, " + "event_info mediumtext, " + "PRIMARY KEY (event_id)" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8;"; local SqlObj = MysqlPool.GetInstance().GetConnect(); SqlObj.Exec_Sql(CreateSql1); SqlObj.Exec_Sql(CreateSql2); MysqlPool.GetInstance().PutConnect(SqlObj); } // 保存战力榜数据到数据库 function saveRanklistToDatabase() { local SqlObj = MysqlPool.GetInstance().GetConnect(); local ranklistJson = Json.Encode(Ranklist); local query = "REPLACE INTO DP_S.event (event_id, event_info) VALUES ('ranklist', '" + ranklistJson + "')"; SqlObj.Select(query, []); MysqlPool.GetInstance().PutConnect(SqlObj); } // 从数据库加载战力榜数据 function loadRanklistFromDatabase() { local SqlObj = MysqlPool.GetInstance().GetConnect(); local query = "SELECT event_info FROM DP_S.event WHERE event_id = 'ranklist'"; local result = SqlObj.Select(query, ["string"]); if (result.len() > 0) { local savedRanklist = Json.Decode(result[0][0]); if (savedRanklist != null) { Ranklist = savedRanklist; } } MysqlPool.GetInstance().PutConnect(SqlObj); } // 服务器被Kill时(不含炸频道等)保存战力榜数据 Cb_Server_ClossByKill_Leave_Func.ServerClossByKill <- function(args) { local result = args.pop(); if (result <= 0) { saveRanklistToDatabase(); } } // 服务器异常崩溃时保存战力榜数据 Cb_Server_Close_Enter_Func.Server_Close <- function(args) { saveRanklistToDatabase(); } function _Dps_Rank_nangua_Main_() { local Config = GlobalConfig.Get("战力榜配置_南瓜.json"); local PoolObj = MysqlPool.GetInstance(); local Ip = Config["数据库IP 不是外置数据库不要更改"]; local Port = Config["数据库端口 不懂不要更改"]; local DbName = Config["数据库用户名 本地用户名不懂不要更改"]; local Password = Config["数据库密码 本地密码不懂不要更改"]; PoolObj.SetBaseConfiguration(Ip, Port, DbName, Password); PoolObj.PoolSize = 10; PoolObj.Init(); // 创建表 createRankEventTable(); // 加载战力榜数据 loadRanklistFromDatabase(); // 玩家下线时 Cb_CUser_LogoutToPCRoom_Enter_Func.ReturnSelectCharac <- function(args) { local SUser = User(args[0]); SetRankingBynangua(SUser); SendRankLists(SUser, false); }; //玩家登录时 Cb_reach_game_world_Func.RankByNangua <- function(SUser) { Timer.SetTimeOut(function(SUser) { SendRankLists(SUser, true); }, 3, SUser); }; }