Compare commits
18 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
2815d5e898 | |
|
|
5baa2cff0a | |
|
|
ee09eb5efc | |
|
|
36c144dc6d | |
|
|
b2881499c6 | |
|
|
616a254c31 | |
|
|
b5fba5bed3 | |
|
|
c9d989f8b8 | |
|
|
868a9f3c9a | |
|
|
4de459884c | |
|
|
513caa5347 | |
|
|
58b5ebfcc2 | |
|
|
877ab0b8bc | |
|
|
3cf9eaaa29 | |
|
|
b2e4be7d06 | |
|
|
a1e5af4ef9 | |
|
|
153de52d6b | |
|
|
a162ecee48 |
4
Main.nut
4
Main.nut
|
|
@ -1,8 +1,10 @@
|
|||
function sqr_main() {
|
||||
GameManager.OpenHotFix("/dp_s/OfficialConfig");
|
||||
GameManager.OpenHotFix("/dp_s/OfficialProject");
|
||||
GameManager.OpenHotFix("/dp_s/_DPS_/_Core");
|
||||
GameManager.OpenHotFix("/dp_s/_DPS_/_BuiltProject");
|
||||
GameManager.OpenHotFix("/dp_s/MyProject");
|
||||
GameManager.SetGameMaxLevel(86);
|
||||
// GameManager.SetGameMaxLevel(86);
|
||||
// Cb_History_MileageSet_Func["TW_reach_game_world"] <- function(SUser, Data) {
|
||||
// //第一次上线
|
||||
// if (SUser.GetCharacLevel() > 70) {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ Gm_InputFunc_Handle["给"] <- function(SUser, CmdString) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Gm_InputFunc_Handle["转职"] <- function(SUser, CmdString) {
|
||||
local count = -1;
|
||||
local pos = 0;
|
||||
|
|
@ -69,6 +71,8 @@ Gm_InputFunc_Handle["完成任务"] <- function(SUser, CmdString) {
|
|||
SUser.ClearQuest_Gm(221);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Gm_InputFunc_Handle["升级"] <- function(SUser, CmdString) {
|
||||
local count = -1;
|
||||
local pos = 0;
|
||||
|
|
@ -109,15 +113,62 @@ Gm_InputFunc_Handle["点券"] <- function(SUser, CmdString) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Gm_InputFunc_Handle["test"] <- function(SUser, CmdString) {
|
||||
|
||||
|
||||
|
||||
|
||||
Sq_CallFunc(S_Ptr("0x0866C46A"), "void", ["pointer"], SUser.C_Object);
|
||||
}
|
||||
|
||||
|
||||
Timer.SetTimeOut(function() {
|
||||
// _Dps_Equ2AvaJewel_Main_()
|
||||
// local Pack = Packet();
|
||||
// print("包位置: " + Pack.GetPos());
|
||||
// Pack.Put_Int(666);
|
||||
// print("包位置: " + Pack.GetPos());
|
||||
// // Sq_Rsa_GenerateKey();
|
||||
// local str = format("%08x010101010101010101010101010101010101010101010101010101010101010155914510010403030101", 1);
|
||||
// local Byte = Sq_Rsa_Private_Encrypt(str);
|
||||
// local EnStr = _base64_encode(Byte);
|
||||
// print(EnStr);
|
||||
|
||||
// local passwd = "1";
|
||||
|
||||
// Sq_WriteByteArr(S_Ptr("0x081E907E"), [0x90, 0x90, 0x90, 0x90, 0x90]);
|
||||
// Sq_WriteByteArr(S_Ptr("0x0081E9085"), [0x0F, 0x94, 0xC0]);
|
||||
|
||||
// Sq_WriteByteArr(S_Ptr("0x81731F2"), Haker.AsmGenerateMcd(
|
||||
// "mov eax,0",
|
||||
// "ret" ));
|
||||
|
||||
}, 1);
|
||||
|
||||
|
||||
|
||||
// // //玩家新增道具时
|
||||
// Cb_wdzsdfge_Enter_Func <- {};
|
||||
// Cb_wdzsdfge_Leave_Func <- {};
|
||||
// _Hook_Register_Currency_Func_("0x81731F2", ["pointer", "pointer", "pointer", "int"], Cb_wdzsdfge_Enter_Func, Cb_wdzsdfge_Leave_Func);
|
||||
|
||||
|
||||
|
||||
// Cb_wdzsdfge_Leave_Func["11"] <- function(args) {
|
||||
// print("登录请求: ");
|
||||
// print("args[0]: " + args[0]);
|
||||
// NativePointer(args[0]).Output(512);
|
||||
// print("args[1]: " + args[1]);
|
||||
// //NativePointer(args[1]).Output(512);
|
||||
// print("args[2]: " + args[2]);
|
||||
// NativePointer(args[2]).Output(512);
|
||||
// }
|
||||
|
||||
|
||||
Gm_InputFunc_Handle["我要升级"] <- function(SUser, CmdString) {
|
||||
SUser.SetCharacLevel(85);
|
||||
}
|
||||
|
||||
Gm_InputFunc_Handle["南瓜村"] <- function(SUser, CmdString) {
|
||||
getroottable()._NewTitle_.AddTitle(SUser, 1);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,168 @@
|
|||
class _DPS_Login_Gateway_ {
|
||||
|
||||
//数据库连接
|
||||
MysqlObject = null;
|
||||
|
||||
PackHandleMap = null;
|
||||
|
||||
constructor() {
|
||||
PackHandleMap = {};
|
||||
|
||||
MysqlObject = Mysql(Str_Ptr("127.0.0.1"), 3306, Str_Ptr("taiwan_cain"), Str_Ptr("game"), Str_Ptr("uu5!^%jg"));
|
||||
MysqlObject.Exec_Sql(format("SET NAMES %s", "latin1"));
|
||||
|
||||
//创建一个Http Server
|
||||
try {
|
||||
local HS = HttpServer("0.0.0.0", "41817");
|
||||
HS.Listen(function(SocketObject, Header, Msg) {
|
||||
print("HS.Listen")
|
||||
getroottable()._DPS_Login_Gateway_Object_._HttpServer_Event_DPS_(SocketObject, Header, Msg);
|
||||
});
|
||||
} catch (exception) {
|
||||
|
||||
}
|
||||
|
||||
PackHandleMap["/GetConfig"] <- function(SocketObject, Header, Jso) {
|
||||
local Config = sq_ReadJsonFile("/dp_s/OfficialConfig/登录器配置.json");
|
||||
//读取DPS登录器的配置并发送
|
||||
SocketObject.Write(Config);
|
||||
}
|
||||
|
||||
|
||||
PackHandleMap["/Login"] <- function(SocketObject, Header, Jso) {
|
||||
if (!Jso.rawin("account")) return;
|
||||
if (!Jso.rawin("passwd")) return;
|
||||
local account = Jso.account;
|
||||
local passwd = Jso.passwd;
|
||||
local passwd_hash = MD5_Hash(passwd);
|
||||
|
||||
|
||||
//正则表达式 只允许字母和数字
|
||||
local regex = regexp("^[A-Za-z0-9]{1,19}$");
|
||||
if (!regex.match(account)) {
|
||||
SocketObject.Write({
|
||||
error = "账号只能包含字母和数字且长度小于20"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
local sql = format("select UID from d_taiwan.accounts where accountname='%s' and password='%s';", account, passwd_hash);
|
||||
local Ret = MysqlObject.Select(sql, ["int"]);
|
||||
if (Ret && Ret.len() > 0) {
|
||||
local Uid = Ret[0][0];
|
||||
local str = format("%08x010101010101010101010101010101010101010101010101010101010101010155914510010403030101", Uid);
|
||||
local Byte = Sq_Rsa_Private_Encrypt(str);
|
||||
local EnStr = MD5.base64_encode(Byte);
|
||||
//发送登录Token
|
||||
SocketObject.Write({
|
||||
token = EnStr
|
||||
});
|
||||
} else {
|
||||
SocketObject.Write({
|
||||
error = "账号或密码错误!"
|
||||
});
|
||||
}
|
||||
}.bindenv(this);
|
||||
|
||||
|
||||
PackHandleMap["/Register"] <- function(SocketObject, Header, Jso) {
|
||||
|
||||
if (!Jso.rawin("account")) return;
|
||||
if (!Jso.rawin("passwd")) return;
|
||||
|
||||
local account = Jso.account;
|
||||
local passwd = Jso.passwd;
|
||||
|
||||
|
||||
//正则表达式 只允许字母和数字
|
||||
local regex = regexp("^[A-Za-z0-9]{1,19}$");
|
||||
if (account.len() == 0 || !regex.match(account)) {
|
||||
SocketObject.Write({
|
||||
error = "账号只能包含字母和数字且长度大于0小于20"
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (passwd.len() == 0 || !regex.match(passwd)) {
|
||||
SocketObject.Write({
|
||||
error = "密码只能包含字母和数字且长度大于0小于20"
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (GetAccountByName(account) != null) {
|
||||
SocketObject.Write({
|
||||
error = "账号已存在"
|
||||
})
|
||||
return;
|
||||
}
|
||||
local passwd_hash = MD5_Hash(passwd);
|
||||
|
||||
|
||||
local sql = format("INSERT INTO d_taiwan.accounts(accountname, password)VALUES( '%s' , '%s');", account, passwd_hash);
|
||||
MysqlObject.Exec_Sql(sql);
|
||||
local Ret = MysqlObject.Select("SELECT LAST_INSERT_ID()", ["int"]);
|
||||
if (Ret && Ret.len() > 0) {
|
||||
local Uid = Ret[0][0].tostring();
|
||||
MysqlObject.Exec_Sql(format("INSERT INTO d_taiwan.member_info(m_id, user_id)VALUES('%s','%s');", Uid, Uid));
|
||||
MysqlObject.Exec_Sql(format("INSERT INTO d_taiwan.member_white_account(m_id)VALUES('%s')", Uid));
|
||||
MysqlObject.Exec_Sql(format("INSERT INTO taiwan_login.member_login(m_id)VALUES('%s')", Uid));
|
||||
MysqlObject.Exec_Sql(format("INSERT INTO taiwan_billing.cash_cera(account, cera,mod_tran,mod_date, reg_date)VALUES('%s',0,0,NOW(), NOW())", Uid));
|
||||
MysqlObject.Exec_Sql(format("INSERT INTO taiwan_billing.cash_cera_point(account, cera_point,mod_date, reg_date)VALUES('%s',0,NOW(), NOW())", Uid));
|
||||
SocketObject.Write({
|
||||
success = "账号注册成功,现在您可以登录了!"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
}.bindenv(this);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function GetAccountByName(account) {
|
||||
local sql = format("select UID , accountname, password from d_taiwan.accounts where accountname='%s'", account);
|
||||
local Ret = MysqlObject.Select(sql, ["int", "string", "string"]);
|
||||
if (!Ret || Ret.len() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
uid = Ret[0][0],
|
||||
account = Ret[0][1],
|
||||
passwd = Ret[0][2]
|
||||
}
|
||||
}
|
||||
|
||||
function _HttpServer_Event_DPS_(SocketObject, Header, Msg) {
|
||||
print("_HttpServer_Event_DPS_")
|
||||
if (PackHandleMap.rawin(Header.path)) {
|
||||
local Jso = null;
|
||||
try {
|
||||
Jso = Json.Decode(Msg);
|
||||
} catch (exception) {
|
||||
|
||||
}
|
||||
if (!Jso) return;
|
||||
PackHandleMap[Header.path](SocketObject, Header, Jso);
|
||||
|
||||
} else {
|
||||
SocketObject.Write({
|
||||
error = "error url"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function MD5_Hash(str) {
|
||||
local Ctx = Memory.alloc(0x100);
|
||||
MD5.MD5_Init(Ctx.C_Object);
|
||||
MD5.MD5_Update(Ctx.C_Object, Memory.allocUtf8String(str).C_Object, str.len());
|
||||
local Result = Memory.alloc(16);
|
||||
MD5.MD5_Final(Result.C_Object, Ctx.C_Object);
|
||||
return MD5.hex_encode(Result.readUtf8String(16));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Timer.SetTimeOut(function() {
|
||||
getroottable()._DPS_Login_Gateway_Object_ <- _DPS_Login_Gateway_();
|
||||
}, 1);
|
||||
|
|
@ -0,0 +1,396 @@
|
|||
/*
|
||||
文件名:灵魂救赎武器.nut
|
||||
路径:_DPS_/_BuiltProject/灵魂救赎武器/灵魂救赎武器.nut
|
||||
创建日期:2026-01-20 19:24
|
||||
文件用途:
|
||||
*/
|
||||
|
||||
class SoulSalvationC {
|
||||
|
||||
|
||||
MysqlObject = null;
|
||||
|
||||
//灵魂救赎武器标识 (阶段1)
|
||||
Equipment1List = null;
|
||||
//1阶段所需灵魂数量
|
||||
Stage1SoulCount = 1000;
|
||||
//1阶段进阶所需材料
|
||||
Equipment1Upgrade = null;
|
||||
//灵魂救赎武器标识 (阶段2)
|
||||
Equipment2List = null;
|
||||
//2阶段所需灵魂数量
|
||||
Stage2SoulCount = 100;
|
||||
//灵魂救赎武器标识 (阶段3)
|
||||
Equipment3List = null;
|
||||
|
||||
//数据
|
||||
data = null;
|
||||
|
||||
constructor() {
|
||||
Equipment1List = {};
|
||||
Equipment1Upgrade = {};
|
||||
Equipment2List = {};
|
||||
Equipment3List = {};
|
||||
data = {};
|
||||
|
||||
//创建数据库
|
||||
MysqlObject = Mysql(Str_Ptr("127.0.0.1"), 3306, Str_Ptr("taiwan_cain"), Str_Ptr("game"), Str_Ptr("uu5!^%jg"));
|
||||
MysqlObject.Exec_Sql(format("SET NAMES %s", "latin1"));
|
||||
|
||||
local check_table_sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'soulsalvation';"
|
||||
local Ret = MysqlObject.Select(check_table_sql, ["int"]);
|
||||
if (Ret.len() == 0 || Ret[0][0] == 0) {
|
||||
local sql = "CREATE TABLE soulsalvation (`uid` INT(11) NOT NULL COMMENT '主键ID',`soul_id` INT(11) NOT NULL DEFAULT 0 COMMENT '灵魂ID', `soul_count` INT(11) NOT NULL DEFAULT 0 COMMENT '数值字段(默认值0)',PRIMARY KEY (`uid`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='soulsalvation表';";
|
||||
MysqlObject.Exec_Sql(sql);
|
||||
}
|
||||
|
||||
//读取PVF
|
||||
InitPvf();
|
||||
|
||||
//注册客户端收包
|
||||
RegisterClient();
|
||||
|
||||
//读取数据库数据到缓存
|
||||
InitMysqlData();
|
||||
|
||||
}
|
||||
|
||||
function RegisterClient() {
|
||||
//测试用客户端主动查询灵魂数
|
||||
ClientSocketPackFuncMap.rawset(21011001, function(SUser, Jso) {
|
||||
local SendInfo = GetUserData(SUser);
|
||||
SUser.SendJso({
|
||||
op = 21011002,
|
||||
Info = SendInfo
|
||||
})
|
||||
}.bindenv(this));
|
||||
|
||||
Cb_CParty_OnKillMonster_Leave_Func.rawset("SoulSalvationC", function(args) {
|
||||
local SUser = User(args[1]);
|
||||
//获取佩戴的武器
|
||||
local Weapon = GetUserWeapon(SUser);
|
||||
local WeaponIndex = Weapon.GetIndex();
|
||||
//可积累灵魂数量
|
||||
if (Equipment1List.rawin(WeaponIndex) || Equipment2List.rawin(WeaponIndex)) {
|
||||
local uuid = Weapon.GetUuid();
|
||||
//有数据则+1 无数据则新增
|
||||
if (data.rawin(uuid)) {
|
||||
if (data[uuid].soul_count< Stage1SoulCount)
|
||||
data[uuid].soul_count += 1;
|
||||
} else {
|
||||
data[uuid] <- {
|
||||
soul_count = 1,
|
||||
soul_id = 0
|
||||
};
|
||||
}
|
||||
SUser.SendJso({
|
||||
op = 21011004,
|
||||
uuid = uuid,
|
||||
info = data[uuid]
|
||||
})
|
||||
}
|
||||
}.bindenv(this));
|
||||
|
||||
//上线时 获取自己的灵魂武器信息
|
||||
Cb_reach_game_world_Func.rawset("SoulSalvationC", function(SUser) {
|
||||
local SendInfo = GetUserData(SUser);
|
||||
SUser.SendJso({
|
||||
op = 21011002,
|
||||
Info = SendInfo
|
||||
})
|
||||
}.bindenv(this));
|
||||
|
||||
//查看他人信息的时候 获取灵魂武器信息
|
||||
Cb_GetUserInfo_Leave_Func.rawset("SoulSalvationC", function(args) {
|
||||
local SUser = User(args[1])
|
||||
local CheckWorldId = NativePointer(args[2]).add(13).readShort();
|
||||
local CheckUser = World.GetUserBySession(CheckWorldId);
|
||||
if (CheckUser) {
|
||||
local SendInfo = GetUserData(CheckUser);
|
||||
SUser.SendJso({
|
||||
op = 21011006,
|
||||
Info = SendInfo
|
||||
})
|
||||
}
|
||||
}.bindenv(this));
|
||||
|
||||
//每5分钟固化一次数据到数据库
|
||||
Timer.RemoveCronTask("SoulSalvationC");
|
||||
Timer.SetCronTask(function() {
|
||||
local DataList = [];
|
||||
foreach(uuid, value in data) {
|
||||
local str = format("(%d,%d,%d),", uuid, value.soul_id, value.soul_count);
|
||||
DataList.push(str);
|
||||
}
|
||||
local sql = "REPLACE INTO soulsalvation (uid, soul_id, soul_count) VALUES";
|
||||
foreach(value in DataList) {
|
||||
sql += value;
|
||||
}
|
||||
//去除最后一个,
|
||||
sql = sql.slice(0, -1);
|
||||
sql += ";";
|
||||
MysqlObject.Exec_Sql(sql);
|
||||
// }.bindenv(this), {
|
||||
// Cron = "0 */5 * * * *",
|
||||
// Name = "SoulSalvationC"
|
||||
// });
|
||||
}.bindenv(this), {
|
||||
Cron = "*/5 * * * * *",
|
||||
Name = "SoulSalvationC"
|
||||
});
|
||||
|
||||
|
||||
ClientSocketPackFuncMap.rawset(21011007, function(SUser, Jso) {
|
||||
//获取背包
|
||||
local InvenObj = SUser.GetInven();
|
||||
//装备ID
|
||||
local Id = Jso.item.ItemId;
|
||||
//判断是否为灵魂武器一阶段
|
||||
if (!Equipment1List.rawin(Id)) {
|
||||
SUser.SendJso({
|
||||
op = 21011008,
|
||||
error = 1
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// //判断灵魂数量是否已经达到要求
|
||||
// local SlotItem = InvenObj.GetSlot(Inven.INVENTORY_TYPE_ITEM, 9 + Jso.item.Pos);
|
||||
// local uuid = SlotItem.GetUuid();
|
||||
// local SoulCount = 0;
|
||||
// if(data.rawin(uuid)){
|
||||
// SoulCount = data[uuid].soul_count;
|
||||
// }
|
||||
// if(SoulCount < Stage1SoulCount){
|
||||
// SUser.SendJso({
|
||||
// op = 21011008,
|
||||
// error = 2
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
|
||||
|
||||
local MgArr = [];
|
||||
foreach(Index, Count in Equipment1Upgrade) {
|
||||
//查询自己有多少个道具
|
||||
MgArr.push({
|
||||
Item = Index,
|
||||
RealCount = InvenObj.GetCountById(Index),
|
||||
NeedCount = Count.tointeger()
|
||||
});
|
||||
}
|
||||
SUser.SendJso({
|
||||
op = 21011008,
|
||||
MgInfo = MgArr
|
||||
});
|
||||
|
||||
}.bindenv(this));
|
||||
|
||||
|
||||
ClientSocketPackFuncMap.rawset(21011009, function(SUser, Jso) {
|
||||
//获取背包
|
||||
local InvenObj = SUser.GetInven();
|
||||
//装备ID
|
||||
local Id = Jso.item.ItemId;
|
||||
//判断是否为灵魂武器一阶段
|
||||
if (!Equipment1List.rawin(Id)) {
|
||||
SUser.SendJso({
|
||||
op = 21011008,
|
||||
error = 1
|
||||
});
|
||||
return;
|
||||
}
|
||||
//要给予的装备ID
|
||||
local giveid = Id + 1;
|
||||
|
||||
//获取对应槽位的装备
|
||||
local SlotItem = InvenObj.GetSlot(Inven.INVENTORY_TYPE_ITEM, 9 + Jso.item.Pos);
|
||||
local uuid = SlotItem.GetUuid();
|
||||
if (SlotItem.GetIndex() != Id) {
|
||||
SUser.SendNotiBox(" 升级失败 升级时请不要操作背包", 1);
|
||||
return;
|
||||
} else {
|
||||
local MgArr = [];
|
||||
foreach(Index, Count in Equipment1Upgrade) {
|
||||
//查询自己有多少个道具
|
||||
MgArr.push({
|
||||
Id = Index,
|
||||
Count = Count.tointeger()
|
||||
});
|
||||
}
|
||||
|
||||
local Flag = InvenObj.CheckArrItemCount(MgArr);
|
||||
if (!Flag) {
|
||||
print("扣除失败");
|
||||
SUser.SendNotiBox(" 升级失败 升级时请不要操作背包", 1);
|
||||
return;
|
||||
} else {
|
||||
local SlogInfo = SUser.GiveItem(giveid, 1);
|
||||
if (!SlogInfo) {
|
||||
SUser.SendNotiBox(" 升级失败 请确定背包有空余空间", 1);
|
||||
return;
|
||||
}
|
||||
local giveItemObj = InvenObj.GetSlot(1, SlogInfo[1])
|
||||
//扣除道具
|
||||
InvenObj.DeleteArrItemCount(MgArr);
|
||||
|
||||
local forging = SlotItem.GetForging(); //锻造
|
||||
local upgrade = SlotItem.GetUpgrade(); //强化
|
||||
local amplification = SlotItem.GetAmplification(); //增幅
|
||||
local enchanting = SlotItem.GetEnchanting(); //附魔
|
||||
if (forging > 0) {
|
||||
giveItemObj.SetForging(forging);
|
||||
}
|
||||
if (upgrade > 0) {
|
||||
giveItemObj.SetUpgrade(upgrade);
|
||||
}
|
||||
if (amplification != 0) {
|
||||
giveItemObj.SetAmplification(amplification);
|
||||
}
|
||||
giveItemObj.SetEnchanting(enchanting);
|
||||
giveItemObj.SetAdd_Info(SlotItem.GetAdd_Info()); //品级
|
||||
giveItemObj.Flush();
|
||||
|
||||
//销毁背包中的道具
|
||||
SlotItem.Delete();
|
||||
//刷新玩家背包列表
|
||||
SUser.SendUpdateItemList(1, 0, 9 + Jso.item.Pos);
|
||||
SUser.SendUpdateItemList(1, 0, SlogInfo[1]);
|
||||
|
||||
//刷新
|
||||
SUser.SendNotiBox(" 升级成功", 1);
|
||||
SUser.SendJso({
|
||||
op = 21011010
|
||||
});
|
||||
|
||||
//从缓存中移除这个uuid
|
||||
data.rawdelete(uuid);
|
||||
local Sql = "DELETE FROM soulsalvation WHERE uid = " + uuid + ";";
|
||||
MysqlObject.Exec_Sql(Sql);
|
||||
}
|
||||
}
|
||||
}.bindenv(this));
|
||||
};
|
||||
|
||||
//获取角色的武器
|
||||
function GetUserWeapon(SUser) {
|
||||
local InvenObj = SUser.GetInven();
|
||||
if (!InvenObj) return null;
|
||||
return InvenObj.GetSlot(Inven.INVENTORY_TYPE_BODY, 10);
|
||||
}
|
||||
|
||||
//获取角色的灵魂武器信息
|
||||
function GetUserData(SUser) {
|
||||
//获取背包对象
|
||||
local InvenObj = SUser.GetInven();
|
||||
if (!InvenObj) return {};
|
||||
local UUIDList = [];
|
||||
//遍历身上
|
||||
for (local i = 0; i< 26; i++) {
|
||||
local Inven_Item = InvenObj.GetSlot(Inven.INVENTORY_TYPE_BODY, i);
|
||||
if (Inven_Item) {
|
||||
local Index = Inven_Item.GetIndex();
|
||||
if (Equipment1List.rawin(Index) || Equipment2List.rawin(Index)) {
|
||||
local uuid = Inven_Item.GetUuid();
|
||||
UUIDList.push(uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
//遍历物品栏
|
||||
for (local i = 0; i< 70; i++) {
|
||||
local Inven_Item = InvenObj.GetSlot(Inven.INVENTORY_TYPE_ITEM, i);
|
||||
if (Inven_Item) {
|
||||
local Index = Inven_Item.GetIndex();
|
||||
if (Equipment1List.rawin(Index) || Equipment2List.rawin(Index)) {
|
||||
local uuid = Inven_Item.GetUuid();
|
||||
UUIDList.push(uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
local SendInfo = {};
|
||||
foreach(uuid in UUIDList) {
|
||||
if (data.rawin(uuid)) {
|
||||
SendInfo.rawset(uuid, data[uuid]);
|
||||
} else {
|
||||
data[uuid] <- {
|
||||
soul_count = 0,
|
||||
soul_id = 0
|
||||
};
|
||||
}
|
||||
}
|
||||
return SendInfo;
|
||||
}
|
||||
|
||||
function InitPvf() {
|
||||
Script();
|
||||
ScriptData.GetFileData("etc/rindro/expandequipment/soulsalvation.etc", function(DataTable, Data) {
|
||||
while (!Data.Eof()) {
|
||||
local Fragment = Data.Get();
|
||||
if (Fragment == "[EQUIPMENT1]") {
|
||||
Equipment1List = {};
|
||||
while (true) {
|
||||
local Fbuf = Data.Get();
|
||||
if (Fbuf == "[/EQUIPMENT1]") {
|
||||
break;
|
||||
}
|
||||
Equipment1List.rawset(Fbuf, true);
|
||||
}
|
||||
} else if (Fragment == "[EQUIPMENT2]") {
|
||||
Equipment2List = {};
|
||||
while (true) {
|
||||
local Fbuf = Data.Get();
|
||||
if (Fbuf == "[/EQUIPMENT2]") {
|
||||
break;
|
||||
}
|
||||
Equipment2List.rawset(Fbuf, true);
|
||||
}
|
||||
} else if (Fragment == "[EQUIPMENT3]") {
|
||||
Equipment3List = {};
|
||||
while (true) {
|
||||
local Fbuf = Data.Get();
|
||||
if (Fbuf == "[/EQUIPMENT3]") {
|
||||
break;
|
||||
}
|
||||
Equipment3List.rawset(Fbuf, true);
|
||||
}
|
||||
} else if (Fragment == "[STAGE1 VALUE]") {
|
||||
Stage1SoulCount = Data.Get();
|
||||
} else if (Fragment == "[STAGE2 VALUE]") {
|
||||
Stage2SoulCount = Data.Get();
|
||||
} else if (Fragment == "[STAGE1 NEED ITEM]") {
|
||||
Equipment1Upgrade = {};
|
||||
while (true) {
|
||||
local Fbuf = Data.Get();
|
||||
if (Fbuf == "[/STAGE1 NEED ITEM]") {
|
||||
break;
|
||||
}
|
||||
Equipment1Upgrade.rawset(Fbuf, Data.Get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}.bindenv(this));
|
||||
}
|
||||
|
||||
function InitMysqlData() {
|
||||
local Sql = "SELECT * FROM soulsalvation"
|
||||
local Ret = MysqlObject.Select(Sql, ["int", "int", "int"]);
|
||||
foreach(Row in Ret) {
|
||||
local uuid = Row[0];
|
||||
local soul_id = Row[1];
|
||||
local soul_count = Row[2];
|
||||
data.rawset(uuid, {
|
||||
soul_id = soul_id,
|
||||
soul_count = soul_count
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Timer.SetTimeOut(function() {
|
||||
|
||||
getroottable()._SoulSalvation_ <- SoulSalvationC();
|
||||
print("双端插件·灵魂救赎武器 - 已加载");
|
||||
}, 1);
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
文件名:装备拓展.nut
|
||||
路径:MyProject/装备拓展.nut
|
||||
创建日期:2026-01-15 10:02
|
||||
文件用途:
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
Cb_ItemGloballyUniqueIdentifier_t_SetServerId_Enter_Func <- {};
|
||||
Cb_ItemGloballyUniqueIdentifier_t_SetServerId_Leave_Func <- {};
|
||||
_Hook_Register_Currency_Func_("0x08894782", ["pointer", "int", "pointer"], Cb_ItemGloballyUniqueIdentifier_t_SetServerId_Enter_Func, Cb_ItemGloballyUniqueIdentifier_t_SetServerId_Leave_Func);
|
||||
|
||||
// Cb_CInventory_MakeItemPacket_Enter_Func <- {};
|
||||
// Cb_CInventory_MakeItemPacket_Leave_Func <- {};
|
||||
// _Hook_Register_Currency_Func_("0x084FC6BC", ["pointer", "int", "int", "pointer", "int"], Cb_CInventory_MakeItemPacket_Enter_Func, Cb_CInventory_MakeItemPacket_Leave_Func);
|
||||
|
||||
|
||||
|
||||
|
||||
class EquipmentExpandC {
|
||||
|
||||
MysqlObject = null;
|
||||
|
||||
constructor() {
|
||||
MysqlObject = Mysql(Str_Ptr("127.0.0.1"), 3306, Str_Ptr("taiwan_cain"), Str_Ptr("game"), Str_Ptr("uu5!^%jg"));
|
||||
MysqlObject.Exec_Sql(format("SET NAMES %s", "latin1"));
|
||||
|
||||
local check_table_sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'equip_only_id';"
|
||||
local Ret = MysqlObject.Select(check_table_sql, ["int"]);
|
||||
if (Ret.len() == 0 || Ret[0][0] == 0) {
|
||||
local sql = "CREATE TABLE equip_only_id (id INT(11) NOT NULL AUTO_INCREMENT COMMENT '32位自增唯一ID,初始值10000', PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '纯自增ID表' AUTO_INCREMENT=10000;";
|
||||
MysqlObject.Exec_Sql(sql);
|
||||
}
|
||||
|
||||
//HOOKServerId生成uuid
|
||||
Cb_ItemGloballyUniqueIdentifier_t_SetServerId_Enter_Func["_装备拓展_"] <- function(args) {
|
||||
args[1] = GenerateUUID();
|
||||
// print("赋予唯一id: " + args[1]);
|
||||
return args;
|
||||
}.bindenv(this);
|
||||
|
||||
// //补充数据包
|
||||
// Cb_CInventory_MakeItemPacket_Leave_Func["_装备拓展_"] <- function(args) {
|
||||
|
||||
// // local ItemObj = Item(Sq_CallFunc(S_Ptr("0x084FC1DE"), "int", ["pointer", "int", "int", "pointer"], args[0], args[1], args[2]));
|
||||
// // print("装备编号: " + ItemObj.GetIndex());
|
||||
// // local Pack = Packet(args[3]);
|
||||
// // local Buffer = Memory.alloc(30);
|
||||
// // //无需重置为0 需要写数据的地方自己会覆写
|
||||
|
||||
// // Buffer.add(18).writeInt(NativePointer())
|
||||
|
||||
// // Pack.Put_BinaryEx(DB_JewelSocketData.C_Object, 30);
|
||||
// }.bindenv(this);
|
||||
|
||||
//额外数据包,发送装备数据给本地处理
|
||||
Cb_InterfacePacketBuf_put_packet_Leave_Func["_装备拓展_"] <- function(args) {
|
||||
local Inven_Item = NativePointer(args[1]);
|
||||
if (Inven_Item.add(1).readU8() == 1) {
|
||||
local Uuid = Inven_Item.add(21).readInt();
|
||||
if (Uuid< 10000) {
|
||||
local uuid = GenerateUUID();
|
||||
Inven_Item.add(21).writeInt(uuid);
|
||||
}
|
||||
}
|
||||
}.bindenv(this);
|
||||
}
|
||||
|
||||
function GenerateUUID() {
|
||||
MysqlObject.Exec_Sql("INSERT INTO equip_only_id VALUES ();");
|
||||
local Ret = MysqlObject.Select("SELECT LAST_INSERT_ID() AS new_auto_id;", ["int"]);
|
||||
return Ret[0][0];
|
||||
}
|
||||
|
||||
// Cb_CInventory_insertItemIntoInventory_Leave_Func["_装备拓展_"] <- function(args) {
|
||||
// local SUser = User(NativePointer(args[0]).readPointer());
|
||||
// local ItemObject = Item(NativePointer(Haker.CpuContext.ebp).add(12).C_Object);
|
||||
// local ServerId = NativePointer(ItemObject.C_Object).add(21).readInt();
|
||||
// //数据库主键从10000开始自增
|
||||
// if (ServerId< 10000) {
|
||||
// local NewUuid = GenerateUUID();
|
||||
// NativePointer(ItemObject.C_Object).add(21).writeInt(NewUuid);
|
||||
// }
|
||||
// }.bindenv(this);
|
||||
}
|
||||
|
||||
|
||||
Timer.SetTimeOut(function() {
|
||||
|
||||
getroottable()._EquipmentExpand_ <- EquipmentExpandC();
|
||||
|
||||
print("特殊插件·装备拓展 - 已加载");
|
||||
}, 1);
|
||||
|
|
@ -83,6 +83,11 @@
|
|||
"毁梦定制战力系统/毁梦定制战力系统.nut"
|
||||
]
|
||||
},
|
||||
"毁梦定制装备继承": {
|
||||
"Script": [
|
||||
"毁梦定制装备继承/毁梦定制装备继承.nut"
|
||||
]
|
||||
},
|
||||
"卢克": {
|
||||
"Script": [
|
||||
"卢克/LukeClass.nut"
|
||||
|
|
@ -107,6 +112,36 @@
|
|||
"Script": [
|
||||
"装备跨界/装备跨界.nut"
|
||||
]
|
||||
},
|
||||
"灵魂救赎武器": {
|
||||
"Script": [
|
||||
"灵魂救赎武器/灵魂救赎武器.nut"
|
||||
]
|
||||
},
|
||||
"装备拓展": {
|
||||
"Script": [
|
||||
"装备拓展/装备拓展.nut"
|
||||
]
|
||||
},
|
||||
"异界装备升级": {
|
||||
"Script": [
|
||||
"异界装备升级/异界装备升级.nut"
|
||||
]
|
||||
},
|
||||
"黄金哥布林袖珍罐": {
|
||||
"Script": [
|
||||
"黄金哥布林袖珍罐/黄金哥布林袖珍罐.nut"
|
||||
]
|
||||
},
|
||||
"誉名录": {
|
||||
"Script": [
|
||||
"誉名录/誉名录.nut"
|
||||
]
|
||||
},
|
||||
"换装系统": {
|
||||
"Script": [
|
||||
"换装系统/换装系统.nut"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
文件名:升级券.nut
|
||||
路径:MyProject/升级券/升级券.nut
|
||||
创建日期:2025-12-14 21:32
|
||||
文件用途:
|
||||
*/
|
||||
|
||||
class ItemEquipmentUpgrade {
|
||||
|
||||
//配置表
|
||||
Info = null;
|
||||
|
||||
//用户状态表
|
||||
UserState = null;
|
||||
|
||||
//基础所需材料
|
||||
BasicMaterials = null;
|
||||
//等级倍率
|
||||
LevelRate = 1.0;
|
||||
//品级倍率
|
||||
RarityRate = 1.0;
|
||||
//禁止升级Map
|
||||
BanEquipmentMap = null;
|
||||
//特殊装备Map
|
||||
SpecialEquipmentMap = null;
|
||||
//特殊材料组
|
||||
SpecialMaterialsGroup = null;
|
||||
|
||||
constructor() {
|
||||
Info = {};
|
||||
UserState = {};
|
||||
|
||||
//读取PVF
|
||||
InitPvf();
|
||||
|
||||
//注册客户端收包
|
||||
RegisterClient();
|
||||
}
|
||||
|
||||
|
||||
function RegisterClient() {
|
||||
ClientSocketPackFuncMap.rawset(21010001, function(SUser, Jso) {
|
||||
//获取背包
|
||||
local InvenObj = SUser.GetInven();
|
||||
//装备ID
|
||||
local Id = Jso.item.ItemId;
|
||||
local pvfItem = PvfItem.GetPvfItemById(Id)
|
||||
local Level = pvfItem.GetUsableLevel();
|
||||
|
||||
//判断是否为异界装备 不是就返回 或者等级已经是85了也返回
|
||||
if (pvfItem.GetRarity() != 5 || Level == 85) {
|
||||
SUser.SendJso({
|
||||
op = 21010002,
|
||||
error = 1
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
//普通升级装备
|
||||
else {
|
||||
local equ = PvfItem.GetPvfItemById(Id);
|
||||
local Rarity = equ.GetRarity();
|
||||
local Level = equ.GetUsableLevel();
|
||||
local RarityCalculateRate = Rarity * RarityRate;
|
||||
local LevelCalculateRate = Level * LevelRate;
|
||||
local MgArr = [];
|
||||
foreach(object in BasicMaterials) {
|
||||
//查询自己有多少个道具
|
||||
MgArr.push({
|
||||
Item = object.Item,
|
||||
RealCount = InvenObj.GetCountById(object.Item),
|
||||
NeedCount = (object.Count * RarityCalculateRate * LevelCalculateRate).tointeger()
|
||||
});
|
||||
}
|
||||
SUser.SendJso({
|
||||
op = 21010002,
|
||||
MgInfo = MgArr
|
||||
});
|
||||
}
|
||||
}.bindenv(this));
|
||||
|
||||
ClientSocketPackFuncMap.rawset(21010003, function(SUser, Jso) {
|
||||
//获取背包
|
||||
local InvenObj = SUser.GetInven();
|
||||
//装备ID
|
||||
local Id = Jso.item.ItemId;
|
||||
local equ = PvfItem.GetPvfItemById(Id);
|
||||
local Level = equ.GetUsableLevel();
|
||||
local giveid = Id + 220000000;
|
||||
if (Level == 75 || Level == 80) {
|
||||
giveid = Id + 1000000;
|
||||
}
|
||||
|
||||
//获取对应槽位的装备
|
||||
local SlotItem = InvenObj.GetSlot(Inven.INVENTORY_TYPE_ITEM, 9 + Jso.item.Pos);
|
||||
if (SlotItem.GetIndex() != Id) {
|
||||
SUser.SendNotiBox(" 升级失败 升级时请不要操作背包", 1);
|
||||
return;
|
||||
} else {
|
||||
local equ = PvfItem.GetPvfItemById(Id);
|
||||
local Rarity = equ.GetRarity();
|
||||
local Level = equ.GetUsableLevel();
|
||||
local RarityCalculateRate = Rarity * RarityRate;
|
||||
local LevelCalculateRate = Level * LevelRate;
|
||||
local MgArr = [];
|
||||
foreach(object in BasicMaterials) {
|
||||
//查询自己有多少个道具
|
||||
MgArr.push({
|
||||
Id = object.Item,
|
||||
Count = (object.Count * RarityCalculateRate * LevelCalculateRate).tointeger()
|
||||
});
|
||||
}
|
||||
|
||||
local Flag = InvenObj.CheckArrItemCount(MgArr);
|
||||
if (!Flag) {
|
||||
print("扣除失败");
|
||||
SUser.SendNotiBox(" 升级失败 升级时请不要操作背包", 1);
|
||||
return;
|
||||
} else {
|
||||
local SlogInfo = SUser.GiveItem(giveid, 1);
|
||||
if (!SlogInfo) {
|
||||
SUser.SendNotiBox(" 升级失败 请确定背包有空余空间", 1);
|
||||
return;
|
||||
}
|
||||
|
||||
local giveItemObj = InvenObj.GetSlot(1, SlogInfo[1])
|
||||
//扣除道具
|
||||
InvenObj.DeleteArrItemCount(MgArr);
|
||||
|
||||
local forging = SlotItem.GetForging(); //锻造
|
||||
local upgrade = SlotItem.GetUpgrade(); //强化
|
||||
local amplification = SlotItem.GetAmplification(); //增幅
|
||||
local enchanting = SlotItem.GetEnchanting(); //附魔
|
||||
|
||||
if (forging > 0) {
|
||||
giveItemObj.SetForging(forging);
|
||||
}
|
||||
|
||||
if (upgrade > 0) {
|
||||
giveItemObj.SetUpgrade(upgrade);
|
||||
}
|
||||
|
||||
if (amplification != 0) {
|
||||
giveItemObj.SetAmplification(amplification);
|
||||
}
|
||||
giveItemObj.SetEnchanting(enchanting);
|
||||
giveItemObj.SetAdd_Info(SlotItem.GetAdd_Info()); //品级
|
||||
giveItemObj.Flush();
|
||||
|
||||
//销毁背包中的道具
|
||||
SlotItem.Delete();
|
||||
//刷新玩家背包列表
|
||||
SUser.SendUpdateItemList(1, 0, 9 + Jso.item.Pos);
|
||||
SUser.SendUpdateItemList(1, 0, SlogInfo[1]);
|
||||
|
||||
//刷新账号金库列表
|
||||
SUser.SendNotiBox(" 升级成功", 1);
|
||||
SUser.SendJso({
|
||||
op = 21010004
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}.bindenv(this));
|
||||
};
|
||||
|
||||
function InitPvf() {
|
||||
// getroottable()._Script_Data_Init_ <- false;
|
||||
Script();
|
||||
ScriptData.GetFileData("etc/rindro/itemtool/itemotherworldupgrade/itemotherworldupgrade.etc", function(DataTable, Data) {
|
||||
while (!Data.Eof()) {
|
||||
local Fragment = Data.Get();
|
||||
if (Fragment == "[BASIC MATERIALS]") {
|
||||
BasicMaterials = [];
|
||||
while (true) {
|
||||
local Fbuf = Data.Get();
|
||||
if (Fbuf == "[/BASIC MATERIALS]") {
|
||||
break;
|
||||
}
|
||||
local T = {
|
||||
Item = Fbuf,
|
||||
Count = Data.Get()
|
||||
}
|
||||
BasicMaterials.push(T);
|
||||
}
|
||||
} else if (Fragment == "[LEVEL RATE]") {
|
||||
LevelRate = Data.Get()
|
||||
} else if (Fragment == "[RARITY RATE]") {
|
||||
RarityRate = Data.Get()
|
||||
}
|
||||
}
|
||||
}.bindenv(this));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Timer.SetTimeOut(function() {
|
||||
|
||||
getroottable()._ItemEquipmentUpgrade_ <- ItemEquipmentUpgrade();
|
||||
print("装备升级 - 已加载");
|
||||
}, 1);
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
文件名:换装系统.nut
|
||||
路径:_DPS_/_BuiltProject/换装系统/换装系统.nut
|
||||
创建日期:2026-03-02 04:16
|
||||
文件用途:
|
||||
*/
|
||||
|
||||
class OutfitSystem {
|
||||
|
||||
MysqlObject = null;
|
||||
|
||||
ItemSlot = [
|
||||
[0, 13], //护肩
|
||||
[0, 14], //下装
|
||||
[0, 15], //鞋子
|
||||
[0, 12], //上衣
|
||||
[0, 16], //腰带
|
||||
[0, 10], //武器
|
||||
[0, 18], //手镯
|
||||
[0, 20], //辅助装备
|
||||
[-1, -1], //耳环
|
||||
[0, 11], //称号
|
||||
[0, 17], //项链
|
||||
[0, 19], //戒指
|
||||
[0, 21], //魔法石
|
||||
[-1, -1], //武器装扮
|
||||
[1, 9], //光环
|
||||
[1, 1], //头部
|
||||
[1, 6], //胸部
|
||||
[1, 7], //腰部
|
||||
[1, 0], //帽子
|
||||
[1, 3], //上衣
|
||||
[1, 4], //下装
|
||||
[1, 2], //脸部
|
||||
[1, 8], //皮肤
|
||||
[1, 5], //鞋
|
||||
[2, 22] //宠物
|
||||
];
|
||||
|
||||
|
||||
constructor() {
|
||||
|
||||
MysqlObject = Mysql(Str_Ptr("127.0.0.1"), 3306, Str_Ptr("taiwan_cain"), Str_Ptr("game"), Str_Ptr("uu5!^%jg"));
|
||||
MysqlObject.Exec_Sql(format("SET NAMES %s", "latin1"));
|
||||
|
||||
local check_table_sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'OutfitSystem';"
|
||||
local Ret = MysqlObject.Select(check_table_sql, ["int"]);
|
||||
if (Ret.len() == 0 || Ret[0][0] == 0) {
|
||||
local sql = "CREATE TABLE OutfitSystem (cid VARCHAR(128) NOT NULL COMMENT '角色CID', info VARCHAR(512) NOT NULL COMMENT '信息字符串', PRIMARY KEY (cid)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '角色换装信息表';";
|
||||
MysqlObject.Exec_Sql(sql);
|
||||
}
|
||||
|
||||
//记录装备
|
||||
ClientSocketPackFuncMap.rawset(21015001, function(SUser, Jso) {
|
||||
local Slot = Jso.Slot;
|
||||
local EquipInfo = Json.Encode(Jso.EquipInfo);
|
||||
local SetKey = format("%d_%d", SUser.GetCID(), Slot);
|
||||
MysqlObject.Exec_Sql(format("INSERT INTO OutfitSystem (cid, info) VALUES ('%s', '%s') ON DUPLICATE KEY UPDATE info = '%s';", SetKey, EquipInfo, EquipInfo));
|
||||
}.bindenv(this));
|
||||
|
||||
//清空装备
|
||||
ClientSocketPackFuncMap.rawset(21015005, function(SUser, Jso) {
|
||||
local Slot = Jso.Slot;
|
||||
local SetKey = format("%d_%d", SUser.GetCID(), Slot);
|
||||
MysqlObject.Exec_Sql(format("DELETE FROM OutfitSystem WHERE cid = '%s';", SetKey));
|
||||
}.bindenv(this));
|
||||
|
||||
//查询配置
|
||||
ClientSocketPackFuncMap.rawset(21015003, function(SUser, Jso) {
|
||||
local Slot = Jso.Slot;
|
||||
local SetKey = format("%d_%d", SUser.GetCID(), Slot);
|
||||
local Ret = MysqlObject.Select(format("SELECT info FROM OutfitSystem WHERE cid = '%s';", SetKey), ["string"]);
|
||||
if (Ret.len() == 0) {
|
||||
SUser.SendJso({
|
||||
op = 21015004,
|
||||
Slot = Slot,
|
||||
EquipInfo = null
|
||||
});
|
||||
} else {
|
||||
SUser.SendJso({
|
||||
op = 21015004,
|
||||
Slot = Slot,
|
||||
EquipInfo = Json.Decode(Ret[0][0])
|
||||
});
|
||||
}
|
||||
|
||||
}.bindenv(this));
|
||||
|
||||
//换装请求
|
||||
Gm_InputFunc_Handle["HZ"] <- function(SUser, CmdString) {
|
||||
local count = -1;
|
||||
local pos = 0;
|
||||
local handler = [];
|
||||
do {
|
||||
local start = pos;
|
||||
pos = CmdString.find(" ", pos + 1);
|
||||
if (pos != null) {
|
||||
handler.append(CmdString.slice(start + 1, pos));
|
||||
} else
|
||||
handler.append(CmdString.slice(start + 1));
|
||||
count = count + 1
|
||||
} while (pos != null)
|
||||
|
||||
//得到空格数量
|
||||
if (count != 1) return;
|
||||
local Slot = handler[1].tointeger() - 1;
|
||||
local SetKey = format("%d_%d", SUser.GetCID(), Slot);
|
||||
local Ret = MysqlObject.Select(format("SELECT info FROM OutfitSystem WHERE cid = '%s';", SetKey), ["string"]);
|
||||
if (Ret.len() != 0) {
|
||||
local EquipInfoList = Json.Decode(Ret[0][0]);
|
||||
local ChangeFlag = true;
|
||||
foreach(_Index, EquipInfo in EquipInfoList) {
|
||||
local EquipIndex = EquipInfo[0];
|
||||
//没有装备
|
||||
if (EquipIndex == 0) continue;
|
||||
//耳环和武器装扮
|
||||
if (ItemSlot[_Index][0] == -1) continue;
|
||||
//寻找符合的装备
|
||||
local Flag = ChanageEquip(SUser, ItemSlot[_Index], EquipInfo);
|
||||
if(!Flag) ChangeFlag = false;
|
||||
}
|
||||
|
||||
Sq_CallFunc(S_Ptr("0x0867ba5c"), "int", ["pointer", "int", "int", "int"], SUser.C_Object, 0, 2, 0);
|
||||
Sq_CallFunc(S_Ptr("0x0867ba5c"), "int", ["pointer", "int", "int", "int"], SUser.C_Object, 1, 2, 1);
|
||||
Sq_CallFunc(S_Ptr("0x0867ba5c"), "int", ["pointer", "int", "int", "int"], SUser.C_Object, 7, 2, 7);
|
||||
SUser.SendItemSpace(7);
|
||||
SUser.SendItemSpace(1);
|
||||
SUser.SendItemSpace(0);
|
||||
|
||||
if(ChangeFlag) {
|
||||
SUser.SendNotiPacketMessage("换装成功!", 8);
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
}.bindenv(this);
|
||||
}
|
||||
|
||||
function ChanageEquip(SUser, SlotInfo, EquipInfo) {
|
||||
local InvenObj = SUser.GetInven();
|
||||
local EquipIndex = EquipInfo[0];
|
||||
local Upgrade = EquipInfo[1];
|
||||
local Amplification = EquipInfo[2];
|
||||
local Forging = EquipInfo[3];
|
||||
local Enchanting = EquipInfo[4];
|
||||
local StartIndex = 0;
|
||||
local EndIndex = 0;
|
||||
local FindType = 0;
|
||||
|
||||
//装备
|
||||
if (SlotInfo[0] == 0) {
|
||||
StartIndex = 3;
|
||||
EndIndex = 56;
|
||||
FindType = 1;
|
||||
}
|
||||
//时装
|
||||
else if (SlotInfo[0] == 1) {
|
||||
StartIndex = 0;
|
||||
EndIndex = 104;
|
||||
FindType = 2;
|
||||
}
|
||||
//宠物
|
||||
else if (SlotInfo[0] == 2) {
|
||||
StartIndex = 0;
|
||||
EndIndex = 104;
|
||||
FindType = 3;
|
||||
}
|
||||
|
||||
for (local i = StartIndex; i< EndIndex; i++) {
|
||||
local Inven_Item = InvenObj.GetSlot(FindType, i);
|
||||
if (Inven_Item) {
|
||||
local Index = Inven_Item.GetIndex();
|
||||
if (Index == EquipIndex) {
|
||||
//对比属性
|
||||
local EquipUpgrade = Inven_Item.GetUpgrade();
|
||||
local EquipAmplification = Inven_Item.GetAmplification();
|
||||
local EquipForging = Inven_Item.GetForging();
|
||||
local EquipEnchanting = Inven_Item.GetEnchanting();
|
||||
// if (EquipUpgrade == Upgrade && EquipAmplification == Amplification && EquipForging == Forging && EquipEnchanting == Enchanting) {
|
||||
//对比成功
|
||||
if (SlotInfo[0] == 2) {
|
||||
Sq_CallFunc(S_Ptr("0x08500688"), "int", ["pointer", "int", "int", "int", "int"], InvenObj.C_Object, 3, i, 0, 22);
|
||||
return true;
|
||||
} else {
|
||||
//装备和时装
|
||||
Sq_CallFunc(S_Ptr("0x0865EED2"), "int", ["pointer", "int", "short", "int"], SUser.C_Object, SlotInfo[0], i, SlotInfo[1]);
|
||||
return true;
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Timer.SetTimeOut(function() {
|
||||
getroottable()._OutfitSystem_ <- OutfitSystem();
|
||||
print("换装系统 - 已加载");
|
||||
|
||||
|
||||
/*
|
||||
对于宠物的更换 走的不是装备的变更逻辑
|
||||
//move item
|
||||
Sq_CallFunc(S_Ptr("0x08500688"), "int", ["pointer", "int", "int", "int", "int"], InvenObj.C_Object, 3, 0, 0, 22);
|
||||
//刷新宠物
|
||||
Sq_CallFunc(S_Ptr("0x0867ba5c"), "int", ["pointer", "int", "int", "int"], SUser.C_Object, 1, 2, 1);
|
||||
//刷新宠物背包
|
||||
SUser.SendItemSpace(7);
|
||||
*/
|
||||
}, 1);
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
class HM_InheritC {
|
||||
|
||||
|
||||
constructor() {
|
||||
//注册客户端收包
|
||||
RegisterClient();
|
||||
|
||||
}
|
||||
|
||||
function RegisterClient() {
|
||||
ClientSocketPackFuncMap.rawset(21013001, function(SUser, Jso) {
|
||||
//获取背包
|
||||
local InvenObj = SUser.GetInven();
|
||||
local Equip1 = InvenObj.GetSlot(Inven.INVENTORY_TYPE_ITEM, 9 + Jso.item.Pos);
|
||||
local Equip2 = InvenObj.GetSlot(Inven.INVENTORY_TYPE_ITEM, 9 + Jso.item2.Pos);
|
||||
|
||||
local Level1 = PvfItem.GetPvfItemById(Equip1.GetIndex()).GetUsableLevel();
|
||||
local Level2 = PvfItem.GetPvfItemById(Equip2.GetIndex()).GetUsableLevel();
|
||||
|
||||
|
||||
|
||||
if (Level1< 50 || Level2< 50) {
|
||||
SUser.SendNotiBox(" 继承失败 装备等级不可低于50", 1);
|
||||
return;
|
||||
}
|
||||
|
||||
local Rarity1 = PvfItem.GetPvfItemById(Equip1.GetIndex()).GetRarity();
|
||||
local Rarity2 = PvfItem.GetPvfItemById(Equip2.GetIndex()).GetRarity();
|
||||
|
||||
if (Rarity1< 4 || Rarity2< 4) {
|
||||
SUser.SendNotiBox(" 继承失败 装备品级不可低于史诗", 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Equip1.GetIndex() != Jso.item.ItemId || Equip2.GetIndex() != Jso.item2.ItemId) {
|
||||
SUser.SendNotiBox(" 继承失败 继承时请不要操作背包", 1);
|
||||
return;
|
||||
}
|
||||
|
||||
local itemType1 = NativePointer(PvfItem.GetPvfItemById(Jso.item.ItemId).C_Object).add(141 * 4).readU32();
|
||||
local itemType2 = NativePointer(PvfItem.GetPvfItemById(Jso.item2.ItemId).C_Object).add(141 * 4).readU32();
|
||||
if (itemType1 != itemType2) {
|
||||
SUser.SendNotiBox(" 继承失败 继承时需要同类型装备", 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
local forging = Equip1.GetForging(); //锻造
|
||||
local upgrade = Equip1.GetUpgrade(); //强化
|
||||
local amplification = Equip1.GetAmplification(); //增幅
|
||||
local enchanting = Equip1.GetEnchanting(); //附魔
|
||||
local Jewel = NativePointer(Equip1.C_Object).add(25).readU32(); //镶嵌
|
||||
|
||||
Equip2.SetForging(forging);
|
||||
Equip2.SetUpgrade(upgrade);
|
||||
Equip2.SetAmplification(amplification);
|
||||
Equip2.SetEnchanting(enchanting);
|
||||
Equip2.Flush();
|
||||
|
||||
NativePointer(Equip2.C_Object).add(25).writeU32(Jewel);
|
||||
Equip1.Delete();
|
||||
SUser.SendUpdateItemList(1, 0, 9 + Jso.item.Pos);
|
||||
SUser.SendUpdateItemList(1, 0, 9 + Jso.item2.Pos);
|
||||
SUser.GiveItem(Jso.item.ItemId, 1);
|
||||
|
||||
SUser.SendNotiBox(" 继承成功", 1);
|
||||
SUser.SendJso({
|
||||
op = 21013002
|
||||
});
|
||||
|
||||
}.bindenv(this));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Timer.SetTimeOut(function() {
|
||||
getroottable()._HM_InheritC_ <- HM_InheritC();
|
||||
|
||||
print("双端插件·毁梦定制继承系统 - 已加载");
|
||||
}, 1);
|
||||
|
|
@ -0,0 +1,419 @@
|
|||
/*
|
||||
文件名:灵魂救赎武器.nut
|
||||
路径:_DPS_/_BuiltProject/灵魂救赎武器/灵魂救赎武器.nut
|
||||
创建日期:2026-01-20 19:24
|
||||
文件用途:
|
||||
*/
|
||||
|
||||
class SoulSalvationC {
|
||||
|
||||
|
||||
MysqlObject = null;
|
||||
|
||||
//灵魂救赎武器标识 (阶段1)
|
||||
Equipment1List = null;
|
||||
//1阶段所需灵魂数量
|
||||
Stage1SoulCount = 1000;
|
||||
//1阶段进阶所需材料
|
||||
Equipment1Upgrade = null;
|
||||
//灵魂救赎武器标识 (阶段2)
|
||||
Equipment2List = null;
|
||||
//2阶段通关镇魂曲副本的ID
|
||||
Stage2DgnList = null;
|
||||
//灵魂救赎武器标识 (阶段3)
|
||||
Equipment3List = null;
|
||||
|
||||
//数据
|
||||
data = null;
|
||||
|
||||
constructor() {
|
||||
Equipment1List = {};
|
||||
Equipment1Upgrade = {};
|
||||
Equipment2List = {};
|
||||
Stage2DgnList = {};
|
||||
Equipment3List = {};
|
||||
data = {};
|
||||
|
||||
//创建数据库
|
||||
MysqlObject = Mysql(Str_Ptr("127.0.0.1"), 3306, Str_Ptr("taiwan_cain"), Str_Ptr("game"), Str_Ptr("uu5!^%jg"));
|
||||
MysqlObject.Exec_Sql(format("SET NAMES %s", "latin1"));
|
||||
|
||||
local check_table_sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'soulsalvation';"
|
||||
local Ret = MysqlObject.Select(check_table_sql, ["int"]);
|
||||
if (Ret.len() == 0 || Ret[0][0] == 0) {
|
||||
local sql = "CREATE TABLE soulsalvation (`uid` INT(11) NOT NULL COMMENT '主键ID',`soul_id` INT(11) NOT NULL DEFAULT 0 COMMENT '灵魂ID', `soul_count` INT(11) NOT NULL DEFAULT 0 COMMENT '数值字段(默认值0)',PRIMARY KEY (`uid`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='soulsalvation表';";
|
||||
MysqlObject.Exec_Sql(sql);
|
||||
}
|
||||
|
||||
//读取PVF
|
||||
InitPvf();
|
||||
|
||||
//注册客户端收包
|
||||
RegisterClient();
|
||||
|
||||
//读取数据库数据到缓存
|
||||
InitMysqlData();
|
||||
|
||||
}
|
||||
|
||||
function RegisterClient() {
|
||||
//测试用客户端主动查询灵魂数
|
||||
ClientSocketPackFuncMap.rawset(21011001, function(SUser, Jso) {
|
||||
local SendInfo = GetUserData(SUser);
|
||||
SUser.SendJso({
|
||||
op = 21011002,
|
||||
Info = SendInfo
|
||||
})
|
||||
}.bindenv(this));
|
||||
|
||||
Cb_CParty_OnKillMonster_Leave_Func.rawset("SoulSalvationC", function(args) {
|
||||
local SUser = User(args[1]);
|
||||
//获取佩戴的武器
|
||||
local Weapon = GetUserWeapon(SUser);
|
||||
local WeaponIndex = Weapon.GetIndex();
|
||||
//可积累灵魂数量
|
||||
if (Equipment1List.rawin(WeaponIndex)) {
|
||||
local uuid = Weapon.GetUuid();
|
||||
//有数据则+1 无数据则新增
|
||||
if (data.rawin(uuid)) {
|
||||
if (data[uuid].soul_count< Stage1SoulCount)
|
||||
data[uuid].soul_count += 1;
|
||||
} else {
|
||||
data[uuid] <- {
|
||||
soul_count = 1,
|
||||
soul_id = 0
|
||||
};
|
||||
}
|
||||
SUser.SendJso({
|
||||
op = 21011004,
|
||||
uuid = uuid,
|
||||
info = data[uuid]
|
||||
})
|
||||
}
|
||||
}.bindenv(this));
|
||||
|
||||
//上线时 获取自己的灵魂武器信息
|
||||
Cb_reach_game_world_Func.rawset("SoulSalvationC", function(SUser) {
|
||||
local SendInfo = GetUserData(SUser);
|
||||
SUser.SendJso({
|
||||
op = 21011002,
|
||||
Info = SendInfo
|
||||
})
|
||||
}.bindenv(this));
|
||||
|
||||
//查看他人信息的时候 获取灵魂武器信息
|
||||
Cb_GetUserInfo_Leave_Func.rawset("SoulSalvationC", function(args) {
|
||||
local SUser = User(args[1])
|
||||
local CheckWorldId = NativePointer(args[2]).add(13).readShort();
|
||||
local CheckUser = World.GetUserBySession(CheckWorldId);
|
||||
if (CheckUser) {
|
||||
local SendInfo = GetUserData(CheckUser);
|
||||
SUser.SendJso({
|
||||
op = 21011006,
|
||||
Info = SendInfo
|
||||
})
|
||||
}
|
||||
}.bindenv(this));
|
||||
|
||||
//每5分钟固化一次数据到数据库
|
||||
Timer.RemoveCronTask("SoulSalvationC");
|
||||
Timer.SetCronTask(function() {
|
||||
local DataList = [];
|
||||
foreach(uuid, value in data) {
|
||||
local str = format("(%d,%d,%d),", uuid, value.soul_id, value.soul_count);
|
||||
DataList.push(str);
|
||||
}
|
||||
local sql = "REPLACE INTO soulsalvation (uid, soul_id, soul_count) VALUES";
|
||||
foreach(value in DataList) {
|
||||
sql += value;
|
||||
}
|
||||
//去除最后一个,
|
||||
sql = sql.slice(0, -1);
|
||||
sql += ";";
|
||||
MysqlObject.Exec_Sql(sql);
|
||||
}.bindenv(this), {
|
||||
Cron = "0 */5 * * * *",
|
||||
Name = "SoulSalvationC"
|
||||
});
|
||||
|
||||
//1阶段晋级逻辑
|
||||
ClientSocketPackFuncMap.rawset(21011007, function(SUser, Jso) {
|
||||
//获取背包
|
||||
local InvenObj = SUser.GetInven();
|
||||
//装备ID
|
||||
local Id = Jso.item.ItemId;
|
||||
//判断是否为灵魂武器一阶段
|
||||
if (!Equipment1List.rawin(Id)) {
|
||||
SUser.SendJso({
|
||||
op = 21011008,
|
||||
error = 1
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
//判断灵魂数量是否已经达到要求
|
||||
local SlotItem = InvenObj.GetSlot(Inven.INVENTORY_TYPE_ITEM, 9 + Jso.item.Pos);
|
||||
local uuid = SlotItem.GetUuid();
|
||||
local SoulCount = 0;
|
||||
if (data.rawin(uuid)) {
|
||||
SoulCount = data[uuid].soul_count;
|
||||
}
|
||||
if (SoulCount< Stage1SoulCount) {
|
||||
SUser.SendJso({
|
||||
op = 21011008,
|
||||
error = 2
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
local MgArr = [];
|
||||
foreach(Index, Count in Equipment1Upgrade) {
|
||||
//查询自己有多少个道具
|
||||
MgArr.push({
|
||||
Item = Index,
|
||||
RealCount = InvenObj.GetCountById(Index),
|
||||
NeedCount = Count.tointeger()
|
||||
});
|
||||
}
|
||||
SUser.SendJso({
|
||||
op = 21011008,
|
||||
MgInfo = MgArr
|
||||
});
|
||||
}.bindenv(this));
|
||||
|
||||
//1阶段晋级逻辑
|
||||
ClientSocketPackFuncMap.rawset(21011009, function(SUser, Jso) {
|
||||
//获取背包
|
||||
local InvenObj = SUser.GetInven();
|
||||
//装备ID
|
||||
local Id = Jso.item.ItemId;
|
||||
//判断是否为灵魂武器一阶段
|
||||
if (!Equipment1List.rawin(Id)) {
|
||||
SUser.SendJso({
|
||||
op = 21011008,
|
||||
error = 1
|
||||
});
|
||||
return;
|
||||
}
|
||||
//要给予的装备ID
|
||||
local giveid = Id + 1;
|
||||
|
||||
//获取对应槽位的装备
|
||||
local SlotItem = InvenObj.GetSlot(Inven.INVENTORY_TYPE_ITEM, 9 + Jso.item.Pos);
|
||||
local uuid = SlotItem.GetUuid();
|
||||
if (SlotItem.GetIndex() != Id) {
|
||||
SUser.SendNotiBox(" 升级失败 升级时请不要操作背包", 1);
|
||||
return;
|
||||
} else {
|
||||
local MgArr = [];
|
||||
foreach(Index, Count in Equipment1Upgrade) {
|
||||
//查询自己有多少个道具
|
||||
MgArr.push({
|
||||
Id = Index,
|
||||
Count = Count.tointeger()
|
||||
});
|
||||
}
|
||||
|
||||
local Flag = InvenObj.CheckArrItemCount(MgArr);
|
||||
if (!Flag) {
|
||||
SUser.SendNotiBox(" 升级失败 升级时请不要操作背包", 1);
|
||||
return;
|
||||
} else {
|
||||
local SlogInfo = SUser.GiveItem(giveid, 1);
|
||||
if (!SlogInfo) {
|
||||
SUser.SendNotiBox(" 升级失败 请确定背包有空余空间", 1);
|
||||
return;
|
||||
}
|
||||
local giveItemObj = InvenObj.GetSlot(1, SlogInfo[1])
|
||||
//扣除道具
|
||||
InvenObj.DeleteArrItemCount(MgArr);
|
||||
|
||||
local forging = SlotItem.GetForging(); //锻造
|
||||
local upgrade = SlotItem.GetUpgrade(); //强化
|
||||
local amplification = SlotItem.GetAmplification(); //增幅
|
||||
local enchanting = SlotItem.GetEnchanting(); //附魔
|
||||
if (forging > 0) {
|
||||
giveItemObj.SetForging(forging);
|
||||
}
|
||||
if (upgrade > 0) {
|
||||
giveItemObj.SetUpgrade(upgrade);
|
||||
}
|
||||
if (amplification != 0) {
|
||||
giveItemObj.SetAmplification(amplification);
|
||||
}
|
||||
giveItemObj.SetEnchanting(enchanting);
|
||||
giveItemObj.SetAdd_Info(SlotItem.GetAdd_Info()); //品级
|
||||
giveItemObj.Flush();
|
||||
|
||||
//销毁背包中的道具
|
||||
SlotItem.Delete();
|
||||
//刷新玩家背包列表
|
||||
SUser.SendUpdateItemList(1, 0, 9 + Jso.item.Pos);
|
||||
SUser.SendUpdateItemList(1, 0, SlogInfo[1]);
|
||||
|
||||
//刷新
|
||||
SUser.SendNotiBox(" 升级成功", 1);
|
||||
SUser.SendJso({
|
||||
op = 21011010
|
||||
});
|
||||
|
||||
//从缓存中移除这个uuid
|
||||
data.rawdelete(uuid);
|
||||
local Sql = "DELETE FROM soulsalvation WHERE uid = " + uuid + ";";
|
||||
MysqlObject.Exec_Sql(Sql);
|
||||
}
|
||||
}
|
||||
}.bindenv(this));
|
||||
|
||||
//2阶段通关镇魂曲获取璀璨灵魂结晶
|
||||
Cb_ClearDungeon_Enter_Func.rawset("SoulSalvationC", function(args) {
|
||||
local PartyObj = Party(args[0]);
|
||||
if (PartyObj) {
|
||||
local Bfobj = PartyObj.GetBattleField();
|
||||
local DgnObj = Bfobj.GetDgn();
|
||||
if (DgnObj) {
|
||||
local Dungeon_Id = DgnObj.GetId();
|
||||
if (Stage2DgnList.rawin(Dungeon_Id)) {
|
||||
//对小队每一个人进行操作
|
||||
PartyObj.ForeachMember(function(SUser, Pos) {
|
||||
//获取佩戴的武器
|
||||
local Weapon = GetUserWeapon(SUser);
|
||||
local WeaponIndex = Weapon.GetIndex();
|
||||
//释魂武器
|
||||
if (Equipment2List.rawin(WeaponIndex)) {
|
||||
SUser.GiveItem(92000 + Dungeon_Id + 1, 1);
|
||||
}
|
||||
print("通关镇魂曲副本");
|
||||
}.bindenv(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
}.bindenv(this));
|
||||
};
|
||||
|
||||
//获取角色的武器
|
||||
function GetUserWeapon(SUser) {
|
||||
local InvenObj = SUser.GetInven();
|
||||
if (!InvenObj) return null;
|
||||
return InvenObj.GetSlot(Inven.INVENTORY_TYPE_BODY, 10);
|
||||
}
|
||||
|
||||
//获取角色的灵魂武器信息
|
||||
function GetUserData(SUser) {
|
||||
//获取背包对象
|
||||
local InvenObj = SUser.GetInven();
|
||||
if (!InvenObj) return {};
|
||||
local UUIDList = [];
|
||||
//遍历身上
|
||||
for (local i = 0; i< 26; i++) {
|
||||
local Inven_Item = InvenObj.GetSlot(Inven.INVENTORY_TYPE_BODY, i);
|
||||
if (Inven_Item) {
|
||||
local Index = Inven_Item.GetIndex();
|
||||
if (Equipment1List.rawin(Index) || Equipment3List.rawin(Index)) {
|
||||
local uuid = Inven_Item.GetUuid();
|
||||
UUIDList.push(uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
//遍历物品栏
|
||||
for (local i = 0; i< 70; i++) {
|
||||
local Inven_Item = InvenObj.GetSlot(Inven.INVENTORY_TYPE_ITEM, i);
|
||||
if (Inven_Item) {
|
||||
local Index = Inven_Item.GetIndex();
|
||||
if (Equipment1List.rawin(Index) || Equipment3List.rawin(Index)) {
|
||||
local uuid = Inven_Item.GetUuid();
|
||||
UUIDList.push(uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
local SendInfo = {};
|
||||
foreach(uuid in UUIDList) {
|
||||
if (data.rawin(uuid)) {
|
||||
SendInfo.rawset(uuid, data[uuid]);
|
||||
} else {
|
||||
data[uuid] <- {
|
||||
soul_count = 0,
|
||||
soul_id = 0
|
||||
};
|
||||
}
|
||||
}
|
||||
return SendInfo;
|
||||
}
|
||||
|
||||
function InitPvf() {
|
||||
Script();
|
||||
ScriptData.GetFileData("etc/rindro/expandequipment/soulsalvation.etc", function(DataTable, Data) {
|
||||
while (!Data.Eof()) {
|
||||
local Fragment = Data.Get();
|
||||
if (Fragment == "[EQUIPMENT1]") {
|
||||
Equipment1List = {};
|
||||
while (true) {
|
||||
local Fbuf = Data.Get();
|
||||
if (Fbuf == "[/EQUIPMENT1]") {
|
||||
break;
|
||||
}
|
||||
Equipment1List.rawset(Fbuf, true);
|
||||
}
|
||||
} else if (Fragment == "[EQUIPMENT2]") {
|
||||
Equipment2List = {};
|
||||
while (true) {
|
||||
local Fbuf = Data.Get();
|
||||
if (Fbuf == "[/EQUIPMENT2]") {
|
||||
break;
|
||||
}
|
||||
Equipment2List.rawset(Fbuf, true);
|
||||
}
|
||||
} else if (Fragment == "[EQUIPMENT3]") {
|
||||
Equipment3List = {};
|
||||
while (true) {
|
||||
local Fbuf = Data.Get();
|
||||
if (Fbuf == "[/EQUIPMENT3]") {
|
||||
break;
|
||||
}
|
||||
Equipment3List.rawset(Fbuf, true);
|
||||
}
|
||||
} else if (Fragment == "[STAGE1 VALUE]") {
|
||||
Stage1SoulCount = Data.Get();
|
||||
} else if (Fragment == "[STAGE1 NEED ITEM]") {
|
||||
Equipment1Upgrade = {};
|
||||
while (true) {
|
||||
local Fbuf = Data.Get();
|
||||
if (Fbuf == "[/STAGE1 NEED ITEM]") {
|
||||
break;
|
||||
}
|
||||
Equipment1Upgrade.rawset(Fbuf, Data.Get());
|
||||
}
|
||||
} else if (Fragment == "[STAGE2 DUNGEON]") {
|
||||
Stage2DgnList = {};
|
||||
while (true) {
|
||||
local Fbuf = Data.Get();
|
||||
if (Fbuf == "[/STAGE2 DUNGEON]") {
|
||||
break;
|
||||
}
|
||||
Stage2DgnList.rawset(Fbuf, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}.bindenv(this));
|
||||
}
|
||||
|
||||
function InitMysqlData() {
|
||||
local Sql = "SELECT * FROM soulsalvation"
|
||||
local Ret = MysqlObject.Select(Sql, ["int", "int", "int"]);
|
||||
foreach(Row in Ret) {
|
||||
local uuid = Row[0];
|
||||
local soul_id = Row[1];
|
||||
local soul_count = Row[2];
|
||||
data.rawset(uuid, {
|
||||
soul_id = soul_id,
|
||||
soul_count = soul_count
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer.SetTimeOut(function() {
|
||||
|
||||
getroottable()._SoulSalvation_ <- SoulSalvationC();
|
||||
print("双端插件·灵魂救赎武器 - 已加载");
|
||||
}, 1);
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
文件名:装备拓展.nut
|
||||
路径:MyProject/装备拓展.nut
|
||||
创建日期:2026-01-15 10:02
|
||||
文件用途:
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
Cb_ItemGloballyUniqueIdentifier_t_SetServerId_Enter_Func <- {};
|
||||
Cb_ItemGloballyUniqueIdentifier_t_SetServerId_Leave_Func <- {};
|
||||
_Hook_Register_Currency_Func_("0x08894782", ["pointer", "int", "pointer"], Cb_ItemGloballyUniqueIdentifier_t_SetServerId_Enter_Func, Cb_ItemGloballyUniqueIdentifier_t_SetServerId_Leave_Func);
|
||||
|
||||
// Cb_CInventory_MakeItemPacket_Enter_Func <- {};
|
||||
// Cb_CInventory_MakeItemPacket_Leave_Func <- {};
|
||||
// _Hook_Register_Currency_Func_("0x084FC6BC", ["pointer", "int", "int", "pointer", "int"], Cb_CInventory_MakeItemPacket_Enter_Func, Cb_CInventory_MakeItemPacket_Leave_Func);
|
||||
|
||||
|
||||
|
||||
|
||||
class EquipmentExpandC {
|
||||
|
||||
MysqlObject = null;
|
||||
|
||||
constructor() {
|
||||
MysqlObject = Mysql(Str_Ptr("127.0.0.1"), 3306, Str_Ptr("taiwan_cain"), Str_Ptr("game"), Str_Ptr("uu5!^%jg"));
|
||||
MysqlObject.Exec_Sql(format("SET NAMES %s", "latin1"));
|
||||
|
||||
local check_table_sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'equip_only_id';"
|
||||
local Ret = MysqlObject.Select(check_table_sql, ["int"]);
|
||||
if (Ret.len() == 0 || Ret[0][0] == 0) {
|
||||
local sql = "CREATE TABLE equip_only_id (id INT(11) NOT NULL AUTO_INCREMENT COMMENT '32位自增唯一ID,初始值10000', PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '纯自增ID表' AUTO_INCREMENT=10000;";
|
||||
MysqlObject.Exec_Sql(sql);
|
||||
}
|
||||
|
||||
//HOOKServerId生成uuid
|
||||
Cb_ItemGloballyUniqueIdentifier_t_SetServerId_Enter_Func["_装备拓展_"] <- function(args) {
|
||||
args[1] = GenerateUUID();
|
||||
return args;
|
||||
}.bindenv(this);
|
||||
|
||||
// //补充数据包
|
||||
// Cb_CInventory_MakeItemPacket_Leave_Func["_装备拓展_"] <- function(args) {
|
||||
|
||||
// // local ItemObj = Item(Sq_CallFunc(S_Ptr("0x084FC1DE"), "int", ["pointer", "int", "int", "pointer"], args[0], args[1], args[2]));
|
||||
// // print("装备编号: " + ItemObj.GetIndex());
|
||||
// // local Pack = Packet(args[3]);
|
||||
// // local Buffer = Memory.alloc(30);
|
||||
// // //无需重置为0 需要写数据的地方自己会覆写
|
||||
|
||||
// // Buffer.add(18).writeInt(NativePointer())
|
||||
|
||||
// // Pack.Put_BinaryEx(DB_JewelSocketData.C_Object, 30);
|
||||
// }.bindenv(this);
|
||||
|
||||
//额外数据包,发送装备数据给本地处理
|
||||
// Cb_InterfacePacketBuf_put_packet_Enter_Func["_装备拓展_"] <- function(args) {
|
||||
// local Inven_Item = NativePointer(args[1]);
|
||||
// if (Inven_Item.add(1).readU8() == 1) {
|
||||
// local Uuid = Inven_Item.add(21).readInt();
|
||||
// if (Uuid< 10000) {
|
||||
// local uuid = GenerateUUID();
|
||||
// Inven_Item.add(21).writeInt(uuid);
|
||||
// }
|
||||
// }
|
||||
// }.bindenv(this);
|
||||
|
||||
//因为装备镶嵌那边更改的数据导致 购买装备时金币会错乱 任意方式刷新一下金币就可以了
|
||||
// Cb_BuyItem_send_Enter["_装备拓展_"] <- function(args) {
|
||||
// local SUser = User(args[1]);
|
||||
// Timer.SetTimeOut(function() {
|
||||
// print("刷新");
|
||||
// SUser.SendItemSpace(0);
|
||||
// }, 1);
|
||||
// }.bindenv(this);
|
||||
}
|
||||
|
||||
function GenerateUUID() {
|
||||
MysqlObject.Exec_Sql("INSERT INTO equip_only_id VALUES ();");
|
||||
local Ret = MysqlObject.Select("SELECT LAST_INSERT_ID() AS new_auto_id;", ["int"]);
|
||||
return Ret[0][0];
|
||||
}
|
||||
|
||||
// Cb_CInventory_insertItemIntoInventory_Leave_Func["_装备拓展_"] <- function(args) {
|
||||
// local SUser = User(NativePointer(args[0]).readPointer());
|
||||
// local ItemObject = Item(NativePointer(Haker.CpuContext.ebp).add(12).C_Object);
|
||||
// local ServerId = NativePointer(ItemObject.C_Object).add(21).readInt();
|
||||
// //数据库主键从10000开始自增
|
||||
// if (ServerId< 10000) {
|
||||
// local NewUuid = GenerateUUID();
|
||||
// NativePointer(ItemObject.C_Object).add(21).writeInt(NewUuid);
|
||||
// }
|
||||
// }.bindenv(this);
|
||||
}
|
||||
|
||||
|
||||
Timer.SetTimeOut(function() {
|
||||
|
||||
getroottable()._EquipmentExpand_ <- EquipmentExpandC();
|
||||
|
||||
print("特殊插件·装备拓展 - 已加载");
|
||||
}, 1);
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
文件名:誉名录.nut
|
||||
路径:_DPS_/_BuiltProject/誉名录/誉名录.nut
|
||||
创建日期:2026-02-01 02:19
|
||||
文件用途:
|
||||
*/
|
||||
|
||||
class NewTitleC {
|
||||
|
||||
|
||||
MysqlObject = null;
|
||||
|
||||
|
||||
//数据
|
||||
data = null;
|
||||
|
||||
constructor() {
|
||||
|
||||
//创建数据库
|
||||
MysqlObject = Mysql(Str_Ptr("127.0.0.1"), 3306, Str_Ptr("taiwan_cain"), Str_Ptr("game"), Str_Ptr("uu5!^%jg"));
|
||||
MysqlObject.Exec_Sql(format("SET NAMES %s", "latin1"));
|
||||
|
||||
local check_table_sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'newtitle';"
|
||||
local Ret = MysqlObject.Select(check_table_sql, ["int"]);
|
||||
if (Ret.len() == 0 || Ret[0][0] == 0) {
|
||||
local sql = "CREATE TABLE `taiwan_cain`.`newtitle` (`cid` int(11) NOT NULL,`data` text NULL,PRIMARY KEY (`cid`));";
|
||||
MysqlObject.Exec_Sql(sql);
|
||||
}
|
||||
|
||||
|
||||
//读取数据库数据到缓存
|
||||
InitMysqlData();
|
||||
//固化缓存数据到数据库
|
||||
SaveCacheData();
|
||||
|
||||
|
||||
|
||||
//注册客户端收包
|
||||
RegisterClient();
|
||||
|
||||
//注册GM命令
|
||||
Gm_InputFunc_Handle["Title"] <- function(SUser, CmdString) {
|
||||
local count = -1;
|
||||
local pos = 0;
|
||||
local handler = [];
|
||||
do {
|
||||
local start = pos;
|
||||
pos = CmdString.find(" ", pos + 1);
|
||||
if (pos != null) {
|
||||
handler.append(CmdString.slice(start + 1, pos));
|
||||
} else
|
||||
handler.append(CmdString.slice(start + 1));
|
||||
count = count + 1
|
||||
} while (pos != null)
|
||||
|
||||
//得到空格数量
|
||||
if (count == 1) {
|
||||
AddTitle(SUser, handler[1]);
|
||||
}
|
||||
}.bindenv(this);
|
||||
|
||||
//注册区域移动添加角色的Hook
|
||||
Cb_Area_insert_user_Leave.rawset("NewTitleC", function(args) {
|
||||
local UserList = World.GetAreaUserList(args[0]);
|
||||
if (UserList) {
|
||||
local ShowList = GenerateDrawInfo(UserList);
|
||||
foreach(AreaUser in UserList) {
|
||||
AreaUser.SendJso({
|
||||
op = 21012004,
|
||||
ShowData = ShowList
|
||||
});
|
||||
}
|
||||
}
|
||||
}.bindenv(this));
|
||||
|
||||
//上线时 下发自己的渲染信息
|
||||
Cb_reach_game_world_Func.rawset("NewTitleC", function(SUser) {
|
||||
local ShowCidList = [SUser];
|
||||
local ShowList = GenerateDrawInfo(ShowCidList);
|
||||
SUser.SendJso({
|
||||
op = 21012004,
|
||||
ShowData = ShowList
|
||||
});
|
||||
}.bindenv(this));
|
||||
}
|
||||
|
||||
function RegisterClient() {
|
||||
//查询自身称号簿数据
|
||||
ClientSocketPackFuncMap.rawset(21012001, function(SUser, Jso) {
|
||||
local SendInfo = {};
|
||||
local Cid = SUser.GetCID().tostring();
|
||||
print(data.rawin(Cid))
|
||||
if (data.rawin(Cid)) {
|
||||
SendInfo = data.rawget(Cid);
|
||||
}
|
||||
SUser.SendJso({
|
||||
op = 21012002,
|
||||
Info = SendInfo
|
||||
})
|
||||
}.bindenv(this));
|
||||
|
||||
//保存称号簿配置
|
||||
ClientSocketPackFuncMap.rawset(21012003, function(SUser, Jso) {
|
||||
local SaveInfo = Jso.SendInfo;
|
||||
local SaveId = Jso.Id;
|
||||
local Cid = SUser.GetCID().tostring();
|
||||
//因为json传输过程会导致INT key变成string 所以这里的缓存里一律要使用string 的编号
|
||||
data[Cid].rawset(SaveId.tostring(), SaveInfo);
|
||||
RefreshAreaDrawInfo(SUser);
|
||||
}.bindenv(this));
|
||||
}
|
||||
|
||||
|
||||
//给玩家添加称号
|
||||
function AddTitle(SUser, TitleId) {
|
||||
local Cid = SUser.GetCID().tostring();
|
||||
if (!data.rawin(Cid)) {
|
||||
data.rawset(Cid, {});
|
||||
}
|
||||
data[Cid].rawset(TitleId, {
|
||||
IsDisplay = false,
|
||||
Scale = 1.0,
|
||||
XOffset = 0,
|
||||
YOffset = 0,
|
||||
ZOrder = 1
|
||||
})
|
||||
}
|
||||
|
||||
//给玩家移除称号
|
||||
function RemoveTitle(SUser, TitleId) {
|
||||
local Cid = SUser.GetCID().tostring();
|
||||
if (!data.rawin(Cid)) {
|
||||
data.rawset(Cid, {});
|
||||
}
|
||||
data[Cid].rawdelete(TitleId);
|
||||
}
|
||||
|
||||
//刷新角色区域内的渲染信息
|
||||
function RefreshAreaDrawInfo(SUser) {
|
||||
local Location = SUser.GetLocation();
|
||||
local Area = World.GetArea(Location.Town, Location.Area);
|
||||
local UserList = World.GetAreaUserList(Area);
|
||||
if (UserList) {
|
||||
local ShowList = GenerateDrawInfo(UserList);
|
||||
foreach(AreaUser in UserList) {
|
||||
AreaUser.SendJso({
|
||||
op = 21012004,
|
||||
ShowData = ShowList
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//生成指定List的渲染信息
|
||||
function GenerateDrawInfo(ShowCidList) {
|
||||
local ShowList = {};
|
||||
foreach(SUserObj in ShowCidList) {
|
||||
local Cid = SUserObj.GetCID().tostring();
|
||||
local ShowData = null;
|
||||
if (data.rawin(Cid)) {
|
||||
ShowData = data.rawget(Cid);
|
||||
}
|
||||
local Data = [];
|
||||
if (ShowData) {
|
||||
foreach(TitleId, RealData in ShowData) {
|
||||
if (!RealData.IsDisplay) continue;
|
||||
RealData.Id <- TitleId;
|
||||
Data.push(RealData);
|
||||
}
|
||||
}
|
||||
Data.sort(function(a, b) {
|
||||
return a.ZOrder <=> b.ZOrder;
|
||||
});
|
||||
ShowList.rawset(SUserObj.GetUniqueId(), Data);
|
||||
}
|
||||
return ShowList.len() > 0 ? ShowList : null;
|
||||
}
|
||||
|
||||
function InitMysqlData() {
|
||||
data = {};
|
||||
local Sql = "SELECT * FROM newtitle"
|
||||
local Ret = MysqlObject.Select(Sql, ["int", "string"]);
|
||||
foreach(Row in Ret) {
|
||||
local cid = Row[0];
|
||||
local jso = Json.Decode(Row[1]);
|
||||
data.rawset(cid.tostring(), jso);
|
||||
}
|
||||
}
|
||||
|
||||
function SaveCacheData() {
|
||||
//每5分钟固化一次数据到数据库
|
||||
Timer.RemoveCronTask("NewTitleC");
|
||||
Timer.SetCronTask(function() {
|
||||
local DataList = [];
|
||||
foreach(cid, value in data) {
|
||||
local str = format("(%s,'%s'),", cid.tostring(), Json.Encode(value));
|
||||
DataList.push(str);
|
||||
}
|
||||
local sql = "REPLACE INTO newtitle (cid, data) VALUES";
|
||||
foreach(value in DataList) {
|
||||
sql += value;
|
||||
}
|
||||
//去除最后一个,
|
||||
sql = sql.slice(0, -1);
|
||||
sql += ";";
|
||||
MysqlObject.Exec_Sql(sql);
|
||||
}.bindenv(this), {
|
||||
Cron = "* */5 * * * *",
|
||||
Name = "NewTitleC"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Timer.SetTimeOut(function() {
|
||||
|
||||
getroottable()._NewTitle_ <- NewTitleC();
|
||||
print("誉名录 - 已加载");
|
||||
}, 1);
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
文件名:哥布林袖珍罐.nut
|
||||
路径:_DPS_/_BuiltProject/哥布林袖珍罐/哥布林袖珍罐.nut
|
||||
创建日期:2026-02-06 09:37
|
||||
文件用途:哥布林袖珍罐
|
||||
*/
|
||||
|
||||
class GoblinSmallBox {
|
||||
|
||||
//记录玩家缓存
|
||||
playerCache = null;
|
||||
|
||||
//数据
|
||||
data = null;
|
||||
|
||||
constructor() {
|
||||
playerCache = {};
|
||||
data = {};
|
||||
//读取PVF数据
|
||||
InitPvf();
|
||||
//注册道具使用回调
|
||||
RegistUseItemCallBack();
|
||||
|
||||
|
||||
ClientSocketPackFuncMap.rawset(21014003, function(SUser, Jso) {
|
||||
local CID = SUser.GetCID();
|
||||
if (playerCache.rawin(CID)) {
|
||||
local ItemArr = playerCache.rawget(CID);
|
||||
local ItemId = ItemArr[0].ItemId;
|
||||
local ItemCount = ItemArr[0].ItemCount;
|
||||
SUser.GiveItem(ItemId, ItemCount);
|
||||
ItemArr.remove(0);
|
||||
if (ItemArr.len() == 0) {
|
||||
playerCache.rawdelete(CID);
|
||||
}
|
||||
}
|
||||
}.bindenv(this));
|
||||
}
|
||||
|
||||
|
||||
function InitPvf() {
|
||||
Script();
|
||||
ScriptData.GetFileData("etc/rindro/goldgoblin/goldgoblin.lst", function(_n, DataA) {
|
||||
while (!DataA.Eof()) {
|
||||
local Id = DataA.Get();
|
||||
local Path = DataA.Get();
|
||||
|
||||
local Info = ScriptData.GetFileData("etc/" + Path, function(DataTable, Data) {
|
||||
while (!Data.Eof()) {
|
||||
local Fragment = Data.Get();
|
||||
if (Fragment == "[production]") {
|
||||
DataTable.production <- [Data.Get(), Data.Get()];
|
||||
} else if (Fragment == "[trigger]") {
|
||||
DataTable.trigger <- Data.Get();
|
||||
} else if (Fragment == "[item]") {
|
||||
DataTable.item <- [];
|
||||
DataTable.item_total_probability <- 0;
|
||||
while (true) {
|
||||
local Ret = Data.Get();
|
||||
if (Ret == "[/item]") {
|
||||
break;
|
||||
}
|
||||
local ItemInfo = {};
|
||||
ItemInfo.ItemId <- Ret;
|
||||
ItemInfo.ItemCount <- Data.Get();
|
||||
ItemInfo.Probability <- Data.Get();
|
||||
DataTable.item_total_probability += ItemInfo.Probability;
|
||||
ItemInfo.IsNoti <- Data.Get();
|
||||
|
||||
ItemInfo.Grade <- GetItemGrade(ItemInfo.ItemId);
|
||||
DataTable.item.push(ItemInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}.bindenv(this));
|
||||
data.rawset(Id, Info);
|
||||
}
|
||||
}.bindenv(this));
|
||||
}
|
||||
|
||||
|
||||
function RegistUseItemCallBack() {
|
||||
foreach(id, info in data) {
|
||||
if ("trigger" in info) {
|
||||
Cb_Use_Item_Sp_Func[info.trigger] <- function(SUser, Item_id) {
|
||||
local Count = MathClass.Rand(data[id].production[0], data[id].production[1]);
|
||||
local ItemArr = [];
|
||||
for (local i = 0; i< Count; i++) {
|
||||
local RandNum = MathClass.Rand(0, data[id].item_total_probability);
|
||||
local ItemInfo = null;
|
||||
for (local j = 0; j< data[id].item.len(); j++) {
|
||||
if (RandNum< data[id].item[j].Probability) {
|
||||
ItemInfo = clone(data[id].item[j]);
|
||||
break;
|
||||
}
|
||||
RandNum -= data[id].item[j].Probability;
|
||||
}
|
||||
ItemInfo.rawdelete("Probability");
|
||||
if (ItemInfo != null) {
|
||||
ItemArr.push(ItemInfo);
|
||||
}
|
||||
}
|
||||
playerCache[SUser.GetCID()] <- ItemArr;
|
||||
SUser.SendJso({
|
||||
op = 21014002,
|
||||
RewardPackage = ItemArr,
|
||||
BoxId = info.trigger,
|
||||
})
|
||||
}.bindenv(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function GetItemGrade(ItemId) {
|
||||
local Equ = PvfItem.GetPvfItemById(ItemId);
|
||||
local Rarity = Equ.GetRarity();
|
||||
return Rarity;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Timer.SetTimeOut(function() {
|
||||
|
||||
getroottable()._GoblinSmallBox_ <- GoblinSmallBox();
|
||||
print("哥布林袖珍罐 - 已加载");
|
||||
}, 1);
|
||||
|
|
@ -262,12 +262,17 @@ class HttpServer {
|
|||
|
||||
//处理函数
|
||||
Handler = null;
|
||||
//服务ID
|
||||
ServerId = null;
|
||||
|
||||
|
||||
constructor(host, service = "80") {
|
||||
Host = host;
|
||||
Service = service;
|
||||
|
||||
if (getroottable().rawin("HttpServer_" + Host + "_" + Service)){
|
||||
throw "端口被占用";
|
||||
}
|
||||
getroottable()["HttpServer_" + Host + "_" + Service] <- this;
|
||||
}
|
||||
|
||||
|
|
@ -275,15 +280,21 @@ class HttpServer {
|
|||
//记录处理函数
|
||||
Handler = Func;
|
||||
|
||||
local success = Sq_CreateHttpServer(Host, Service, this);
|
||||
if (success) {
|
||||
ServerId = Sq_CreateHttpServer(Host, Service, this);
|
||||
if (ServerId) {
|
||||
::print("Server started successfully.");
|
||||
} else {
|
||||
::print("Failed to start server.");
|
||||
}
|
||||
}
|
||||
|
||||
function Event(SocketObject, Msg) {
|
||||
Timer.SetTimeOut(Handler, 1, HttpResponse(SocketObject), Msg);
|
||||
function Stop()
|
||||
{
|
||||
Sq_StopHttpServer(ServerId);
|
||||
}
|
||||
|
||||
function Event(SocketObject, Header, Msg) {
|
||||
print("Event");
|
||||
Timer.SetTimeOut(Handler, 1, HttpResponse(SocketObject), Header, Msg);
|
||||
}
|
||||
}
|
||||
|
|
@ -146,7 +146,11 @@ class Item extends Base_C_Object {
|
|||
this = null;
|
||||
}
|
||||
|
||||
|
||||
//获取UUID
|
||||
function GetUuid() {
|
||||
Attribute.seek(21);
|
||||
return Attribute.readn('i');
|
||||
}
|
||||
}
|
||||
|
||||
//是否可打包
|
||||
|
|
|
|||
|
|
@ -21,31 +21,78 @@ class MD5 {
|
|||
Sq_CallFunc(MD5_Final_ptr, "void", ["pointer", "pointer"], Ctx, Result);
|
||||
}
|
||||
|
||||
// 16进制编码函数
|
||||
// 参数: input - 可以是字符串或字节数组或Memory对象
|
||||
// 返回: 32位16进制小写字符串(默认格式)
|
||||
function hex_encode(input) {
|
||||
local byteArray = [];
|
||||
|
||||
// 如果输入是字符串,转换为字节数组
|
||||
if (typeof input == "string") {
|
||||
for (local i = 0; i < input.len(); i++) {
|
||||
byteArray.append(input[i].tointeger() & 0xFF);
|
||||
}
|
||||
}
|
||||
// 如果输入是数组,直接使用
|
||||
else {
|
||||
byteArray = input;
|
||||
}
|
||||
|
||||
local encoded = "";
|
||||
|
||||
for (local i = 0; i < byteArray.len(); i++) {
|
||||
local byte = byteArray[i] & 0xFF;
|
||||
encoded += format("%02x", byte);
|
||||
}
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
// Base64 编码函数
|
||||
// 参数: input - 可以是字符串或字节数组
|
||||
// 返回: base64 编码后的字符串
|
||||
function base64_encode(input) {
|
||||
local base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
local inputLength = input.len();
|
||||
|
||||
// 如果输入是字符串,转换为字节数组
|
||||
local byteArray = [];
|
||||
if (typeof input == "string") {
|
||||
for (local i = 0; i< input.len(); i++) {
|
||||
byteArray.append(input[i].tointeger() & 0xFF);
|
||||
}
|
||||
} else {
|
||||
// 假设是数组,直接使用
|
||||
byteArray = input;
|
||||
}
|
||||
|
||||
local inputLength = byteArray.len();
|
||||
local i = 0;
|
||||
local j = 0;
|
||||
local charArray3 = array(3);
|
||||
local charArray4 = array(4);
|
||||
local encoded = "";
|
||||
|
||||
while (inputLength--) {
|
||||
charArray3[i++] = input[inputLength];
|
||||
// 处理每3个字节为一组
|
||||
local pos = 0;
|
||||
while (pos< inputLength) {
|
||||
charArray3[i++] = byteArray[pos++];
|
||||
|
||||
if (i == 3) {
|
||||
// 将3个字节转换为4个base64字符
|
||||
charArray4[0] = (charArray3[0] & 0xfc) >> 2;
|
||||
charArray4[1] = ((charArray3[0] & 0x03) << 4) + ((charArray3[1] & 0xf0) >> 4);
|
||||
charArray4[2] = ((charArray3[1] & 0x0f) << 2) + ((charArray3[2] & 0xc0) >> 6);
|
||||
charArray4[3] = charArray3[2] & 0x3f;
|
||||
|
||||
for (i = 0; i< 4; i++) {
|
||||
encoded += base64_chars[charArray4[i]];
|
||||
encoded += base64_chars.slice(charArray4[i], charArray4[i] + 1);
|
||||
}
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
// 处理剩余的字节(不足3个字节的情况)
|
||||
if (i > 0) {
|
||||
for (j = i; j< 3; j++) {
|
||||
charArray3[j] = 0;
|
||||
}
|
||||
|
|
@ -56,9 +103,10 @@ class MD5 {
|
|||
charArray4[3] = charArray3[2] & 0x3f;
|
||||
|
||||
for (j = 0; j< i + 1; j++) {
|
||||
encoded += base64_chars[charArray4[j]];
|
||||
encoded += base64_chars.slice(charArray4[j], charArray4[j] + 1);
|
||||
}
|
||||
|
||||
// 添加填充字符 '='
|
||||
while (i++<3) {
|
||||
encoded += "=";
|
||||
}
|
||||
|
|
@ -67,6 +115,7 @@ class MD5 {
|
|||
return encoded;
|
||||
}
|
||||
|
||||
|
||||
function GetFile(FileName) {
|
||||
local Io = IO(FileName, "r+");
|
||||
|
||||
|
|
|
|||
|
|
@ -101,9 +101,9 @@ class Packet extends Base_C_Object {
|
|||
}
|
||||
|
||||
|
||||
function GetString(a3,a4) {
|
||||
function GetString(a3, a4) {
|
||||
local data = Memory.alloc(a3);
|
||||
if (Sq_CallFunc(S_Ptr("0x858D2BC"), "int", ["pointer", "pointer","int","int","int"], this.C_Object, data.C_Object,a3,a4)) {
|
||||
if (Sq_CallFunc(S_Ptr("0x858D2BC"), "int", ["pointer", "pointer", "int", "int", "int"], this.C_Object, data.C_Object, a3, a4)) {
|
||||
return data;
|
||||
}
|
||||
return null;
|
||||
|
|
@ -114,4 +114,16 @@ class Packet extends Base_C_Object {
|
|||
Sq_Delete_Point(this.C_Object);
|
||||
// Sq_Packet_Delete(this.C_Object);
|
||||
}
|
||||
|
||||
function GetPos() {
|
||||
return Sq_CallFunc(S_Ptr("0x8110B4C"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
|
||||
function SetPos(pos) {
|
||||
Sq_CallFunc(S_Ptr("0x822B7B0"), "int", ["pointer", "int"], this.C_Object, pos);
|
||||
}
|
||||
|
||||
function GetLength() {
|
||||
return Sq_CallFunc(S_Ptr("0x848F438"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,6 @@ class Script {
|
|||
getroottable()._Script_Data_Init_ = true;
|
||||
}
|
||||
|
||||
|
||||
function GetFileInfo(Path) {
|
||||
local size = Asset_GetPvfFileSize(C_Object, Path);
|
||||
if (size) {
|
||||
|
|
|
|||
|
|
@ -272,4 +272,30 @@ class World {
|
|||
Sq_Delete_Point(end);
|
||||
return PlayerArr;
|
||||
}
|
||||
|
||||
//获取区域
|
||||
function GetArea(TownId, AreaId) {
|
||||
local GameWorld = Sq_CallFunc(S_Ptr("0x080DA3A7"), "pointer", []);
|
||||
local Town = Sq_CallFunc(S_Ptr("0x086D1764"), "pointer", ["pointer", "int"], GameWorld, TownId);
|
||||
local Area = Sq_CallFunc(S_Ptr("0x086C3BA2"), "pointer", ["pointer", "int"], Town, AreaId);
|
||||
return Area;
|
||||
}
|
||||
|
||||
//获取区域的玩家列表
|
||||
function GetAreaUserList(Area) {
|
||||
local List = [];
|
||||
local VectorM = Memory.alloc(4 * 3);
|
||||
Sq_CallFunc(S_Ptr("0x08168420"), "int", ["pointer"], VectorM.C_Object);
|
||||
local Flag = Sq_CallFunc(S_Ptr("0x086C305E"), "bool", ["pointer", "pointer"], Area, VectorM.C_Object);
|
||||
local start = VectorM.readPointer();
|
||||
local finish = VectorM.add(4).readPointer();
|
||||
local Size = Sq_Ptr2Int(Sq_PointerOperationPointer(finish, start, "-")) / 2;
|
||||
for (local i = 0; i< Size; i++) {
|
||||
local UserId = NativePointer(start).add(i * 2).readUShort();
|
||||
local SUser = GetUserBySession(UserId);
|
||||
if (SUser) List.push(SUser);
|
||||
}
|
||||
return List.len() > 0 ? List : null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -6,15 +6,24 @@
|
|||
*/
|
||||
if (!("Cb_Use_Item_Sp_Func" in getroottable())) Cb_Use_Item_Sp_Func <- {};
|
||||
|
||||
// function Cb_use_item_sp(C_User, ItemId) {
|
||||
// if (ItemId in Cb_Use_Item_Sp_Func) {
|
||||
// local SUser = User(C_User);
|
||||
// if (SUser) {
|
||||
// local Ret = Cb_Use_Item_Sp_Func[ItemId](SUser, ItemId);
|
||||
// if (Ret == false) return false;
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
|
||||
|
||||
function Cb_use_item_sp(C_User, ItemId) {
|
||||
Cb_History_ItemDown_Func["UseSharedEffectItem"] <- function(SUser, Data) {
|
||||
if (Data[18] == "3") {
|
||||
local ItemId = Data[15].tointeger();
|
||||
if (ItemId in Cb_Use_Item_Sp_Func) {
|
||||
local SUser = User(C_User);
|
||||
if (SUser) {
|
||||
local Ret = Cb_Use_Item_Sp_Func[ItemId](SUser, ItemId);
|
||||
if (Ret == false) return false;
|
||||
Cb_Use_Item_Sp_Func[ItemId](SUser, ItemId);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -686,7 +686,7 @@ _Hook_Register_Currency_Func_("0x81f92ca", ["pointer", "int", "int", "int", "poi
|
|||
//移动物品
|
||||
Cb_DisPatcher_MoveItem_Enter_Func <- {};
|
||||
Cb_DisPatcher_MoveItem_Leave_Func <- {};
|
||||
_Hook_Register_Currency_Func_("0x81C5B76", ["pointer", "pointer", "pointer", "void"],Cb_DisPatcher_MoveItem_Enter_Func, Cb_DisPatcher_MoveItem_Leave_Func);
|
||||
_Hook_Register_Currency_Func_("0x81C5B76", ["pointer", "pointer", "pointer", "void"], Cb_DisPatcher_MoveItem_Enter_Func, Cb_DisPatcher_MoveItem_Leave_Func);
|
||||
|
||||
// 注册道具转职Hook
|
||||
Cb_ChangeGrowType_Item_Enter_Func <- {};
|
||||
|
|
@ -699,6 +699,57 @@ Cb_ItemVendingMachine_ProcessIPG_ResultOutput_Leave_Func <- {};
|
|||
_Hook_Register_Currency_Func_("0x8178676", ["pointer", "pointer", "int", "int", "pointer", "int"], Cb_ItemVendingMachine_ProcessIPG_ResultOutput_Enter_Func, Cb_ItemVendingMachine_ProcessIPG_ResultOutput_Leave_Func);
|
||||
|
||||
|
||||
//商城购买道具收包
|
||||
Cb_ItemVendingMachine_BuyAuctionItem_Enter_Func <- {};
|
||||
Cb_ItemVendingMachine_BuyAuctionItem_Leave_Func <- {};
|
||||
_Hook_Register_Currency_Func_("0x81769f6", ["pointer", "pointer", "int", "pointer"], Cb_ItemVendingMachine_BuyAuctionItem_Enter_Func, Cb_ItemVendingMachine_BuyAuctionItem_Leave_Func);
|
||||
|
||||
|
||||
// 构建地图
|
||||
Cb_CBattle_Field_ConsistMap_Enter_Func <- {};
|
||||
Cb_CBattle_Field_ConsistMap_Leave_Func <- {};
|
||||
_Hook_Register_Currency_Func_("0x083031D2", ["pointer", "void"], Cb_CBattle_Field_ConsistMap_Enter_Func, Cb_CBattle_Field_ConsistMap_Leave_Func);
|
||||
|
||||
// 击杀怪物时
|
||||
Cb_CBattle_Field_kill_monster_Enter_Func <- {};
|
||||
Cb_CBattle_Field_kill_monster_Leave_Func <- {};
|
||||
_Hook_Register_Currency_Func_("0x0830BC78", ["pointer", "pointer", "pointer", "pointer", "pointer", "int"], Cb_CBattle_Field_kill_monster_Enter_Func, Cb_CBattle_Field_kill_monster_Leave_Func);
|
||||
|
||||
// 副本中角色死亡
|
||||
Cb_CParty_die_user_Enter_Func <- {};
|
||||
Cb_CParty_die_user_Leave_Func <- {};
|
||||
_Hook_Register_Currency_Func_("0x085A7828", ["pointer", "pointer", "void"], Cb_CParty_die_user_Enter_Func, Cb_CParty_die_user_Leave_Func);
|
||||
|
||||
//NPC商店购买发包
|
||||
Cb_BuyItem_send_Enter <- {};
|
||||
Cb_BuyItem_send_Leave <- {};
|
||||
_Hook_Register_Currency_Func_("0x081BE20A", ["pointer", "pointer", "pointer", "void"], Cb_BuyItem_send_Enter, Cb_BuyItem_send_Leave);
|
||||
|
||||
//获取深渊派对
|
||||
Cb_GetHellPartyDifficulty_Enter_Func <- {};
|
||||
Cb_GetHellPartyDifficulty_Leave_Func <- {};
|
||||
_Hook_Register_Currency_Func_("0x082FFA2E", ["pointer", "int", "int"], Cb_GetHellPartyDifficulty_Enter_Func, Cb_GetHellPartyDifficulty_Leave_Func);
|
||||
|
||||
// 初始化并启动活动
|
||||
Cb_CEventManager_TriggerEventStart_Enter <- {};
|
||||
Cb_CEventManager_TriggerEventStart_Leave <- {};
|
||||
_Hook_Register_Currency_Func_("0x08115CC6", ["pointer", "int", "int", "int"], Cb_CEventManager_TriggerEventStart_Enter, Cb_CEventManager_TriggerEventStart_Leave);
|
||||
|
||||
// 装备红字打书检查
|
||||
Cb_CItemAmplifier_checkInvestableItem_Enter <- {};
|
||||
Cb_CItemAmplifier_checkInvestableItem_Leave <- {};
|
||||
_Hook_Register_Currency_Func_("0x08234980", ["pointer", "pointer", "pointer", "int", "bool"], Cb_CItemAmplifier_checkInvestableItem_Enter, Cb_CItemAmplifier_checkInvestableItem_Leave);
|
||||
|
||||
// 物品删除 CInventory::delete_item
|
||||
Cb_CInventory_delete_item_Enter <- {};
|
||||
Cb_CInventory_delete_item_Leave <- {};
|
||||
_Hook_Register_Currency_Func_("0x0850400C", ["pointer", "int", "int", "int", "int", "int", "int"], Cb_CInventory_delete_item_Enter, Cb_CInventory_delete_item_Leave);
|
||||
|
||||
// 物品删除 CInventory::delete_item
|
||||
Cb_Area_insert_user_Enter <- {};
|
||||
Cb_Area_insert_user_Leave <- {};
|
||||
_Hook_Register_Currency_Func_("0x086C25A6", ["pointer", "pointer", "void"], Cb_Area_insert_user_Enter, Cb_Area_insert_user_Leave);
|
||||
|
||||
function _Hook_Register_Currency_DelayHook_() {
|
||||
//五国时的热点函数
|
||||
//获取Item Rarity
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ function InitPluginInfo() {
|
|||
try {
|
||||
local Io = IO("/java_plugin/Restart", "r");
|
||||
Io.Close();
|
||||
Sq_CreatCConnectPool(2, 4, "127.0.0.1", 3306, "game", "uu5!^%jg");
|
||||
Sq_CreatSocketConnect("127.0.0.1", "65109");
|
||||
} catch (exception) {
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue