Files
DP-S_Script/示例项目/SP_TP属性石返还/SP_TP属性石返还.nut
2026-04-16 16:27:53 +08:00

309 lines
13 KiB
Plaintext

// 创建数据库和表
function createAttributesTable() {
local Config = GlobalConfig.Get("SP_TP属性石返还_Nangua.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();
local CreateSql1 = "create database if not exists DP_S default charset utf8;";
local CreateSql2 = "CREATE TABLE IF NOT EXISTS DP_S.charac_attributes (" +
"id int(11) AUTO_INCREMENT, " +
"charac_no int(11) NOT NULL, " +
"item_id int(11) DEFAULT NULL, " +
"type int(11) DEFAULT NULL, " +
"guildExpBook int(11) DEFAULT NULL, " +
"total_sp int(11) DEFAULT 0, " +
"total_tp int(11) DEFAULT 0, " +
"PRIMARY KEY (id), " +
"UNIQUE KEY unique_char_item (charac_no, item_id)" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8;";
local SqlObj = MysqlPool.GetInstance().GetConnect();
SqlObj.Exec_Sql(CreateSql1);
SqlObj.Exec_Sql(CreateSql2);
MysqlPool.GetInstance().PutConnect(SqlObj);
}
// 初始化技能时返还SP/TP
Cb_SkillInit_process_skill_Leave_Func.SkillInitByNangua <- function(args) {
local SUser = User(args[1]);
local Skill = SUser.GetSkillW();
local charac_no = SUser.GetCID();
local SqlObj = MysqlPool.GetInstance().GetConnect();
local query = "SELECT IFNULL(total_sp, 0) as total_sp, IFNULL(total_tp, 0) as total_tp " +
"FROM DP_S.charac_attributes WHERE charac_no = " + charac_no + " AND item_id IS NULL";
local result = SqlObj.Select(query, ["int", "int"]);
MysqlPool.GetInstance().PutConnect(SqlObj);
local total_sp = 0;
local total_tp = 0;
if (result.len() > 0) {
total_sp = result[0][0];
total_tp = result[0][1];
}
local SkillTreeIndex = Sq_CallFunc(S_Ptr("0x0822f33c"), "int", ["pointer"], SUser.C_Object);
local remain_sp_0 = Sq_CallFunc(S_Ptr("0x08603528"), "int", ["pointer", "int"], Skill, 0);
local remain_sp_1 = Sq_CallFunc(S_Ptr("0x08603528"), "int", ["pointer", "int"], Skill, 1);
local remain_tp_0 = Sq_CallFunc(S_Ptr("0x086035f2"), "int", ["pointer", "int"], Skill, 2);
local remain_tp_1 = Sq_CallFunc(S_Ptr("0x086035f2"), "int", ["pointer", "int"], Skill, 3);
if (SkillTreeIndex == -1 || SkillTreeIndex == 0) {
Sq_CallFunc(S_Ptr("0x086034f8"), "int", ["pointer", "int", "int"], Skill, remain_sp_0 + total_sp, 0);
Sq_CallFunc(S_Ptr("0x08603590"), "int", ["pointer", "int", "int"], Skill, remain_tp_0 + total_tp, 2);
}
if (SkillTreeIndex == 1) {
Sq_CallFunc(S_Ptr("0x086034f8"), "int", ["pointer", "int", "int"], Skill, remain_sp_1 + total_sp, 1);
Sq_CallFunc(S_Ptr("0x08603590"), "int", ["pointer", "int", "int"], Skill, remain_tp_1 + total_tp, 3);
}
}
// 转职时返还SP/TP和属性石
Cb_User_set_grow_Leave_Func.changegrowByNangua <- function(args) {
local SUser = User(args[0]);
local grow = args[2];
local charac_no = SUser.GetCID();
local Skill = SUser.GetSkillW();
local SqlObj = MysqlPool.GetInstance().GetConnect();
// 查询SP/TP
local querySpTp = "SELECT IFNULL(total_sp, 0) as total_sp, IFNULL(total_tp, 0) as total_tp " +
"FROM DP_S.charac_attributes WHERE charac_no = " + charac_no + " AND item_id IS NULL";
local spTpResult = SqlObj.Select(querySpTp, ["int", "int"]);
local total_sp = 0;
local total_tp = 0;
if (spTpResult.len() > 0) {
total_sp = spTpResult[0][0];
total_tp = spTpResult[0][1];
}
// 根据转职类型决定是否查询属性石
local attrResult = [];
if (grow == 0) {
local queryAttr = "SELECT type, guildExpBook FROM DP_S.charac_attributes " +
"WHERE charac_no = " + charac_no + " AND item_id IS NOT NULL";
attrResult = SqlObj.Select(queryAttr, ["int", "int"]);
}
MysqlPool.GetInstance().PutConnect(SqlObj);
// 处理SP/TP
local SkillTreeIndex = Sq_CallFunc(S_Ptr("0x0822f33c"), "int", ["pointer"], SUser.C_Object);
local remain_sp_0 = Sq_CallFunc(S_Ptr("0x08603528"), "int", ["pointer", "int"], Skill, 0);
local remain_sp_1 = Sq_CallFunc(S_Ptr("0x08603528"), "int", ["pointer", "int"], Skill, 1);
local remain_tp_0 = Sq_CallFunc(S_Ptr("0x086035f2"), "int", ["pointer", "int"], Skill, 2);
local remain_tp_1 = Sq_CallFunc(S_Ptr("0x086035f2"), "int", ["pointer", "int"], Skill, 3);
if (SkillTreeIndex == -1) {
Sq_CallFunc(S_Ptr("0x086034f8"), "int", ["pointer", "int", "int"], Skill, remain_sp_0 + total_sp, 0);
Sq_CallFunc(S_Ptr("0x08603590"), "int", ["pointer", "int", "int"], Skill, remain_tp_0 + total_tp, 2);
Sq_CallFunc(S_Ptr("0x866C46A"), "void", ["pointer"], SUser.C_Object);
}
if (SkillTreeIndex == 0 || SkillTreeIndex == 1) {
Sq_CallFunc(S_Ptr("0x086034f8"), "int", ["pointer", "int", "int"], Skill, remain_sp_0 + total_sp, 0);
Sq_CallFunc(S_Ptr("0x086034f8"), "int", ["pointer", "int", "int"], Skill, remain_sp_1 + total_sp, 1);
Sq_CallFunc(S_Ptr("0x08603590"), "int", ["pointer", "int", "int"], Skill, remain_tp_0 + total_tp, 2);
Sq_CallFunc(S_Ptr("0x08603590"), "int", ["pointer", "int", "int"], Skill, remain_tp_1 + total_tp, 3);
Sq_CallFunc(S_Ptr("0x866C46A"), "void", ["pointer"], SUser.C_Object);
}
// 处理属性石(仅当 grow == 0 时)
if (grow == 0 && attrResult.len() > 0) {
local userAddInfo = Sq_CallFunc(S_Ptr("0x086960d8"), "pointer", ["pointer"], SUser.C_Object);
foreach (idx, row in attrResult) {
local type = row[0];
local guildExpBook = row[1];
switch (type) {
case 2:
NativePointer(userAddInfo).writeU32(NativePointer(userAddInfo).readU32() + guildExpBook);
break;
case 3:
NativePointer(userAddInfo).add(4).writeU32(NativePointer(userAddInfo).add(4).readU32() + guildExpBook);
break;
case 4:
NativePointer(userAddInfo).add(8).writeU16(NativePointer(userAddInfo).add(8).readU16() + guildExpBook);
break;
case 5:
NativePointer(userAddInfo).add(10).writeU16(NativePointer(userAddInfo).add(10).readU16() + guildExpBook);
break;
case 6:
NativePointer(userAddInfo).add(12).writeU16(NativePointer(userAddInfo).add(12).readU16() + guildExpBook);
break;
case 7:
NativePointer(userAddInfo).add(14).writeU16(NativePointer(userAddInfo).add(14).readU16() + guildExpBook);
break;
case 8:
NativePointer(userAddInfo).add(66).writeU32(NativePointer(userAddInfo).add(66).readU32() + guildExpBook);
break;
case 9:
for (local j = 0; j < 4; j++) {
local offset = 2 * j * 8;
local ptr = NativePointer(userAddInfo).add(offset);
ptr.writeU16(ptr.readU16() + guildExpBook);
}
break;
}
api_recover_attributes(SUser, type, guildExpBook, -1);
}
}
}
// 使用道具时更新数据库
Cb_User_increase_status_Enter_Func.UseItemByNangua <- function(args) {
local SUser = User(args[0]);
local Slot = args[1];
local userItem = Memory.alloc(128);
local InvenObj = SUser.GetInven();
if (!InvenObj) {
return;
}
Sq_CallFunc(S_Ptr("0x084fb918"), "pointer", ["pointer", "pointer", "int", "int"], userItem.C_Object, InvenObj.C_Object, 1, Slot);
local item_id = NativePointer(userItem.C_Object).add(2).readU32();
local charac_no = SUser.GetCID();
local SqlObj = MysqlPool.GetInstance().GetConnect();
// SP道具
if (item_id == 1031) {
updateSPTP(SqlObj, charac_no, 5, false);
} else if (item_id == 1038) {
updateSPTP(SqlObj, charac_no, 20, false);
}
// TP道具
else if (item_id == 1204) {
updateSPTP(SqlObj, charac_no, 1, true);
} else if (item_id == 1205) {
updateSPTP(SqlObj, charac_no, 5, true);
}
// 属性石
else {
local type = -1;
local guildExpBook = 0;
switch (item_id) {
case 1039: type = 4; guildExpBook = 50; break;
case 1040: type = 6; guildExpBook = 50; break;
case 1041: type = 5; guildExpBook = 50; break;
case 1042: type = 7; guildExpBook = 50; break;
case 1043: type = 2; guildExpBook = 250; break;
case 1044: type = 3; guildExpBook = 250; break;
case 1045: type = 8; guildExpBook = 10; break;
case 1046: type = 9; guildExpBook = 10; break;
}
if (type != -1) {
local query = "INSERT INTO DP_S.charac_attributes (charac_no, item_id, type, guildExpBook) " +
"VALUES (" + charac_no + ", " + item_id + ", " + type + ", " + guildExpBook + ") " +
"ON DUPLICATE KEY UPDATE guildExpBook = guildExpBook + " + guildExpBook;
SqlObj.Select(query, []);
}
}
MysqlPool.GetInstance().PutConnect(SqlObj);
}
Cb_ChangeGrowType_Item_Leave_Func.ApplyAttributesByNangua <- function(args) {
local SUser = User(args[0]);
local slot = args[2];
local charac_no = SUser.GetCID();
local userItem = Memory.alloc(128);
local InvenObj = SUser.GetInven();
if (!InvenObj) return;
Sq_CallFunc(S_Ptr("0x084fb918"), "pointer", ["pointer", "pointer", "int", "int"], userItem.C_Object, InvenObj.C_Object, 1, slot);
local item_id = NativePointer(userItem.C_Object).add(2).readU32();
if (!(item_id == 2660779 || item_id == 2660702)) return;
local SqlObj = MysqlPool.GetInstance().GetConnect();
local query = "SELECT type, guildExpBook FROM DP_S.charac_attributes " +
"WHERE charac_no = " + charac_no + " AND item_id IS NOT NULL";
local attrResult = SqlObj.Select(query, ["int", "int"]);
MysqlPool.GetInstance().PutConnect(SqlObj);
if (attrResult.len() == 0) return;
local userAddInfo = Sq_CallFunc(S_Ptr("0x086960d8"), "pointer", ["pointer"], SUser.C_Object);
foreach (row in attrResult) {
local type = row[0];
local guildExpBook = row[1];
switch (type) {
case 2: NativePointer(userAddInfo).writeU32(NativePointer(userAddInfo).readU32() + guildExpBook); break;
case 3: NativePointer(userAddInfo).add(4).writeU32(NativePointer(userAddInfo).add(4).readU32() + guildExpBook); break;
case 4: NativePointer(userAddInfo).add(8).writeU16(NativePointer(userAddInfo).add(8).readU16() + guildExpBook); break;
case 5: NativePointer(userAddInfo).add(10).writeU16(NativePointer(userAddInfo).add(10).readU16() + guildExpBook); break;
case 6: NativePointer(userAddInfo).add(12).writeU16(NativePointer(userAddInfo).add(12).readU16() + guildExpBook); break;
case 7: NativePointer(userAddInfo).add(14).writeU16(NativePointer(userAddInfo).add(14).readU16() + guildExpBook); break;
case 8: NativePointer(userAddInfo).add(66).writeU32(NativePointer(userAddInfo).add(66).readU32() + guildExpBook); break;
case 9:
for (local j = 0; j < 4; j++) {
local ptr = NativePointer(userAddInfo).add(2 * j * 8);
ptr.writeU16(ptr.readU16() + guildExpBook);
}
break;
}
api_recover_attributes(SUser, type, guildExpBook, -1);
}
}
// 更新SP/TP值
function updateSPTP(SqlObj, charac_no, value, is_tp) {
local query = "SELECT id, total_sp, total_tp FROM DP_S.charac_attributes " +
"WHERE charac_no = " + charac_no + " AND item_id IS NULL";
local result = SqlObj.Select(query, ["int", "int", "int"]);
if (result.len() > 0) {
local current_sp = result[0][1];
local current_tp = result[0][2];
local new_sp = is_tp ? current_sp : (current_sp + value);
local new_tp = is_tp ? (current_tp + value) : current_tp;
query = "UPDATE DP_S.charac_attributes " +
"SET total_sp = " + new_sp + ", total_tp = " + new_tp + " " +
"WHERE charac_no = " + charac_no + " AND item_id IS NULL";
} else {
query = "INSERT INTO DP_S.charac_attributes (charac_no, total_sp, total_tp) " +
"VALUES (" + charac_no + ", " +
(is_tp ? "0" : value.tostring()) + ", " +
(is_tp ? value.tostring() : "0") + ")";
}
SqlObj.Select(query, []);
}
// 发包更新增加玩家属性
function api_recover_attributes(SUser, type, guildExpBook, slof) {
local Pack = Packet();
Pack.Put_Header(1, 32);
Pack.Put_Byte(1);
Pack.Put_Short(slof);
Pack.Put_Byte(type);
Pack.Put_Int(guildExpBook);
Pack.Put_Short(0);
Pack.Put_Short(0);
Pack.Finalize(true);
SUser.Send(Pack);
Pack.Delete();
}
// 主函数
function _Dps_SPTP_Attributes_Main_() {
createAttributesTable();
}