添加示例项目
This commit is contained in:
326
示例项目/战力榜/战力榜.nut
Normal file
326
示例项目/战力榜/战力榜.nut
Normal file
@@ -0,0 +1,326 @@
|
||||
// 排行榜前三名数组 默认数据
|
||||
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);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user