Files
DP-S_Script/示例项目/战力榜/战力榜.nut
2026-04-16 16:27:53 +08:00

326 lines
9.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 排行榜前三名数组 默认数据
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);
};
}