// 创建数据库和表 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(); }