保存标准
This commit is contained in:
commit
887ef6f85a
|
|
@ -0,0 +1,15 @@
|
|||
function sqr_main() {
|
||||
GameManager.OpenHotFix("/dp_s/OfficialConfig");
|
||||
GameManager.OpenHotFix("/dp_s/_DPS_/_Core");
|
||||
GameManager.OpenHotFix("/dp_s/MyProject");
|
||||
// GameManager.SetGameMaxLevel(70);
|
||||
// Cb_History_MileageSet_Func["TW_reach_game_world"] <- function(SUser, Data) {
|
||||
// //第一次上线
|
||||
// if (SUser.GetCharacLevel() > 70) {
|
||||
// SUser.SetCharacLevel(70);
|
||||
// SUser.SendItemSpace(0);
|
||||
// SUser.SendItemSpace(1);
|
||||
// SUser.SendItemSpace(7);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
Gm_InputFunc_Handle["给"] <- 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) {
|
||||
local Ret = SUser.GiveItem(handler[1].tointeger(), 1);
|
||||
if (!Ret) SUser.SendNotiPacketMessage("发送失败背包是不是满了", 8);
|
||||
} else if (count == 2) {
|
||||
local Ret = SUser.GiveItem(handler[1].tointeger(), handler[2].tointeger());
|
||||
if (!Ret) SUser.SendNotiPacketMessage("发送失败背包是不是满了", 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Timer.SetTimeOut(function() {
|
||||
|
||||
|
||||
Haker.LoadHook("0x0830ADF6", ["pointer", "pointer", "pointer", "pointer", "int", "int", "int", "int", "int", "pointer", "float", "int", "void"],
|
||||
function(args) {
|
||||
local SParty = Party(NativePointer(args[0]).readPointer());
|
||||
local map_monster_param = NativePointer(Haker.CpuContext.ebp).add(0x10).readPointer();
|
||||
local monster_uid = NativePointer(NativePointer(Haker.CpuContext.ebp).add(0x18).readPointer()).readU16();
|
||||
|
||||
Sq_WriteByteArr(S_Ptr("0x830ADFB"), Haker.AsmGenerateMcd(
|
||||
"pop esi",
|
||||
"pop edi",
|
||||
"pop ebp",
|
||||
"ret"));
|
||||
return null;
|
||||
},
|
||||
function(args) {
|
||||
//还原
|
||||
Sq_WriteByteArr(S_Ptr("0x830ADFB"), [0x53, 0x81, 0xec, 0x7c, 0x01]);
|
||||
return null;
|
||||
});
|
||||
}, 1)
|
||||
|
||||
|
||||
|
||||
Timer.SetTimeOut(function() {
|
||||
local Config = sq_ReadJsonFile("/dp_s/OfficialConfig" + "/" + "门票进入副本配置_Maomi.json");
|
||||
// local Config = GlobalConfig.Get("门票进入副本配置_Maomi.json");
|
||||
print(Config);
|
||||
}, 1);
|
||||
|
||||
|
||||
function get_required_gradeByMaomi(dgn_id, dgn_diff) {
|
||||
local Config = GlobalConfig.Get("门票进入副本配置_Maomi.json");
|
||||
if (Config["门票进入副本"]["副本配置"].rawin(dgn_id.tostring())) {
|
||||
local requirements = Config["门票进入副本"]["副本配置"][dgn_id.tostring()];
|
||||
for (local i = 0; i< requirements.len(); i += 2) {
|
||||
if (requirements[i] == dgn_diff) {
|
||||
return requirements[i + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Cb_SelectDungeon_Check_Error_Leave_Func.Check_TicketByMaomi <- function(args) {
|
||||
|
||||
local Config = sq_ReadJsonFile("/dp_s/OfficialConfig" + "/" + "门票进入副本配置_Maomi.json");
|
||||
// local Config = GlobalConfig.Get("门票进入副本配置_Maomi.json");
|
||||
|
||||
local SUser = User(args[1]);
|
||||
local msg_base = args[2];
|
||||
local dgn_id = NativePointer(msg_base).add(13).readU16(); // 获取副本ID
|
||||
local dgn_diff = NativePointer(msg_base).add(15).readU8(); // 获取副本难度
|
||||
local PartyObj = SUser.GetParty();
|
||||
|
||||
local required_Item = get_required_gradeByMaomi(dgn_id, dgn_diff);
|
||||
local diff_name = Config["副本难度命名"][(dgn_diff).tostring()];
|
||||
|
||||
if (!required_Item) return null;
|
||||
|
||||
if (PartyObj && Config["门票进入副本"]["门票进入副本开关(true为开启,false为关闭)"]) {
|
||||
for (local i = 0; i< 4; ++i) {
|
||||
local Tuser = PartyObj.GetUser(i);
|
||||
if (Tuser) {
|
||||
local InvenObj = Tuser.GetInven();
|
||||
if (InvenObj) {
|
||||
if (InvenObj.CheckItemCount(required_Item, 1))
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SUser.SendNotiBox("队伍中所有玩家均无副本所需门票,无法进入!", 2)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
文件名:史诗药剂.nut
|
||||
路径:MyProject/史诗药剂.nut
|
||||
创建日期:2025-03-28 10:21
|
||||
文件用途:史诗药剂
|
||||
*/
|
||||
|
||||
//➢SS药剂的ID
|
||||
EpicPotionID <- 2600006;
|
||||
//➢默认的药剂增加倍率
|
||||
EpicPotionOdds <- 0.1;
|
||||
//➢指定玩家增加深渊爆率
|
||||
EpicPotionlist <- {};
|
||||
//角色ID:增加个人深渊爆率
|
||||
EpicPotionlist[1] <- 1;
|
||||
|
||||
|
||||
Cb_GetItemRarity_Enter_Func["史诗药剂_逻辑"] <- function(args) {
|
||||
local Addr = NativePointer(args[0]);
|
||||
local VectorSize = (Addr.add(4).readU32() - Addr.readU32()) / 4;
|
||||
// 遍历队伍成员,找到使用了史诗药剂的玩家
|
||||
local userWithPotion = null;
|
||||
for (local i = 0; i< VectorSize; i++) {
|
||||
local elementAddr = NativePointer(Addr.readPointer()).add(i * 4);
|
||||
local user = elementAddr.readPointer();
|
||||
if (user && Sq_CallFunc(S_Ptr("0x865E994"), "int", ["pointer", "int", ], user, EpicPotionID) ) {
|
||||
userWithPotion = User(user);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (userWithPotion && Haker.NextReturnAddress == "0x853583a") {
|
||||
local partyobj = userWithPotion.GetParty();
|
||||
// 检查是否单人
|
||||
if (Sq_CallFunc(S_Ptr("0x0859A16A"), "int", ["pointer"], partyobj.C_Object) == 1) {
|
||||
local MaxRoll = NativePointer(args[1]).add(16).readU32();
|
||||
local odds = EpicPotionOdds; // 默认药剂的增加几率
|
||||
// 检查是否VIP玩家
|
||||
local charac_no = userWithPotion.GetCID();
|
||||
if (EpicPotionlist.rawin(charac_no)) {
|
||||
odds = EpicPotionlist[charac_no];
|
||||
}
|
||||
// 计算新的roll值
|
||||
args[2] = MathClass.getMin(args[2] + args[2] * odds, MaxRoll);
|
||||
}
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Gm_InputFunc_Handle["okok"] <- function(SUser, cmd) {
|
||||
|
||||
SUser.SendNotiPacketMessage("出纳上asdasdasda到几点方柏霓撒娇扩大年级卡萨", 7);
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"烟花道具ID": 7577,
|
||||
"提示1": "很遗憾,您没有获得任何物品",
|
||||
"提示2": "获得周年庆爆竹奖励 [%s]",
|
||||
"提示1类型": 1,
|
||||
"提示2类型": 1,
|
||||
"道具列表": [
|
||||
{
|
||||
"itemId": 3037,
|
||||
"count": 10,
|
||||
"probability": 100
|
||||
},{
|
||||
"itemId": 3038,
|
||||
"count": 20,
|
||||
"probability": 100
|
||||
},
|
||||
{
|
||||
"itemId": null,
|
||||
"count": 20,
|
||||
"probability": 100
|
||||
}
|
||||
],
|
||||
"PK经验道具ID": 7576
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"转职初始职业":[7577],
|
||||
"转职第一职业":[7577],
|
||||
"转职第二职业":[7577],
|
||||
"转职第三职业":[7577],
|
||||
"转职第四职业":[7577],
|
||||
"转职第五职业":[7577]
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"副本播报开关(true开启,false关闭)":true,
|
||||
"不需要播报的副本ID(实例中的ID为怪物攻城的副本ID尽量不要删)":[20002, 20001, 20002, 20003, 20004, 20005, 20006, 20007, 20008, 20009, 20010, 20020, 20021, 20022, 20023, 20024],
|
||||
"指定角色CID不播报":[1, 2],
|
||||
"提示": "角色ID可以查看数据库中 taiwan_cain → charac_info → charac_no代表角色ID",
|
||||
"通关播报信息":"玩家[%s]通关[%s - %s]用时:[%s],击杀怪物数量<%d>",
|
||||
"未通过一个小地图播报信息":"玩家[%s]在[%s%s-%s]中连一个地图都没通过,击杀怪物数量<%d>",
|
||||
"放弃副本":"很遗憾,玩家[%s]在[%s%s-%s]中被打的落荒而逃,用时: %s,击杀怪物数量<%d>",
|
||||
"在队伍中提前退出副本":"玩家[%s]在<%s>的队伍中,提前退出了[%s%s-%s],用时: %s,击杀怪物数量<%d>",
|
||||
"发送信息位置":14,
|
||||
"副本难度命名" : {
|
||||
"0": "普通级",
|
||||
"1": "冒险级",
|
||||
"2": "勇士级",
|
||||
"3": "王者级",
|
||||
"4": "地狱级"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
{
|
||||
"信息提示窗口提示(true开启/false关闭)": false,
|
||||
"信息播报发送位置": 37,
|
||||
"品级回收配置": {
|
||||
"开启品级以及装备等级的回收(true开启/false关闭)": false,
|
||||
"提示": "奖励[道具ID(0代表点券),数量最小值,数量最大值]",
|
||||
"配置列表": [
|
||||
{
|
||||
"奖励": [
|
||||
[
|
||||
3037,
|
||||
10,
|
||||
20
|
||||
]
|
||||
],
|
||||
"装备品级": 2,
|
||||
"装备等级": 55
|
||||
},
|
||||
{
|
||||
"奖励": [
|
||||
[
|
||||
7421,
|
||||
10,
|
||||
20
|
||||
]
|
||||
],
|
||||
"装备品级": 3,
|
||||
"装备等级": 10
|
||||
},
|
||||
{
|
||||
"奖励": [
|
||||
[
|
||||
3037,
|
||||
10,
|
||||
20
|
||||
]
|
||||
],
|
||||
"装备品级": 4,
|
||||
"装备等级": 50
|
||||
},
|
||||
{
|
||||
"奖励": [
|
||||
[
|
||||
3037,
|
||||
10,
|
||||
20
|
||||
]
|
||||
],
|
||||
"装备品级": 4,
|
||||
"装备等级": 55
|
||||
},
|
||||
{
|
||||
"奖励": [
|
||||
[
|
||||
3037,
|
||||
10,
|
||||
20
|
||||
]
|
||||
],
|
||||
"装备品级": 4,
|
||||
"装备等级": 60
|
||||
},
|
||||
{
|
||||
"奖励": [
|
||||
[
|
||||
3037,
|
||||
10,
|
||||
20
|
||||
]
|
||||
],
|
||||
"装备品级": 4,
|
||||
"装备等级": 65
|
||||
},
|
||||
{
|
||||
"奖励": [
|
||||
[
|
||||
3037,
|
||||
10,
|
||||
20
|
||||
]
|
||||
],
|
||||
"装备品级": 4,
|
||||
"装备等级": 70
|
||||
}
|
||||
]
|
||||
},
|
||||
"回收失败信息": " 装备回收失败\n 没有合适的装备或已上锁",
|
||||
"回收成功是否返还回收券道具(true返还/false不返还)": false,
|
||||
"回收配置": {
|
||||
"回收位置": [
|
||||
140,
|
||||
156
|
||||
],
|
||||
"回收箱道具ID": 75771,
|
||||
"指定宠物装备回收": [
|
||||
[
|
||||
64007,
|
||||
3340,
|
||||
1,
|
||||
10
|
||||
],
|
||||
[
|
||||
27102,
|
||||
0,
|
||||
1,
|
||||
10
|
||||
],
|
||||
[
|
||||
2711001,
|
||||
3038,
|
||||
1,
|
||||
10
|
||||
]
|
||||
],
|
||||
"指定装备ID不参与回收": [
|
||||
27099,
|
||||
27100,
|
||||
27101
|
||||
],
|
||||
"提示1": "[回收装备的ID,奖励道具的ID(0代表点券),数量最小值,数量最大值]",
|
||||
"提示2": "回收位置快捷栏(快捷栏3-8),装备栏(快捷栏9-56,如第一排为9-16,第二排为17-24,第三排为25-32,第四排为33-40,第五排为41-48,第六排为49-56)",
|
||||
"提示3": "如果指定装备回收和品级回收都命中的情况下,优先以指定装备回收为准",
|
||||
"提示4": "排除装备ID中的装备不会参与回收,即使它们符合其他回收条件"
|
||||
},
|
||||
"成功回收": {
|
||||
"单位": "个",
|
||||
"奖励提示": "奖励",
|
||||
"标题": " 成功回收"
|
||||
},
|
||||
"提示": "开启弹窗提示需在群文件下载 <客户端消息框233.dll> 插件,否则会导致游戏崩溃",
|
||||
"表情ID": 59
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"抗魔值进入副本":{
|
||||
"提示":"抗魔值进入副本配置(副本ID[普通级,所需抗魔值,冒险级,所需抗魔值,勇士级,所需抗魔值,王者级,所需抗魔值,地狱级,所需抗魔值])",
|
||||
"抗魔值进入副本开关(true为开启,false为关闭)":true,
|
||||
"副本配置":{
|
||||
"1":[0, 0, 1, 200, 2, 300, 3, 400, 4, 500, 5, 600],
|
||||
"2":[0, 100, 1, 200, 2, 300, 3, 400, 4, 500, 5, 600],
|
||||
"3":[0, 100, 1, 200, 2, 300, 3, 400, 4, 500, 5, 600],
|
||||
"4":[0, 100, 1, 200, 2, 300, 3, 400, 4, 500, 5, 600],
|
||||
"5":[0, 100, 1, 200, 2, 300, 3, 400, 4, 500, 5, 600],
|
||||
"6":[0, 100, 1, 200, 2, 300, 3, 400, 4, 500, 5, 600],
|
||||
"7":[0, 100, 1, 200, 2, 300, 3, 400, 4, 500, 5, 600]
|
||||
}
|
||||
},
|
||||
"副本难度命名" : {
|
||||
"0": "普通级",
|
||||
"1": "冒险级",
|
||||
"2": "勇士级",
|
||||
"3": "王者级",
|
||||
"4": "地狱级"
|
||||
},
|
||||
"PVF储存路径_没有更改的话不要改动此配置":"/home/neople/game/Script.pvf"
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"1" : "哥布林",
|
||||
"2" : "投掷哥布林"
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"时装清除卷ID": 2021458808,
|
||||
"宠物清除卷ID": 2021458807,
|
||||
"时装清除完成提示": "清除前两行时装成功",
|
||||
"宠物清除完成提示": "清除前两行宠物成功",
|
||||
"时装清除券是否返还": true,
|
||||
"宠物清除券是否返还": true,
|
||||
"数据库IP 不是外置数据库不要更改": "127.0.0.1",
|
||||
"数据库端口 不懂不要更改": 3306,
|
||||
"数据库用户名 本地用户名不懂不要更改": "game",
|
||||
"数据库密码 本地密码不懂不要更改": "uu5!^%jg"
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"副本集合": {
|
||||
"1": 0.2,
|
||||
"2": 0.01,
|
||||
"3": 0.01
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"充值卡配置": {
|
||||
"2024120601": 1000,
|
||||
"2024120602": 5000,
|
||||
"2024120603": 10000,
|
||||
"2024120604": 30000,
|
||||
"2024120605": 50000
|
||||
},
|
||||
"提示": "如果使用233发包需要客户端插件,在群文件搜索<客户端插件消息框233>下载使用,否则会导致游戏崩溃",
|
||||
"启用233发包(true/false)": false,
|
||||
"充值成功提示": "成功充值 %d 点券"
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
{
|
||||
"信息提示窗口提示(true开启/false关闭)": false,
|
||||
"信息播报发送位置": 37,
|
||||
"品级回收配置": {
|
||||
"开启品级以及装备等级的回收(true开启/false关闭)": false,
|
||||
"提示": "奖励[道具ID(0代表点券),数量最小值,数量最大值]",
|
||||
"配置列表": [
|
||||
{
|
||||
"奖励": [
|
||||
[
|
||||
3037,
|
||||
10,
|
||||
20
|
||||
]
|
||||
],
|
||||
"装备品级": 2,
|
||||
"装备等级": 55
|
||||
},
|
||||
{
|
||||
"奖励": [
|
||||
[
|
||||
7421,
|
||||
10,
|
||||
20
|
||||
]
|
||||
],
|
||||
"装备品级": 3,
|
||||
"装备等级": 10
|
||||
},
|
||||
{
|
||||
"奖励": [
|
||||
[
|
||||
3037,
|
||||
10,
|
||||
20
|
||||
]
|
||||
],
|
||||
"装备品级": 4,
|
||||
"装备等级": 50
|
||||
},
|
||||
{
|
||||
"奖励": [
|
||||
[
|
||||
3037,
|
||||
10,
|
||||
20
|
||||
]
|
||||
],
|
||||
"装备品级": 4,
|
||||
"装备等级": 55
|
||||
},
|
||||
{
|
||||
"奖励": [
|
||||
[
|
||||
3037,
|
||||
10,
|
||||
20
|
||||
]
|
||||
],
|
||||
"装备品级": 4,
|
||||
"装备等级": 60
|
||||
},
|
||||
{
|
||||
"奖励": [
|
||||
[
|
||||
3037,
|
||||
10,
|
||||
20
|
||||
]
|
||||
],
|
||||
"装备品级": 4,
|
||||
"装备等级": 65
|
||||
},
|
||||
{
|
||||
"奖励": [
|
||||
[
|
||||
3037,
|
||||
10,
|
||||
20
|
||||
]
|
||||
],
|
||||
"装备品级": 4,
|
||||
"装备等级": 70
|
||||
}
|
||||
]
|
||||
},
|
||||
"回收失败信息": " 装备回收失败\n 没有合适的装备或已上锁",
|
||||
"回收成功是否返还回收券道具(true返还/false不返还)": false,
|
||||
"回收配置": {
|
||||
"回收位置": [
|
||||
9,
|
||||
16
|
||||
],
|
||||
"回收箱道具ID": 17577,
|
||||
"指定装备ID不参与回收": [
|
||||
27099,
|
||||
27100,
|
||||
27101
|
||||
],
|
||||
"指定装备回收": [
|
||||
[
|
||||
27098,
|
||||
3340,
|
||||
1,
|
||||
10
|
||||
],
|
||||
[
|
||||
27102,
|
||||
0,
|
||||
1,
|
||||
10
|
||||
],
|
||||
[
|
||||
2711001,
|
||||
3038,
|
||||
1,
|
||||
10
|
||||
]
|
||||
],
|
||||
"提示1": "[回收装备的ID,奖励道具的ID(0代表点券),数量最小值,数量最大值]",
|
||||
"提示2": "回收位置快捷栏(快捷栏3-8),装备栏(快捷栏9-56,如第一排为9-16,第二排为17-24,第三排为25-32,第四排为33-40,第五排为41-48,第六排为49-56)",
|
||||
"提示3": "如果指定装备回收和品级回收都命中的情况下,优先以指定装备回收为准",
|
||||
"提示4": "排除装备ID中的装备不会参与回收,即使它们符合其他回收条件"
|
||||
},
|
||||
"成功回收": {
|
||||
"单位": "个",
|
||||
"奖励提示": "奖励",
|
||||
"标题": " 成功回收"
|
||||
},
|
||||
"提示": "开启弹窗提示需在群文件下载 <客户端消息框233.dll> 插件,否则会导致游戏崩溃",
|
||||
"表情ID": 59
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"数据库IP 不是外置数据库不要更改": "127.0.0.1",
|
||||
"数据库端口 不懂不要更改": 3306,
|
||||
"数据库用户名 本地用户名不懂不要更改": "game",
|
||||
"数据库密码 本地密码不懂不要更改": "uu5!^%jg"
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"门票进入副本":{
|
||||
"提示":"门票进入副本配置(副本ID[普通级,门票,冒险级,门票,勇士级,门票,王者级,门票,地狱级,门票])",
|
||||
"门票进入副本开关(true为开启,false为关闭)":true,
|
||||
"副本配置":{
|
||||
"1":[0, 3037, 1, 3037, 2, 3037, 3, 3037, 4, 3037, 5, 3037]
|
||||
}
|
||||
},
|
||||
"副本难度命名" : {
|
||||
"0": "普通级",
|
||||
"1": "冒险级",
|
||||
"2": "勇士级",
|
||||
"3": "王者级",
|
||||
"4": "地狱级"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"制裁开关(true开启false关闭)": true,
|
||||
"制裁配置 达到次数 制裁时长(秒)": [2, 300],
|
||||
"角色CID白名单": [1, 2],
|
||||
"副本ID白名单(非正常副本接口进入的副本)": [11111,222222],
|
||||
"温馨提示1":"副本ID白名单并不是加了就关闭检测,只是关闭其中一项检测",
|
||||
"温馨提示2": "角色ID可以查看数据库中 taiwan_cain → charac_info → charac_no代表角色ID",
|
||||
|
||||
"msgtype1": "你已经被限制获取道具和金币,剩余:[%d]秒...",
|
||||
"msgtype2": "你已经被限制获取经验,剩余:[%d]秒...",
|
||||
"msgtype3": "玩家[%s]因使用第三方软件已被限制进入副本,剩余:[%d]秒..."
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"ProjectName": "全职业通用转职书",
|
||||
"ProjectDescribe": "全职业都可用的转职书。每个转职职业是个数组,可以写多个转职卷编号,仿照7577的道具类型即可,使用\",\"隔开。",
|
||||
"ProjectAuthor": "倾泪寒",
|
||||
"ProjectVersion": 1.0,
|
||||
"ProjectConfig": "",
|
||||
"ProjectConfig": "全职业通用转职书_Lenheart.json",
|
||||
"ProjectFiles": [
|
||||
"全职业通用转职书.nut"
|
||||
],
|
||||
"ProjectRunFunc": "_Dps_GeneralJobTransferCertificateForAllProfessions_Main_"
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
文件名:全职业通用转职书.nut
|
||||
路径:OfficialProject/全职业通用转职书/全职业通用转职书.nut
|
||||
创建日期:2025-10-24 22:26
|
||||
文件用途:
|
||||
*/
|
||||
|
||||
//重载入口
|
||||
function _Dps_GeneralJobTransferCertificateForAllProfessions_Main_Reload_(OldConfig) {
|
||||
//先销毁原来注册的
|
||||
local JobArr = [];
|
||||
JobArr.push(GlobalConfig["转职初始职业"]);
|
||||
JobArr.push(GlobalConfig["转职第一职业"]);
|
||||
JobArr.push(GlobalConfig["转职第二职业"]);
|
||||
JobArr.push(GlobalConfig["转职第三职业"]);
|
||||
JobArr.push(GlobalConfig["转职第四职业"]);
|
||||
JobArr.push(GlobalConfig["转职第五职业"]);
|
||||
|
||||
foreach(Index, arr in JobArr) {
|
||||
foreach(ItemId in arr) {
|
||||
if (Cb_Use_Item_Sp_Func.rawin(ItemId)) Cb_Use_Item_Sp_Func.rawdelete(ItemId);
|
||||
}
|
||||
}
|
||||
|
||||
//重新注册
|
||||
_Dps_GeneralJobTransferCertificateForAllProfessions_Main_();
|
||||
}
|
||||
|
||||
function _Dps_GeneralJobTransferCertificateForAllProfessions_Main_() {
|
||||
local Config = GlobalConfig.Get("全职业通用转职书_Lenheart.json");
|
||||
local JobArr = [];
|
||||
JobArr.push(Config["转职初始职业"]);
|
||||
JobArr.push(Config["转职第一职业"]);
|
||||
JobArr.push(Config["转职第二职业"]);
|
||||
JobArr.push(Config["转职第三职业"]);
|
||||
JobArr.push(Config["转职第四职业"]);
|
||||
JobArr.push(Config["转职第五职业"]);
|
||||
|
||||
|
||||
|
||||
foreach(Index, arr in JobArr) {
|
||||
foreach(ItemId in arr) {
|
||||
Cb_Use_Item_Sp_Func[ItemId] <- function(SUser, ItemId) {
|
||||
SUser.ChangeGrowType(Index, 0);
|
||||
SUser.SendNotiPacket(0, 2, 0);
|
||||
SUser.InitSkillW(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"ProjectName": "宠物装备回收",
|
||||
"ProjectDescribe": "宠物装备回收,根据指定回收的ID奖励随机数量的奖励,以及根据品级以及装备等级进行回收给与奖励",
|
||||
"ProjectAuthor": "猫咪",
|
||||
"ProjectVersion": 1.4,
|
||||
"ProjectConfig": "宠物装备回收配置_Maomi.json",
|
||||
"ProjectFiles": [
|
||||
"宠物装备回收.nut"
|
||||
],
|
||||
"ProjectRunFunc": "_Dps_PetEquipmentRecycling_Main_"
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
|
|
@ -0,0 +1,341 @@
|
|||
// 回收装备的主函数
|
||||
function PetEquipmentRecyclingFuncBymaomi(SUser, ItemId) {
|
||||
local Config = GlobalConfig.Get("宠物装备回收配置_Maomi.json");
|
||||
|
||||
// 获取用户的背包对象,如果不存在则直接返回
|
||||
local InvenObj = SUser.GetInven();
|
||||
if (!InvenObj) {
|
||||
return;
|
||||
}
|
||||
|
||||
local foundValidSlot = false;
|
||||
local index = 0;
|
||||
local allRewards = [];
|
||||
|
||||
// 遍历装备栏指定范围的格子
|
||||
for (local i = Config["回收配置"]["回收位置"][0]; i <= Config["回收配置"]["回收位置"][1]; i++) {
|
||||
local ItemObj = InvenObj.GetSlot(3, i);
|
||||
|
||||
// 如果该槽为空,跳过
|
||||
if (ItemObj.IsEmpty) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查装备是否上锁,若上锁则跳过该装备
|
||||
local CheckItemLock = Sq_CallFunc(S_Ptr("0x8646942"), "int", ["pointer", "int", "int"], SUser.C_Object, 1, i);
|
||||
if (CheckItemLock) {
|
||||
continue;
|
||||
}
|
||||
|
||||
local Item_Id = ItemObj.GetIndex();
|
||||
|
||||
// 检查装备是否在排除列表中,如果在则跳过
|
||||
if ("指定装备ID不参与回收" in Config["回收配置"] && Config["回收配置"]["指定装备ID不参与回收"].len() > 0) {
|
||||
local isExcluded = false;
|
||||
foreach (excludeId in Config["回收配置"]["指定装备ID不参与回收"]) {
|
||||
if (excludeId == Item_Id) {
|
||||
isExcluded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isExcluded) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
local PvfItemObj = PvfItem.GetPvfItemById(Item_Id);
|
||||
local rarity = PvfItemObj.GetRarity();
|
||||
local level = PvfItemObj.GetUsableLevel();
|
||||
local Recycleitem_name = PvfItem.GetNameById(Item_Id);
|
||||
|
||||
// 检查指定宠物装备回收配置
|
||||
local found = false;
|
||||
foreach(item in Config["回收配置"]["指定宠物装备回收"]) {
|
||||
if(item[0] == Item_Id) {
|
||||
local Rewarditem = item[1];
|
||||
local minCount = item[2];
|
||||
local maxCount = item[3];
|
||||
local Rewarditem_name = PvfItem.GetNameById(Rewarditem);
|
||||
local RewardItemObj = PvfItem.GetPvfItemById(Rewarditem);
|
||||
local item_upgrade = ItemObj.GetUpgrade();
|
||||
local totalRewards = [];
|
||||
if (item_upgrade > 0) {
|
||||
Recycleitem_name = "+" + item_upgrade + Recycleitem_name;
|
||||
}
|
||||
|
||||
local count = MathClass.Rand(minCount, maxCount + 1);
|
||||
if (Rewarditem == 0) {
|
||||
SUser.RechargeCera(count);
|
||||
_RecycleItem_nangua.sendRewardMessageForCera(SUser, Recycleitem_name, ItemObj, count, Item_Id);
|
||||
} else {
|
||||
local equ_type = NativePointer(RewardItemObj.C_Object).add(141 * 4).readU32();
|
||||
if (equ_type > 0) {
|
||||
count = 1;
|
||||
}
|
||||
totalRewards.append([Rewarditem, count]);
|
||||
allRewards.append([Rewarditem, count]); // 添加到总奖励列表
|
||||
_RecycleItem_nangua.api_CUser_Add_Item_list(SUser, totalRewards);
|
||||
_RecycleItem_nangua.sendRewardMessageForItem(SUser, Recycleitem_name, ItemObj, Rewarditem_name, count, equ_type, Item_Id, Rewarditem);
|
||||
}
|
||||
foundValidSlot = true;
|
||||
ItemObj.Delete();
|
||||
SUser.SendUpdateItemList(1, 3, i);
|
||||
index++;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(found) continue;
|
||||
|
||||
// 检查品级回收配置
|
||||
if (Config["品级回收配置"]["开启品级以及装备等级的回收(true开启/false关闭)"]) {
|
||||
foreach(cfg in Config["品级回收配置"]["配置列表"]) {
|
||||
if (cfg["装备品级"] == rarity && cfg["装备等级"] == level) {
|
||||
foundValidSlot = true;
|
||||
local reward = cfg["奖励"][0];
|
||||
local count = MathClass.Rand(reward[1], reward[2] + 1);
|
||||
local totalReward = [];
|
||||
if (reward[0] == 0) {
|
||||
SUser.RechargeCera(count);
|
||||
_RecycleItem_nangua.sendRewardMessageForCera(SUser, Recycleitem_name, ItemObj, count, Item_Id);
|
||||
} else {
|
||||
local Rewarditem_name = PvfItem.GetNameById(reward[0]);
|
||||
// 获取装备类型大于0为装备
|
||||
local RewardItemObj = PvfItem.GetPvfItemById(reward[0]);
|
||||
local equ_type = NativePointer(RewardItemObj.C_Object).add(141 * 4).readU32();
|
||||
if (equ_type > 0) {
|
||||
count = 1;
|
||||
}
|
||||
totalReward.append([reward[0], count]);
|
||||
allRewards.append([reward[0], count]);
|
||||
_RecycleItem_nangua.api_CUser_Add_Item_list(SUser, totalReward);
|
||||
_RecycleItem_nangua.sendRewardMessageForItem(SUser, Recycleitem_name, ItemObj, Rewarditem_name, count, equ_type, Item_Id, reward[0]);
|
||||
}
|
||||
ItemObj.Delete();
|
||||
SUser.SendUpdateItemList(1, 0, i);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 发送结果消息
|
||||
if (foundValidSlot) {
|
||||
if (index > 0) {
|
||||
SUser.SendNotiPacketMessage("恭喜: " + index + " 件宠物装备回收成功。", Config["信息播报发送位置"]);
|
||||
if (allRewards.len() > 0) {
|
||||
_RecycleItem_nangua.SendItemWindowNotification(SUser, allRewards);
|
||||
}
|
||||
}
|
||||
if(Config["回收成功是否返还回收券道具(true返还/false不返还)"]){
|
||||
SUser.GiveItem(ItemId, 1);
|
||||
}
|
||||
} else {
|
||||
_RecycleItem_nangua.RecycleError(SUser, Config["回收失败信息"], ItemId);
|
||||
}
|
||||
}
|
||||
class _RecycleItem_nangua {
|
||||
// 发送通知和返还道具
|
||||
function RecycleError(SUser, msg, ItemId) {
|
||||
local Config = GlobalConfig.Get("宠物装备回收配置_Maomi.json");
|
||||
if(Config["信息提示窗口提示(true开启/false关闭)"]) {
|
||||
SUser.SendNotiBox(msg, 1);
|
||||
} else {
|
||||
SUser.SendNotiPacketMessage(msg, Config["信息播报发送位置"]);
|
||||
}
|
||||
SUser.GiveItem(ItemId, 1);
|
||||
}
|
||||
|
||||
// 发送点券奖励消息
|
||||
function sendRewardMessageForCera(SUser, Recycleitem_name, ItemObj, count, Item_Id) {
|
||||
local Config = GlobalConfig.Get("宠物装备回收配置_Maomi.json");
|
||||
local AdMsgObj = AdMsg();
|
||||
AdMsgObj.PutType(Config["信息播报发送位置"]);
|
||||
AdMsgObj.PutString(" ");
|
||||
AdMsgObj.PutImoticon(Config["表情ID"]);
|
||||
AdMsgObj.PutString(Config["成功回收"]["标题"]);
|
||||
AdMsgObj.PutEquipment("[" + Recycleitem_name + "]", ItemObj, _RecycleItem_nangua.RarityColor(Item_Id));
|
||||
AdMsgObj.PutString(Config["成功回收"]["奖励提示"]);
|
||||
AdMsgObj.PutColorString("[" + count + "]", [255, 20, 0]);
|
||||
AdMsgObj.PutString("点券");
|
||||
AdMsgObj.Finalize();
|
||||
SUser.Send(AdMsgObj.MakePack());
|
||||
AdMsgObj.Delete();
|
||||
}
|
||||
|
||||
// 发送道具奖励消息
|
||||
function sendRewardMessageForItem(SUser, Recycleitem_name, ItemObj, Rewarditem_name, count, equ_type, Item_Id, Rewarditem) {
|
||||
local Config = GlobalConfig.Get("宠物装备回收配置_Maomi.json");
|
||||
local AdMsgObj = AdMsg();
|
||||
AdMsgObj.PutType(Config["信息播报发送位置"]);
|
||||
AdMsgObj.PutString(" ");
|
||||
AdMsgObj.PutImoticon(Config["表情ID"]);
|
||||
AdMsgObj.PutString(Config["成功回收"]["标题"]);
|
||||
AdMsgObj.PutEquipment("[" + Recycleitem_name + "]", ItemObj, _RecycleItem_nangua.RarityColor(Item_Id));
|
||||
AdMsgObj.PutString(Config["成功回收"]["奖励提示"]);
|
||||
if (equ_type > 0) {
|
||||
AdMsgObj.PutColorString("[" + Rewarditem_name + "]", _RecycleItem_nangua.RarityColor(Rewarditem));
|
||||
} else {
|
||||
AdMsgObj.PutColorString("[" + count + "]", [255, 20, 0]);
|
||||
AdMsgObj.PutString(Config["成功回收"]["单位"]);
|
||||
AdMsgObj.PutColorString("[" + Rewarditem_name + "]", _RecycleItem_nangua.RarityColor(Rewarditem));
|
||||
}
|
||||
AdMsgObj.Finalize();
|
||||
SUser.Send(AdMsgObj.MakePack());
|
||||
AdMsgObj.Delete();
|
||||
}
|
||||
function RarityColor(item_id) {
|
||||
local PvfItemObj = PvfItem.GetPvfItemById(item_id);
|
||||
if (PvfItemObj == null) {
|
||||
return;
|
||||
}
|
||||
local CItem_get_rarity = PvfItemObj.GetRarity(); // 装备品级
|
||||
return _RecycleItem_nangua.rarityColorMap[(CItem_get_rarity).tostring()];
|
||||
}
|
||||
//品级对应的RGB
|
||||
rarityColorMap = {
|
||||
"0": [255, 255, 255], // 普通
|
||||
"1": [104, 213, 237], // 高级
|
||||
"2": [179, 107, 255], // 稀有
|
||||
"3": [255, 0, 255], // 神器
|
||||
"4": [255, 180, 0], // 史诗
|
||||
"5": [255, 102, 102], // 勇者
|
||||
"6": [255, 20, 147], // 深粉红色
|
||||
"7": [255, 215, 0] // 金色
|
||||
};
|
||||
function api_CUser_Add_Item_list(SUser, item_list) {
|
||||
for (local i = 0; i < item_list.len(); i++) {
|
||||
local item_id = item_list[i][0]; // 道具代码
|
||||
local quantity = item_list[i][1]; // 道具数量
|
||||
local InvenObj = SUser.GetInven();
|
||||
|
||||
// 获取道具对象
|
||||
local PvfItemObj = PvfItem.GetPvfItemById(item_id);
|
||||
// 获取道具类型
|
||||
local equ_type = NativePointer(PvfItemObj.C_Object).add(141 * 4).readU32();
|
||||
// 获取最大堆叠数量
|
||||
local maxStack = Sq_CallFunc(S_Ptr("0x0822C9FC"), "int", ["pointer"], PvfItemObj.C_Object);
|
||||
|
||||
// 如果是装备,直接检查空格并处理
|
||||
if (equ_type > 0) {
|
||||
local cnt = _RecycleItem_nangua.checkInventorySlot(SUser, item_id);
|
||||
if (cnt == 1) {
|
||||
SUser.GiveItem(item_id, quantity);
|
||||
} else {
|
||||
local RewardItems = [];
|
||||
RewardItems.append([item_id, quantity]);
|
||||
local title = "GM";
|
||||
local Text = "由于背包空间不足,已通过邮件发送,请查收!";
|
||||
SUser.ReqDBSendMultiMail(title, Text, 0, RewardItems);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取道具在背包中的槽位
|
||||
local slot = InvenObj.GetSlotById(item_id);
|
||||
if (slot != -1) {
|
||||
// 获取槽位中的道具对象
|
||||
local ItemObj = InvenObj.GetSlot(1, slot);
|
||||
// 获取当前堆叠数量
|
||||
local currentCount = Sq_CallFunc(S_Ptr("0x80F783A"), "int", ["pointer"], ItemObj.C_Object);
|
||||
|
||||
// 如果当前堆叠未满,计算可以添加的数量
|
||||
if (currentCount < maxStack) {
|
||||
local canAdd = maxStack - currentCount;
|
||||
if (quantity <= canAdd) {
|
||||
// 如果奖励数量小于等于可添加数量,直接添加
|
||||
Sq_CallFunc(S_Ptr("0x80CB884"), "int", ["pointer", "int"], ItemObj.C_Object, currentCount + quantity);
|
||||
// 刷新背包显示
|
||||
SUser.SendUpdateItemList(1, 0, slot);
|
||||
} else {
|
||||
// 如果奖励数量大于可添加数量
|
||||
// 先将当前堆叠设置为最大
|
||||
Sq_CallFunc(S_Ptr("0x80CB884"), "int", ["pointer", "int"], ItemObj.C_Object, maxStack);
|
||||
SUser.SendUpdateItemList(1, 0, slot);
|
||||
// 将剩余数量通过邮件发送
|
||||
local remaining = quantity - canAdd;
|
||||
local RewardItems = [];
|
||||
RewardItems.append([item_id, remaining]);
|
||||
local title = "GM";
|
||||
local Text = "由于背包堆叠已满,部分道具已通过邮件发送,请查收!";
|
||||
SUser.ReqDBSendMultiMail(title, Text, 0, RewardItems);
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
local RewardItems = [];
|
||||
RewardItems.append([item_id, quantity]);
|
||||
local title = "GM";
|
||||
local Text = "由于背包堆叠已满,已通过邮件发送,请查收!";
|
||||
SUser.ReqDBSendMultiMail(title, Text, 0, RewardItems);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果道具不在背包中,检查空格
|
||||
local cnt = _RecycleItem_nangua.checkInventorySlot(SUser, item_id);
|
||||
if (cnt == 1) {
|
||||
// 如果道具有空格,直接添加到背包
|
||||
SUser.GiveItem(item_id, quantity);
|
||||
} else {
|
||||
// 如果背包空间不足,通过邮件发送
|
||||
local RewardItems = [];
|
||||
RewardItems.append([item_id, quantity]);
|
||||
local title = "GM";
|
||||
local Text = "由于背包空间不足,已通过邮件发送,请查收!";
|
||||
SUser.ReqDBSendMultiMail(title, Text, 0, RewardItems);
|
||||
}
|
||||
}
|
||||
}
|
||||
function SendItemWindowNotification(SUser, item_list) {
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(1, 163); //协议
|
||||
Pack.Put_Byte(1); //默认1
|
||||
Pack.Put_Short(0); //槽位id 填入0即可
|
||||
Pack.Put_Int(0); //未知 0以上即可
|
||||
Pack.Put_Short(item_list.len()); //道具组数
|
||||
//写入道具代码和道具数量
|
||||
for (local i = 0; i < item_list.len(); i++) {
|
||||
Pack.Put_Int(item_list[i][0]); //道具代码
|
||||
Pack.Put_Int(item_list[i][1]); //道具数量 装备/时装时 任意均可
|
||||
}
|
||||
Pack.Finalize(true); //确定发包内容
|
||||
SUser.Send(Pack); //发包
|
||||
Pack.Delete(); //清空buff区
|
||||
}
|
||||
/**
|
||||
* 根据道具类型背包空格数量
|
||||
* @param {pointer} SUser - 用户
|
||||
* @param {int} item_id - 需要查找的道具ID
|
||||
* @returns {int} - 空格数量
|
||||
*/
|
||||
function checkInventorySlot(SUser, itemid) {
|
||||
local InvenObj = SUser.GetInven();
|
||||
local type = Sq_CallFunc(S_Ptr("0x085018D2"), "int", ["pointer", "int"], InvenObj.C_Object, itemid);
|
||||
local cnt = Sq_CallFunc(S_Ptr("0x08504F64"), "int", ["pointer", "int", "int"], InvenObj.C_Object, type, 1);
|
||||
|
||||
return cnt;
|
||||
}
|
||||
}
|
||||
|
||||
//加载入口
|
||||
function _Dps_PetEquipmentRecycling_Main_() {
|
||||
_Dps_PetEquipmentRecycling_Logic_();
|
||||
}
|
||||
|
||||
//重载入口
|
||||
function _Dps_PetEquipmentRecycling_Main_Reload_(OldConfig) {
|
||||
local Cofig = GlobalConfig.Get("宠物装备回收配置_Maomi.json");
|
||||
Cb_Use_Item_Sp_Func.rawdelete(OldConfig["回收配置"]["回收箱道具ID"].tointeger());
|
||||
|
||||
//重新注册
|
||||
_Dps_PetEquipmentRecycling_Logic_();
|
||||
}
|
||||
|
||||
function _Dps_PetEquipmentRecycling_Logic_() {
|
||||
local Cofig = GlobalConfig.Get("宠物装备回收配置_Maomi.json");
|
||||
// 宠物装备回收
|
||||
Cb_Use_Item_Sp_Func[Cofig["回收配置"]["回收箱道具ID"]] <- PetEquipmentRecyclingFuncBymaomi;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
{
|
||||
"回收配置": {
|
||||
"回收箱道具ID": 2021458811,
|
||||
"回收位置": [9, 16],
|
||||
"指定宠物装备回收": [
|
||||
[27098, 3340, 1, 10],
|
||||
[27102, 0, 1, 10],
|
||||
[2711001, 3038, 1, 10]
|
||||
],
|
||||
"指定装备ID不参与回收": [27099, 27100, 27101],
|
||||
"提示1":"[回收装备的ID,奖励道具的ID(0代表点券),数量最小值,数量最大值]",
|
||||
"提示2":"回收位置快捷栏(快捷栏3-8),装备栏(快捷栏9-56,如第一排为9-16,第二排为17-24,第三排为25-32,第四排为33-40,第五排为41-48,第六排为49-56)",
|
||||
"提示3":"如果指定装备回收和品级回收都命中的情况下,优先以指定装备回收为准",
|
||||
"提示4":"排除装备ID中的装备不会参与回收,即使它们符合其他回收条件"
|
||||
},
|
||||
"品级回收配置": {
|
||||
"开启品级以及装备等级的回收(true开启/false关闭)": false,
|
||||
"提示": "奖励[道具ID(0代表点券),数量最小值,数量最大值]",
|
||||
"配置列表": [{
|
||||
"装备品级": 2,
|
||||
"装备等级": 55,
|
||||
"奖励": [
|
||||
[3037, 10, 20]
|
||||
]
|
||||
},
|
||||
{
|
||||
"装备品级": 3,
|
||||
"装备等级": 10,
|
||||
"奖励": [
|
||||
[7421, 10, 20]
|
||||
]
|
||||
},
|
||||
{
|
||||
"装备品级": 4,
|
||||
"装备等级": 50,
|
||||
"奖励": [
|
||||
[3037, 10, 20]
|
||||
]
|
||||
},
|
||||
{
|
||||
"装备品级": 4,
|
||||
"装备等级": 55,
|
||||
"奖励": [
|
||||
[3037, 10, 20]
|
||||
]
|
||||
},
|
||||
{
|
||||
"装备品级": 4,
|
||||
"装备等级": 60,
|
||||
"奖励": [
|
||||
[3037, 10, 20]
|
||||
]
|
||||
},
|
||||
{
|
||||
"装备品级": 4,
|
||||
"装备等级": 65,
|
||||
"奖励": [
|
||||
[3037, 10, 20]
|
||||
]
|
||||
},
|
||||
{
|
||||
"装备品级": 4,
|
||||
"装备等级": 70,
|
||||
"奖励": [
|
||||
[3037, 10, 20]
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"回收失败信息": " 装备回收失败\n 没有合适的装备或已上锁",
|
||||
"信息播报发送位置": 37,
|
||||
"信息提示窗口提示(true开启/false关闭)": false,
|
||||
"提示":"开启弹窗提示需在群文件下载 <客户端消息框233.dll> 插件,否则会导致游戏崩溃",
|
||||
"回收成功是否返还回收券道具(true返还/false不返还)":false,
|
||||
"表情ID": 59,
|
||||
"成功回收": {
|
||||
"标题": " 成功回收",
|
||||
"奖励提示":"奖励",
|
||||
"单位": "个"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"ProjectName": "宠物附魔",
|
||||
"ProjectDescribe": "可以实现宠物附魔,需要登录器或dll支持!",
|
||||
"ProjectAuthor": "七游云赞助",
|
||||
"ProjectVersion": 1.0,
|
||||
"ProjectConfig": "",
|
||||
"ProjectFiles": [
|
||||
"宠物附魔.nut"
|
||||
],
|
||||
"ProjectRunFunc": "_Dps_PetEnchantment_Main_"
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
function _Dps_UpdateCreatureEnchantMysql_(card_id, charac_no, uuid) {
|
||||
local sql = "select card from `taiwan_cain_2nd`.`creature_items_enchant` where ui_id = " + uuid + ";";
|
||||
local column_type_list = ["int"];
|
||||
local SqlObj = MysqlPool.GetInstance().GetConnect();
|
||||
local result = SqlObj.Select(sql, column_type_list);
|
||||
local UpdateSql = "update `taiwan_cain_2nd`.`creature_items_enchant` set `card` = " + card_id + " where `ui_id` = " + uuid + ";";
|
||||
if (result.len() <= 0 || result[0].len() <= 0) {
|
||||
UpdateSql = "INSERT INTO `taiwan_cain_2nd`.`creature_items_enchant`(`ui_id`, `charac_no`, `card`) VALUES (" + uuid + "," + charac_no + "," + card_id + ");";
|
||||
}
|
||||
SqlObj.Exec_Sql(UpdateSql);
|
||||
MysqlPool.GetInstance().PutConnect(SqlObj);
|
||||
}
|
||||
|
||||
function _Dps_GetCreatureEnchantMysql_(charac_no) {
|
||||
local sql = "select ui_id,card from `taiwan_cain_2nd`.`creature_items_enchant` where charac_no = " + charac_no + ";";
|
||||
local column_type_list = ["int", "int"];
|
||||
local SqlObj = MysqlPool.GetInstance().GetConnect();
|
||||
local result = SqlObj.Select(sql, column_type_list);
|
||||
MysqlPool.GetInstance().PutConnect(SqlObj);
|
||||
return result;
|
||||
}
|
||||
|
||||
function _Dps_PetEnchantment_Main_() {
|
||||
//初始建表指令
|
||||
local CreateSql = "CREATE TABLE `taiwan_cain_2nd`.`creature_items_enchant` (`ui_id` int(11) NOT NULL DEFAULT '0',`charac_no` int(11) DEFAULT NULL,`card` int(11) NOT NULL DEFAULT '0',PRIMARY KEY (`ui_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;";
|
||||
local SqlObj = MysqlPool.GetInstance().GetConnect();
|
||||
SqlObj.Exec_Sql(CreateSql);
|
||||
MysqlPool.GetInstance().PutConnect(SqlObj);
|
||||
//忽略宠物附魔错误
|
||||
Sq_WriteByteArr(S_Ptr("0x850dede"), array(2, 0x90));
|
||||
|
||||
Cb_ExpertOnEnchantByBead_Leave_Func["宠物附魔"] <- function(args) {
|
||||
if (args[5] > 56) {
|
||||
local SUser = User(args[1]);
|
||||
local InvenObj = SUser.GetInven();
|
||||
local Bead_id = InvenObj.GetSlot(1, args[3]).GetIndex()
|
||||
local PvfItemObj = PvfItem.GetPvfItemById(InvenObj.GetSlot(1, args[3]).GetIndex())
|
||||
local Card_Id = Sq_CallFunc(S_Ptr("0x0849F530"), "int", ["pointer"], PvfItemObj.C_Object);
|
||||
local a7 = args[5] - 57;
|
||||
local ItemObj = InvenObj.GetSlot(3, a7)
|
||||
local Item_Id = ItemObj.GetIndex();
|
||||
NativePointer(ItemObj.C_Object).add(13).writeU32(Card_Id);
|
||||
if (a7< 140) {
|
||||
local uuid = NativePointer(ItemObj.C_Object).add(7).readInt();
|
||||
_Dps_UpdateCreatureEnchantMysql_(Card_Id, SUser.GetCID(), uuid);
|
||||
}
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(1, 275);
|
||||
Pack.Put_Byte(1);
|
||||
Pack.Finalize(true);
|
||||
SUser.Send(Pack);
|
||||
Pack.Delete();
|
||||
SUser.SendUpdateItemList(1, 7, a7);
|
||||
InvenObj.DeleteItemCount(Bead_id, 1);
|
||||
SUser.SendUpdateItemList(1, 0, args[3]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Cb_reach_game_world_Func["宠物附魔"] <- function(SUser) {
|
||||
local Data = _Dps_GetCreatureEnchantMysql_(SUser.GetCID());
|
||||
local DMap = {};
|
||||
foreach(data_obj in Data) {
|
||||
local uuid = data_obj[0];
|
||||
local card_id = data_obj[1];
|
||||
DMap.rawset(uuid, card_id);
|
||||
}
|
||||
local InvenObj = SUser.GetInven();
|
||||
for (local i = 0; i< 141; i++) {
|
||||
local equ;
|
||||
if (i == 140) {
|
||||
equ = InvenObj.GetSlot(0, 22); //获取当前格子的宠物
|
||||
} else {
|
||||
equ = InvenObj.GetSlot(3, i);
|
||||
}
|
||||
local equ_uuid = NativePointer(equ.C_Object).add(7).readInt();
|
||||
if (DMap.rawin(equ_uuid)) {
|
||||
NativePointer(equ.C_Object).add(13).writeU32(DMap[equ_uuid]);
|
||||
if (i == 140) SUser.SendUpdateItemList(1, 0, 22);
|
||||
else SUser.SendUpdateItemList(1, 7, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"ProjectName": "技能拓展14键",
|
||||
"ProjectDescribe": "14键位技能的服务端修复程序,需要客户端已经加载了14键技能的插件。",
|
||||
"ProjectAuthor": "倾泪寒",
|
||||
"ProjectVersion": 1.0,
|
||||
"ProjectConfig": "",
|
||||
"ProjectFiles": [
|
||||
"技能拓展14键.nut"
|
||||
],
|
||||
"ProjectRunFunc": "_Dps_SkillExpansion_14Keys_Main_"
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
|
||||
|
||||
function _Dps_SkillExpansion_14Keys_Main_()
|
||||
{
|
||||
GameManager.Fix14Skill();
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"ProjectName": "抗魔值进入副本",
|
||||
"ProjectDescribe": "指定的副本按难度及抗魔值才能进入副本",
|
||||
"ProjectAuthor": "南瓜",
|
||||
"ProjectVersion": 1.0,
|
||||
"ProjectConfig": "抗魔值进入副本配置_Nangua.json",
|
||||
"ProjectFiles": [
|
||||
"抗魔值进入副本.nut"
|
||||
],
|
||||
"ProjectRunFunc": "_Dps_anti_evilDgnBynangua_Main_"
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
class _evilDgnBynangua {
|
||||
function get_required_gradeBynangua(dgn_id, dgn_diff) {
|
||||
local Config = GlobalConfig.Get("抗魔值进入副本配置_Nangua.json");
|
||||
if (Config["抗魔值进入副本"]["副本配置"].rawin(dgn_id.tostring())) {
|
||||
local requirements = Config["抗魔值进入副本"]["副本配置"][dgn_id.tostring()];
|
||||
for (local i = 0; i < requirements.len(); i += 2) {
|
||||
if (requirements[i] == dgn_diff) {
|
||||
return requirements[i + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function api_CDungeon_getDungeonName(dungeon_id) {
|
||||
local G_CDataManager = Sq_CallFunc(S_Ptr("0x80CC19B"), "pointer", []);
|
||||
local cdungeon = Sq_CallFunc(S_Ptr("0x835F9F8"), "pointer", ["pointer", "int"], G_CDataManager, dungeon_id);
|
||||
if (!cdungeon) {
|
||||
return;
|
||||
}
|
||||
if (cdungeon) {
|
||||
local dgnobj = Sq_CallFunc(S_Ptr("0x81455A6"), "pointer", ["pointer"], cdungeon);
|
||||
local name = NativePointer(dgnobj).readUtf8String();
|
||||
return name;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function join(array, delimiter) {
|
||||
local result = "";
|
||||
for (local i = 0; i < array.len(); ++i) {
|
||||
if (i > 0) {
|
||||
result += delimiter;
|
||||
}
|
||||
result += array[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
getroottable()._Nangua_EquipmentData_List_ <- {};
|
||||
getroottable()._Nangua_EquipmentData_Anti_ <- {};
|
||||
function _Nangua_GetEquipmentData_Anti_(Equipment_id) {
|
||||
try {
|
||||
//如果数据存在 返回数据
|
||||
if (getroottable()._Nangua_EquipmentData_Anti_.rawin(Equipment_id))return getroottable()._Nangua_EquipmentData_Anti_[Equipment_id];
|
||||
//通过装备ID获取装备路径
|
||||
local Path = getroottable()._Nangua_EquipmentData_List_[Equipment_id];
|
||||
Path = "equipment/" + Path;
|
||||
//读取装备数据
|
||||
local Data = ScriptData.GetFileData(Path, function(DataTable, Data) {
|
||||
while (!Data.Eof()) {
|
||||
local Key = Data.Get();
|
||||
if (Key == "[anti evil]") {
|
||||
getroottable()._Nangua_EquipmentData_Anti_[Equipment_id] <- Data.Get();
|
||||
return getroottable()._Nangua_EquipmentData_Anti_[Equipment_id];
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (exception){
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function _Dps_anti_evilDgnBynangua_Main_() {
|
||||
local Config = GlobalConfig.Get("抗魔值进入副本配置_Nangua.json");
|
||||
Script(Config["PVF储存路径_没有更改的话不要改动此配置"]);
|
||||
//if (Config["PVF储存路径_没有更改的话不要改动此配置"].len() > 0) Script(Config["PVF储存路径_没有更改的话不要改动此配置"]);
|
||||
//else Script();
|
||||
|
||||
//读取装备列表
|
||||
getroottable()._Nangua_EquipmentData_List_ = ScriptData.GetFileData("equipment/equipment.lst", function(DataTable, Data) {
|
||||
while (!Data.Eof()) {
|
||||
local Key = Data.Get();
|
||||
//注册装备列表 路径写入 数据未读取
|
||||
DataTable.rawset(Key, Data.Get());
|
||||
}
|
||||
});
|
||||
|
||||
Cb_SelectDungeon_Check_Error_Leave_Func.Check_anti_evilByNangua <- function(args) {
|
||||
local Config = GlobalConfig.Get("抗魔值进入副本配置_Nangua.json");
|
||||
local SUser = User(args[1]);
|
||||
local msg_base = args[2];
|
||||
local PartyObj = SUser.GetParty();
|
||||
local dgn_id = NativePointer(msg_base).add(13).readU16(); // 获取副本ID
|
||||
local dgn_diff = NativePointer(msg_base).add(15).readU8(); // 获取副本难度
|
||||
local required_grade = _evilDgnBynangua.get_required_gradeBynangua(dgn_id, dgn_diff);
|
||||
local diff_name = Config["副本难度命名"][(dgn_diff).tostring()];
|
||||
local Dungeon_Name = _evilDgnBynangua.api_CDungeon_getDungeonName(dgn_id);
|
||||
|
||||
if (PartyObj && Config["抗魔值进入副本"]["抗魔值进入副本开关(true为开启,false为关闭)"]) {
|
||||
local not_enough_users = [];
|
||||
for (local i = 0; i < 4; ++i) {
|
||||
local Tuser = PartyObj.GetUser(i);
|
||||
if (Tuser) {
|
||||
local total_grade = 0;
|
||||
local InvenObj = Tuser.GetInven();
|
||||
if (InvenObj) {
|
||||
for (local j = 0; j <= 25; j++) {
|
||||
local ItemObj = InvenObj.GetSlot(0, j);
|
||||
if (!ItemObj.IsEmpty) {
|
||||
local item_id = ItemObj.GetIndex();
|
||||
print(item_id);
|
||||
local Anti = _Nangua_GetEquipmentData_Anti_(item_id);
|
||||
total_grade += Anti;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 比对抗魔值是否足够
|
||||
if (total_grade < required_grade) {
|
||||
not_enough_users.push(Tuser.GetCharacName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理未达到抗魔值要求的用户
|
||||
if (not_enough_users.len() > 0) {
|
||||
local joinedNames = _evilDgnBynangua.join(not_enough_users, ", ");
|
||||
SUser.SendNotiBox("队伍中玩家[" + joinedNames + "] 抗魔值低于 " + required_grade + " ,无法进入 [" + Dungeon_Name + " - " + diff_name + "]", 2)
|
||||
return 1; // 禁止进入副本
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"ProjectName": "点券充值卡",
|
||||
"ProjectDescribe": "根据道具ID充值对应的点券数量",
|
||||
"ProjectAuthor": "南瓜",
|
||||
"ProjectVersion": 1.0,
|
||||
"ProjectConfig": "点券充值卡配置_Nangua.json",
|
||||
"ProjectFiles": [
|
||||
"点券充值卡.nut"
|
||||
],
|
||||
"ProjectRunFunc": "_Dps_handleCeraCard_Main_"
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
CeraCardCoolT <- {};
|
||||
|
||||
function handleCeraCardBynangua(SUser, ItemId) {
|
||||
local Config = GlobalConfig.Get("点券充值卡配置_Nangua.json");
|
||||
local ItemIdStr = ItemId.tostring();
|
||||
local UseCount = 0;
|
||||
|
||||
|
||||
if (!CeraCardCoolT.rawin(SUser.GetUID())) {
|
||||
CeraCardCoolT.rawset(SUser.GetUID(), 0);
|
||||
} else {
|
||||
UseCount = CeraCardCoolT.rawget(SUser.GetUID());
|
||||
}
|
||||
if (UseCount >= 30) {
|
||||
if (Config["启用233发包(true/false)"]) {
|
||||
SUser.SendNotiBox("点券充值卡已达到本日使用上限!", 1);
|
||||
} else {
|
||||
SUser.SendNotiPacketMessage("点券充值卡已达到本日使用上限!", 8);
|
||||
}
|
||||
}
|
||||
|
||||
if (Config["充值卡配置"].rawin(ItemIdStr)) {
|
||||
local CeraAmount = Config["充值卡配置"][ItemIdStr];
|
||||
SUser.RechargeCera(CeraAmount);
|
||||
if (Config["启用233发包(true/false)"]) {
|
||||
SUser.SendNotiBox(format(Config["充值成功提示"], CeraAmount), 1);
|
||||
SUser.SendNotiBox(format("充值卡本日已使用次数%d / 30", UseCount + 1), 1);
|
||||
} else {
|
||||
SUser.SendNotiPacketMessage(format(Config["充值成功提示"], CeraAmount), 8);
|
||||
SUser.SendNotiPacketMessage(format("充值卡本日已使用次数%d / 30", UseCount + 1), 8);
|
||||
}
|
||||
}
|
||||
|
||||
CeraCardCoolT.rawset(SUser.GetUID(), UseCount + 1);
|
||||
}
|
||||
|
||||
//加载入口
|
||||
function _Dps_handleCeraCard_Main_() {
|
||||
_Dps_handleCeraCard_Logic_();
|
||||
|
||||
|
||||
Timer.SetCronTask(function() {
|
||||
getroottable().CeraCardCoolT = {};
|
||||
}, {
|
||||
Cron = "0 0 6 * * *",
|
||||
Name = "刷新点卷充值卡每日限额"
|
||||
});
|
||||
}
|
||||
|
||||
//重载入口
|
||||
function _Dps_handleCeraCard_Main_Reload_(OldConfig) {
|
||||
local Config = GlobalConfig.Get("点券充值卡配置_Nangua.json");
|
||||
// 删除旧的注册
|
||||
foreach(itemId, _ in OldConfig["充值卡配置"]) {
|
||||
Cb_Use_Item_Sp_Func.rawdelete(itemId.tointeger());
|
||||
}
|
||||
//重新注册
|
||||
_Dps_handleCeraCard_Logic_();
|
||||
}
|
||||
|
||||
function _Dps_handleCeraCard_Logic_() {
|
||||
local Config = GlobalConfig.Get("点券充值卡配置_Nangua.json");
|
||||
// 注册所有充值卡
|
||||
foreach(itemId, _ in Config["充值卡配置"]) {
|
||||
Cb_Use_Item_Sp_Func[itemId.tointeger()] <- handleCeraCardBynangua;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"BaseScript":["enum.nut","BaseClass/MoudleClass/MoudleClass.nut","BaseClass/BlobExClass/BlobExClass.nut","BaseClass/HttpClass/HttpClass.nut","BaseClass/ScriptManager/ScriptManager.nut","BaseClass/AdMsg/AdMsg.nut","BaseClass/BaseObjectClass/BaseObjectClass.nut","BaseClass/BattleFieldClass/BattleFieldClass.nut","BaseClass/DungeonClass/DungeonClass.nut","BaseClass/GameManagerClass/GameManagerClass.nut","BaseClass/InvenClass/InvenClass.nut","BaseClass/IOClass/IOClass.nut","BaseClass/ItemClass/ItemClass.nut","BaseClass/JsonClass/Json.nut","BaseClass/JsonClass/JsonClass.nut","BaseClass/MathClass/MathCalss.nut","BaseClass/MD5Class/MD5Class.nut","BaseClass/MysqlClass/MysqlClass.nut","BaseClass/PacketClass/PacketClass.nut","BaseClass/PartyClass/PartyClass.nut","BaseClass/PvfClass/PvfItemClass.nut","BaseClass/Socket/SocketBase.nut","BaseClass/UserClass/UserClass.nut","BaseClass/WorldClass/WorldClass.nut","BaseClass/BaseInfoClass/BaseBindenvClass.nut","BaseClass/UserAccountCargoClass/AccountCargoClass.nut","BaseClass/GameManagerClass/GameManagerClass.nut","BaseClass/MemoryClass/MemoryClass.nut","BaseClass/RedBlackTreeClass/RedBlackTreeClass.nut","BaseClass/TimerClass/TimerClass.nut","BaseClass/HackerClass/HackerClass.nut","New_Hook.nut","BaseClass/LogClass/LogClass.nut","BaseClass/ConfigClass/ConfigClass.nut","BaseClass/OfficialProject/OfficialProject.nut","CallBack/Base_Input.nut","CallBack/GameWorld_move_position.nut","CallBack/Gm_Input.nut","CallBack/History_Log.nut","CallBack/InsertUser.nut","CallBack/MoveArea.nut","CallBack/Reach_Game_World.nut","CallBack/Send_Area_User.nut","CallBack/Use_Item_Sp.nut","CallBack/BossDie.nut","CallBack/Return_SelectCharacter.nut","CallBack/Chacter_Exit.nut","CallBack/GiveupDgn.nut","CallBack/UserPartyCreate.nut","CallBack/UserWorkPerFiveMin.nut","CallBack/Timer_Dispatch.nut","CallBack/SetUserMaxLevel.nut","CallBack/Cb_Player_Chanage_Equ.nut","CallBack/UserPartyAgree.nut","CallBack/UserPartyExit.nut","CallBack/UserPartyGiveMaster.nut","CallBack/UserPartyGiveKick.nut","ServerControl/ServerControl.nut","ServerControl/EquimentUseJewel.nut","Interface.nut"]}
|
||||
|
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
文件名:AntonClass.nut
|
||||
路径:Dps_A/ProjectClass/Anton/AntonClass.nut
|
||||
创建日期:2024-07-15 20:46
|
||||
文件用途:安图恩服务的文件
|
||||
*/
|
||||
class Anton {
|
||||
//频道
|
||||
Channel = 18;
|
||||
//城镇
|
||||
Town = 188;
|
||||
|
||||
//服务端区域移动添加玩家HOOK 让大家不可见
|
||||
function insert_user_hook(C_Area, C_User) {
|
||||
//如果有城镇配置
|
||||
if (Town) {
|
||||
local SUser = User(C_User);
|
||||
if (SUser.GetLocation().Town == Town) {
|
||||
if (SUser.GetLocation().Area > 1) Sq_WriteAddress(C_Area, 0x68, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
//服务端区域移动HOOK 让玩家不可以直接去另一个区域
|
||||
function move_area_hook(CUser, TownIndex, AreaIndex) {
|
||||
// return true;//TODO
|
||||
if (!CUser) return true;
|
||||
local SUser = User(CUser);
|
||||
//安图恩频道
|
||||
if (Sq_Game_GetConfig().find("18") != null) {
|
||||
if (AreaIndex <= 1) {
|
||||
return true;
|
||||
} else {
|
||||
local Jso = {
|
||||
op = 20064023,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
regionId = AreaIndex
|
||||
}
|
||||
Socket.SendGateway(Jso);
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//玩家发送消息HOOK 为了攻坚队频道和团长公告
|
||||
function base_input_hook(CUser, CmdString) {
|
||||
if (!CUser) return true;
|
||||
local SUser = User(CUser);
|
||||
|
||||
//安图恩频道
|
||||
if (Sq_Game_GetConfig().find("18") != null) {
|
||||
local Localtion = SUser.GetLocation();
|
||||
if (Localtion.Area <= 1) {
|
||||
return true;
|
||||
} else {
|
||||
local Jso = {
|
||||
op = 20064027,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
msg = CmdString
|
||||
}
|
||||
Socket.SendGateway(Jso);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function base_input_hook2(args) {
|
||||
local type = args[2];
|
||||
local SUser = User(args[1]);
|
||||
local msg = args[3];
|
||||
if ((type == 8 || type == 3) && Sq_Game_GetConfig().find("18") != null) {
|
||||
local Localtion = SUser.GetLocation();
|
||||
if (Localtion.Area <= 1) {
|
||||
return true;
|
||||
} else {
|
||||
local Jso = {
|
||||
op = 20064027,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
msg = msg
|
||||
}
|
||||
Socket.SendGateway(Jso);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//玩家消息分发
|
||||
function PlayerNotiMsgDistribute(Jso) {
|
||||
local SUser = World.GetUserByUidCid(Jso.uid, Jso.cid);
|
||||
if (!SUser) return;
|
||||
local CUserList = Jso.list;
|
||||
local RealList = [];
|
||||
foreach(_i, obj in CUserList) {
|
||||
local SUser = World.GetUserByUidCid(obj.uid, obj.cid);
|
||||
if (SUser && SUser.GetState() >= 3) RealList.append(SUser);
|
||||
}
|
||||
local SUserName = SUser.GetCharacName();
|
||||
local Type = Jso.type;
|
||||
|
||||
Jso.msg = Jso.msg;
|
||||
if (Type == -1) {
|
||||
Jso.Name <- SUserName;
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SendObj = Value;
|
||||
SendObj.SendJso(Jso);
|
||||
}
|
||||
Type = "长"
|
||||
}
|
||||
local NotiStr = "(攻坚队" + Type + ") " + "" + SUserName + " : " + Jso.msg;
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SendObj = Value;
|
||||
SendObj.SendNotiPacketMessage(NotiStr, 8);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function AntonSendAreaUserCallBack(Jso) {
|
||||
local CUserList = Jso.list;
|
||||
local RealList = [];
|
||||
foreach(_i, obj in CUserList) {
|
||||
local SUser = World.GetUserByUidCid(obj.uid, obj.cid);
|
||||
if (SUser && SUser.GetState() >= 3) RealList.append(SUser);
|
||||
}
|
||||
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SUser = Value;
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(0, 24);
|
||||
Pack.Put_Byte(SUser.GetLocation().Town); //城镇
|
||||
Pack.Put_Byte(SUser.GetArea(1)); //区域
|
||||
Pack.Put_Short((RealList.len() - 1)); //几个玩家 要减去自己
|
||||
foreach(__Index, MapObj in RealList) {
|
||||
if (SUser.GetUID() == MapObj.GetUID()) continue;
|
||||
Pack.Put_Short(MapObj.GetUniqueId());
|
||||
Pack.Put_Short(MapObj.GetAreaPos().X);
|
||||
Pack.Put_Short(MapObj.GetAreaPos().Y);
|
||||
Pack.Put_Byte(MapObj.GetDirections()); //朝向
|
||||
Pack.Put_Byte(MapObj.GetVisibleValues()); //是否可见
|
||||
}
|
||||
Pack.Put_Byte(1); //是否可见
|
||||
Pack.Finalize(true);
|
||||
SUser.Send(Pack);
|
||||
Pack.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
function AntonPlayerMoveMapCallBack(Jso) {
|
||||
local MoveSUser = World.GetUserByUidCid(Jso.uid, Jso.cid);
|
||||
if (!MoveSUser) return;
|
||||
|
||||
local CUserList = Jso.list;
|
||||
local RealList = [];
|
||||
foreach(_i, obj in CUserList) {
|
||||
local SUser = World.GetUserByUidCid(obj.uid, obj.cid);
|
||||
if (SUser && SUser.GetState() >= 3) RealList.append(SUser);
|
||||
}
|
||||
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(0, 22);
|
||||
Pack.Put_Short(MoveSUser.GetUniqueId());
|
||||
Pack.Put_Short(Jso.XPos);
|
||||
Pack.Put_Short(Jso.YPos);
|
||||
Pack.Put_Byte(Jso.Direction);
|
||||
Pack.Put_Short(Jso.Code);
|
||||
Pack.Finalize(true);
|
||||
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SUser = Value;
|
||||
if (SUser.GetUniqueId() == MoveSUser.GetUniqueId()) continue;
|
||||
SUser.Send(Pack);
|
||||
}
|
||||
Pack.Delete();
|
||||
}
|
||||
|
||||
function ClientGetConfigCallBack(SUser, Jso) {
|
||||
local evv = {
|
||||
op = 20064502,
|
||||
town_index = Town,
|
||||
channel_index = Channel
|
||||
}
|
||||
SUser.SendJso(evv);
|
||||
}
|
||||
|
||||
function ClientCreateOrJoinParty(SUser, Jso) {
|
||||
Jso.uid <- SUser.GetUID();
|
||||
Jso.cid <- SUser.GetCID();
|
||||
Jso.PlayerName <- SUser.GetCharacName();
|
||||
Jso.PlayerLevel <- SUser.GetCharacLevel();
|
||||
Jso.PlayerJob <- SUser.GetCharacJob();
|
||||
Jso.PlayerGrowTypeJob <- SUser.GetCharacGrowType();
|
||||
Jso.IsPrepare <- false;
|
||||
Jso.PlayerSession <- World.GetSessionByUid(SUser.GetUID());
|
||||
Jso.PlayCoin <- SUser.GetCoin();
|
||||
Jso.PlayFatigue <- SUser.GetMaxFatigue() - SUser.GetFatigue();
|
||||
Socket.SendGateway(Jso);
|
||||
}
|
||||
|
||||
//玩家上线
|
||||
function Login_Hook(SUser) {
|
||||
//玩家上线发信息包
|
||||
local evv = {
|
||||
op = 20064502,
|
||||
town_index = Town,
|
||||
channel_index = Channel
|
||||
}
|
||||
SUser.SendJso(evv);
|
||||
|
||||
local T = {
|
||||
op = 20064063,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
}
|
||||
Socket.SendGateway(T);
|
||||
}
|
||||
|
||||
//团本配置信息获取回调
|
||||
function GetPluginConfig(Jso) {
|
||||
Town = Jso.Town;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
local ConfigPath = Sq_Game_GetConfig();
|
||||
Channel = ConfigPath.slice(ConfigPath.find("cfg/") + 4, ConfigPath.len());
|
||||
|
||||
//注册HOOK
|
||||
Cb_Insert_User_Func.Anton <- insert_user_hook.bindenv(this); //区域添加角色
|
||||
Cb_Move_Area_Func.Anton <- move_area_hook.bindenv(this); //区域移动
|
||||
//Base_InputHookFunc_Handle.Anton <- base_input_hook.bindenv(this); //玩家发送消息
|
||||
Cb_reach_game_world_Func.Anton <- Login_Hook.bindenv(this); //上线HOOK
|
||||
Cb_Server_Chat_Log_Leave_Func.Anton <- base_input_hook2.bindenv(this); //玩家发送消息
|
||||
|
||||
|
||||
//注册收包
|
||||
GatewaySocketPackFuncMap.rawset(20064010, AntonSendAreaUserCallBack.bindenv(this)); //玩家移动后的区域广播包
|
||||
GatewaySocketPackFuncMap.rawset(20064012, AntonPlayerMoveMapCallBack.bindenv(this)); //玩家移动回调
|
||||
//玩家消息分发
|
||||
GatewaySocketPackFuncMap.rawset(20064018, PlayerNotiMsgDistribute.bindenv(this)); //玩家打字发送的信息
|
||||
GatewaySocketPackFuncMap.rawset(20064778, GetPluginConfig.bindenv(this)); //服务端配置
|
||||
|
||||
//注册来自客户端的收包
|
||||
ClientSocketPackFuncMap.rawset(20230718, ClientGetConfigCallBack.bindenv(this));
|
||||
ClientSocketPackFuncMap.rawset(20064501, ClientGetConfigCallBack.bindenv(this));
|
||||
ClientSocketPackFuncMap.rawset(20064001, ClientCreateOrJoinParty.bindenv(this));
|
||||
ClientSocketPackFuncMap.rawset(20064005, ClientCreateOrJoinParty.bindenv(this));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ProjectInitFuncMap.P_Anton <- Anton();
|
||||
|
|
@ -0,0 +1 @@
|
|||
AntonClass.nut
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
文件名:FiendwarClass.nut
|
||||
路径:ProjectClass/Fiendwar/FiendwarClass.nut
|
||||
创建日期:2024-04-08 03:00
|
||||
文件用途:超时空服务器文件
|
||||
*/
|
||||
class Fiendwar {
|
||||
//频道
|
||||
Channel = null;
|
||||
//城镇
|
||||
Town = null;
|
||||
|
||||
//服务端区域移动添加玩家HOOK 让大家不可见
|
||||
function insert_user_hook(C_Area, C_User) {
|
||||
//如果有城镇配置
|
||||
if (Town) {
|
||||
local SUser = User(C_User);
|
||||
if (SUser.GetLocation().Town == Town) {
|
||||
if (SUser.GetLocation().Area > 1) Sq_WriteAddress(C_Area, 0x68, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
//服务端区域移动HOOK 让玩家不可以直接去另一个区域
|
||||
function move_area_hook(CUser, TownIndex, AreaIndex) {
|
||||
// return true;//TODO
|
||||
if (!CUser) return true;
|
||||
local SUser = User(CUser);
|
||||
//超时空频道
|
||||
if (Sq_Game_GetConfig().find("20") != null) {
|
||||
if (AreaIndex <= 1) {
|
||||
return true;
|
||||
} else {
|
||||
local Jso = {
|
||||
op = 20063023,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
regionId = AreaIndex
|
||||
}
|
||||
Socket.SendGateway(Jso);
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//玩家发送消息HOOK 为了攻坚队频道和团长公告
|
||||
function base_input_hook(CUser, CmdString) {
|
||||
print(111);
|
||||
if (!CUser) return true;
|
||||
local SUser = User(CUser);
|
||||
//超时空频道
|
||||
if (Sq_Game_GetConfig().find("20") != null) {
|
||||
local Localtion = SUser.GetLocation();
|
||||
if (Localtion.Area <= 1) {
|
||||
return true;
|
||||
} else {
|
||||
print(111);
|
||||
if (CmdString.find("RindroType") == 8) {
|
||||
local Jso = {
|
||||
op = 20063027,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
msg = CmdString.slice(0, CmdString.find("RindroType"))
|
||||
}
|
||||
Socket.SendGateway(Jso);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function base_input_hook2(args) {
|
||||
print(1111);
|
||||
local type = args[2];
|
||||
local SUser = User(args[1]);
|
||||
local msg = args[3];
|
||||
if ((type == 8 || type == 3) && Sq_Game_GetConfig().find("20") != null) {
|
||||
local Localtion = SUser.GetLocation();
|
||||
if (Localtion.Area <= 1) {
|
||||
return true;
|
||||
} else {
|
||||
local Jso = {
|
||||
op = 20063027,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
msg = msg
|
||||
}
|
||||
Socket.SendGateway(Jso);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//玩家消息分发
|
||||
function PlayerNotiMsgDistribute(Jso) {
|
||||
|
||||
local SUser = World.GetUserByUidCid(Jso.uid, Jso.cid);
|
||||
if (!SUser) return;
|
||||
local CUserList = Jso.list;
|
||||
local RealList = [];
|
||||
foreach(_i, obj in CUserList) {
|
||||
local SUser = World.GetUserByUidCid(obj.uid, obj.cid);
|
||||
if (SUser && SUser.GetState() >= 3) RealList.append(SUser);
|
||||
}
|
||||
local SUserName = SUser.GetCharacName();
|
||||
local Type = Jso.type;
|
||||
|
||||
Jso.msg = Jso.msg;
|
||||
if (Type == -1) {
|
||||
Jso.Name <- SUserName;
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SendObj = Value;
|
||||
SendObj.SendJso(Jso);
|
||||
}
|
||||
Type = "长"
|
||||
}
|
||||
local NotiStr = "(攻坚队" + Type + ") " + "" + SUserName + " : " + Jso.msg;
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SendObj = Value;
|
||||
SendObj.SendNotiPacketMessage(NotiStr, 8);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function FiendwarSendAreaUserCallBack(Jso) {
|
||||
local CUserList = Jso.list;
|
||||
local RealList = [];
|
||||
foreach(_i, obj in CUserList) {
|
||||
local SUser = World.GetUserByUidCid(obj.uid, obj.cid);
|
||||
if (SUser && SUser.GetState() >= 3) RealList.append(SUser);
|
||||
}
|
||||
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SUser = Value;
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(0, 24);
|
||||
Pack.Put_Byte(SUser.GetLocation().Town); //城镇
|
||||
Pack.Put_Byte(SUser.GetArea(1)); //区域
|
||||
Pack.Put_Short((RealList.len() - 1)); //几个玩家 要减去自己
|
||||
foreach(__Index, MapObj in RealList) {
|
||||
if (SUser.GetUID() == MapObj.GetUID()) continue;
|
||||
Pack.Put_Short(MapObj.GetUniqueId());
|
||||
Pack.Put_Short(MapObj.GetAreaPos().X);
|
||||
Pack.Put_Short(MapObj.GetAreaPos().Y);
|
||||
Pack.Put_Byte(MapObj.GetDirections()); //朝向
|
||||
Pack.Put_Byte(MapObj.GetVisibleValues()); //是否可见
|
||||
}
|
||||
Pack.Put_Byte(1); //是否可见
|
||||
Pack.Finalize(true);
|
||||
SUser.Send(Pack);
|
||||
Pack.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
function FiendwarPlayerMoveMapCallBack(Jso) {
|
||||
local MoveSUser = World.GetUserByUidCid(Jso.uid, Jso.cid);
|
||||
if (!MoveSUser) return;
|
||||
|
||||
local CUserList = Jso.list;
|
||||
local RealList = [];
|
||||
foreach(_i, obj in CUserList) {
|
||||
local SUser = World.GetUserByUidCid(obj.uid, obj.cid);
|
||||
if (SUser && SUser.GetState() >= 3) RealList.append(SUser);
|
||||
}
|
||||
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(0, 22);
|
||||
Pack.Put_Short(MoveSUser.GetUniqueId());
|
||||
Pack.Put_Short(Jso.XPos);
|
||||
Pack.Put_Short(Jso.YPos);
|
||||
Pack.Put_Byte(Jso.Direction);
|
||||
Pack.Put_Short(Jso.Code);
|
||||
Pack.Finalize(true);
|
||||
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SUser = Value;
|
||||
if (SUser.GetUniqueId() == MoveSUser.GetUniqueId()) continue;
|
||||
SUser.Send(Pack);
|
||||
}
|
||||
Pack.Delete();
|
||||
}
|
||||
|
||||
function ClientGetConfigCallBack(SUser, Jso) {
|
||||
local evv = {
|
||||
op = 20063502,
|
||||
town_index = Town,
|
||||
channel_index = Channel
|
||||
}
|
||||
SUser.SendJso(evv);
|
||||
}
|
||||
|
||||
function ClientCreateOrJoinParty(SUser, Jso) {
|
||||
Jso.uid <- SUser.GetUID();
|
||||
Jso.cid <- SUser.GetCID();
|
||||
Jso.PlayerName <- SUser.GetCharacName();
|
||||
Jso.PlayerLevel <- SUser.GetCharacLevel();
|
||||
Jso.PlayerJob <- SUser.GetCharacJob();
|
||||
Jso.PlayerGrowTypeJob <- SUser.GetCharacGrowType();
|
||||
Jso.IsPrepare <- false;
|
||||
Jso.PlayerSession <- World.GetSessionByUid(SUser.GetUID());
|
||||
Jso.PlayCoin <- SUser.GetCoin();
|
||||
Jso.PlayFatigue <- SUser.GetMaxFatigue() - SUser.GetFatigue();
|
||||
Socket.SendGateway(Jso);
|
||||
}
|
||||
|
||||
//玩家上线
|
||||
function Login_Hook(SUser) {
|
||||
//玩家上线发信息包
|
||||
local evv = {
|
||||
op = 20063502,
|
||||
town_index = Town,
|
||||
channel_index = Channel
|
||||
}
|
||||
SUser.SendJso(evv);
|
||||
|
||||
local T = {
|
||||
op = 20063063,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
}
|
||||
Socket.SendGateway(T);
|
||||
}
|
||||
|
||||
//团本配置信息获取回调
|
||||
function GetPluginConfig(Jso) {
|
||||
Town = Jso.Town;
|
||||
|
||||
if ("hookparty" in Jso) {
|
||||
Cb_User_Party_Create_Func["Fiendwar"] <- function(SUser) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constructor() {
|
||||
local ConfigPath = Sq_Game_GetConfig();
|
||||
Channel = ConfigPath.slice(ConfigPath.find("cfg/") + 4, ConfigPath.len());
|
||||
|
||||
//注册HOOK
|
||||
Cb_Insert_User_Func.Fiendwar <- insert_user_hook.bindenv(this); //区域添加角色
|
||||
Cb_Move_Area_Func.Fiendwar <- move_area_hook.bindenv(this); //区域移动
|
||||
Base_InputHookFunc_Handle.Fiendwar <- base_input_hook.bindenv(this); //玩家发送消息
|
||||
Cb_reach_game_world_Func.Fiendwar <- Login_Hook.bindenv(this); //上线HOOK
|
||||
Cb_Server_Chat_Log_Leave_Func.Luke <- base_input_hook2.bindenv(this); //玩家发送消息
|
||||
|
||||
//注册收包
|
||||
GatewaySocketPackFuncMap.rawset(20063010, FiendwarSendAreaUserCallBack.bindenv(this)); //玩家移动后的区域广播包
|
||||
GatewaySocketPackFuncMap.rawset(20063012, FiendwarPlayerMoveMapCallBack.bindenv(this)); //玩家移动回调
|
||||
//玩家消息分发
|
||||
GatewaySocketPackFuncMap.rawset(20063018, PlayerNotiMsgDistribute.bindenv(this)); //玩家打字发送的信息
|
||||
GatewaySocketPackFuncMap.rawset(20063778, GetPluginConfig.bindenv(this)); //服务端配置
|
||||
|
||||
//注册来自客户端的收包
|
||||
ClientSocketPackFuncMap.rawset(20230718, ClientGetConfigCallBack.bindenv(this));
|
||||
ClientSocketPackFuncMap.rawset(20063501, ClientGetConfigCallBack.bindenv(this));
|
||||
ClientSocketPackFuncMap.rawset(20063001, ClientCreateOrJoinParty.bindenv(this));
|
||||
ClientSocketPackFuncMap.rawset(20063005, ClientCreateOrJoinParty.bindenv(this));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ProjectInitFuncMap.P_Fiendwar <- Fiendwar();
|
||||
|
|
@ -0,0 +1 @@
|
|||
FiendwarClass.nut
|
||||
|
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
文件名:LukeClass.nut
|
||||
路径:Dps_A/ProjectClass/Luke/LukeClass.nut
|
||||
创建日期:2024-07-15 20:46
|
||||
文件用途:卢克服务的文件
|
||||
*/
|
||||
class Luke {
|
||||
//频道
|
||||
Channel = 19;
|
||||
//城镇
|
||||
Town = 18;
|
||||
|
||||
//服务端区域移动添加玩家HOOK 让大家不可见
|
||||
function insert_user_hook(C_Area, C_User) {
|
||||
//如果有城镇配置
|
||||
if (Town) {
|
||||
local SUser = User(C_User);
|
||||
if (SUser.GetLocation().Town == Town) {
|
||||
if (SUser.GetLocation().Area > 1) Sq_WriteAddress(C_Area, 0x68, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
//服务端区域移动HOOK 让玩家不可以直接去另一个区域
|
||||
function move_area_hook(CUser, TownIndex, AreaIndex) {
|
||||
// return true;//TODO
|
||||
if (!CUser) return true;
|
||||
local SUser = User(CUser);
|
||||
//卢克频道
|
||||
if (Sq_Game_GetConfig().find("19") != null) {
|
||||
if (AreaIndex <= 1) {
|
||||
return true;
|
||||
} else {
|
||||
local Jso = {
|
||||
op = 20084023,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
regionId = AreaIndex
|
||||
}
|
||||
Socket.SendGateway(Jso);
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//玩家发送消息HOOK 为了攻坚队频道和团长公告
|
||||
function base_input_hook(CUser, CmdString) {
|
||||
if (!CUser) return true;
|
||||
local SUser = User(CUser);
|
||||
print(111);
|
||||
//卢克频道
|
||||
if (Sq_Game_GetConfig().find("19") != null) {
|
||||
local Localtion = SUser.GetLocation();
|
||||
if (Localtion.Area <= 1) {
|
||||
return true;
|
||||
} else {
|
||||
local Jso = {
|
||||
op = 20084027,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
msg = CmdString
|
||||
}
|
||||
Socket.SendGateway(Jso);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function base_input_hook2(args) {
|
||||
local type = args[2];
|
||||
local SUser = User(args[1]);
|
||||
local msg = args[3];
|
||||
|
||||
if ((type == 8 || type == 3) && Sq_Game_GetConfig().find("19") != null) {
|
||||
|
||||
local Localtion = SUser.GetLocation();
|
||||
if (Localtion.Area <= 1) {
|
||||
return true;
|
||||
} else {
|
||||
local Jso = {
|
||||
op = 20084027,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
msg = msg
|
||||
}
|
||||
Socket.SendGateway(Jso);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//玩家消息分发
|
||||
function PlayerNotiMsgDistribute(Jso) {
|
||||
local SUser = World.GetUserByUidCid(Jso.uid, Jso.cid);
|
||||
if (!SUser) return;
|
||||
local CUserList = Jso.list;
|
||||
local RealList = [];
|
||||
foreach(_i, obj in CUserList) {
|
||||
local SUser = World.GetUserByUidCid(obj.uid, obj.cid);
|
||||
if (SUser && SUser.GetState() >= 3) RealList.append(SUser);
|
||||
}
|
||||
local SUserName = SUser.GetCharacName();
|
||||
local Type = Jso.type;
|
||||
|
||||
Jso.msg = Jso.msg;
|
||||
if (Type == -1) {
|
||||
Jso.Name <- SUserName;
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SendObj = Value;
|
||||
SendObj.SendJso(Jso);
|
||||
}
|
||||
Type = "长"
|
||||
}
|
||||
local NotiStr = "(攻坚队" + Type + ") " + "" + SUserName + " : " + Jso.msg;
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SendObj = Value;
|
||||
SendObj.SendNotiPacketMessage(NotiStr, 8);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function LukeSendAreaUserCallBack(Jso) {
|
||||
local CUserList = Jso.list;
|
||||
local RealList = [];
|
||||
foreach(_i, obj in CUserList) {
|
||||
local SUser = World.GetUserByUidCid(obj.uid, obj.cid);
|
||||
if (SUser && SUser.GetState() >= 3) RealList.append(SUser);
|
||||
}
|
||||
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SUser = Value;
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(0, 24);
|
||||
Pack.Put_Byte(SUser.GetLocation().Town); //城镇
|
||||
Pack.Put_Byte(SUser.GetArea(1)); //区域
|
||||
Pack.Put_Short((RealList.len() - 1)); //几个玩家 要减去自己
|
||||
foreach(__Index, MapObj in RealList) {
|
||||
if (SUser.GetUID() == MapObj.GetUID()) continue;
|
||||
Pack.Put_Short(MapObj.GetUniqueId());
|
||||
Pack.Put_Short(MapObj.GetAreaPos().X);
|
||||
Pack.Put_Short(MapObj.GetAreaPos().Y);
|
||||
Pack.Put_Byte(MapObj.GetDirections()); //朝向
|
||||
Pack.Put_Byte(MapObj.GetVisibleValues()); //是否可见
|
||||
}
|
||||
Pack.Put_Byte(1); //是否可见
|
||||
Pack.Finalize(true);
|
||||
SUser.Send(Pack);
|
||||
Pack.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
function LukePlayerMoveMapCallBack(Jso) {
|
||||
local MoveSUser = World.GetUserByUidCid(Jso.uid, Jso.cid);
|
||||
if (!MoveSUser) return;
|
||||
|
||||
local CUserList = Jso.list;
|
||||
local RealList = [];
|
||||
foreach(_i, obj in CUserList) {
|
||||
local SUser = World.GetUserByUidCid(obj.uid, obj.cid);
|
||||
if (SUser && SUser.GetState() >= 3) RealList.append(SUser);
|
||||
}
|
||||
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(0, 22);
|
||||
Pack.Put_Short(MoveSUser.GetUniqueId());
|
||||
Pack.Put_Short(Jso.XPos);
|
||||
Pack.Put_Short(Jso.YPos);
|
||||
Pack.Put_Byte(Jso.Direction);
|
||||
Pack.Put_Short(Jso.Code);
|
||||
Pack.Finalize(true);
|
||||
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SUser = Value;
|
||||
if (SUser.GetUniqueId() == MoveSUser.GetUniqueId()) continue;
|
||||
SUser.Send(Pack);
|
||||
}
|
||||
Pack.Delete();
|
||||
}
|
||||
|
||||
function ClientGetConfigCallBack(SUser, Jso) {
|
||||
local evv = {
|
||||
op = 20084502,
|
||||
town_index = Town,
|
||||
channel_index = Channel
|
||||
}
|
||||
SUser.SendJso(evv);
|
||||
}
|
||||
|
||||
function ClientCreateOrJoinParty(SUser, Jso) {
|
||||
Jso.uid <- SUser.GetUID();
|
||||
Jso.cid <- SUser.GetCID();
|
||||
Jso.PlayerName <- SUser.GetCharacName();
|
||||
Jso.PlayerLevel <- SUser.GetCharacLevel();
|
||||
Jso.PlayerJob <- SUser.GetCharacJob();
|
||||
Jso.PlayerGrowTypeJob <- SUser.GetCharacGrowType();
|
||||
Jso.IsPrepare <- false;
|
||||
Jso.PlayerSession <- World.GetSessionByUid(SUser.GetUID());
|
||||
Jso.PlayCoin <- SUser.GetCoin();
|
||||
Jso.PlayFatigue <- SUser.GetMaxFatigue() - SUser.GetFatigue();
|
||||
Socket.SendGateway(Jso);
|
||||
}
|
||||
|
||||
//玩家上线
|
||||
function Login_Hook(SUser) {
|
||||
Timer.SetTimeOut(function(SUser) {
|
||||
//玩家上线发信息包
|
||||
local evv = {
|
||||
op = 20084502,
|
||||
town_index = Town,
|
||||
channel_index = Channel
|
||||
}
|
||||
SUser.SendJso(evv);
|
||||
}.bindenv(this), 5, SUser);
|
||||
|
||||
local T = {
|
||||
op = 20084063,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
}
|
||||
Socket.SendGateway(T);
|
||||
}
|
||||
|
||||
//团本配置信息获取回调
|
||||
function GetPluginConfig(Jso) {
|
||||
Town = Jso.Town;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
local ConfigPath = Sq_Game_GetConfig();
|
||||
Channel = ConfigPath.slice(ConfigPath.find("cfg/") + 4, ConfigPath.len());
|
||||
|
||||
//注册HOOK
|
||||
Cb_Insert_User_Func.Luke <- insert_user_hook.bindenv(this); //区域添加角色
|
||||
Cb_Move_Area_Func.Luke <- move_area_hook.bindenv(this); //区域移动
|
||||
//Base_InputHookFunc_Handle.Luke <- base_input_hook.bindenv(this); //玩家发送消息
|
||||
Cb_reach_game_world_Func.Luke <- Login_Hook.bindenv(this); //上线HOOK
|
||||
Cb_Server_Chat_Log_Leave_Func.Luke <- base_input_hook2.bindenv(this); //玩家发送消息
|
||||
|
||||
//注册收包
|
||||
GatewaySocketPackFuncMap.rawset(20084010, LukeSendAreaUserCallBack.bindenv(this)); //玩家移动后的区域广播包
|
||||
GatewaySocketPackFuncMap.rawset(20084012, LukePlayerMoveMapCallBack.bindenv(this)); //玩家移动回调
|
||||
//玩家消息分发
|
||||
GatewaySocketPackFuncMap.rawset(20084018, PlayerNotiMsgDistribute.bindenv(this)); //玩家打字发送的信息
|
||||
GatewaySocketPackFuncMap.rawset(20084778, GetPluginConfig.bindenv(this)); //服务端配置
|
||||
|
||||
//注册来自客户端的收包
|
||||
ClientSocketPackFuncMap.rawset(20230718, ClientGetConfigCallBack.bindenv(this));
|
||||
ClientSocketPackFuncMap.rawset(20084501, ClientGetConfigCallBack.bindenv(this));
|
||||
ClientSocketPackFuncMap.rawset(20084001, ClientCreateOrJoinParty.bindenv(this));
|
||||
ClientSocketPackFuncMap.rawset(20084005, ClientCreateOrJoinParty.bindenv(this));
|
||||
}
|
||||
}
|
||||
|
||||
ProjectInitFuncMap.P_Luke <- Luke();
|
||||
|
|
@ -0,0 +1 @@
|
|||
LukeClass.nut
|
||||
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
文件名:NpcTransaction.nut
|
||||
路径:Dps_A/ProjectClass/NpcTransaction/NpcTransaction.nut
|
||||
创建日期:2025-10-23 14:37
|
||||
文件用途:
|
||||
*/
|
||||
|
||||
class NpcTransaction {
|
||||
|
||||
//装备价值
|
||||
EquValue = null;
|
||||
//品级装备组
|
||||
EquGroup = null;
|
||||
//金币易物浮动比例
|
||||
GoldFloat = 0.5;
|
||||
//最低交换品级
|
||||
MinRarity = 0;
|
||||
//交易消耗物品
|
||||
TradeItem = null;
|
||||
//交易冷却时间
|
||||
TradingCooldownTime = 3600000;
|
||||
|
||||
//装备易物浮动等级
|
||||
EquFloatMin = 5;
|
||||
EquFloatMax = 5;
|
||||
|
||||
//事件概率
|
||||
EventRate = null;
|
||||
|
||||
//用户状态表
|
||||
UserState = null;
|
||||
|
||||
|
||||
|
||||
constructor() {
|
||||
//注册客户端收包
|
||||
RegisterClient();
|
||||
EquValue = {};
|
||||
UserState = {};
|
||||
EquGroup = [{}, {}, {}, {}, {}, {}, {}, {}];
|
||||
|
||||
//读取PVF
|
||||
InitPvf();
|
||||
}
|
||||
|
||||
|
||||
function RegisterClient() {
|
||||
ClientSocketPackFuncMap.rawset(21005001, function(SUser, Jso) {
|
||||
local lastTime = GetTransactionInfo(SUser, Jso);
|
||||
if (lastTime && Sq_GetTimestampString().slice(-9).tointeger() - lastTime.time< TradingCooldownTime) {
|
||||
local T = {
|
||||
op = 21005002,
|
||||
flag = 3
|
||||
}
|
||||
SUser.SendJso(T);
|
||||
return;
|
||||
}
|
||||
local InvenObj = SUser.GetInven();
|
||||
local DFlag = InvenObj.DeleteItemCount(TradeItem.item, TradeItem.count);
|
||||
if(!DFlag){
|
||||
local T = {
|
||||
op = 21005002,
|
||||
flag = 3
|
||||
}
|
||||
SUser.SendJso(T);
|
||||
SUser.SendNotiPacketMessage("没有足够的道具用于交易!", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
local InvenObj = SUser.GetInven();
|
||||
local Equ = InvenObj.GetSlot(Inven.INVENTORY_TYPE_ITEM, 9 + Jso.pos);
|
||||
if (Equ) {
|
||||
local EquId = Equ.GetIndex();
|
||||
if (EquId) {
|
||||
local equ = PvfItem.GetPvfItemById(EquId);
|
||||
local Rarity = equ.GetRarity();
|
||||
local Level = equ.GetUsableLevel();
|
||||
//判断是否解封装
|
||||
local CanTrade = GetTrade(InvenObj, 9 + Jso.pos);
|
||||
|
||||
if ((Rarity == 2 || Rarity == 3) && CanTrade == 0) {
|
||||
local T = {
|
||||
op = 21005006,
|
||||
}
|
||||
SUser.SendJso(T);
|
||||
SUser.SendNotiPacketMessage("该装备属于封装装备,并已解封,无法进行交易!", 0);
|
||||
} else {
|
||||
//判断是进行什么交易逻辑
|
||||
local Random = MathClass.Rand(0, 1000);
|
||||
//嘲讽
|
||||
if (Random <= EventRate[0]) {
|
||||
local T = {
|
||||
op = 21005002,
|
||||
flag = 0
|
||||
}
|
||||
SUser.SendJso(T);
|
||||
local Cid = SUser.GetCID();
|
||||
if (!UserState.rawin(Cid)) UserState[Cid] <- {};
|
||||
UserState[Cid].rawset(Jso.npc, {
|
||||
time = Sq_GetTimestampString().slice(-9).tointeger()
|
||||
});
|
||||
}
|
||||
//金币易物
|
||||
else if (Random <= EventRate[1]) {
|
||||
local FloatValue = (EquValue[EquId] * GoldFloat).tointeger();
|
||||
local RandValue = MathClass.Rand(0, FloatValue);
|
||||
local RandType = MathClass.Rand(0, 2);
|
||||
if (RandType == 0) RandValue = -RandValue;
|
||||
local Glod = EquValue[EquId] + RandValue;
|
||||
local T = {
|
||||
op = 21005002,
|
||||
flag = 1,
|
||||
glod = Glod
|
||||
}
|
||||
SUser.SendJso(T);
|
||||
|
||||
local Cid = SUser.GetCID();
|
||||
if (!UserState.rawin(Cid)) UserState[Cid] <- {};
|
||||
UserState[Cid].rawset(Jso.npc, {
|
||||
glod = Glod,
|
||||
pos = Jso.pos,
|
||||
oldid = EquId
|
||||
time = Sq_GetTimestampString().slice(-9).tointeger()
|
||||
});
|
||||
}
|
||||
//装备易物
|
||||
else if (Random <= EventRate[2]) {
|
||||
local setarr = [];
|
||||
local findtable = EquGroup[Rarity];
|
||||
foreach(index, level in findtable) {
|
||||
if (level >= Level - EquFloatMin && level <= Level + EquFloatMax) {
|
||||
setarr.append(index);
|
||||
}
|
||||
}
|
||||
|
||||
local SendId = setarr[MathClass.Rand(0, setarr.len() - 1)];
|
||||
local T = {
|
||||
op = 21005002,
|
||||
flag = 2,
|
||||
equ = SendId
|
||||
}
|
||||
SUser.SendJso(T);
|
||||
|
||||
local Cid = SUser.GetCID();
|
||||
if (!UserState.rawin(Cid)) UserState[Cid] <- {};
|
||||
UserState[Cid].rawset(Jso.npc, {
|
||||
equ = SendId,
|
||||
pos = Jso.pos,
|
||||
oldid = EquId
|
||||
time = Sq_GetTimestampString().slice(-9).tointeger()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.bindenv(this));
|
||||
|
||||
|
||||
ClientSocketPackFuncMap.rawset(21005003, function(SUser, Jso) {
|
||||
//获取交易结构体
|
||||
local Info = GetTransactionInfo(SUser, Jso);
|
||||
if (!Info) return;
|
||||
//获取旧装备ID
|
||||
local oldid = Info.oldid;
|
||||
//获取旧装备格子
|
||||
local pos = Info.pos;
|
||||
//检测扣除
|
||||
local InvenObj = SUser.GetInven();
|
||||
local Equ = InvenObj.GetSlot(Inven.INVENTORY_TYPE_ITEM, 9 + Info.pos);
|
||||
if (Equ.GetIndex() != oldid) {
|
||||
SUser.SendNotiBox("交易时请不要移动背包中装备的位置!", 1);
|
||||
return;
|
||||
}
|
||||
Equ.Delete();
|
||||
|
||||
if (Info.rawin("equ")) {
|
||||
SUser.GiveItem(Info.equ, 1);
|
||||
SUser.SendNotiBox("与NPC交易获得装备 [" + PvfItem.GetNameById(Info.equ) + "]", 1);
|
||||
} else if (Info.rawin("glod")) {
|
||||
SUser.RechargeMoney(Info.glod);
|
||||
SUser.SendNotiBox("与NPC交易获得金币: " + Info.glod, 1);
|
||||
}
|
||||
SUser.SendItemSpace(0);
|
||||
}.bindenv(this));
|
||||
}
|
||||
|
||||
function GetTransactionInfo(SUser, Jso) {
|
||||
try {
|
||||
local Info = UserState[SUser.GetCID()][Jso.npc];
|
||||
return Info;
|
||||
} catch (exception) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
function InitPvf() {
|
||||
Script();
|
||||
ScriptData.GetFileData("etc/rindro/npctransaction/npctransaction.etc", function(DataTable, Data) {
|
||||
while (!Data.Eof()) {
|
||||
local Fragment = Data.Get();
|
||||
if (Fragment == "[value]") {
|
||||
while (true) {
|
||||
local Fbuf = Data.Get();
|
||||
if (Fbuf == "[/value]") {
|
||||
break;
|
||||
}
|
||||
local Value = Data.Get();
|
||||
EquValue.rawset(Fbuf, Value);
|
||||
//读取装备品级
|
||||
local equ = PvfItem.GetPvfItemById(Fbuf);
|
||||
local Rarity = equ.GetRarity();
|
||||
local Level = equ.GetUsableLevel();
|
||||
EquGroup[Rarity].rawset(Fbuf, Level);
|
||||
}
|
||||
} else if (Fragment == "[random]") {
|
||||
GoldFloat = Data.Get().tofloat() / 1000.0;
|
||||
} else if (Fragment == "[allow rarity]") {
|
||||
MinRarity = Data.Get();
|
||||
} else if (Fragment == "[exchange cost item]") {
|
||||
TradeItem = {
|
||||
item = Data.Get(),
|
||||
count = Data.Get()
|
||||
}
|
||||
} else if (Fragment == "[equipment random level lower]") {
|
||||
EquFloatMin = Data.Get();
|
||||
} else if (Fragment == "[equipment random level upper]") {
|
||||
EquFloatMax = Data.Get();
|
||||
} else if (Fragment == "[event rate]") {
|
||||
local o1 = Data.Get();
|
||||
local o2 = Data.Get();
|
||||
local o3 = Data.Get();
|
||||
|
||||
EventRate = [o1, o1 + o2, o1 + o2 + o3];
|
||||
}else if (Fragment == "[exchange term]") {
|
||||
TradingCooldownTime = Data.Get();
|
||||
}
|
||||
}
|
||||
}.bindenv(this));
|
||||
}
|
||||
|
||||
function GetTrade(InvenObj, pos) {
|
||||
local ptr = Memory.alloc(10240);
|
||||
Sq_CallFunc(S_Ptr("0x084FB918"), "int", ["pointer", "pointer", "int", "int"], ptr.C_Object, InvenObj.C_Object, 1, pos);
|
||||
return ptr.readS8();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Timer.SetTimeOut(function() {
|
||||
ProjectInitFuncMap.P_NpcTransaction <- NpcTransaction();
|
||||
}, 10000);
|
||||
|
|
@ -0,0 +1 @@
|
|||
NpcTransaction.nut
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
文件名:CombatRank.nut
|
||||
路径:Dps_A/ProjectClass/CombatRank/CombatRank.nut
|
||||
创建日期:2024-06-26 23:10
|
||||
文件用途:战斗力系统
|
||||
*/
|
||||
class CombatRank {
|
||||
|
||||
//角色更换了装备事件包
|
||||
PacketId_0 = 20072102;
|
||||
|
||||
constructor() {
|
||||
|
||||
//注册服务端收包
|
||||
RegisterServer();
|
||||
//注册客户端收包
|
||||
RegisterClient();
|
||||
|
||||
}
|
||||
|
||||
function RegisterServer() {
|
||||
Cb_player_chanage_equ_Func.CombatRankFunc <- function(SUser) {
|
||||
local T = {
|
||||
op = PacketId_0
|
||||
}
|
||||
SUser.SendJso(T);
|
||||
}.bindenv(this);
|
||||
}
|
||||
|
||||
|
||||
function RegisterClient() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ProjectInitFuncMap.P_CombatRank <- CombatRank();
|
||||
|
|
@ -0,0 +1 @@
|
|||
CombatRank.nut
|
||||
|
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
文件名:LukeClass.nut
|
||||
路径:Dps_A/ProjectClass/Luke/LukeClass.nut
|
||||
创建日期:2024-07-15 20:46
|
||||
文件用途:卢克服务的文件
|
||||
*/
|
||||
class Luke {
|
||||
//频道
|
||||
Channel = 19;
|
||||
//城镇
|
||||
Town = 18;
|
||||
|
||||
//服务端区域移动添加玩家HOOK 让大家不可见
|
||||
function insert_user_hook(C_Area, C_User) {
|
||||
//如果有城镇配置
|
||||
if (Town) {
|
||||
local SUser = User(C_User);
|
||||
if (SUser.GetLocation().Town == Town) {
|
||||
if (SUser.GetLocation().Area > 1) Sq_WriteAddress(C_Area, 0x68, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
//服务端区域移动HOOK 让玩家不可以直接去另一个区域
|
||||
function move_area_hook(CUser, TownIndex, AreaIndex) {
|
||||
// return true;//TODO
|
||||
if (!CUser) return true;
|
||||
local SUser = User(CUser);
|
||||
//卢克频道
|
||||
if (Sq_Game_GetConfig().find("19") != null) {
|
||||
if (AreaIndex <= 1) {
|
||||
return true;
|
||||
} else {
|
||||
local Jso = {
|
||||
op = 20084023,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
regionId = AreaIndex
|
||||
}
|
||||
Socket.SendGateway(Jso);
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//玩家发送消息HOOK 为了攻坚队频道和团长公告
|
||||
function base_input_hook(CUser, CmdString) {
|
||||
if (!CUser) return true;
|
||||
local SUser = User(CUser);
|
||||
print(111);
|
||||
//卢克频道
|
||||
if (Sq_Game_GetConfig().find("19") != null) {
|
||||
local Localtion = SUser.GetLocation();
|
||||
if (Localtion.Area <= 1) {
|
||||
return true;
|
||||
} else {
|
||||
local Jso = {
|
||||
op = 20084027,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
msg = CmdString
|
||||
}
|
||||
Socket.SendGateway(Jso);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function base_input_hook2(args) {
|
||||
local type = args[2];
|
||||
local SUser = User(args[1]);
|
||||
local msg = args[3];
|
||||
|
||||
if ((type == 8 || type == 3) && Sq_Game_GetConfig().find("19") != null) {
|
||||
|
||||
local Localtion = SUser.GetLocation();
|
||||
if (Localtion.Area <= 1) {
|
||||
return true;
|
||||
} else {
|
||||
local Jso = {
|
||||
op = 20084027,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
msg = msg
|
||||
}
|
||||
Socket.SendGateway(Jso);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//玩家消息分发
|
||||
function PlayerNotiMsgDistribute(Jso) {
|
||||
local SUser = World.GetUserByUidCid(Jso.uid, Jso.cid);
|
||||
if (!SUser) return;
|
||||
local CUserList = Jso.list;
|
||||
local RealList = [];
|
||||
foreach(_i, obj in CUserList) {
|
||||
local SUser = World.GetUserByUidCid(obj.uid, obj.cid);
|
||||
if (SUser && SUser.GetState() >= 3) RealList.append(SUser);
|
||||
}
|
||||
local SUserName = SUser.GetCharacName();
|
||||
local Type = Jso.type;
|
||||
|
||||
Jso.msg = Jso.msg;
|
||||
if (Type == -1) {
|
||||
Jso.Name <- SUserName;
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SendObj = Value;
|
||||
SendObj.SendJso(Jso);
|
||||
}
|
||||
Type = "长"
|
||||
}
|
||||
local NotiStr = "(攻坚队" + Type + ") " + "" + SUserName + " : " + Jso.msg;
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SendObj = Value;
|
||||
SendObj.SendNotiPacketMessage(NotiStr, 8);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function LukeSendAreaUserCallBack(Jso) {
|
||||
local CUserList = Jso.list;
|
||||
local RealList = [];
|
||||
foreach(_i, obj in CUserList) {
|
||||
local SUser = World.GetUserByUidCid(obj.uid, obj.cid);
|
||||
if (SUser && SUser.GetState() >= 3) RealList.append(SUser);
|
||||
}
|
||||
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SUser = Value;
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(0, 24);
|
||||
Pack.Put_Byte(SUser.GetLocation().Town); //城镇
|
||||
Pack.Put_Byte(SUser.GetArea(1)); //区域
|
||||
Pack.Put_Short((RealList.len() - 1)); //几个玩家 要减去自己
|
||||
foreach(__Index, MapObj in RealList) {
|
||||
if (SUser.GetUID() == MapObj.GetUID()) continue;
|
||||
Pack.Put_Short(MapObj.GetUniqueId());
|
||||
Pack.Put_Short(MapObj.GetAreaPos().X);
|
||||
Pack.Put_Short(MapObj.GetAreaPos().Y);
|
||||
Pack.Put_Byte(MapObj.GetDirections()); //朝向
|
||||
Pack.Put_Byte(MapObj.GetVisibleValues()); //是否可见
|
||||
}
|
||||
Pack.Put_Byte(1); //是否可见
|
||||
Pack.Finalize(true);
|
||||
SUser.Send(Pack);
|
||||
Pack.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
function LukePlayerMoveMapCallBack(Jso) {
|
||||
local MoveSUser = World.GetUserByUidCid(Jso.uid, Jso.cid);
|
||||
if (!MoveSUser) return;
|
||||
|
||||
local CUserList = Jso.list;
|
||||
local RealList = [];
|
||||
foreach(_i, obj in CUserList) {
|
||||
local SUser = World.GetUserByUidCid(obj.uid, obj.cid);
|
||||
if (SUser && SUser.GetState() >= 3) RealList.append(SUser);
|
||||
}
|
||||
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(0, 22);
|
||||
Pack.Put_Short(MoveSUser.GetUniqueId());
|
||||
Pack.Put_Short(Jso.XPos);
|
||||
Pack.Put_Short(Jso.YPos);
|
||||
Pack.Put_Byte(Jso.Direction);
|
||||
Pack.Put_Short(Jso.Code);
|
||||
Pack.Finalize(true);
|
||||
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SUser = Value;
|
||||
if (SUser.GetUniqueId() == MoveSUser.GetUniqueId()) continue;
|
||||
SUser.Send(Pack);
|
||||
}
|
||||
Pack.Delete();
|
||||
}
|
||||
|
||||
function ClientGetConfigCallBack(SUser, Jso) {
|
||||
local evv = {
|
||||
op = 20084502,
|
||||
town_index = Town,
|
||||
channel_index = Channel
|
||||
}
|
||||
SUser.SendJso(evv);
|
||||
}
|
||||
|
||||
function ClientCreateOrJoinParty(SUser, Jso) {
|
||||
Jso.uid <- SUser.GetUID();
|
||||
Jso.cid <- SUser.GetCID();
|
||||
Jso.PlayerName <- SUser.GetCharacName();
|
||||
Jso.PlayerLevel <- SUser.GetCharacLevel();
|
||||
Jso.PlayerJob <- SUser.GetCharacJob();
|
||||
Jso.PlayerGrowTypeJob <- SUser.GetCharacGrowType();
|
||||
Jso.IsPrepare <- false;
|
||||
Jso.PlayerSession <- World.GetSessionByUid(SUser.GetUID());
|
||||
Jso.PlayCoin <- SUser.GetCoin();
|
||||
Jso.PlayFatigue <- SUser.GetMaxFatigue() - SUser.GetFatigue();
|
||||
Socket.SendGateway(Jso);
|
||||
}
|
||||
|
||||
//玩家上线
|
||||
function Login_Hook(SUser) {
|
||||
Timer.SetTimeOut(function(SUser) {
|
||||
//玩家上线发信息包
|
||||
local evv = {
|
||||
op = 20084502,
|
||||
town_index = Town,
|
||||
channel_index = Channel
|
||||
}
|
||||
SUser.SendJso(evv);
|
||||
}.bindenv(this), 5, SUser);
|
||||
|
||||
local T = {
|
||||
op = 20084063,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
}
|
||||
Socket.SendGateway(T);
|
||||
}
|
||||
|
||||
//团本配置信息获取回调
|
||||
function GetPluginConfig(Jso) {
|
||||
Town = Jso.Town;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
local ConfigPath = Sq_Game_GetConfig();
|
||||
Channel = ConfigPath.slice(ConfigPath.find("cfg/") + 4, ConfigPath.len());
|
||||
|
||||
//注册HOOK
|
||||
Cb_Insert_User_Func.Luke <- insert_user_hook.bindenv(this); //区域添加角色
|
||||
Cb_Move_Area_Func.Luke <- move_area_hook.bindenv(this); //区域移动
|
||||
//Base_InputHookFunc_Handle.Luke <- base_input_hook.bindenv(this); //玩家发送消息
|
||||
Cb_reach_game_world_Func.Luke <- Login_Hook.bindenv(this); //上线HOOK
|
||||
Cb_Server_Chat_Log_Leave_Func.Luke <- base_input_hook2.bindenv(this); //玩家发送消息
|
||||
|
||||
//注册收包
|
||||
GatewaySocketPackFuncMap.rawset(20084010, LukeSendAreaUserCallBack.bindenv(this)); //玩家移动后的区域广播包
|
||||
GatewaySocketPackFuncMap.rawset(20084012, LukePlayerMoveMapCallBack.bindenv(this)); //玩家移动回调
|
||||
//玩家消息分发
|
||||
GatewaySocketPackFuncMap.rawset(20084018, PlayerNotiMsgDistribute.bindenv(this)); //玩家打字发送的信息
|
||||
GatewaySocketPackFuncMap.rawset(20084778, GetPluginConfig.bindenv(this)); //服务端配置
|
||||
|
||||
//注册来自客户端的收包
|
||||
ClientSocketPackFuncMap.rawset(20230718, ClientGetConfigCallBack.bindenv(this));
|
||||
ClientSocketPackFuncMap.rawset(20084501, ClientGetConfigCallBack.bindenv(this));
|
||||
ClientSocketPackFuncMap.rawset(20084001, ClientCreateOrJoinParty.bindenv(this));
|
||||
ClientSocketPackFuncMap.rawset(20084005, ClientCreateOrJoinParty.bindenv(this));
|
||||
}
|
||||
}
|
||||
|
||||
ProjectInitFuncMap.P_Luke <- Luke();
|
||||
|
|
@ -0,0 +1 @@
|
|||
LukeClass.nut
|
||||
|
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
文件名:AntonClass.nut
|
||||
路径:Dps_A/ProjectClass/Anton/AntonClass.nut
|
||||
创建日期:2024-07-15 20:46
|
||||
文件用途:安图恩服务的文件
|
||||
*/
|
||||
class Anton {
|
||||
//频道
|
||||
Channel = 18;
|
||||
//城镇
|
||||
Town = 188;
|
||||
|
||||
//服务端区域移动添加玩家HOOK 让大家不可见
|
||||
function insert_user_hook(C_Area, C_User) {
|
||||
//如果有城镇配置
|
||||
if (Town) {
|
||||
local SUser = User(C_User);
|
||||
if (SUser.GetLocation().Town == Town) {
|
||||
if (SUser.GetLocation().Area > 1) Sq_WriteAddress(C_Area, 0x68, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
//服务端区域移动HOOK 让玩家不可以直接去另一个区域
|
||||
function move_area_hook(CUser, TownIndex, AreaIndex) {
|
||||
// return true;//TODO
|
||||
if (!CUser) return true;
|
||||
local SUser = User(CUser);
|
||||
//安图恩频道
|
||||
if (Sq_Game_GetConfig().find("18") != null) {
|
||||
if (AreaIndex <= 1) {
|
||||
return true;
|
||||
} else {
|
||||
local Jso = {
|
||||
op = 20064023,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
regionId = AreaIndex
|
||||
}
|
||||
Socket.SendGateway(Jso);
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//玩家发送消息HOOK 为了攻坚队频道和团长公告
|
||||
function base_input_hook(CUser, CmdString) {
|
||||
if (!CUser) return true;
|
||||
local SUser = User(CUser);
|
||||
|
||||
//安图恩频道
|
||||
if (Sq_Game_GetConfig().find("18") != null) {
|
||||
local Localtion = SUser.GetLocation();
|
||||
if (Localtion.Area <= 1) {
|
||||
return true;
|
||||
} else {
|
||||
local Jso = {
|
||||
op = 20064027,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
msg = CmdString
|
||||
}
|
||||
Socket.SendGateway(Jso);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function base_input_hook2(args) {
|
||||
local type = args[2];
|
||||
local SUser = User(args[1]);
|
||||
local msg = args[3];
|
||||
if ((type == 8 || type == 3) && Sq_Game_GetConfig().find("18") != null) {
|
||||
local Localtion = SUser.GetLocation();
|
||||
if (Localtion.Area <= 1) {
|
||||
return true;
|
||||
} else {
|
||||
local Jso = {
|
||||
op = 20064027,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
msg = msg
|
||||
}
|
||||
Socket.SendGateway(Jso);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//玩家消息分发
|
||||
function PlayerNotiMsgDistribute(Jso) {
|
||||
local SUser = World.GetUserByUidCid(Jso.uid, Jso.cid);
|
||||
if (!SUser) return;
|
||||
local CUserList = Jso.list;
|
||||
local RealList = [];
|
||||
foreach(_i, obj in CUserList) {
|
||||
local SUser = World.GetUserByUidCid(obj.uid, obj.cid);
|
||||
if (SUser && SUser.GetState() >= 3) RealList.append(SUser);
|
||||
}
|
||||
local SUserName = SUser.GetCharacName();
|
||||
local Type = Jso.type;
|
||||
|
||||
Jso.msg = Jso.msg;
|
||||
if (Type == -1) {
|
||||
Jso.Name <- SUserName;
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SendObj = Value;
|
||||
SendObj.SendJso(Jso);
|
||||
}
|
||||
Type = "长"
|
||||
}
|
||||
local NotiStr = "(攻坚队" + Type + ") " + "" + SUserName + " : " + Jso.msg;
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SendObj = Value;
|
||||
SendObj.SendNotiPacketMessage(NotiStr, 8);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function AntonSendAreaUserCallBack(Jso) {
|
||||
local CUserList = Jso.list;
|
||||
local RealList = [];
|
||||
foreach(_i, obj in CUserList) {
|
||||
local SUser = World.GetUserByUidCid(obj.uid, obj.cid);
|
||||
if (SUser && SUser.GetState() >= 3) RealList.append(SUser);
|
||||
}
|
||||
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SUser = Value;
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(0, 24);
|
||||
Pack.Put_Byte(SUser.GetLocation().Town); //城镇
|
||||
Pack.Put_Byte(SUser.GetArea(1)); //区域
|
||||
Pack.Put_Short((RealList.len() - 1)); //几个玩家 要减去自己
|
||||
foreach(__Index, MapObj in RealList) {
|
||||
if (SUser.GetUID() == MapObj.GetUID()) continue;
|
||||
Pack.Put_Short(MapObj.GetUniqueId());
|
||||
Pack.Put_Short(MapObj.GetAreaPos().X);
|
||||
Pack.Put_Short(MapObj.GetAreaPos().Y);
|
||||
Pack.Put_Byte(MapObj.GetDirections()); //朝向
|
||||
Pack.Put_Byte(MapObj.GetVisibleValues()); //是否可见
|
||||
}
|
||||
Pack.Put_Byte(1); //是否可见
|
||||
Pack.Finalize(true);
|
||||
SUser.Send(Pack);
|
||||
Pack.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
function AntonPlayerMoveMapCallBack(Jso) {
|
||||
local MoveSUser = World.GetUserByUidCid(Jso.uid, Jso.cid);
|
||||
if (!MoveSUser) return;
|
||||
|
||||
local CUserList = Jso.list;
|
||||
local RealList = [];
|
||||
foreach(_i, obj in CUserList) {
|
||||
local SUser = World.GetUserByUidCid(obj.uid, obj.cid);
|
||||
if (SUser && SUser.GetState() >= 3) RealList.append(SUser);
|
||||
}
|
||||
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(0, 22);
|
||||
Pack.Put_Short(MoveSUser.GetUniqueId());
|
||||
Pack.Put_Short(Jso.XPos);
|
||||
Pack.Put_Short(Jso.YPos);
|
||||
Pack.Put_Byte(Jso.Direction);
|
||||
Pack.Put_Short(Jso.Code);
|
||||
Pack.Finalize(true);
|
||||
|
||||
foreach(_Index, Value in RealList) {
|
||||
local SUser = Value;
|
||||
if (SUser.GetUniqueId() == MoveSUser.GetUniqueId()) continue;
|
||||
SUser.Send(Pack);
|
||||
}
|
||||
Pack.Delete();
|
||||
}
|
||||
|
||||
function ClientGetConfigCallBack(SUser, Jso) {
|
||||
local evv = {
|
||||
op = 20064502,
|
||||
town_index = Town,
|
||||
channel_index = Channel
|
||||
}
|
||||
SUser.SendJso(evv);
|
||||
}
|
||||
|
||||
function ClientCreateOrJoinParty(SUser, Jso) {
|
||||
Jso.uid <- SUser.GetUID();
|
||||
Jso.cid <- SUser.GetCID();
|
||||
Jso.PlayerName <- SUser.GetCharacName();
|
||||
Jso.PlayerLevel <- SUser.GetCharacLevel();
|
||||
Jso.PlayerJob <- SUser.GetCharacJob();
|
||||
Jso.PlayerGrowTypeJob <- SUser.GetCharacGrowType();
|
||||
Jso.IsPrepare <- false;
|
||||
Jso.PlayerSession <- World.GetSessionByUid(SUser.GetUID());
|
||||
Jso.PlayCoin <- SUser.GetCoin();
|
||||
Jso.PlayFatigue <- SUser.GetMaxFatigue() - SUser.GetFatigue();
|
||||
Socket.SendGateway(Jso);
|
||||
}
|
||||
|
||||
//玩家上线
|
||||
function Login_Hook(SUser) {
|
||||
//玩家上线发信息包
|
||||
local evv = {
|
||||
op = 20064502,
|
||||
town_index = Town,
|
||||
channel_index = Channel
|
||||
}
|
||||
SUser.SendJso(evv);
|
||||
|
||||
local T = {
|
||||
op = 20064063,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
}
|
||||
Socket.SendGateway(T);
|
||||
}
|
||||
|
||||
//团本配置信息获取回调
|
||||
function GetPluginConfig(Jso) {
|
||||
Town = Jso.Town;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
local ConfigPath = Sq_Game_GetConfig();
|
||||
Channel = ConfigPath.slice(ConfigPath.find("cfg/") + 4, ConfigPath.len());
|
||||
|
||||
//注册HOOK
|
||||
Cb_Insert_User_Func.Anton <- insert_user_hook.bindenv(this); //区域添加角色
|
||||
Cb_Move_Area_Func.Anton <- move_area_hook.bindenv(this); //区域移动
|
||||
//Base_InputHookFunc_Handle.Anton <- base_input_hook.bindenv(this); //玩家发送消息
|
||||
Cb_reach_game_world_Func.Anton <- Login_Hook.bindenv(this); //上线HOOK
|
||||
Cb_Server_Chat_Log_Leave_Func.Anton <- base_input_hook2.bindenv(this); //玩家发送消息
|
||||
|
||||
|
||||
//注册收包
|
||||
GatewaySocketPackFuncMap.rawset(20064010, AntonSendAreaUserCallBack.bindenv(this)); //玩家移动后的区域广播包
|
||||
GatewaySocketPackFuncMap.rawset(20064012, AntonPlayerMoveMapCallBack.bindenv(this)); //玩家移动回调
|
||||
//玩家消息分发
|
||||
GatewaySocketPackFuncMap.rawset(20064018, PlayerNotiMsgDistribute.bindenv(this)); //玩家打字发送的信息
|
||||
GatewaySocketPackFuncMap.rawset(20064778, GetPluginConfig.bindenv(this)); //服务端配置
|
||||
|
||||
//注册来自客户端的收包
|
||||
ClientSocketPackFuncMap.rawset(20230718, ClientGetConfigCallBack.bindenv(this));
|
||||
ClientSocketPackFuncMap.rawset(20064501, ClientGetConfigCallBack.bindenv(this));
|
||||
ClientSocketPackFuncMap.rawset(20064001, ClientCreateOrJoinParty.bindenv(this));
|
||||
ClientSocketPackFuncMap.rawset(20064005, ClientCreateOrJoinParty.bindenv(this));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ProjectInitFuncMap.P_Anton <- Anton();
|
||||
|
|
@ -0,0 +1 @@
|
|||
AntonClass.nut
|
||||
|
|
@ -0,0 +1,327 @@
|
|||
/*
|
||||
文件名:Exchange.nut
|
||||
路径:Dps_A/ProjectClass/Exchange/Exchange.nut
|
||||
创建日期:2025-07-21 19:05
|
||||
文件用途:
|
||||
*/
|
||||
|
||||
class Exchange {
|
||||
|
||||
MysqlObject = null;
|
||||
Commission = 0;
|
||||
|
||||
constructor() {
|
||||
Script();
|
||||
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"));
|
||||
|
||||
SelectSql("CREATE TABLE `zyk`.`exchange` ( `uuid` int NOT NULL AUTO_INCREMENT, `type` int NULL, `itemid` int NULL, `itemcount` int NULL, `itemdata` varchar(512) NULL, `price` int NULL, `uid` int NULL , `cid` int NULL , `name` varchar(128) NULL, PRIMARY KEY (`uuid`));", []);
|
||||
|
||||
|
||||
|
||||
local Ct = ScriptData.GetFileData("etc/rindro/exchange/exchange.etc", function(DataTable, Data) {
|
||||
DataTable.Attribute <- {};
|
||||
while (!Data.Eof()) {
|
||||
local Str = Data.Get();
|
||||
if (Str == "[commission]") {
|
||||
Commission = Data.Get().tofloat() * 0.01;
|
||||
}
|
||||
}
|
||||
}.bindenv(this));
|
||||
|
||||
//上架商品
|
||||
ClientSocketPackFuncMap.rawset(21001001, function(SUser, Jso) {
|
||||
//获取玩家背包
|
||||
local InvenObj = SUser.GetInven();
|
||||
if (!InvenObj) {
|
||||
return;
|
||||
}
|
||||
|
||||
//获取道具
|
||||
local ItemObj = InvenObj.GetSlot(1, Jso.pos + 9 + (Jso.type * 48));
|
||||
if (!ItemObj) return;
|
||||
|
||||
//获取道具类型
|
||||
ItemObj.Attribute.seek(1);
|
||||
local ItemType = ItemObj.Attribute.readn('c');
|
||||
//副职业材料是10 这里给转成5
|
||||
if (ItemType == 10) ItemType = 5;
|
||||
|
||||
//获取道具Id
|
||||
local ItemId = ItemObj.GetIndex();
|
||||
//获取数量
|
||||
local ItemCount = ItemObj.GetAdd_Info();
|
||||
//如果是装备 数量恒定为1
|
||||
if (ItemType == 1) ItemCount = 1;
|
||||
|
||||
//获取道具数据
|
||||
local ItemData = "0x00";
|
||||
|
||||
//获取价格
|
||||
local Price = Jso.value;
|
||||
//获取上架者cid
|
||||
local Uid = SUser.GetUID();
|
||||
local Cid = SUser.GetCID();
|
||||
local Name = SUser.GetCharacName();
|
||||
|
||||
local InfoTable = {
|
||||
ItemType = ItemType,
|
||||
ItemId = ItemId,
|
||||
ItemCount = ItemCount,
|
||||
ItemData = ItemData,
|
||||
Price = Price,
|
||||
Uid = Uid,
|
||||
Cid = Cid,
|
||||
Name = Name
|
||||
}
|
||||
|
||||
if (ItemType == 1) {
|
||||
EquipLogic(SUser, Jso.pos + 9, InfoTable, ItemObj);
|
||||
return;
|
||||
}
|
||||
|
||||
//插入数据库
|
||||
local Sql = format("INSERT INTO `zyk`.`exchange` (`type`, `itemid`, `itemcount`, `itemdata`, `price`, `uid` ,`cid`,`name`) VALUES (%d, %d, %d, \'%s\', %d, %d, %d, \'%s\');", InfoTable.ItemType, InfoTable.ItemId, InfoTable.ItemCount, InfoTable.ItemData, InfoTable.Price, InfoTable.Uid, InfoTable.Cid, InfoTable.Name);
|
||||
local Ret = SelectSql(Sql, []);
|
||||
|
||||
//删除道具
|
||||
ItemObj.Delete();
|
||||
//发送刷新背包消息
|
||||
SUser.SendUpdateItemList(1, 1, Jso.pos + 9 + (Jso.type * 48));
|
||||
SUser.SendItemSpace(0);
|
||||
}.bindenv(this));
|
||||
|
||||
|
||||
//查询上架商品
|
||||
ClientSocketPackFuncMap.rawset(21001003, function(SUser, Jso) {
|
||||
local Offset = Jso.offset;
|
||||
local Sql = format("SELECT * FROM `zyk`.`exchange` WHERE `type` = %d LIMIT 7 OFFSET %d;", Jso.type, Offset);
|
||||
local Ret = SelectSql(Sql, ["int", "int", "int", "int", "binary", "int", "int", "int", "string"]);
|
||||
|
||||
local CountSql = format("SELECT COUNT(*) AS total FROM `zyk`.`exchange` WHERE `type` = %d;", Jso.type);
|
||||
local CountRet = SelectSql(CountSql, ["int"]);
|
||||
|
||||
local TotalCount = 0;
|
||||
if (CountRet.len() > 0) TotalCount = CountRet[0][0];
|
||||
|
||||
local Pack = {};
|
||||
Pack.op <- 21001004;
|
||||
Pack.info <- [];
|
||||
Pack.total <- TotalCount;
|
||||
foreach(info in Ret) {
|
||||
local T = {
|
||||
uid = info[0],
|
||||
itemId = info[2],
|
||||
count = info[3],
|
||||
price = info[5],
|
||||
name = info[8]
|
||||
}
|
||||
Pack.info.push(T);
|
||||
}
|
||||
SUser.SendJso(Pack);
|
||||
|
||||
}.bindenv(this));
|
||||
|
||||
//购买商品
|
||||
ClientSocketPackFuncMap.rawset(21001005, function(SUser, Jso) {
|
||||
local uuid = Jso.uuid;
|
||||
|
||||
local Sql = format("SELECT * FROM `zyk`.`exchange` WHERE `uuid` = %d;", uuid);
|
||||
local Ret = SelectSql(Sql, ["int", "int", "int", "int", "string", "int", "int", "int", "string"]);
|
||||
if (Ret.len() == 0) return;
|
||||
|
||||
local ItemObj = null;
|
||||
local ItemType = Ret[0][1];
|
||||
local ItemId = Ret[0][2];
|
||||
local ItemCount = Ret[0][3];
|
||||
local ItemPrice = Ret[0][5];
|
||||
local ItemData = Ret[0][4];
|
||||
local uid = Ret[0][6];
|
||||
local cid = Ret[0][7];
|
||||
|
||||
local SelfCid = SUser.GetCID();
|
||||
if (SelfCid == cid) return;
|
||||
|
||||
local UserPoint = SUser.GetCera();
|
||||
if (UserPoint< ItemPrice) return;
|
||||
|
||||
//扣除点券
|
||||
SUser.RechargeCera(-ItemPrice);
|
||||
|
||||
//如果是装备
|
||||
if (ItemType == 1) {
|
||||
local ItemDataJso = Json.Decode(ItemData);
|
||||
SendItemExMail(SUser.GetUID(), SUser.GetCID(), [ItemDataJso], "交易所小助手", "您在交易所购买的商品已发货,请查收!");
|
||||
} else {
|
||||
//发送道具
|
||||
local SendInfo = SUser.GiveItem(ItemId, 1);
|
||||
SUser.SendItemSpace(0);
|
||||
}
|
||||
|
||||
//给上架者加钱
|
||||
local RealItemPrice = (ItemPrice * (1.0 - Commission.tofloat()).tofloat()).tointeger();
|
||||
User.SendItemMail(uid, cid, [{
|
||||
item = 2022110573,
|
||||
num = RealItemPrice
|
||||
}], "交易所小助手", "恭喜您在交易所成功出售商品,获得点券奖励");
|
||||
|
||||
//删除数据库中的记录
|
||||
Sql = format("DELETE FROM `zyk`.`exchange` WHERE `uuid` = %d;", uuid);
|
||||
SelectSql(Sql, []);
|
||||
|
||||
}.bindenv(this));
|
||||
|
||||
|
||||
Cb_Use_Item_Sp_Func[2022110573] <- function(SUser, ItemId) {
|
||||
local Cid = SUser.GetCID();
|
||||
local InvenObj = SUser.GetInven();
|
||||
if (InvenObj) {
|
||||
local SlotIdx = InvenObj.GetSlotById(ItemId);
|
||||
local ItemObj = InvenObj.GetSlot(1, SlotIdx);
|
||||
|
||||
local ItemCount = ItemObj.GetAdd_Info();
|
||||
ItemObj.Delete();
|
||||
SUser.SendItemSpace(0);
|
||||
SUser.RechargeCera(ItemCount);
|
||||
SUser.SendNotiPacketMessage("获得交易所点卷收益: " + ItemCount + "点卷", 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function EquipLogic(SUser, slot, InfoTable, ItemObj) {
|
||||
Sq_CallFunc(S_Ptr("0x0864FE52"), "int", ["pointer"], SUser.C_Object);
|
||||
Timer.SetTimeOut(function() {
|
||||
local SqlObj = MysqlPool.GetInstance().GetConnect();
|
||||
local Ret = SqlObj.Select("SELECT inventory FROM taiwan_cain_2nd.inventory WHERE charac_no = " + SUser.GetCID() + ";", ["binary"]);
|
||||
//把连接还池子
|
||||
MysqlPool.GetInstance().PutConnect(SqlObj);
|
||||
if (Ret.len()< 1 || Ret[0][0] == null) {
|
||||
return false;
|
||||
} else {
|
||||
local LengthPointer = Memory.alloc(4);
|
||||
LengthPointer.writeInt(18238);
|
||||
|
||||
local ReadPointer = Memory.alloc(18238);
|
||||
|
||||
local Flag = Sq_CallFunc(S_Ptr("0x086B2102"), "bool", ["pointer", "pointer", "pointer", "int"], ReadPointer.C_Object, LengthPointer.C_Object, Ret[0][0].C_Object, Ret[0][0].Size);
|
||||
|
||||
local RealP = ReadPointer.add(2 + slot * 61);
|
||||
|
||||
//装备编号
|
||||
local ItemId = RealP.readInt();
|
||||
// print("装备编号: " + ItemId);
|
||||
|
||||
//强化等级
|
||||
local EnhancementLevel = RealP.add(4).readS8();
|
||||
// print("强化等级: " + EnhancementLevel);
|
||||
|
||||
//红字类型
|
||||
local AmplifyType = RealP.add(15).readS8();
|
||||
// print("红字类型: " + AmplifyType);
|
||||
|
||||
//红字属性值
|
||||
local AmplifyValue = RealP.add(16).readS8();
|
||||
// print("红字属性值: " + AmplifyValue);
|
||||
|
||||
//锻造等级
|
||||
local ForgingGrade = RealP.add(49).readS8();
|
||||
// print("锻造等级: " + ForgingGrade);
|
||||
|
||||
//附魔卡片
|
||||
local CardId = RealP.add(11).readShort();
|
||||
// print("附魔卡片: " + CardId);
|
||||
|
||||
//品级
|
||||
local Grade = RealP.add(5).readInt();
|
||||
// print("品级: " + Grade);
|
||||
|
||||
//耐久度
|
||||
local Durability = RealP.add(9).readS8();
|
||||
// print("耐久度: " + Durability)
|
||||
|
||||
//魔法封印
|
||||
local MagicSealP = "0x";
|
||||
for (local i = 0; i< 14; i++) {
|
||||
MagicSealP += format("%02x", RealP.add(35 + i).readU8());
|
||||
}
|
||||
// print(MagicSealP);
|
||||
|
||||
local SendT = {
|
||||
ItemId = ItemId,
|
||||
Grade = Grade,
|
||||
Durability = Durability,
|
||||
EnhancementLevel = EnhancementLevel,
|
||||
AmplifyType = AmplifyType,
|
||||
AmplifyValue = AmplifyValue,
|
||||
MagicSealP = MagicSealP,
|
||||
CardId = CardId,
|
||||
}
|
||||
|
||||
local Json = Json.Encode(SendT);
|
||||
InfoTable.ItemData = Json;
|
||||
|
||||
//插入数据库
|
||||
local Sql = format("INSERT INTO `zyk`.`exchange` (`type`, `itemid`, `itemcount`, `itemdata`, `price`, `uid` ,`cid`,`name`) VALUES (%d, %d, %d, \'%s\', %d, %d, %d, \'%s\');", InfoTable.ItemType, InfoTable.ItemId, InfoTable.ItemCount, InfoTable.ItemData, InfoTable.Price, InfoTable.Uid, InfoTable.Cid, InfoTable.Name);
|
||||
local Ret = SelectSql(Sql, []);
|
||||
|
||||
//删除道具
|
||||
ItemObj.Delete();
|
||||
//发送刷新背包消息
|
||||
SUser.SendUpdateItemList(1, 1, slot);
|
||||
SUser.SendItemSpace(0);
|
||||
}
|
||||
}.bindenv(this), 100)
|
||||
}
|
||||
|
||||
|
||||
function SendItemExMail(UID, CID, ItemList, title, content) {
|
||||
local SUser = World.GetUserByUid(UID);
|
||||
local sql = "select letter_id from taiwan_cain_2nd.postal order by letter_id DESC";
|
||||
local column_type_list = ["int"];
|
||||
|
||||
local SqlObj = MysqlPool.GetInstance().GetConnect();
|
||||
local result = SqlObj.Select(sql, column_type_list);
|
||||
local sl = 1;
|
||||
if (result.len() > 0) {
|
||||
sl = result[0][0] + 1;
|
||||
}
|
||||
|
||||
local time = date();
|
||||
local timeStr = time["year"] + "-" + (time["month"] + 1) + "-" + time["day"] + " " + time["hour"] + ":" + time["min"] + ":" + time["sec"];
|
||||
|
||||
foreach(value in ItemList) {
|
||||
//时间 发送者名字 接收者id 装备ID 品级 耐久度 强化等级 红字类型 红字属性值 魔法封印属性 letterid
|
||||
local sql1 = format("insert into taiwan_cain_2nd.postal (occ_time,send_charac_name,receive_charac_no,item_id,add_info,endurance,upgrade,amplify_option,amplify_value,random_option,letter_id,extend_info) values ('%s','%s',%d,%d,%d,%d,%d,%d,%d,%s,%d,%d)", timeStr, title, CID, value.ItemId, value.Grade, value.Durability, value.EnhancementLevel, value.AmplifyType, value.AmplifyValue, value.MagicSealP, sl, value.CardId)
|
||||
SqlObj.Select(sql1, []);
|
||||
}
|
||||
|
||||
local sql2 = "insert into taiwan_cain_2nd.letter (letter_id,charac_no,send_charac_name,letter_text,reg_date,stat) values ('" + sl + "'," + CID + ",'" + title + "','" + content + "','" + timeStr + "','1')";
|
||||
SqlObj.Select(sql2, []);
|
||||
|
||||
MysqlPool.GetInstance().PutConnect(SqlObj);
|
||||
|
||||
// if (SUser) {
|
||||
// local Pack = Packet();
|
||||
// Pack.Put_Header(0, 9);
|
||||
// local MailBox = Sq_CallFunc(S_Ptr("0x0823020C"), "int", ["pointer"], SUser.C_Object);
|
||||
// Sq_CallFunc(S_Ptr("0x0823455A"), "int", ["int"], MailBox);
|
||||
// local Not_Count = Sq_CallFunc(S_Ptr("0x084ED330"), "int", ["int"], MailBox);
|
||||
// Pack.Put_Short(Not_Count);
|
||||
// Pack.Finalize(true);
|
||||
// SUser.Send(Pack);
|
||||
// Pack.Delete();
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
//执行数据库命令
|
||||
function SelectSql(Sql, Type) {
|
||||
local Ret = MysqlObject.Select(Sql, Type);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
ProjectInitFuncMap.P_Exchange <- Exchange();
|
||||
|
|
@ -0,0 +1 @@
|
|||
Exchange.nut
|
||||
|
|
@ -0,0 +1,447 @@
|
|||
/*
|
||||
文件名:FatalismStone.nut
|
||||
路径:Dps_A/ProjectClass/FatalismStone/FatalismStone.nut
|
||||
创建日期:2025-06-22 12:54
|
||||
文件用途:
|
||||
*/
|
||||
|
||||
|
||||
class FatalismStone_Stone {
|
||||
//编号
|
||||
Id = 0;
|
||||
//类型
|
||||
StoneType = 0;
|
||||
//洗练度
|
||||
CultivationDegree = 0;
|
||||
|
||||
|
||||
|
||||
//特殊 ! 石头的储存数据大小
|
||||
Size = 8;
|
||||
|
||||
constructor(FatalismStoneID = 0) {
|
||||
Id = FatalismStoneID;
|
||||
CultivationDegree = MathClass.Rand(1, 100);
|
||||
}
|
||||
|
||||
function Blob2Hex(buf) {
|
||||
local str = "";
|
||||
for (local i = 0; i< buf.len(); i++) {
|
||||
str += format("%02X", buf[i]);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
function Serialize() {
|
||||
local B = blob(0);
|
||||
|
||||
B.writen(Id, 'i'); //写入ID
|
||||
B.writen(CultivationDegree, 'i'); //写入洗练值
|
||||
|
||||
return Blob2Hex(B);
|
||||
}
|
||||
|
||||
function Deserialize(Data) {
|
||||
local Buf = FatalismStone_Stone();
|
||||
Buf.Id = Data.readn('i');
|
||||
Buf.CultivationDegree = Data.readn('i');
|
||||
if (Buf.Id == 0) return Buf;
|
||||
Buf.StoneType = ProjectInitFuncMap.P_FatalismStone.GetStoneData(Buf.Id)["stone type"];
|
||||
return Buf;
|
||||
}
|
||||
|
||||
function SerializeTable(Obj) {
|
||||
local T = {
|
||||
id = Obj.Id,
|
||||
cultivationDegree = Obj.CultivationDegree
|
||||
};
|
||||
return T;
|
||||
}
|
||||
}
|
||||
|
||||
class FatalismStone {
|
||||
|
||||
//总格子数
|
||||
GridCount = 77;
|
||||
//总穿戴数
|
||||
WearCount = 6;
|
||||
|
||||
//属性数据位数
|
||||
AttrCount = 2;
|
||||
|
||||
//魂石Lst
|
||||
FatalismStoneLst = null;
|
||||
|
||||
constructor() {
|
||||
local PoolObj = MysqlPool.GetInstance();
|
||||
PoolObj.SetBaseConfiguration("127.0.0.1", 3306, "game", "uu5!^%jg");
|
||||
//连接池大小
|
||||
PoolObj.PoolSize = 10;
|
||||
//初始化
|
||||
PoolObj.Init();
|
||||
|
||||
//读取pvf的魂石相关数据
|
||||
InitFatalismStoneData();
|
||||
|
||||
//注册客户端收包
|
||||
RegisterClient();
|
||||
//注册调试命令
|
||||
RegisterDebugCmd();
|
||||
|
||||
|
||||
|
||||
SelectSql("CREATE TABLE `zyk`.`fatalismstone` ( `cid` int(250) NOT NULL, `data` varbinary(10240) NULL, `wearpack` varbinary(1024) NULL, PRIMARY KEY (`cid`));", []);
|
||||
}
|
||||
|
||||
|
||||
//通过数组生成魂石序列化数据
|
||||
function GenerateSerializeData(StoneList) {
|
||||
local Str = "0x";
|
||||
foreach(Stone in StoneList) {
|
||||
Str += Stone.Serialize();
|
||||
}
|
||||
return Str;
|
||||
}
|
||||
|
||||
//通过数据反序列化魂石列表 数据 序列化个数
|
||||
function GenerateDeserializeData(Data, Count) {
|
||||
local BData = Sq_Point2Blob(Data.C_Object, FatalismStone_Stone.Size * Count);
|
||||
local DataArr = [];
|
||||
|
||||
//一直读到最后
|
||||
while (!BData.eos()) {
|
||||
DataArr.push(FatalismStone_Stone.Deserialize(BData));
|
||||
}
|
||||
return DataArr;
|
||||
}
|
||||
|
||||
//给指定玩家新增魂石
|
||||
function AddFatalismStone(SUser, FatalismStoneID) {
|
||||
local CID = SUser.GetCID();
|
||||
local Ret = SelectSql("select data from zyk.fatalismstone where cid = " + CID, ["binary"]);
|
||||
//获得玩家魂石数据
|
||||
local DataArr = GenerateDeserializeData(Ret[0][0], GridCount * 3);
|
||||
//获取魂石属性
|
||||
local info = GetStoneData(FatalismStoneID);
|
||||
//根据页数分割
|
||||
local Offset = (info["stone type"] * GridCount);
|
||||
|
||||
local DataBuffer = DataArr.slice(Offset);
|
||||
//找到第一个空格子
|
||||
local Index = null;
|
||||
foreach(Pos, Obj in DataBuffer) {
|
||||
if (Obj.Id == 0) {
|
||||
Index = Pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Index == null) {
|
||||
SUser.SendNotiPacketMessage("您的魂石背包已满!", 8);
|
||||
return false;
|
||||
}
|
||||
//添加魂石
|
||||
DataArr[Offset + Index] = FatalismStone_Stone(FatalismStoneID);
|
||||
local backpackBinary = GenerateSerializeData(DataArr);
|
||||
SelectSql("update zyk.fatalismstone set data = (" + backpackBinary + ") where cid = " + CID, ["int"]);
|
||||
FlushPlayerFatalismStoneBackpack(SUser);
|
||||
return true;
|
||||
}
|
||||
|
||||
//给指定玩家刷新魂石背包
|
||||
function FlushPlayerFatalismStoneBackpack(SUser) {
|
||||
local Ret = SelectSql("select data,wearpack from zyk.fatalismstone where cid = " + SUser.GetCID(), ["binary", "binary"]);
|
||||
//背包数量*背包类型数量全部使用默认的构造石头填充会是0
|
||||
local BackPackArr = array(GridCount * 3, FatalismStone_Stone());
|
||||
local WearArr = array(WearCount, FatalismStone_Stone());
|
||||
//没有初始化背包的时候先初始化背包
|
||||
if (Ret.len() == 0) {
|
||||
local backpackBinary = GenerateSerializeData(BackPackArr);
|
||||
local wearBinary = GenerateSerializeData(WearArr);
|
||||
SelectSql("insert into zyk.fatalismstone(cid,data,wearpack) values(" + SUser.GetCID() + ",(" + backpackBinary + "),(" + wearBinary + "))", ["int"]);
|
||||
} else {
|
||||
BackPackArr = GenerateDeserializeData(Ret[0][0], GridCount * 3);
|
||||
WearArr = GenerateDeserializeData(Ret[0][1], WearCount);
|
||||
}
|
||||
SUser.SendJso({
|
||||
op = 21000002,
|
||||
BackPackData = BackPackArr.map(FatalismStone_Stone.SerializeTable),
|
||||
WearData = WearArr.map(FatalismStone_Stone.SerializeTable)
|
||||
});
|
||||
}
|
||||
|
||||
function RegisterClient() {
|
||||
//查询魂石背包数据
|
||||
ClientSocketPackFuncMap.rawset(21000001, function(SUser, Jso) {
|
||||
FlushPlayerFatalismStoneBackpack(SUser);
|
||||
}.bindenv(this));
|
||||
|
||||
//交换魂石位置
|
||||
ClientSocketPackFuncMap.rawset(21000003, function(SUser, Jso) {
|
||||
local OldType = Jso.oldtype;
|
||||
local OldIndex = Jso.oldpos;
|
||||
|
||||
local NewType = Jso.newtype;
|
||||
local NewIndex = Jso.newpos;
|
||||
|
||||
|
||||
local Ret = SelectSql("select data,wearpack from zyk.fatalismstone where cid = " + SUser.GetCID(), ["binary", "binary"]);
|
||||
local BackPackArr = GenerateDeserializeData(Ret[0][0], GridCount * 3);
|
||||
local WearArr = GenerateDeserializeData(Ret[0][1], WearCount);
|
||||
|
||||
//如果有魂石要移动到穿戴栏 需要检测魂石的类型是否与穿戴栏符合
|
||||
// if (OldType == -1 || NewType == -1) {
|
||||
// if(OldType == -1){
|
||||
// local OldStone = WearArr[OldIndex];
|
||||
// if(OldStone.Id != 0){
|
||||
// local Info = GetStoneData(OldStone.Id);
|
||||
// if(Info["stone type"] != NewType){
|
||||
// SUser.SendNotiPacketMessage("该魂石无法穿戴在当前位置", 8);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if(NewType == -1){
|
||||
// local NewStone = BackPackArr[NewIndex];
|
||||
// if(NewStone.Id != 0){
|
||||
// local Info = GetStoneData(NewStone.Id);
|
||||
// if(Info["stone type"] != OldType){
|
||||
// SUser.SendNotiPacketMessage("该魂石无法穿戴在当前位置", 8);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
//如果Type等于-1 说明是穿戴的魂石的槽位
|
||||
local OldTemp, NewTemp;
|
||||
if (OldType == -1) {
|
||||
OldTemp = WearArr[OldIndex];
|
||||
} else {
|
||||
OldTemp = BackPackArr[OldType * GridCount + OldIndex];
|
||||
}
|
||||
if (NewType == -1) {
|
||||
NewTemp = WearArr[NewIndex];
|
||||
} else {
|
||||
NewTemp = BackPackArr[NewType * GridCount + NewIndex];
|
||||
}
|
||||
|
||||
|
||||
// //比对两个魂石的槽位类型
|
||||
// local ComparisonType;
|
||||
// if (NewType == -1) {
|
||||
// ComparisonType = NewIndex + 1;
|
||||
// } else {
|
||||
// ComparisonType = (NewType + 1);
|
||||
// }
|
||||
// print("旧类型: " + OldTemp.StoneType + "\n 新类型: " + ComparisonType);
|
||||
// print("旧ID: " + OldTemp.Id + "\n 新ID: " + NewTemp.Id);
|
||||
// if (OldTemp.StoneType != ComparisonType) {
|
||||
// SUser.SendNotiPacketMessage("该魂石无法穿戴在当前位置", 8);
|
||||
// return;
|
||||
// }
|
||||
|
||||
//交换数据
|
||||
if (OldType == -1) {
|
||||
WearArr[OldIndex] = NewTemp;
|
||||
} else {
|
||||
BackPackArr[OldType * GridCount + OldIndex] = NewTemp;
|
||||
}
|
||||
if (NewType == -1) {
|
||||
WearArr[NewIndex] = OldTemp;
|
||||
} else {
|
||||
BackPackArr[NewType * GridCount + NewIndex] = OldTemp;
|
||||
}
|
||||
|
||||
|
||||
//序列化数据
|
||||
local backpackBinary = GenerateSerializeData(BackPackArr);
|
||||
local wearBinary = GenerateSerializeData(WearArr);
|
||||
|
||||
|
||||
//更新数据库
|
||||
SelectSql("update zyk.fatalismstone set data = (" + backpackBinary + "),wearpack = (" + wearBinary + ") where cid = " + SUser.GetCID(), ["int"]);
|
||||
|
||||
//发送数据
|
||||
SUser.SendJso({
|
||||
op = 21000002,
|
||||
BackPackData = BackPackArr.map(FatalismStone_Stone.SerializeTable),
|
||||
WearData = WearArr.map(FatalismStone_Stone.SerializeTable)
|
||||
});
|
||||
}.bindenv(this));
|
||||
|
||||
|
||||
Cb_User_Insert_Item_Leave_Func["宿命魂石"] <- function(args) {
|
||||
local SUser = User(NativePointer(args[0]).readPointer());
|
||||
local InvenObj = SUser.GetInven();
|
||||
local idx = args.pop();
|
||||
if (idx > 0) {
|
||||
local inven_item = InvenObj.GetSlot(1, idx);
|
||||
local item_id = inven_item.GetIndex();
|
||||
if (item_id >= 200625000 && item_id< 200626000) {
|
||||
local Ret = AddFatalismStone(SUser, item_id - 200625000);
|
||||
//删除原道具
|
||||
Timer.SetTimeOut(function() {
|
||||
inven_item.Delete();
|
||||
SUser.SendUpdateItemList(1, 0, idx);
|
||||
}, 100);
|
||||
//如果满了就发邮件
|
||||
if (!Ret) {
|
||||
local T = {};
|
||||
T.rawset(item_id, 1);
|
||||
SUser.SendMail(T, {
|
||||
Title = "系统",
|
||||
Text = "由于你的魂石包裹已满, 请留出足够的空间来接收道具."
|
||||
});
|
||||
}
|
||||
SUser.SendItemSpace(0);
|
||||
}
|
||||
}
|
||||
}.bindenv(this);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function RegisterDebugCmd() {
|
||||
Gm_InputFunc_Handle["给魂石"] <- 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) {
|
||||
AddFatalismStone(SUser, handler[1].tointeger());
|
||||
}
|
||||
}.bindenv(this);
|
||||
}
|
||||
|
||||
function InitFatalismStoneData() {
|
||||
Script();
|
||||
FatalismStoneLst = {};
|
||||
ScriptData.GetFileData("fatalismstone/fatalismstone.lst", function(DataTable, Data) {
|
||||
while (!Data.Eof()) {
|
||||
local Id = Data.Get();
|
||||
local Path = Data.Get();
|
||||
FatalismStoneLst.rawset(Id, Path);
|
||||
}
|
||||
}.bindenv(this));
|
||||
}
|
||||
|
||||
function GetStoneData(Index) {
|
||||
if (FatalismStoneLst.rawin(Index)) {
|
||||
//还是路径就读取数据
|
||||
if (typeof FatalismStoneLst[Index] == "string") {
|
||||
FatalismStoneLst[Index] = ScriptData.GetFileData("fatalismstone/" + FatalismStoneLst[Index], function(DataTable, Data) {
|
||||
DataTable.Attribute <- {};
|
||||
while (!Data.Eof()) {
|
||||
local Key = Data.Get();
|
||||
if (Key == "[rarity]" || Key == "[stone type]" || Key == "[move wav]" || Key == "[front effect]" || Key == "[back effect]") {
|
||||
DataTable[Key.slice(1, -1)] <- Data.Get();
|
||||
} else if (Key == "[icon]") {
|
||||
DataTable.icon <- {
|
||||
img = Data.Get(),
|
||||
index = Data.Get()
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return FatalismStoneLst[Index];
|
||||
} else error("没有ID为: " + Index + " 的魂石数据!");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//执行数据库命令
|
||||
function SelectSql(Sql, Type) {
|
||||
local SqlObj = MysqlPool.GetInstance().GetConnect();
|
||||
local Ret = SqlObj.Select(Sql, Type);
|
||||
//把连接还池子
|
||||
MysqlPool.GetInstance().PutConnect(SqlObj);
|
||||
return Ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ProjectInitFuncMap.P_FatalismStone <- FatalismStone();
|
||||
|
||||
print("文件加载!");
|
||||
|
|
@ -0,0 +1 @@
|
|||
FatalismStone.nut
|
||||
|
|
@ -0,0 +1,244 @@
|
|||
/*
|
||||
文件名:AdMsg.nut
|
||||
路径:Dps_A/BaseClass/AdMsg/AdMsg.nut
|
||||
创建日期:2025-04-26 17:12
|
||||
文件用途:高级消息类
|
||||
*/
|
||||
class AdMsg {
|
||||
|
||||
RarityColor = [
|
||||
[255, 255, 255, 255], // 普通
|
||||
[104, 213, 237, 255], // 高级
|
||||
[179, 107, 255, 255], // 稀有
|
||||
[255, 0, 255, 255], // 神器
|
||||
[255, 180, 0, 255], // 史诗
|
||||
[255, 102, 102, 255], // 勇者
|
||||
[255, 20, 147, 255], // 深粉红色
|
||||
[255, 215, 0, 255] // 金色
|
||||
];
|
||||
|
||||
SendBinary = null;
|
||||
SendInfoArr = null;
|
||||
SendStrArr = null;
|
||||
|
||||
//写入分隔
|
||||
function PutSeparate() {
|
||||
SendBinary.writen(0xc2, 'c');
|
||||
SendBinary.writen(0x80, 'c');
|
||||
}
|
||||
//写入普通字符串
|
||||
function WriteStr(Str) {
|
||||
local Point = Memory.allocUtf8String(Str);
|
||||
local Blob = Sq_Point2Blob(Point.C_Object, Str.len());
|
||||
SendBinary.writeblob(Blob);
|
||||
}
|
||||
//写入颜色字符串
|
||||
function WriteColorStr(Str, Color) {
|
||||
//写入分隔
|
||||
PutSeparate();
|
||||
WriteStr(Str);
|
||||
PutSeparate();
|
||||
|
||||
local ColorBlob = blob(104);
|
||||
for (local i = 0; i< 3; i++) {
|
||||
ColorBlob.writen(Color[i], 'c');
|
||||
}
|
||||
for (local i = 0; i< 101; i++) {
|
||||
ColorBlob.writen(0xff, 'c');
|
||||
}
|
||||
SendInfoArr.push(ColorBlob);
|
||||
}
|
||||
//写入表情
|
||||
function WriteImotIcon(Var) {
|
||||
//写入分隔
|
||||
SendBinary.writen(0x1e, 'c');
|
||||
SendBinary.writen(0x25, 'c');
|
||||
SendBinary.writen(Var, 'c');
|
||||
SendBinary.writen(0x1f, 'c');
|
||||
}
|
||||
|
||||
function JumpWrite(Blob, Pos, Value, Type) {
|
||||
Blob.seek(Pos, 'b');
|
||||
Blob.writen(Value, Type);
|
||||
}
|
||||
|
||||
//写入装备
|
||||
function WriteEquipment(Str, Var, Color) {
|
||||
//写入分隔
|
||||
PutSeparate();
|
||||
WriteStr(Str);
|
||||
PutSeparate();
|
||||
|
||||
local InfoBlob = blob(104);
|
||||
for (local i = 0; i< 3; i++) {
|
||||
InfoBlob.writen(Color[i], 'c');
|
||||
}
|
||||
|
||||
// 判断Var类型
|
||||
if (typeof Var == "integer") {
|
||||
// 如果是物品ID
|
||||
local G_CDataManager = Sq_CallFunc(S_Ptr("0x80CC19B"), "pointer", []);
|
||||
local Citem = Sq_CallFunc(S_Ptr("0x835FA32"), "pointer", ["pointer", "int"], G_CDataManager, Var);
|
||||
local PvfItemObj = PvfItem.GetPvfItemById(Var);
|
||||
local Durable = Sq_CallFunc(S_Ptr("0x811ED98"), "int", ["pointer"], Citem);
|
||||
//装备代码
|
||||
JumpWrite(InfoBlob, 0x4, Var, 'i');
|
||||
if (!PvfItemObj.IsStackable()) {
|
||||
// 非堆叠物品(装备)
|
||||
JumpWrite(InfoBlob, 0x8, rand(), 'i'); // 随机add_info
|
||||
JumpWrite(InfoBlob, 0xe, Durable, 's'); // 默认耐久
|
||||
} else {
|
||||
// 堆叠物品,数量默认1
|
||||
JumpWrite(InfoBlob, 0x8, 1, 'i');
|
||||
}
|
||||
} else {
|
||||
// 如果是物品对象
|
||||
local ItemObj = Var;
|
||||
//装备代码
|
||||
JumpWrite(InfoBlob, 0x4, ItemObj.GetIndex(), 'i');
|
||||
//品级
|
||||
JumpWrite(InfoBlob, 0x8, ItemObj.GetAdd_Info(), 'i');
|
||||
//强化等级
|
||||
JumpWrite(InfoBlob, 0xc, ItemObj.GetUpgrade(), 'c');
|
||||
//装备耐久
|
||||
JumpWrite(InfoBlob, 0xe, ItemObj.GetDurable(), 's');
|
||||
//是否封装
|
||||
JumpWrite(InfoBlob, 0x10, ItemObj.GetAttachType(), 'c');
|
||||
//封装次数
|
||||
JumpWrite(InfoBlob, 0x12, ItemObj.GetDurable(), 'c');
|
||||
//附魔卡片
|
||||
JumpWrite(InfoBlob, 0x14, ItemObj.GetEnchanting(), 'i');
|
||||
//红字类型
|
||||
JumpWrite(InfoBlob, 0x18, ItemObj.GetAmplification(), 'c');
|
||||
//红字数值
|
||||
JumpWrite(InfoBlob, 0x1a, 112, 'c');
|
||||
}
|
||||
|
||||
SendInfoArr.push(InfoBlob);
|
||||
}
|
||||
|
||||
constructor() {
|
||||
SendStrArr = [];
|
||||
SendInfoArr = [];
|
||||
SendBinary = blob(0);
|
||||
//写入分隔
|
||||
PutSeparate();
|
||||
}
|
||||
|
||||
//构造信息段结构体
|
||||
function MakeInfo() {
|
||||
return {
|
||||
Str = "",
|
||||
Flag = 0,
|
||||
Var = 0,
|
||||
Color = 0
|
||||
}
|
||||
}
|
||||
|
||||
Type = 0;
|
||||
//put 类型
|
||||
function PutType(gType) {
|
||||
Type = gType;
|
||||
}
|
||||
|
||||
//put 普通信息
|
||||
function PutString(Str) {
|
||||
local Info = MakeInfo();
|
||||
Info.Str = Str;
|
||||
SendStrArr.push(Info);
|
||||
}
|
||||
|
||||
//put 颜色信息
|
||||
function PutColorString(Str, Color) {
|
||||
local Info = MakeInfo();
|
||||
Info.Str = Str;
|
||||
Info.Flag = 1;
|
||||
Info.Color = Color;
|
||||
SendStrArr.push(Info);
|
||||
}
|
||||
|
||||
//put 表情
|
||||
function PutImoticon(Index) {
|
||||
local Info = MakeInfo();
|
||||
Info.Flag = 2;
|
||||
Info.Var = Index;
|
||||
SendStrArr.push(Info);
|
||||
}
|
||||
|
||||
//put 装备
|
||||
function PutEquipment(...) {
|
||||
local Info = MakeInfo();
|
||||
if (vargv.len() > 1) {
|
||||
Info.Str = vargv[0];
|
||||
Info.Var = vargv[1];
|
||||
Info.Color = vargv[2];
|
||||
} else {
|
||||
Info.Var = vargv[0];
|
||||
if (typeof vargv[0] == "integer") {
|
||||
// 如果是物品ID
|
||||
local itemName = PvfItem.GetNameById(vargv[0]);
|
||||
Info.Str = "[" + itemName + "]";
|
||||
local PvfItemObj = PvfItem.GetPvfItemById(vargv[0]);
|
||||
Info.Color = RarityColor[PvfItemObj.GetRarity()];
|
||||
} else {
|
||||
// 如果是物品对象
|
||||
local itemName = PvfItem.GetNameById(vargv[0].GetIndex());
|
||||
local upgrade_level = vargv[0].GetUpgrade();
|
||||
local PvfItemObj = PvfItem.GetPvfItemById(vargv[0].GetIndex());
|
||||
if (upgrade_level > 0) {
|
||||
Info.Str = "[+" + upgrade_level + " " + itemName + "]";
|
||||
} else {
|
||||
Info.Str = "[" + itemName + "]";
|
||||
}
|
||||
Info.Color = RarityColor[PvfItemObj.GetRarity()];
|
||||
}
|
||||
}
|
||||
|
||||
Info.Flag = 3;
|
||||
SendStrArr.push(Info);
|
||||
}
|
||||
|
||||
function Finalize() {
|
||||
//写入字符串
|
||||
foreach(Info in SendStrArr) {
|
||||
//普通字符串
|
||||
if (Info.Flag == 0) WriteStr(Info.Str);
|
||||
//写入颜色字符串
|
||||
else if (Info.Flag == 1) WriteColorStr(Info.Str, Info.Color);
|
||||
//写入表情
|
||||
else if (Info.Flag == 2) WriteImotIcon(Info.Var);
|
||||
//写入装备
|
||||
else if (Info.Flag == 3) WriteEquipment(Info.Str, Info.Var, Info.Color);
|
||||
}
|
||||
}
|
||||
|
||||
Pack = null;
|
||||
|
||||
function MakePack() {
|
||||
//文字信息长度
|
||||
local SendBinaryLen = SendBinary.len();
|
||||
//申请内存
|
||||
local SendStrPoint = Memory.alloc(SendBinaryLen);
|
||||
Sq_WriteBlobToAddress(SendStrPoint.C_Object, SendBinary);
|
||||
|
||||
Pack = Packet();
|
||||
Pack.Put_Header(0, 370);
|
||||
Pack.Put_Byte(Type);
|
||||
Pack.Put_Short(0);
|
||||
Pack.Put_Byte(3);
|
||||
Pack.Put_Int(SendBinaryLen);
|
||||
Pack.Put_BinaryEx(SendStrPoint.C_Object, SendBinaryLen);
|
||||
Pack.Put_Byte(SendInfoArr.len());
|
||||
for (local i = 0; i< SendInfoArr.len(); i++) {
|
||||
local Point = Memory.alloc(104);
|
||||
Sq_WriteBlobToAddress(Point.C_Object, SendInfoArr[i]);
|
||||
Pack.Put_BinaryEx(Point.C_Object, 104);
|
||||
}
|
||||
Pack.Finalize(true);
|
||||
return Pack;
|
||||
}
|
||||
|
||||
function Delete() {
|
||||
Pack.Delete();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
文件名:BaseBindenvClass.nut
|
||||
路径:Dps_A/BaseClass/BaseInfoClass/BaseBindenvClass.nut
|
||||
创建日期:2024-05-04 12:27
|
||||
文件用途:
|
||||
*/
|
||||
class BaseBindenv {
|
||||
Info = null;
|
||||
constructor() {
|
||||
getroottable().rawset("BaseBindenvInfo_" + clock(), this);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
class Base_C_Object {
|
||||
C_Object = null;
|
||||
|
||||
constructor(gObject) {
|
||||
this.C_Object = gObject;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
文件名:BattleFieldClass.nut
|
||||
路径:Dps_A/BaseClass/BattleFieldClass/BattleFieldClass.nut
|
||||
创建日期:2024-04-28 09:34
|
||||
文件用途:
|
||||
*/
|
||||
class BattleField extends Base_C_Object {
|
||||
Attribute = null;
|
||||
constructor(CObject) {
|
||||
base.constructor(CObject);
|
||||
Attribute = Sq_Point2Blob(CObject, 120);
|
||||
}
|
||||
|
||||
|
||||
//获取副本
|
||||
function GetDgn() {
|
||||
local Ret = Sq_BattleField_GetDgn(C_Object);
|
||||
if (Ret) {
|
||||
return Dungeon(Ret);
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
function add_monster_APC_AI(index) {
|
||||
Sq_CallFunc(S_Ptr("0x8301D76"), "void", ["pointer", "int"], C_Object, index);
|
||||
}
|
||||
|
||||
//获取深渊派对情况
|
||||
function GetHellDifficulty() {
|
||||
local Sia = Sq_Point2Blob(C_Object, 500);
|
||||
Sia.seek(460);
|
||||
return (Sia.readn('c'))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
文件名:BlobExClass.nut
|
||||
路径:BaseClass/BaseTool/BlobExClass.nut
|
||||
创建日期:2024-05-07 17:34
|
||||
文件用途:拓展的Blob类
|
||||
*/
|
||||
class BlobEx extends blob {
|
||||
|
||||
constructor(BaseBlob) {
|
||||
base.constructor(BaseBlob.len());
|
||||
writeblob(BaseBlob);
|
||||
}
|
||||
|
||||
function writeblob(B) {
|
||||
base.writeblob(B);
|
||||
seek(0);
|
||||
}
|
||||
|
||||
function GetUShort() {
|
||||
return readn('s');
|
||||
}
|
||||
|
||||
function GetShort() {
|
||||
return readn('w');
|
||||
}
|
||||
|
||||
function charPtrToInt(arr) {
|
||||
local value = ((arr[0]) << 0) |
|
||||
((arr[1]) << 8) |
|
||||
((arr[2]) << 16) |
|
||||
((arr[3]) << 24);
|
||||
return value;
|
||||
}
|
||||
|
||||
// function GetInt() {
|
||||
// local CurTPos = tell();
|
||||
// local Ret = charPtrToInt([this[CurTPos], this[CurTPos + 1], this[CurTPos + 2], this[CurTPos + 3]]);
|
||||
// seek(4, 'c');
|
||||
// return Ret;
|
||||
// }
|
||||
|
||||
function GetInt() {
|
||||
return readn('i');
|
||||
}
|
||||
|
||||
function Get256() {
|
||||
local Buf = readn('c');
|
||||
return (256.0 + Buf.tofloat()) % 256.0;
|
||||
}
|
||||
|
||||
function GetFloat() {
|
||||
return readn('f');
|
||||
}
|
||||
|
||||
function GetString(count) {
|
||||
return stream_myreadstring(count);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class blobex extends blob {
|
||||
|
||||
//-----------------Metamethods--------------------//
|
||||
function _typeof() {
|
||||
return "blobex";
|
||||
}
|
||||
//-----------------Metamethods--------------------//
|
||||
|
||||
constructor(arg) {
|
||||
//通过blob构造
|
||||
if (typeof arg == "blob") {
|
||||
base.constructor(arg.len());
|
||||
writeblob(arg);
|
||||
}
|
||||
//直接构造
|
||||
else {
|
||||
base.constructor(arg);
|
||||
}
|
||||
}
|
||||
|
||||
function writeblob(B) {
|
||||
base.writeblob(B);
|
||||
seek(0);
|
||||
}
|
||||
|
||||
function GetUShort() {
|
||||
return readn('w');
|
||||
}
|
||||
|
||||
function GetShort() {
|
||||
return readn('s');
|
||||
}
|
||||
|
||||
function charPtrToInt(arr) {
|
||||
local value = ((arr[0]) << 0) |
|
||||
((arr[1]) << 8) |
|
||||
((arr[2]) << 16) |
|
||||
((arr[3]) << 24);
|
||||
return value;
|
||||
}
|
||||
|
||||
function GetInt() {
|
||||
local CurTPos = tell();
|
||||
local Ret = charPtrToInt([this[CurTPos], this[CurTPos + 1], this[CurTPos + 2], this[CurTPos + 3]]);
|
||||
seek(4, 'c');
|
||||
return Ret;
|
||||
}
|
||||
|
||||
function Get256() {
|
||||
local Buf = readn('c');
|
||||
return (256.0 + Buf.tofloat()) % 256.0;
|
||||
}
|
||||
|
||||
function GetFloat() {
|
||||
return readn('f');
|
||||
}
|
||||
|
||||
function GetString(count) {
|
||||
return stream_myreadstring(count);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
文件名:ConfigClass.nut
|
||||
路径:Dps_A/BaseClass/ConfigClass/ConfigClass.nut
|
||||
创建日期:2025-03-29 23:54
|
||||
文件用途:全局配置类
|
||||
*/
|
||||
class _GlobalConfig {
|
||||
ConfigMap = null;
|
||||
|
||||
|
||||
constructor() {
|
||||
//在全局中注册自己
|
||||
getroottable().GlobalConfig <- this;
|
||||
|
||||
ConfigMap = {};
|
||||
|
||||
local WorkPath = "/dp_s/OfficialConfig";
|
||||
local FilePaths = sq_GetListFiles(WorkPath);
|
||||
foreach(FilePath in FilePaths) {
|
||||
try {
|
||||
LoadJson(FilePath, WorkPath + "/" + FilePath);
|
||||
} catch (exception) {
|
||||
error("加载配置文件失败:" + FilePath);
|
||||
}
|
||||
}
|
||||
//开启热重载配置
|
||||
GameManager.OpenHotFix("/dp_s/OfficialConfig");
|
||||
}
|
||||
|
||||
function LoadJson(FilePath, Path) {
|
||||
local Config = sq_ReadJsonFile(Path);
|
||||
if (Config) {
|
||||
ConfigMap.rawset(FilePath, Config);
|
||||
}
|
||||
}
|
||||
|
||||
function Get(ConfigName) {
|
||||
if (ConfigMap.rawin(ConfigName)) {
|
||||
return ConfigMap[ConfigName];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
文件名:DungeonClass.nut
|
||||
路径:Dps_A/BaseClass/DungeonClass/DungeonClass.nut
|
||||
创建日期:2024-04-27 20:31
|
||||
文件用途:副本对象类
|
||||
*/
|
||||
|
||||
class Dungeon extends Base_C_Object {
|
||||
Attribute = null;
|
||||
constructor(CObject) {
|
||||
base.constructor(CObject);
|
||||
Attribute = Sq_Point2Blob(CObject, 120);
|
||||
}
|
||||
|
||||
|
||||
//获取副本ID
|
||||
function GetId() {
|
||||
return Sq_Dungeon_GetIdex(C_Object);
|
||||
}
|
||||
|
||||
//获取副本名称
|
||||
function GetName() {
|
||||
return Sq_CallFunc(S_Ptr("0x081455A6"), "string", ["pointer"], this.C_Object);
|
||||
}
|
||||
|
||||
//获取副本等级
|
||||
function GetMinLevel() {
|
||||
return Sq_CallFunc(S_Ptr("0x0814559A"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,365 @@
|
|||
/*
|
||||
文件名:GameManagerClass.nut
|
||||
路径:BaseClass/GameManagerClass/GameManagerClass.nut
|
||||
创建日期:2024-04-09 20:30
|
||||
文件用途:游戏管理器类
|
||||
*/
|
||||
class GameManager extends Base_C_Object {
|
||||
|
||||
constructor() {
|
||||
local CObject = Sq_GameManager_GameManager();
|
||||
base.constructor(CObject);
|
||||
}
|
||||
|
||||
function GetParty() {
|
||||
local C_Party = Sq_GameManager_GetParty(C_Object);
|
||||
return Party(C_Party);
|
||||
}
|
||||
|
||||
//设置游戏最大等级
|
||||
function SetGameMaxLevel(MaxLevel) {
|
||||
NativePointer("0x8360C38").add(3).writeU8(MaxLevel);
|
||||
NativePointer("0x8360C76").add(3).writeU8(MaxLevel);
|
||||
NativePointer("0x8360CC1").add(3).writeU8(MaxLevel);
|
||||
NativePointer("0x84EF802").add(3).writeU8(MaxLevel);
|
||||
NativePointer("0x858F002").add(3).writeU8(MaxLevel);
|
||||
NativePointer("0x865A5C0").add(1).writeU8(MaxLevel);
|
||||
NativePointer("0x865B091").add(4).writeU8(MaxLevel);
|
||||
NativePointer("0x865B757").add(4).writeU8(MaxLevel);
|
||||
NativePointer("0x8662F53").add(2).writeU8(MaxLevel);
|
||||
NativePointer("0x86630F0").add(3).writeU8(MaxLevel);
|
||||
NativePointer("0x86638F4").add(2).writeU8(MaxLevel);
|
||||
NativePointer("0x8665D24").add(4).writeU8(MaxLevel);
|
||||
NativePointer("0x8666E9A").add(2).writeU8(MaxLevel);
|
||||
NativePointer("0x866A4A6").add(2).writeU8(MaxLevel);
|
||||
NativePointer("0x866A657").add(2).writeU8(MaxLevel);
|
||||
NativePointer("0x866A926").add(3).writeU8(MaxLevel);
|
||||
NativePointer("0x866A93F").add(2).writeU8(MaxLevel);
|
||||
NativePointer("0x867AEC0").add(2).writeU8(MaxLevel);
|
||||
NativePointer("0x8689D48").add(3).writeU8(MaxLevel);
|
||||
NativePointer("0x868fecb").add(3).writeU8(MaxLevel);
|
||||
NativePointer("0x868fed4").add(6).writeU8(MaxLevel);
|
||||
}
|
||||
|
||||
//设置装备解锁需要时间
|
||||
function SetItemLockTime(UnLockTime) {
|
||||
NativePointer("0x854242F").writeInt(UnLockTime);
|
||||
NativePointer("0x8402D29").writeInt(UnLockTime);
|
||||
NativePointer("0x854274D").writeInt(UnLockTime);
|
||||
NativePointer("0x854296F").writeInt(UnLockTime);
|
||||
NativePointer("0x8542AD9").writeInt(UnLockTime);
|
||||
NativePointer("0x8542BDE").writeInt(UnLockTime);
|
||||
NativePointer("0x85F3EB9").writeInt(UnLockTime);
|
||||
Cb_CItemLock_DoItemUnlock_Leave_Func["DPS装备解锁定时器注册任务"] <- function(args) {
|
||||
if (UnLockTime > 0) {
|
||||
local SUser = User(args[1]);
|
||||
Timer.SetTimeOut(function(SUser) {
|
||||
Sq_CallFunc(S_Ptr("0x08646912"), "int", ["pointer"], SUser.C_Object);
|
||||
}, UnLockTime * 1000, SUser)
|
||||
} else {
|
||||
Sq_CallFunc(S_Ptr("0x08646912"), "int", ["pointer"], SUser.C_Object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//开启创建鼠标妹
|
||||
function OpenCreateJob_CreatorMage() {
|
||||
Sq_WriteByteArr(S_Ptr("0x81C029F"), [0xf]);
|
||||
}
|
||||
|
||||
//开启获得魔法封印时自动解除魔法封印
|
||||
function OpenRandomAutomaticUnblocking() {
|
||||
Cb_User_Insert_Item_Leave_Func.Rindro <- function(args) {
|
||||
local SUser = User(NativePointer(args[0]).readPointer());
|
||||
local InvenObj = SUser.GetInven();
|
||||
local idx = args.pop();
|
||||
if (idx > 0) {
|
||||
local inven_item = InvenObj.GetSlot(1, idx);
|
||||
local item_id = inven_item.GetIndex();
|
||||
local pvfitem = PvfItem.GetPvfItemById(item_id);
|
||||
//如果是魔法封印装备
|
||||
if (!pvfitem || !pvfitem.IsRandomOption()) {
|
||||
return;
|
||||
}
|
||||
local random_option = NativePointer(inven_item.C_Object).add(37);
|
||||
if (random_option.readU32() || random_option.add(4).readU32() || random_option.add(8).readShort()) {
|
||||
return;
|
||||
}
|
||||
NativePointer(inven_item.C_Object).add(37).add(0).writeU8(1);
|
||||
}
|
||||
SUser.SendItemSpace(0);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//开启自动热重载
|
||||
function OpenHotFix(Path = "/dp_s/MyProject") {
|
||||
if (getroottable()._HotFixPath_.rawin(Path)) return;
|
||||
print("DP-S开启自动重载脚本功能,重载目录为: " + Path + " .");
|
||||
print("请注意如果你不处于DP-S开发环境,请关闭此功能,以免对性能造成影响");
|
||||
Sq_AutoReload(Path);
|
||||
getroottable()._HotFixPath_.rawset(Path, true);
|
||||
}
|
||||
|
||||
//开启时装镶嵌
|
||||
function FixAvatarUseJewel() {
|
||||
//时装镶嵌修复
|
||||
_AvatarUseJewel_Object <- AvatarUseJewel();
|
||||
}
|
||||
|
||||
//开启装备镶嵌
|
||||
function FixEquipUseJewel() {
|
||||
//装备镶嵌修复
|
||||
_EquimentUseJewel_Object <- EquimentUseJewel();
|
||||
}
|
||||
|
||||
//修复14技能
|
||||
function Fix14Skill() {
|
||||
Sq_WriteByteArr(S_Ptr("0x08604B1E"), [0x83, 0x7D, 0xEC, 0x07]);
|
||||
Sq_WriteByteArr(S_Ptr("0x08604B8C"), [0xC7, 0x45, 0xE4, 0x08, 0x00, 0x00, 0x00]);
|
||||
Sq_WriteByteArr(S_Ptr("0x08604A09"), [0x83, 0x7D, 0x0C, 0x07]);
|
||||
Sq_WriteByteArr(S_Ptr("0x086050b1"), [0xC7, 0x45, 0xEC, 0x08, 0x00, 0x00, 0x00]);
|
||||
Sq_WriteByteArr(S_Ptr("0x0860511c"), [0xC7, 0x45, 0xE8, 0x08, 0x00, 0x00, 0x00]);
|
||||
Sq_WriteByteArr(S_Ptr("0x08608D7B"), [0x83, 0xF8, 0x0B]);
|
||||
}
|
||||
|
||||
//修复下线卡城镇
|
||||
function FixSaveTown() {
|
||||
Cb_Set_Charac_Info_Detail_Enter_Func._FixSaveTown_ <- function(arg) {
|
||||
local curArea = NativePointer(arg[3]).add(34).readS8();
|
||||
if (curArea == 12 || curArea == 13) {
|
||||
NativePointer(arg[3]).add(34).writeS8(11);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//修复绝望金币异常
|
||||
function FixDespairGold() {
|
||||
getroottable()._FixDespairGold_Data_ <- {};
|
||||
Cb_UseAncientDungeonItems_Enter_Func._FixDespairGold_ <- function(arg) {
|
||||
local DgnObj = Dungeon(arg[1]);
|
||||
local DgnIndex = DgnObj.GetId();
|
||||
if ((DgnIndex >= 11008) && (DgnIndex <= 11107)) {
|
||||
getroottable()._FixDespairGold_Data_[arg[1]] <- NativePointer(arg[1]).add(2044).readS8();
|
||||
NativePointer(arg[1]).add(2044).writeS8(0);
|
||||
}
|
||||
}
|
||||
Cb_UseAncientDungeonItems_Leave_Func._FixDespairGold_ <- function(arg) {
|
||||
local DgnObj = Dungeon(arg[1]);
|
||||
local DgnIndex = DgnObj.GetId();
|
||||
if ((DgnIndex >= 11008) && (DgnIndex <= 11107)) {
|
||||
//绝望之塔 不再扣除金币
|
||||
NativePointer(arg[1]).add(2044).writeS8(getroottable()._FixDespairGold_Data_[arg[1]]);
|
||||
getroottable()._FixDespairGold_Data_.rawdelete(arg[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//修复绝望之塔通关后可以用门票继续进入
|
||||
function FixDespairDungeon() {
|
||||
/*
|
||||
Cb_User_CheckDailyScheduleTime_Leave_Func.DailyScheduleTime <- function(args) {
|
||||
return true;
|
||||
};
|
||||
|
||||
Cb_User_TOD_UserState_getLastClearTime_Leave_Func.DailyScheduleTime <- function(args) {
|
||||
return 0;
|
||||
};
|
||||
*/
|
||||
}
|
||||
|
||||
//修改交易金币上限
|
||||
function FixGlodTradeDaily(Count) {
|
||||
local Arr = [0xB8];
|
||||
local BlobObj = blob(0);
|
||||
BlobObj.writen(Count, 'i');
|
||||
for (local i = 0; i< 4; i++) {
|
||||
Arr.append(BlobObj[i]);
|
||||
}
|
||||
Arr.append(0x90);
|
||||
Sq_WriteByteArr(S_Ptr("0x86464CE"), Arr);
|
||||
}
|
||||
|
||||
//+13免刷新
|
||||
function Fix_13Upgrade() {
|
||||
Haker.LoadHook("0x080FC850", ["pointer", "pointer", "pointer", "int", "void"],
|
||||
function(args) {
|
||||
return null;
|
||||
},
|
||||
function(args) {
|
||||
local Pos = NativePointer(args[2]).add(27).readU16();
|
||||
local SUser = User(args[1]);
|
||||
SUser.SendUpdateItemList(1, 0, Pos);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
//副本可丢弃品级 传入一个值 3为神器
|
||||
function FixDungeonDropGrade(Level) {
|
||||
NativePointer("0x085A69F2").writeS8(Level);
|
||||
}
|
||||
|
||||
//邮件去除验证
|
||||
function FixEmailRemovalVerification() {
|
||||
local HexCode = Haker.AsmGenerateMcd(
|
||||
"mov eax, 0x0",
|
||||
"ret");
|
||||
Sq_WriteByteArr(S_Ptr("0x0868A51A"), HexCode);
|
||||
}
|
||||
|
||||
//修复拍卖行消耗品上架,设置最大总价,建议值2E
|
||||
function Fix_Auction_Regist_Item() {
|
||||
Haker.LoadHook("0x08213E40", ["int", "int", "bool"],
|
||||
function(args) {
|
||||
return null;
|
||||
},
|
||||
function(args) {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
//开启独立掉落模式 此功能需要传入一个回调函数 参数为 //角色 怪物ID 怪物等级 坐标X 坐标Y 副本名称 副本ID 副本等级 副本难度 深渊标识
|
||||
function OpenIndependenceDropMode(Func) {
|
||||
Haker.LoadHook("0x0830BC78", ["pointer", "pointer", "pointer", "pointer", "pointer", "int"],
|
||||
function(args) {
|
||||
return null;
|
||||
},
|
||||
function(args) {
|
||||
getroottable().LashKillMonsterId <- NativePointer(args[2]).add(3 * 4).readInt();
|
||||
return null;
|
||||
});
|
||||
|
||||
Haker.LoadHook("0x085A27E8", ["pointer", "pointer", "short", "pointer", "pointer", "int"],
|
||||
function(args) {
|
||||
return null;
|
||||
},
|
||||
function(args) {
|
||||
//杀死怪物了 要判断是否掉落
|
||||
//获取队伍
|
||||
local PartyObj = Party(args[0]);
|
||||
//获取战斗对象
|
||||
local BattleFieldObj = PartyObj.GetBattleField();
|
||||
//怪物等级
|
||||
local MonsterLevel = NativePointer(args[4]).add(2605).readInt();
|
||||
//怪物ID
|
||||
local MonsterId = getroottable().LashKillMonsterId;
|
||||
//坐标
|
||||
local Xpos = NativePointer(args[4]).add(2596).readShort();
|
||||
local Ypos = NativePointer(args[4]).add(2598).readShort();
|
||||
local DgnObj = BattleFieldObj.GetDgn();
|
||||
//副本名称
|
||||
local DgnName = DgnObj.GetName();
|
||||
//副本ID
|
||||
local DgnId = DgnObj.GetId();
|
||||
//副本等级
|
||||
local DgnLevel = DgnObj.GetMinLevel();
|
||||
//副本难度
|
||||
local DgnDiff = Sq_CallFunc(S_Ptr("0x080F981C"), "int", ["pointer"], BattleFieldObj.C_Object);
|
||||
//深渊标识
|
||||
local HellDiff = BattleFieldObj.GetHellDifficulty();
|
||||
|
||||
for (local i = 0; i< 4; i++) {
|
||||
local SUser = PartyObj.GetUser(i);
|
||||
if (SUser) {
|
||||
//角色 怪物ID 怪物等级 坐标X 坐标Y 副本名称 副本ID 副本等级 副本难度 深渊标识
|
||||
Func(SUser, MonsterId, MonsterLevel, Xpos, Ypos, DgnName, DgnId, DgnLevel, DgnDiff, HellDiff);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
//修改独立掉落原逻辑为不掉落
|
||||
local HexCode = Haker.AsmGenerateMcd(
|
||||
"mov eax, 0x830CD5D",
|
||||
"jmp eax");
|
||||
Haker.InsertCode("0x830CCE2", HexCode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//开启防入侵
|
||||
function FixInvasion() {
|
||||
NativePointer("0x81DB4EA").writeS8(0x00);
|
||||
|
||||
getroottable()._TH_MEM_K_ <- Memory.allocUtf8String("/"); {
|
||||
local _Execve_Address = Module.getExportByName(null, "execve");
|
||||
local _Execve_Address_Str = "" + _Execve_Address;
|
||||
_Execve_Address_Str = _Execve_Address_Str.slice(_Execve_Address_Str.find("0x0x") + 2, -1);
|
||||
|
||||
Haker.LoadHook(_Execve_Address_Str, ["pointer", "pointer", "pointer", "int"],
|
||||
function(args) {
|
||||
args[0] = getroottable()._TH_MEM_K_.C_Object;
|
||||
return args;
|
||||
},
|
||||
function(args) {
|
||||
return -1;
|
||||
});
|
||||
} {
|
||||
local _System_Address = Module.getExportByName(null, "system");
|
||||
local _System_Address_Str = "" + _System_Address;
|
||||
_System_Address_Str = _System_Address_Str.slice(_System_Address_Str.find("0x0x") + 2, -1);
|
||||
|
||||
Haker.LoadHook(_System_Address_Str, ["pointer", "int"],
|
||||
function(args) {
|
||||
args[0] = getroottable()._TH_MEM_K_.C_Object;
|
||||
return args;
|
||||
},
|
||||
function(args) {
|
||||
return -1;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//修复练习模式
|
||||
function FixPracticemode() {
|
||||
Sq_WriteByteArr(S_Ptr("0x81C820A"), [0xE9, 0xC6, 0x0, 0x0, 0x0, 0x90]);
|
||||
}
|
||||
|
||||
//修复黑暗武士技能
|
||||
function FixDarkWarriorSkillBar()
|
||||
{
|
||||
Cb_CheckMoveComboSkillSlot_Leave_Func["DPSOFF"] <- function (args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//热重载
|
||||
getroottable()._HotFixPath_ <- {};
|
||||
getroottable()._HotFixPathChangeTimer_ <- {};
|
||||
|
||||
function _Reload_List_Write_(Path) {
|
||||
local NowTime = Sq_GetTimestampString().slice(-9).tointeger();
|
||||
if (!getroottable()._HotFixPathChangeTimer_.rawin(Path) || NowTime - getroottable()._HotFixPathChangeTimer_[Path] > 1000) {
|
||||
Timer.SetTimeOut(function() {
|
||||
//判断类型
|
||||
if (endswith(Path, ".nut")) {
|
||||
dofile(Path);
|
||||
print("位于 [" + Path + "] 的脚本已重载")
|
||||
} else if (endswith(Path, ".json")) {
|
||||
try {
|
||||
local PArr = split(Path, "/");
|
||||
local RealName = PArr[PArr.len() - 1];
|
||||
|
||||
//在载入新配置之前 先拿到旧配置保存起来
|
||||
local OldConfig = GlobalConfig.Get(RealName);
|
||||
GlobalConfig.LoadJson(RealName, Path);
|
||||
|
||||
//如果存在项目 并且有重载入口 则调用重载入口
|
||||
if (_GlobalOfficial_Project.ReloadProjectMap.rawin(RealName)) {
|
||||
local ProjectStartFunc = _GlobalOfficial_Project.ReloadProjectMap[RealName];
|
||||
if (getroottable().rawin(ProjectStartFunc + "Reload_")) {
|
||||
getroottable()[ProjectStartFunc + "Reload_"](OldConfig);
|
||||
}
|
||||
}
|
||||
print("位于 [" + Path + "] 的配置已重载");
|
||||
|
||||
} catch (exception) {
|
||||
|
||||
}
|
||||
}
|
||||
}, 500)
|
||||
getroottable()._HotFixPathChangeTimer_[Path] <- NowTime;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
文件名:HackerClass.nut
|
||||
路径:Dps_A/BaseClass/HackerClass/HackerClass.nut
|
||||
创建日期:2024-09-22 11:33
|
||||
文件用途:黑客类
|
||||
*/
|
||||
class _Hacker {
|
||||
HookTable = null;
|
||||
|
||||
HookJumpMemoryTable = null;
|
||||
|
||||
__strtol__function__address__ = null;
|
||||
|
||||
NextReturnAddress = null;
|
||||
CpuContext = null;
|
||||
|
||||
constructor() {
|
||||
HookTable = {};
|
||||
HookJumpMemoryTable = {};
|
||||
}
|
||||
|
||||
|
||||
function UnLoadHook(AddressStr) {
|
||||
Sq_DeHookFunc(HookTable[AddressStr]);
|
||||
}
|
||||
|
||||
function LoadHook(AddressStr, ArgumentArr, EnterFunc, LeaveFunc) {
|
||||
//如果已经HOOK过 需要先卸载原来的HOOK
|
||||
if (HookTable.rawin(AddressStr)) {
|
||||
UnLoadHook(AddressStr);
|
||||
print("地址: " + AddressStr + " 已经装载了Hook,本次操作将会卸载之前的Hook在执行。")
|
||||
}
|
||||
|
||||
local Controler = Sq_HookFunc(S_Ptr(AddressStr), ArgumentArr, EnterFunc, LeaveFunc);
|
||||
HookTable.rawset(AddressStr, Controler);
|
||||
}
|
||||
|
||||
|
||||
function HexStringToInt(Str) {
|
||||
if (!__strtol__function__address__) __strtol__function__address__ = Module.getExportByName(null, "strtol");
|
||||
local Ret = Sq_CallFunc(__strtol__function__address__, "int", ["pointer", "pointer", "int"], Memory.allocUtf8String(Str).C_Object, Memory.alloc(0), 16);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
function AsmGenerateMcd(...) {
|
||||
local CodeArr = [];
|
||||
local CurCode = "";
|
||||
try {
|
||||
foreach(Str in vargv) {
|
||||
CurCode = Str;
|
||||
local Code = Sq_Asmjit_Compile(Str);
|
||||
CodeArr.extend(Code);
|
||||
}
|
||||
} catch (exception) {
|
||||
error("汇编代码有误,错误行: " + CurCode);
|
||||
}
|
||||
return CodeArr;
|
||||
}
|
||||
|
||||
function InsertCode(Address, Code) {
|
||||
//置入代码的大小
|
||||
local CodeSize = Code.len();
|
||||
//申请一块内存
|
||||
local MemBuffer = Memory.alloc(CodeSize);
|
||||
//记录
|
||||
HookJumpMemoryTable.rawset(Address, MemBuffer);
|
||||
//写入置入的代码
|
||||
MemBuffer.writeByteArray(Code);
|
||||
|
||||
//计算偏移
|
||||
local Offset = Sq_PointerOperationPointer(MemBuffer.C_Object, Sq_PointerOperation(S_Ptr(Address), 5, "+"), "-");
|
||||
local Str = "" + Offset;
|
||||
Str = Str.slice(Str.find("0x") + 4, -1);
|
||||
local JumpCodeArr = [0xE9];
|
||||
for (local i = 0; i< 4; i++) {
|
||||
local Index = -2 * (i + 1);
|
||||
local StrBuffer = "0x" + (Str.slice(Index).slice(0, 2));
|
||||
JumpCodeArr.push(HexStringToInt(StrBuffer));
|
||||
}
|
||||
Sq_WriteByteArr(S_Ptr(Address), JumpCodeArr);
|
||||
}
|
||||
}
|
||||
|
||||
function _Haker_SetNextReturnAddress(Address) {
|
||||
local Buffer = "" + Address;
|
||||
Haker.NextReturnAddress = Buffer.slice(Buffer.find("0x") + 2, -1);
|
||||
|
||||
}
|
||||
function _Haker_SetCpuContext(tab) {
|
||||
Haker.CpuContext = tab;
|
||||
|
||||
}
|
||||
//初始化Hacker
|
||||
Haker <- _Hacker();
|
||||
|
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
文件名:HttpClass.nut
|
||||
路径:Dps_A/BaseClass/HttpClass/HttpClass.nut
|
||||
创建日期:2024-10-16 18:41
|
||||
文件用途:Http类
|
||||
*/
|
||||
class Http {
|
||||
|
||||
Host = null;
|
||||
Service = null;
|
||||
|
||||
constructor(host, service = "http") {
|
||||
Host = host;
|
||||
Service = service;
|
||||
}
|
||||
|
||||
// 辅助函数:将参数表编码为 URL 编码字符串
|
||||
function _EncodeParams(params) {
|
||||
local encoded = "";
|
||||
foreach(key, value in params) {
|
||||
if (encoded.len() > 0) encoded += "&";
|
||||
encoded += key + "=" + value; // 需要实现 urlencode
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
|
||||
function Request(Type, Url, Content) {
|
||||
local RequestBuffer = Type + " " + Url + " HTTP/1.1\r\nHost: " + Host + "\r\n";
|
||||
|
||||
if (Content) {
|
||||
RequestBuffer += "Content-Length: " + Content.len() + "\r\n";
|
||||
RequestBuffer += "Content-Type: application/x-www-form-urlencoded\r\n";
|
||||
RequestBuffer += "\r\n";
|
||||
RequestBuffer += Content;
|
||||
} else {
|
||||
RequestBuffer += "Connection: close\r\n\r\n";
|
||||
}
|
||||
return Sq_CreateHttp(Host, Service, RequestBuffer);
|
||||
}
|
||||
|
||||
// 发送请求
|
||||
function Post(Url, params = null) {
|
||||
local content = null;
|
||||
if (params != null && typeof params == "table") {
|
||||
content = _EncodeParams(params); // 编码参数
|
||||
}
|
||||
return Request("POST", Url, content);
|
||||
}
|
||||
|
||||
function Get(Url, Content = null) {
|
||||
return Request("GET", Url, Content);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function xorEncryptDecrypt(BlobObj, Key) {
|
||||
local Arr = [];
|
||||
for (local i = 0; i< BlobObj.len(); i++) {
|
||||
local currentKeyChar = Key[i % Key.len()];
|
||||
Arr.push(BlobObj[i] ^ currentKeyChar);
|
||||
}
|
||||
return Arr;
|
||||
}
|
||||
|
||||
function base64_encode(input) {
|
||||
local base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
local inputLength = input.len();
|
||||
local i = 0;
|
||||
local j = 0;
|
||||
local charArray3 = array(3);
|
||||
local charArray4 = array(4);
|
||||
local encoded = "";
|
||||
|
||||
while (inputLength--) {
|
||||
charArray3[i++] = input[inputLength];
|
||||
if (i == 3) {
|
||||
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.slice(charArray4[i], charArray4[i] + 1);
|
||||
}
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j< 3; j++) {
|
||||
charArray3[j] = 0;
|
||||
}
|
||||
|
||||
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 (j = 0; j< i + 1; j++) {
|
||||
encoded += base64_chars.slice(charArray4[j], charArray4[j] + 1);
|
||||
}
|
||||
|
||||
while (i++<3) {
|
||||
encoded += "=";
|
||||
}
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
|
||||
function AsciiToStr(code) {
|
||||
local str = Memory.alloc(1);
|
||||
str.writeS8(code);
|
||||
return str.readUtf8String();
|
||||
}
|
||||
|
||||
function base64_decode(input) {
|
||||
local base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
local base64_map = {};
|
||||
for (local i = 0; i< base64_chars.len(); i++) {
|
||||
local key = base64_chars.slice(i, i + 1);
|
||||
if (key != "=") {
|
||||
base64_map[key] <- i;
|
||||
}
|
||||
}
|
||||
local inputLength = input.len();
|
||||
local i = 0;
|
||||
local j = 0;
|
||||
local charArray4 = array(4);
|
||||
local charArray3 = array(3);
|
||||
local decoded = [];
|
||||
|
||||
while (inputLength--) {
|
||||
if (input.slice(i, i + 1) == "=") {
|
||||
charArray4[j++] = 0;
|
||||
} else {
|
||||
charArray4[j++] = base64_map[input.slice(i, i + 1)];
|
||||
}
|
||||
i++;
|
||||
if (j == 4) {
|
||||
charArray3[0] = (charArray4[0] << 2) + ((charArray4[1] & 0x30) >> 4);
|
||||
charArray3[1] = ((charArray4[1] & 0xf) << 4) + ((charArray4[2] & 0x3c) >> 2);
|
||||
charArray3[2] = ((charArray4[2] & 0x3) << 6) + charArray4[3];
|
||||
|
||||
for (j = 0; j< 3; j++) {
|
||||
decoded.push(charArray3[j]);
|
||||
}
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (j) {
|
||||
for (local k = j; k< 4; k++) {
|
||||
charArray4[k] = 0;
|
||||
}
|
||||
|
||||
charArray3[0] = (charArray4[0] << 2) + ((charArray4[1] & 0x30) >> 4);
|
||||
charArray3[1] = ((charArray4[1] & 0xf) << 4) + ((charArray4[2] & 0x3c) >> 2);
|
||||
charArray3[2] = ((charArray4[2] & 0x3) << 6) + charArray4[3];
|
||||
|
||||
for (local k = 0; k< j - 1; k++) {
|
||||
decoded.push(charArray3[k]);
|
||||
}
|
||||
}
|
||||
local ret = decoded.reverse();
|
||||
ret.remove(0);
|
||||
ret.push(0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
function GetMyIp() {
|
||||
local Hb = Http("tnedi.me");
|
||||
return Hb.Get("/");
|
||||
}
|
||||
|
||||
function generateRandomString(length) {
|
||||
local alphabet = "abcdefghijklmnopqrstuvwxyz";
|
||||
local result = "";
|
||||
for (local i = 0; i< length; i++) {
|
||||
local randomIndex = math.random(0, alphabet.len() - 1);
|
||||
result += alphabet.get(randomIndex);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function Blend(str1, str2) {
|
||||
local alphabet = "abcdefghijklmnopqrstuvwxyz";
|
||||
local result = "";
|
||||
local len = MathClass.getMin(str1.len(), str2.len());
|
||||
for (local i = 0; i< len; i++) {
|
||||
print((str1[i].tointeger() % alphabet.len()) - 1);
|
||||
result += alphabet.slice((str1[i].tointeger() % alphabet.len()), (str1[i].tointeger() % alphabet.len()) + 1) + str2[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function Encode(Str, Key = [9, 4, 7, 3, 3, 0, 6, 7, 0]) {
|
||||
local StrPointer = Memory.allocUtf8String(Str);
|
||||
local BlobObj = StrPointer.readBinary(Str.len());
|
||||
local str = "";
|
||||
for (local i = 0; i< BlobObj.len(); i++) {
|
||||
str += BlobObj[i].tostring();
|
||||
str += ","
|
||||
}
|
||||
print(str)
|
||||
// printT(BlobObj);
|
||||
local Arr = xorEncryptDecrypt(BlobObj, Key);
|
||||
local encodestr = base64_encode(Arr);
|
||||
return encodestr;
|
||||
}
|
||||
|
||||
function Decode(Str, Key = [9, 4, 7, 3, 3, 0, 6, 7, 0]) {
|
||||
local StrArr = base64_decode(Str);
|
||||
local Arr = xorEncryptDecrypt(StrArr, Key);
|
||||
local str = "";
|
||||
for (local i = 0; i< Arr.len(); i++) {
|
||||
str += Arr[i].tostring();
|
||||
str += ","
|
||||
}
|
||||
print(str)
|
||||
local StrPointer = Memory.alloc(Arr.len());
|
||||
StrPointer.writeByteArray(Arr);
|
||||
local decodestr = StrPointer.readUtf8String(Arr.len());
|
||||
return decodestr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class HttpResponse {
|
||||
C_Object = null;
|
||||
constructor(obj) {
|
||||
C_Object = obj;
|
||||
}
|
||||
|
||||
function Write(Msg) {
|
||||
local response = "HTTP/1.1 200 OK\r\n";
|
||||
if (typeof Msg == "table") {
|
||||
response += "Content-Type: application/json\r\n";
|
||||
local JsonString = Json.Encode(Msg);
|
||||
response += "Content-Length: " + JsonString.len() + "\r\n";
|
||||
response += "\r\n";
|
||||
response += JsonString;
|
||||
}
|
||||
else if(typeof Msg == "string") {
|
||||
response += "Content-Type: text/plain\r\n";
|
||||
response += "Content-Length: " + Msg.len() + "\r\n";
|
||||
response += "\r\n";
|
||||
response += Msg;
|
||||
}
|
||||
|
||||
Sq_HttpServerResponse_Write(C_Object, response);
|
||||
}
|
||||
}
|
||||
|
||||
class HttpServer {
|
||||
|
||||
Host = null;
|
||||
Service = null;
|
||||
|
||||
//处理函数
|
||||
Handler = null;
|
||||
|
||||
|
||||
constructor(host, service = "80") {
|
||||
Host = host;
|
||||
Service = service;
|
||||
|
||||
getroottable()["HttpServer_" + Host + "_" + Service] <- this;
|
||||
}
|
||||
|
||||
function Listen(Func) {
|
||||
//记录处理函数
|
||||
Handler = Func;
|
||||
|
||||
local success = Sq_CreateHttpServer(Host, Service, this);
|
||||
if (success) {
|
||||
::print("Server started successfully.");
|
||||
} else {
|
||||
::print("Failed to start server.");
|
||||
}
|
||||
}
|
||||
|
||||
function Event(SocketObject, Msg) {
|
||||
Timer.SetTimeOut(Handler, 1, HttpResponse(SocketObject), Msg);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
文件名:IOClass.nut
|
||||
路径:Dps_A/BaseClass/IOClass/IOClass.nut
|
||||
创建日期:2024-09-19 14:13
|
||||
文件用途:IO流类
|
||||
*/
|
||||
class IO extends Base_C_Object {
|
||||
_Fopen_Address = Module.getExportByName(null, "fopen");
|
||||
_Fgetc_Address = Module.getExportByName(null, "fgetc");
|
||||
_Fputc_Address = Module.getExportByName(null, "fputc");
|
||||
_Fgets_Address = Module.getExportByName(null, "fgets");
|
||||
_Fputs_Address = Module.getExportByName(null, "fputs");
|
||||
_Fread_Address = Module.getExportByName(null, "fread");
|
||||
_Fwrite_Address = Module.getExportByName(null, "fwrite");
|
||||
_Fclose_Address = Module.getExportByName(null, "fclose");
|
||||
_Fseek_Address = Module.getExportByName(null, "fseek");
|
||||
_Ftell_Address = Module.getExportByName(null, "ftell");
|
||||
_Rewind_Address = Module.getExportByName(null, "rewind");
|
||||
_Flush_Address = Module.getExportByName(null, "fflush");
|
||||
|
||||
|
||||
|
||||
Pos = 0;
|
||||
|
||||
constructor(FileName, Modes) {
|
||||
local FileObj = Sq_CallFunc(_Fopen_Address, "pointer", ["pointer", "pointer"], Str_Ptr(FileName), Str_Ptr(Modes));
|
||||
if (FileObj) {
|
||||
base.constructor(FileObj);
|
||||
} else throw("文件打开错误! FileName: " + FileName);
|
||||
}
|
||||
|
||||
//读取一行
|
||||
function ReadLine() {
|
||||
local Buffer = Memory.alloc(256);
|
||||
local RetFlag = Sq_CallFunc(_Fgets_Address, "pointer", ["pointer", "int", "pointer"], Buffer.C_Object, 256, this.C_Object);
|
||||
if (RetFlag)
|
||||
return Buffer.readUtf8String();
|
||||
}
|
||||
|
||||
//读取一个
|
||||
function Read() {
|
||||
local RetFlag = Sq_CallFunc(_Fgetc_Address, "char", ["pointer"], this.C_Object);
|
||||
if (RetFlag) {
|
||||
return RetFlag;
|
||||
}
|
||||
}
|
||||
|
||||
//读取指定大小
|
||||
function ReadBuffer(size) {
|
||||
local Buffer = Memory.alloc(size);
|
||||
local RetFlag = Sq_CallFunc(_Fread_Address, "int", ["pointer", "int", "int", "pointer"], Buffer.C_Object, 1, size, this.C_Object);
|
||||
if (RetFlag > 0) {
|
||||
return {
|
||||
count = RetFlag,
|
||||
str = Buffer.readUtf8String(RetFlag)
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
count = 0,
|
||||
str = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//写入字符串
|
||||
function Write(Str) {
|
||||
local Buffer = Memory.allocUtf8String(Str);
|
||||
Sq_CallFunc(_Fputs_Address, "int", ["pointer", "pointer"], Buffer.C_Object, this.C_Object);
|
||||
}
|
||||
|
||||
function Flush() {
|
||||
Sq_CallFunc(_Flush_Address, "pointer", ["pointer"], this.C_Object);
|
||||
}
|
||||
|
||||
//关闭文件
|
||||
function Close() {
|
||||
Sq_CallFunc(_Fclose_Address, "pointer", ["pointer"], this.C_Object);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
文件名:InvenClass.nut
|
||||
路径:BaseClass/InvenClass/InvenClass.nut
|
||||
创建日期:2024-04-18 13:26
|
||||
文件用途:背包类
|
||||
*/
|
||||
class Inven extends Base_C_Object {
|
||||
|
||||
static INVENTORY_TYPE_BODY = 0; //身上穿的装备(0-26)
|
||||
static INVENTORY_TYPE_ITEM = 1; //物品栏(0-311)
|
||||
static INVENTORY_TYPE_AVARTAR = 2; //时装栏(0-104)
|
||||
static INVENTORY_TYPE_CREATURE = 3; //宠物装备(0-241)
|
||||
|
||||
|
||||
SUser = null;
|
||||
|
||||
constructor(CObject, gSUser) {
|
||||
base.constructor(CObject);
|
||||
SUser = gSUser;
|
||||
}
|
||||
|
||||
//获得槽位里的对象
|
||||
function GetSlot(Type, Slot) {
|
||||
local P = Sq_Inven_GetItem(this.C_Object, Type, Slot);
|
||||
if (P) {
|
||||
return Item(P);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//通过ID获得槽位
|
||||
function GetSlotById(Idx) {
|
||||
return Sq_Inven_GetItemById(this.C_Object, Idx);
|
||||
}
|
||||
|
||||
|
||||
//获取金币
|
||||
function GetMoney() {
|
||||
return Sq_CallFunc(S_Ptr("0x817a188"), "int", ["pointer"], SUser.C_Object);
|
||||
}
|
||||
|
||||
|
||||
//检查背包是否拥有指定数量的指定道具
|
||||
function CheckItemCount(ItemId, ItemCount) {
|
||||
if (ItemId == 0) {
|
||||
//检查金币
|
||||
local Money = Sq_CallFunc(S_Ptr("0x817a188"), "int", ["pointer"], SUser.C_Object);
|
||||
if (Money >= ItemCount) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (ItemId == -1) {
|
||||
//检查点券
|
||||
if (SUser.GetCera() >= ItemCount) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (ItemId == -2) {
|
||||
//检查代币券
|
||||
if (SUser.GetCeraPoint() >= ItemCount) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
local SlotIdx = GetSlotById(ItemId);
|
||||
if (SlotIdx != -1) {
|
||||
local SlotItem = GetSlot(1, SlotIdx);
|
||||
if (SlotItem) {
|
||||
if (SlotItem.GetType() != "装备") {
|
||||
if (SlotItem.GetAdd_Info() >= ItemCount) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//检查背包是否拥有指定表的道具及数量
|
||||
function CheckArrItemCount(T) {
|
||||
local Flag = true;
|
||||
foreach(value in T) {
|
||||
if (!CheckItemCount(value.Id, value.Count)) Flag = false;
|
||||
}
|
||||
return Flag;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//销毁背包中指定表的道具及数量
|
||||
function DeleteArrItemCount(T) {
|
||||
foreach(value in T) {
|
||||
local Slot = GetSlotById(value.Id);
|
||||
Sq_Inven_RemoveItemFormCount(this.C_Object, 1, Slot, value.Count, 10, 1);
|
||||
SUser.SendUpdateItemList(1, 0, Slot);
|
||||
}
|
||||
}
|
||||
|
||||
//销毁背包中指定的道具及数量
|
||||
function DeleteItemCount(Id, Count) {
|
||||
if (Id == 0) {
|
||||
//处理金币
|
||||
SUser.RechargeMoney(-Count);
|
||||
return 1;
|
||||
}
|
||||
if (Id == -1) {
|
||||
//处理点券
|
||||
SUser.GetCera(-Count);
|
||||
return 1;
|
||||
}
|
||||
if (Id == -2) {
|
||||
//处理代币券
|
||||
SUser.RechargeCeraPoint(-Count);
|
||||
return 1;
|
||||
}
|
||||
|
||||
local Slot = GetSlotById(Id);
|
||||
local Ret = Sq_Inven_RemoveItemFormCount(this.C_Object, 1, Slot, Count, 10, 1);
|
||||
SUser.SendUpdateItemList(1, 0, Slot);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
//获取时装管理器
|
||||
function GetAvatarItemMgr() {
|
||||
return Sq_CallFunc(S_Ptr("0x80DD576"), "pointer", ["pointer"], this.C_Object);
|
||||
}
|
||||
|
||||
|
||||
//销毁背包中指定表的道具及数量 并且需要格子匹配
|
||||
function DeleteArrItemCountRindro(T) {
|
||||
foreach(value in T) {
|
||||
if (value.type == 0) {
|
||||
//如果是装备 按格子直接删除
|
||||
Sq_Inven_RemoveItemFormCount(this.C_Object, 1, value.pos, value.count, 10, 1);
|
||||
SUser.SendUpdateItemList(1, 0, value.pos);
|
||||
} else {
|
||||
//如果不是装备 走原逻辑
|
||||
local Slot = GetSlotById(value.itemId);
|
||||
Sq_Inven_RemoveItemFormCount(this.C_Object, 1, Slot, value.count, 10, 1);
|
||||
SUser.SendUpdateItemList(1, 0, Slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//检查背包是否拥有指定表的道具及数量 并且是装备还要匹配格子
|
||||
function CheckArrItemCountRindro(T) {
|
||||
local Flag = true;
|
||||
foreach(value in T) {
|
||||
if (!CheckItemCountRindro(value.itemId, value.count, value.pos)) Flag = false;
|
||||
}
|
||||
return Flag;
|
||||
}
|
||||
|
||||
//检查背包是否拥有指定数量的指定道具
|
||||
function CheckItemCountRindro(ItemId, ItemCount, Slot) {
|
||||
if (ItemId == 0) {
|
||||
//检查金币
|
||||
local Money = Sq_CallFunc(S_Ptr("0x817a188"), "int", ["pointer"], SUser.C_Object);
|
||||
if (Money >= ItemCount) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (ItemId == -1) {
|
||||
//检查点券
|
||||
if (SUser.GetCera() >= ItemCount) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (ItemId == -2) {
|
||||
//检查代币券
|
||||
if (SUser.GetCeraPoint() >= ItemCount) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
local SlotIdx = GetSlotById(ItemId);
|
||||
if (SlotIdx != -1) {
|
||||
local SlotItem = GetSlot(1, SlotIdx);
|
||||
if (SlotItem) {
|
||||
if (SlotItem.GetType() != "装备") {
|
||||
if (SlotItem.GetAdd_Info() >= ItemCount) return true;
|
||||
} else {
|
||||
//如果是装备 检查格子所在的道具id
|
||||
local ItemId2 = GetSlot(1, Slot).GetIndex();
|
||||
//如果这个格子的道具id就是发来的id 那么返回true
|
||||
if (ItemId == ItemId2) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
文件名:ItemClass.nut
|
||||
路径:BaseClass/ItemClass/ItemClass.nut
|
||||
创建日期:2024-04-18 15:10
|
||||
文件用途:Item类
|
||||
*/
|
||||
class Item extends Base_C_Object {
|
||||
Attribute = null;
|
||||
IsEmpty = false;
|
||||
constructor(CObject) {
|
||||
base.constructor(CObject);
|
||||
Attribute = Sq_Point2Blob(CObject, 62);
|
||||
if (GetIndex() == 0) IsEmpty = true;
|
||||
}
|
||||
|
||||
function Output() {
|
||||
local Str = "[";
|
||||
foreach(Value in Attribute) {
|
||||
Str = format("%s%02X", Str, Value);
|
||||
Str += ",";
|
||||
}
|
||||
Str += "]";
|
||||
print(Str);
|
||||
}
|
||||
|
||||
//获取类型
|
||||
function GetType() {
|
||||
Attribute.seek(1);
|
||||
local Type = Attribute.readn('c');
|
||||
switch (Type) {
|
||||
case 1:
|
||||
return "装备";
|
||||
case 2:
|
||||
return "消耗品";
|
||||
case 3:
|
||||
return "材料";
|
||||
case 4:
|
||||
return "任务材料";
|
||||
case 10:
|
||||
return "副职业材料";
|
||||
default:
|
||||
return "未知类型";
|
||||
}
|
||||
}
|
||||
|
||||
//获取编号
|
||||
function GetIndex() {
|
||||
Attribute.seek(2);
|
||||
return Attribute.readn('i');
|
||||
}
|
||||
//获取品级
|
||||
function GetRarity() {
|
||||
return Sq_CallFunc(S_Ptr("0x80F12D6"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
//设置编号
|
||||
function SetIndex(Index) {
|
||||
Attribute.seek(2);
|
||||
Attribute.writen(Index, 'i');
|
||||
}
|
||||
|
||||
//获取强化等级
|
||||
function GetUpgrade() {
|
||||
Attribute.seek(6);
|
||||
return Attribute.readn('c');
|
||||
}
|
||||
//设置强化等级
|
||||
function SetUpgrade(Level) {
|
||||
Attribute.seek(6);
|
||||
Attribute.writen(Level, 'c');
|
||||
}
|
||||
|
||||
//获取 品级 或 数量 如果是装备就是品级 如果是其他就是数量
|
||||
function GetAdd_Info() {
|
||||
Attribute.seek(7);
|
||||
return Attribute.readn('i');
|
||||
}
|
||||
//设置 品级 或 数量 如果是装备就是品级 如果是其他就是数量
|
||||
function SetAdd_Info(Value) {
|
||||
Attribute.seek(7);
|
||||
Attribute.writen(Value, 'i');
|
||||
}
|
||||
|
||||
//获取耐久度
|
||||
function GetDurable() {
|
||||
Attribute.seek(11);
|
||||
return Attribute.readn('c');
|
||||
}
|
||||
//设置耐久度
|
||||
function SetDurable(Value) {
|
||||
Attribute.seek(11);
|
||||
Attribute.writen(Value, 'c');
|
||||
}
|
||||
|
||||
//获取增幅属性
|
||||
function GetAmplification() {
|
||||
Attribute.seek(17);
|
||||
return Attribute.readn('w');
|
||||
}
|
||||
//设置增幅属性
|
||||
function SetAmplification(Value) {
|
||||
Attribute.seek(17);
|
||||
Attribute.writen(Value, 'w');
|
||||
}
|
||||
|
||||
//获取锻造属性
|
||||
function GetForging() {
|
||||
Attribute.seek(51);
|
||||
return Attribute.readn('c');
|
||||
}
|
||||
//设置锻造属性
|
||||
function SetForging(Value) {
|
||||
Attribute.seek(51);
|
||||
Attribute.writen(Value, 'c');
|
||||
}
|
||||
|
||||
//获取附魔属性
|
||||
function GetEnchanting() {
|
||||
Attribute.seek(13);
|
||||
return Attribute.readn('i');
|
||||
}
|
||||
//设置附魔属性
|
||||
function SetEnchanting(Value) {
|
||||
Attribute.seek(13);
|
||||
Attribute.writen(Value, 'i');
|
||||
}
|
||||
|
||||
|
||||
//获取交易类型
|
||||
function GetAttachType() {
|
||||
return Sq_CallFunc(S_Ptr("0x80F12E2"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
|
||||
//刷写装备数据
|
||||
function Flush() {
|
||||
Sq_WriteBlobToAddress(C_Object, Attribute);
|
||||
}
|
||||
|
||||
//检查是否为空
|
||||
// function IsEmpty() {
|
||||
// return Sq_CallFunc(S_Ptr("0x811ED66"), "int", ["pointer"], this.C_Object);
|
||||
// }
|
||||
|
||||
//删除道具
|
||||
function Delete() {
|
||||
Sq_Inven_RemoveItem(C_Object);
|
||||
this = null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//是否可打包
|
||||
function Item::IsPackagble() {
|
||||
return Sq_CallFunc(S_Ptr("0x828B5B4"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
//Json类
|
||||
class Json {
|
||||
//Table 转 String
|
||||
function Encode(Table) {
|
||||
return JSONEncoder.encode(Table);
|
||||
}
|
||||
|
||||
function OldDecode(Str) {
|
||||
Str = sq_DecondeJson(Str);
|
||||
local NewStr = "local _M = " + Str + ";\n return _M;\n";
|
||||
local Func = compilestring(NewStr);
|
||||
|
||||
try {
|
||||
local Obj = Func();
|
||||
if (typeof(Obj) == "table" || typeof(Obj) == "array") {
|
||||
if (Obj.len() > 0) return Obj;
|
||||
}
|
||||
} catch (exception) {
|
||||
|
||||
}
|
||||
|
||||
error("错误的包内容: " + NewStr);
|
||||
return null;
|
||||
}
|
||||
//String 转 Table
|
||||
function Decode(Str) {
|
||||
|
||||
return JSONParser.parse(Str);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,702 @@
|
|||
/**
|
||||
* JSON Parser
|
||||
*
|
||||
* @author Mikhail Yurasov <mikhail@electricimp.com>
|
||||
* @package JSONParser
|
||||
* @version 1.0.1
|
||||
*/
|
||||
|
||||
/**
|
||||
* JSON Parser
|
||||
* @package JSONParser
|
||||
*/
|
||||
class JSONParser {
|
||||
|
||||
// should be the same for all components within JSONParser package
|
||||
static version = "1.0.1";
|
||||
|
||||
/**
|
||||
* Parse JSON string into data structure
|
||||
*
|
||||
* @param {string} str
|
||||
* @param {function({string} value[, "number"|"string"])|null} converter
|
||||
* @return {*}
|
||||
*/
|
||||
function parse(str, converter = null) {
|
||||
|
||||
local state;
|
||||
local stack = []
|
||||
local container;
|
||||
local key;
|
||||
local value;
|
||||
|
||||
// actions for string tokens
|
||||
local string = {
|
||||
go = function() {
|
||||
state = "ok";
|
||||
},
|
||||
firstokey = function() {
|
||||
key = value;
|
||||
state = "colon";
|
||||
},
|
||||
okey = function() {
|
||||
key = value;
|
||||
state = "colon";
|
||||
},
|
||||
ovalue = function() {
|
||||
value = this._convert(value, "string", converter);
|
||||
state = "ocomma";
|
||||
}.bindenv(this),
|
||||
firstavalue = function() {
|
||||
value = this._convert(value, "string", converter);
|
||||
state = "acomma";
|
||||
}.bindenv(this),
|
||||
avalue = function() {
|
||||
value = this._convert(value, "string", converter);
|
||||
state = "acomma";
|
||||
}.bindenv(this)
|
||||
};
|
||||
|
||||
// the actions for number tokens
|
||||
local number = {
|
||||
go = function() {
|
||||
state = "ok";
|
||||
},
|
||||
ovalue = function() {
|
||||
value = this._convert(value, "number", converter);
|
||||
state = "ocomma";
|
||||
}.bindenv(this),
|
||||
firstavalue = function() {
|
||||
value = this._convert(value, "number", converter);
|
||||
state = "acomma";
|
||||
}.bindenv(this),
|
||||
avalue = function() {
|
||||
value = this._convert(value, "number", converter);
|
||||
state = "acomma";
|
||||
}.bindenv(this)
|
||||
};
|
||||
|
||||
// action table
|
||||
// describes where the state machine will go from each given state
|
||||
local action = {
|
||||
|
||||
"{": {
|
||||
go = function() {
|
||||
stack.push({
|
||||
state = "ok"
|
||||
});
|
||||
container = {};
|
||||
state = "firstokey";
|
||||
},
|
||||
ovalue = function() {
|
||||
stack.push({
|
||||
container = container,
|
||||
state = "ocomma",
|
||||
key = key
|
||||
});
|
||||
container = {};
|
||||
state = "firstokey";
|
||||
},
|
||||
firstavalue = function() {
|
||||
stack.push({
|
||||
container = container,
|
||||
state = "acomma"
|
||||
});
|
||||
container = {};
|
||||
state = "firstokey";
|
||||
},
|
||||
avalue = function() {
|
||||
stack.push({
|
||||
container = container,
|
||||
state = "acomma"
|
||||
});
|
||||
container = {};
|
||||
state = "firstokey";
|
||||
}
|
||||
},
|
||||
|
||||
"}": {
|
||||
firstokey = function() {
|
||||
local pop = stack.pop();
|
||||
value = container;
|
||||
container = ("container" in pop) ? pop.container : null;
|
||||
key = ("key" in pop) ? pop.key : null;
|
||||
state = pop.state;
|
||||
},
|
||||
ocomma = function() {
|
||||
local pop = stack.pop();
|
||||
container[key] <- value;
|
||||
value = container;
|
||||
container = ("container" in pop) ? pop.container : null;
|
||||
key = ("key" in pop) ? pop.key : null;
|
||||
state = pop.state;
|
||||
}
|
||||
},
|
||||
|
||||
"[": {
|
||||
go = function() {
|
||||
stack.push({
|
||||
state = "ok"
|
||||
});
|
||||
container = [];
|
||||
state = "firstavalue";
|
||||
},
|
||||
ovalue = function() {
|
||||
stack.push({
|
||||
container = container,
|
||||
state = "ocomma",
|
||||
key = key
|
||||
});
|
||||
container = [];
|
||||
state = "firstavalue";
|
||||
},
|
||||
firstavalue = function() {
|
||||
stack.push({
|
||||
container = container,
|
||||
state = "acomma"
|
||||
});
|
||||
container = [];
|
||||
state = "firstavalue";
|
||||
},
|
||||
avalue = function() {
|
||||
stack.push({
|
||||
container = container,
|
||||
state = "acomma"
|
||||
});
|
||||
container = [];
|
||||
state = "firstavalue";
|
||||
}
|
||||
},
|
||||
|
||||
"]": {
|
||||
firstavalue = function() {
|
||||
local pop = stack.pop();
|
||||
value = container;
|
||||
container = ("container" in pop) ? pop.container : null;
|
||||
key = ("key" in pop) ? pop.key : null;
|
||||
state = pop.state;
|
||||
},
|
||||
acomma = function() {
|
||||
local pop = stack.pop();
|
||||
container.push(value);
|
||||
value = container;
|
||||
container = ("container" in pop) ? pop.container : null;
|
||||
key = ("key" in pop) ? pop.key : null;
|
||||
state = pop.state;
|
||||
}
|
||||
},
|
||||
|
||||
":": {
|
||||
colon = function() {
|
||||
// Check if the key already exists
|
||||
// NOTE previous code used 'if (key in container)...'
|
||||
// but this finds table ('container') member methods too
|
||||
local err = false;
|
||||
foreach(akey, avalue in container) {
|
||||
if (akey == key) err = true;
|
||||
break
|
||||
}
|
||||
if (err) throw "Duplicate key \"" + key + "\"";
|
||||
state = "ovalue";
|
||||
}
|
||||
},
|
||||
|
||||
",": {
|
||||
ocomma = function() {
|
||||
container[key] <- value;
|
||||
state = "okey";
|
||||
},
|
||||
acomma = function() {
|
||||
container.push(value);
|
||||
state = "avalue";
|
||||
}
|
||||
},
|
||||
|
||||
"true": {
|
||||
go = function() {
|
||||
value = true;
|
||||
state = "ok";
|
||||
},
|
||||
ovalue = function() {
|
||||
value = true;
|
||||
state = "ocomma";
|
||||
},
|
||||
firstavalue = function() {
|
||||
value = true;
|
||||
state = "acomma";
|
||||
},
|
||||
avalue = function() {
|
||||
value = true;
|
||||
state = "acomma";
|
||||
}
|
||||
},
|
||||
|
||||
"false": {
|
||||
go = function() {
|
||||
value = false;
|
||||
state = "ok";
|
||||
},
|
||||
ovalue = function() {
|
||||
value = false;
|
||||
state = "ocomma";
|
||||
},
|
||||
firstavalue = function() {
|
||||
value = false;
|
||||
state = "acomma";
|
||||
},
|
||||
avalue = function() {
|
||||
value = false;
|
||||
state = "acomma";
|
||||
}
|
||||
},
|
||||
|
||||
"null": {
|
||||
go = function() {
|
||||
value = null;
|
||||
state = "ok";
|
||||
},
|
||||
ovalue = function() {
|
||||
value = null;
|
||||
state = "ocomma";
|
||||
},
|
||||
firstavalue = function() {
|
||||
value = null;
|
||||
state = "acomma";
|
||||
},
|
||||
avalue = function() {
|
||||
value = null;
|
||||
state = "acomma";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
state = "go";
|
||||
stack = [];
|
||||
|
||||
// current tokenizeing position
|
||||
local start = 0;
|
||||
|
||||
try {
|
||||
|
||||
local
|
||||
result,
|
||||
token,
|
||||
tokenizer = _JSONTokenizer();
|
||||
|
||||
while (token = tokenizer.nextToken(str, start)) {
|
||||
|
||||
if ("ptfn" == token.type) {
|
||||
// punctuation/true/false/null
|
||||
action[token.value][state]();
|
||||
} else if ("number" == token.type) {
|
||||
// number
|
||||
value = token.value;
|
||||
number[state]();
|
||||
} else if ("string" == token.type) {
|
||||
// string
|
||||
value = tokenizer.unescape(token.value);
|
||||
string[state]();
|
||||
}
|
||||
|
||||
start += token.length;
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
state = e;
|
||||
}
|
||||
|
||||
// check is the final state is not ok
|
||||
// or if there is somethign left in the str
|
||||
if (state != "ok" || regexp("[^\\s]").capture(str, start)) {
|
||||
local min = @(a, b) a< b ? a : b;
|
||||
local near = str.slice(start, min(str.len(), start + 10));
|
||||
throw "JSON Syntax Error near `" + near + "`";
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert strings/numbers
|
||||
* Uses custom converter function
|
||||
*
|
||||
* @param {string} value
|
||||
* @param {string} type
|
||||
* @param {function|null} converter
|
||||
*/
|
||||
function _convert(value, type, converter) {
|
||||
if ("function" == typeof converter) {
|
||||
|
||||
// # of params for converter function
|
||||
|
||||
local parametercCount = 2;
|
||||
|
||||
// .getinfos() is missing on ei platform
|
||||
if ("getinfos" in converter) {
|
||||
parametercCount = converter.getinfos().parameters.len() -
|
||||
1 /* "this" is also included */ ;
|
||||
}
|
||||
|
||||
if (parametercCount == 1) {
|
||||
return converter(value);
|
||||
} else if (parametercCount == 2) {
|
||||
return converter(value, type);
|
||||
} else {
|
||||
throw "Error: converter function must take 1 or 2 parameters"
|
||||
}
|
||||
|
||||
} else if ("number" == type) {
|
||||
return (value.find(".") == null && value.find("e") == null && value.find("E") == null) ? value.tointeger() : value.tofloat();
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON Tokenizer
|
||||
* @package JSONParser
|
||||
*/
|
||||
class _JSONTokenizer {
|
||||
|
||||
_ptfnRegex = null;
|
||||
_numberRegex = null;
|
||||
_stringRegex = null;
|
||||
_ltrimRegex = null;
|
||||
_unescapeRegex = null;
|
||||
|
||||
constructor() {
|
||||
// punctuation/true/false/null
|
||||
this._ptfnRegex = regexp("^(?:\\,|\\:|\\[|\\]|\\{|\\}|true|false|null)");
|
||||
|
||||
// numbers
|
||||
this._numberRegex = regexp("^(?:\\-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)");
|
||||
|
||||
// strings
|
||||
this._stringRegex = regexp("^(?:\\\"((?:[^\\r\\n\\t\\\\\\\"]|\\\\(?:[\"\\\\\\/trnfb]|u[0-9a-fA-F]{4}))*)\\\")");
|
||||
|
||||
// ltrim pattern
|
||||
this._ltrimRegex = regexp("^[\\s\\t\\n\\r]*");
|
||||
|
||||
// string unescaper tokenizer pattern
|
||||
this._unescapeRegex = regexp("\\\\(?:(?:u\\d{4})|[\\\"\\\\/bfnrt])");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get next available token
|
||||
* @param {string} str
|
||||
* @param {integer} start
|
||||
* @return {{type,value,length}|null}
|
||||
*/
|
||||
function nextToken(str, start = 0) {
|
||||
|
||||
local
|
||||
m,
|
||||
type,
|
||||
token,
|
||||
value,
|
||||
length,
|
||||
whitespaces;
|
||||
|
||||
// count # of left-side whitespace chars
|
||||
whitespaces = this._leadingWhitespaces(str, start);
|
||||
start += whitespaces;
|
||||
|
||||
if (m = this._ptfnRegex.capture(str, start)) {
|
||||
// punctuation/true/false/null
|
||||
value = str.slice(m[0].begin, m[0].end);
|
||||
type = "ptfn";
|
||||
} else if (m = this._numberRegex.capture(str, start)) {
|
||||
// number
|
||||
value = str.slice(m[0].begin, m[0].end);
|
||||
type = "number";
|
||||
} else if (m = this._stringRegex.capture(str, start)) {
|
||||
// string
|
||||
value = str.slice(m[1].begin, m[1].end);
|
||||
type = "string";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
token = {
|
||||
type = type,
|
||||
value = value,
|
||||
length = m[0].end - m[0].begin + whitespaces
|
||||
};
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count # of left-side whitespace chars
|
||||
* @param {string} str
|
||||
* @param {integer} start
|
||||
* @return {integer} number of leading spaces
|
||||
*/
|
||||
function _leadingWhitespaces(str, start) {
|
||||
local r = this._ltrimRegex.capture(str, start);
|
||||
|
||||
if (r) {
|
||||
return r[0].end - r[0].begin;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// unesacape() replacements table
|
||||
_unescapeReplacements = {
|
||||
"b": "\b",
|
||||
"f": "\f",
|
||||
"n": "\n",
|
||||
"r": "\r",
|
||||
"t": "\t"
|
||||
};
|
||||
|
||||
/**
|
||||
* Unesacape string escaped per JSON standard
|
||||
* @param {string} str
|
||||
* @return {string}
|
||||
*/
|
||||
function unescape(str) {
|
||||
|
||||
local start = 0;
|
||||
local res = "";
|
||||
|
||||
while (start< str.len()) {
|
||||
local m = this._unescapeRegex.capture(str, start);
|
||||
|
||||
if (m) {
|
||||
local token = str.slice(m[0].begin, m[0].end);
|
||||
|
||||
// append chars before match
|
||||
local pre = str.slice(start, m[0].begin);
|
||||
res += pre;
|
||||
|
||||
if (token.len() == 6) {
|
||||
// unicode char in format \uhhhh, where hhhh is hex char code
|
||||
// todo: convert \uhhhh chars
|
||||
res += token;
|
||||
} else {
|
||||
// escaped char
|
||||
// @see http://www.json.org/
|
||||
local char = token.slice(1);
|
||||
|
||||
if (char in this._unescapeReplacements) {
|
||||
res += this._unescapeReplacements[char];
|
||||
} else {
|
||||
res += char;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// append the rest of the source string
|
||||
res += str.slice(start);
|
||||
break;
|
||||
}
|
||||
|
||||
start = m[0].end;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Copyright (c) 2017 Electric Imp
|
||||
// This file is licensed under the MIT License
|
||||
// http://opensource.org/licenses/MIT
|
||||
|
||||
class JSONEncoder {
|
||||
|
||||
static VERSION = "2.0.0";
|
||||
|
||||
// max structure depth
|
||||
// anything above probably has a cyclic ref
|
||||
static _maxDepth = 32;
|
||||
|
||||
/**
|
||||
* Encode value to JSON
|
||||
* @param {table|array|*} value
|
||||
* @returns {string}
|
||||
*/
|
||||
function encode(value) {
|
||||
return this._encode(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {table|array} val
|
||||
* @param {integer=0} depth – current depth level
|
||||
* @private
|
||||
*/
|
||||
function _encode(val, depth = 0) {
|
||||
|
||||
// detect cyclic reference
|
||||
if (depth > this._maxDepth) {
|
||||
throw "Possible cyclic reference";
|
||||
}
|
||||
|
||||
local
|
||||
r = "",
|
||||
s = "",
|
||||
i = 0;
|
||||
|
||||
switch (typeof val) {
|
||||
|
||||
case "table":
|
||||
case "class":
|
||||
s = "";
|
||||
|
||||
// serialize properties, but not functions
|
||||
foreach(k, v in val) {
|
||||
if (typeof v != "function") {
|
||||
s += ",\"" + k + "\":" + this._encode(v, depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
s = s.len() > 0 ? s.slice(1) : s;
|
||||
r += "{" + s + "}";
|
||||
break;
|
||||
|
||||
case "array":
|
||||
s = "";
|
||||
|
||||
for (i = 0; i< val.len(); i++) {
|
||||
s += "," + this._encode(val[i], depth + 1);
|
||||
}
|
||||
|
||||
s = (i > 0) ? s.slice(1) : s;
|
||||
r += "[" + s + "]";
|
||||
break;
|
||||
|
||||
case "integer":
|
||||
case "float":
|
||||
case "bool":
|
||||
r += val;
|
||||
break;
|
||||
|
||||
case "null":
|
||||
r += "null";
|
||||
break;
|
||||
|
||||
case "instance":
|
||||
|
||||
if ("_serializeRaw" in val && typeof val._serializeRaw == "function") {
|
||||
|
||||
// include value produced by _serializeRaw()
|
||||
r += val._serializeRaw().tostring();
|
||||
|
||||
} else if ("_serialize" in val && typeof val._serialize == "function") {
|
||||
|
||||
// serialize instances by calling _serialize method
|
||||
r += this._encode(val._serialize(), depth + 1);
|
||||
|
||||
} else {
|
||||
|
||||
s = "";
|
||||
|
||||
try {
|
||||
|
||||
// iterate through instances which implement _nexti meta-method
|
||||
foreach(k, v in val) {
|
||||
s += ",\"" + k + "\":" + this._encode(v, depth + 1);
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
|
||||
// iterate through instances w/o _nexti
|
||||
// serialize properties, but not functions
|
||||
foreach(k, v in val.getclass()) {
|
||||
if (typeof v != "function") {
|
||||
s += ",\"" + k + "\":" + this._encode(val[k], depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
s = s.len() > 0 ? s.slice(1) : s;
|
||||
r += "{" + s + "}";
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "blob":
|
||||
// This is a workaround for a known bug:
|
||||
// on device side Blob.tostring() returns null
|
||||
// (instaead of an empty string)
|
||||
r += "\"" + (val.len() ? this._escape(val.tostring()) : "") + "\"";
|
||||
break;
|
||||
|
||||
// strings and all other
|
||||
default:
|
||||
r += "\"" + this._escape(val.tostring()) + "\"";
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape strings according to http://www.json.org/ spec
|
||||
* @param {string} str
|
||||
*/
|
||||
function _escape(str) {
|
||||
local res = "";
|
||||
|
||||
for (local i = 0; i< str.len(); i++) {
|
||||
|
||||
local ch1 = (str[i] & 0xFF);
|
||||
|
||||
if ((ch1 & 0x80) == 0x00) {
|
||||
// 7-bit Ascii
|
||||
|
||||
ch1 = format("%c", ch1);
|
||||
|
||||
if (ch1 == "\"") {
|
||||
res += "\\\"";
|
||||
} else if (ch1 == "\\") {
|
||||
res += "\\\\";
|
||||
} else if (ch1 == "/") {
|
||||
res += "\\/";
|
||||
} else if (ch1 == "\b") {
|
||||
res += "\\b";
|
||||
} else if (ch1 == "\f") {
|
||||
res += "\\f";
|
||||
} else if (ch1 == "\n") {
|
||||
res += "\\n";
|
||||
} else if (ch1 == "\r") {
|
||||
res += "\\r";
|
||||
} else if (ch1 == "\t") {
|
||||
res += "\\t";
|
||||
} else if (ch1 == "\0") {
|
||||
res += "\\u0000";
|
||||
} else {
|
||||
res += ch1;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ((ch1 & 0xE0) == 0xC0) {
|
||||
// 110xxxxx = 2-byte unicode
|
||||
local ch2 = (str[++i] & 0xFF);
|
||||
res += format("%c%c", ch1, ch2);
|
||||
} else if ((ch1 & 0xF0) == 0xE0) {
|
||||
// 1110xxxx = 3-byte unicode
|
||||
local ch2 = (str[++i] & 0xFF);
|
||||
local ch3 = (str[++i] & 0xFF);
|
||||
res += format("%c%c%c", ch1, ch2, ch3);
|
||||
} else if ((ch1 & 0xF8) == 0xF0) {
|
||||
// 11110xxx = 4 byte unicode
|
||||
local ch2 = (str[++i] & 0xFF);
|
||||
local ch3 = (str[++i] & 0xFF);
|
||||
local ch4 = (str[++i] & 0xFF);
|
||||
res += format("%c%c%c%c", ch1, ch2, ch3, ch4);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
文件名:LogClass.nut
|
||||
路径:Dps_A/BaseClass/LogClass/LogClass.nut
|
||||
创建日期:2024-10-10 11:35
|
||||
文件用途:日志类
|
||||
*/
|
||||
class Log {
|
||||
|
||||
//linux创建文件夹
|
||||
// function api_mkdir(path) {
|
||||
// var path_ptr = Memory.allocUtf8String(path);
|
||||
// if (opendir(path_ptr))
|
||||
// return true;
|
||||
// return mkdir(path_ptr, 0x1FF);
|
||||
// }
|
||||
_opendir_Address = Module.getExportByName(null, "opendir");
|
||||
_mkdir_Address = Module.getExportByName(null, "mkdir");
|
||||
|
||||
|
||||
Logger = null;
|
||||
LoggerBuffer = null;
|
||||
|
||||
Coro = null;
|
||||
|
||||
constructor(Info) {
|
||||
Logger = {};
|
||||
LoggerBuffer = {};
|
||||
|
||||
local DirPath = Str_Ptr("/dp_s/log");
|
||||
if (!(Sq_CallFunc(_opendir_Address, "int", ["pointer"], DirPath))) {
|
||||
Sq_CallFunc(_mkdir_Address, "int", ["pointer", "int"], DirPath, 0x1FF);
|
||||
}
|
||||
|
||||
//打开文件输出句柄
|
||||
foreach(Level, Path in Info) {
|
||||
|
||||
try {
|
||||
local Io = IO(Path, "a");
|
||||
Logger[Level] <- Io;
|
||||
LoggerBuffer[Level] <- [];
|
||||
} catch (exception) {
|
||||
error("日志器初始化失败");
|
||||
}
|
||||
}
|
||||
|
||||
getroottable()._Logger_Object_ <- this;
|
||||
Cb_timer_dispatch_Func.rawset("__System__Logger__Event", Update.bindenv(this));
|
||||
|
||||
Coro = newthread(__Write__.bindenv(this));
|
||||
}
|
||||
|
||||
|
||||
function Put(Type, Message) {
|
||||
if (getroottable().rawin("_Logger_Object_")) {
|
||||
if (getroottable()._Logger_Object_.Logger.rawin(Type)) {
|
||||
getroottable()._Logger_Object_.LoggerBuffer[Type].push(Message);
|
||||
// getroottable()._Logger_Object_.Logger[Type].Write(Message);
|
||||
// getroottable()._Logger_Object_.Logger[Type].Flush();
|
||||
} else {
|
||||
error("未知的日志类型");
|
||||
}
|
||||
} else {
|
||||
error("未初始化日志器");
|
||||
}
|
||||
}
|
||||
|
||||
function __Write__() {
|
||||
local ret = suspend("no");
|
||||
foreach(Type, MessageArr in LoggerBuffer) {
|
||||
for (local i = 0; i< MessageArr.len(); i++) {
|
||||
Logger[Type].Write(MessageArr[i]);
|
||||
Logger[Type].Flush();
|
||||
MessageArr.remove(i);
|
||||
i--;
|
||||
suspend("no");
|
||||
}
|
||||
}
|
||||
return "yes";
|
||||
}
|
||||
|
||||
function Update() {
|
||||
local susparam = "noq";
|
||||
if (Coro.getstatus() == "idle") susparam = Coro.call();
|
||||
else if (Coro.getstatus() == "suspended") susparam = Coro.wakeup();
|
||||
|
||||
if (susparam == "yes") {
|
||||
Coro = newthread(__Write__.bindenv(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
文件名:MD5Class.nut
|
||||
路径:Dps_A/BaseClass/MD5Class/MD5Class.nut
|
||||
创建日期:2024-09-20 00:06
|
||||
文件用途:MD5类
|
||||
*/
|
||||
class MD5 {
|
||||
MD5_Init_ptr = Module.getExportByName(null, "MD5_Init");
|
||||
MD5_Update_ptr = Module.getExportByName(null, "MD5_Update");
|
||||
MD5_Final_ptr = Module.getExportByName(null, "MD5_Final");
|
||||
|
||||
function MD5_Init(Ctx) {
|
||||
Sq_CallFunc(MD5_Init_ptr, "void", ["pointer"], Ctx);
|
||||
}
|
||||
|
||||
function MD5_Update(Ctx, Buffer, Size) {
|
||||
Sq_CallFunc(MD5_Update_ptr, "void", ["pointer", "pointer", "int"], Ctx, Buffer, Size);
|
||||
}
|
||||
|
||||
function MD5_Final(Ctx, Result) {
|
||||
Sq_CallFunc(MD5_Final_ptr, "void", ["pointer", "pointer"], Ctx, Result);
|
||||
}
|
||||
|
||||
function base64_encode(input) {
|
||||
local base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
local inputLength = input.len();
|
||||
local i = 0;
|
||||
local j = 0;
|
||||
local charArray3 = array(3);
|
||||
local charArray4 = array(4);
|
||||
local encoded = "";
|
||||
|
||||
while (inputLength--) {
|
||||
charArray3[i++] = input[inputLength];
|
||||
if (i == 3) {
|
||||
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]];
|
||||
}
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j< 3; j++) {
|
||||
charArray3[j] = 0;
|
||||
}
|
||||
|
||||
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 (j = 0; j< i + 1; j++) {
|
||||
encoded += base64_chars[charArray4[j]];
|
||||
}
|
||||
|
||||
while (i++<3) {
|
||||
encoded += "=";
|
||||
}
|
||||
}
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
function GetFile(FileName) {
|
||||
local Io = IO(FileName, "r+");
|
||||
|
||||
local Ctx = Memory.alloc(0x100);
|
||||
MD5.MD5_Init(Ctx.C_Object);
|
||||
|
||||
while (true) {
|
||||
local Buffer = Memory.alloc(0x1000);
|
||||
local Res = Io.ReadBuffer(0x1000);
|
||||
if (Res.count == 0) break;
|
||||
MD5.MD5_Update(Ctx.C_Object, Memory.allocUtf8String(Res.str).C_Object, Res.count);
|
||||
}
|
||||
|
||||
local Result = Memory.alloc(16);
|
||||
MD5.MD5_Final(Result.C_Object, Ctx.C_Object);
|
||||
Io.Close();
|
||||
return base64_encode(Result.readUtf8String(16));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,393 @@
|
|||
/*
|
||||
文件名:MathClass.nut
|
||||
路径:BaseClass/MathClass.nut
|
||||
创建日期:2023-08-26 12:13
|
||||
文件用途:数学类
|
||||
*/
|
||||
class MathClass {
|
||||
|
||||
function getDirectionToTargetX(objX, x) {
|
||||
if (objX > x)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @函数作用: 取随机值 左闭右开
|
||||
* @参数 name
|
||||
* @返回值
|
||||
*/
|
||||
function Rand(Min, Max) {
|
||||
local In = rand();
|
||||
|
||||
local Ret = (Min + (Max - Min) * (In / RAND_MAX.tofloat())).tointeger();
|
||||
return Ret;
|
||||
}
|
||||
|
||||
function getCollisionByObjBox(obj, box) {
|
||||
local x = obj.X;
|
||||
local y = obj.Y;
|
||||
local z = obj.Z;
|
||||
|
||||
local ArrBuf = [];
|
||||
if (obj.Direction == 1) {
|
||||
local pleft = [x + box[0], y + box[1], z + box[2]];
|
||||
local pright = [x + box[0] + box[3], y + box[1] + box[4], z + box[2] + box[5]];
|
||||
|
||||
ArrBuf.extend(pleft);
|
||||
ArrBuf.extend(pright);
|
||||
} else {
|
||||
local pleft = [x - box[0], y + box[1], z + box[2]];
|
||||
local pright = [x - box[0] - box[3], y + box[1] + box[4], z + box[2] + box[5]];
|
||||
|
||||
ArrBuf.extend(pleft);
|
||||
ArrBuf.extend(pright);
|
||||
}
|
||||
return ArrBuf;
|
||||
|
||||
}
|
||||
|
||||
function GetDistancePos(startX, direction, offsetX) {
|
||||
if (direction == 0)
|
||||
return startX - offsetX;
|
||||
|
||||
return startX + offsetX;
|
||||
}
|
||||
|
||||
//通过坐标获得两点旋转角度
|
||||
function getRorateAngleByCurrentPos(x1, y1, z1, x2, y2, z2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//贝塞尔曲线构造的抛物线运动,支持开始z轴(obj,curT,lastZ,moveT)
|
||||
function sq_BParabola(currentT, maxT, initZPos, jumpHeight, lastZPos) {
|
||||
local z = getBeizeri(currentT, maxT, initZPos, initZPos + jumpHeight, initZPos + jumpHeight, lastZPos);
|
||||
return z.tointeger();
|
||||
}
|
||||
|
||||
//获得抛物线(不支持开始z轴)
|
||||
function sq_Parabola(x, b, c) {
|
||||
local a = (-b.tofloat() * 4) / (c.tofloat() * c.tofloat());
|
||||
return a.tofloat() * (x.tofloat() - c.tofloat() / 2) * (x.tofloat() - c.tofloat() / 2) + b.tofloat();
|
||||
}
|
||||
|
||||
//获得两点之间平面的距离.
|
||||
function Get2D_Distance(x1, y1, x2, y2) {
|
||||
local offsetX = x1 - x2;
|
||||
local offsetY = (y1 - y2) * 0.29;
|
||||
|
||||
return sqrt(offsetX * offsetX + offsetY * offsetY);
|
||||
|
||||
}
|
||||
|
||||
//判断给定的角度是否在startA和endA角度之间(startA与endA形成的锐角内)
|
||||
function CheckAngleIsInArea(judge, startA, endA) {
|
||||
|
||||
if (startA< 0)
|
||||
startA = startA + 360.0;
|
||||
|
||||
if (endA< 0)
|
||||
endA = endA + 360.0;
|
||||
|
||||
if (startA > 360.0)
|
||||
startA = startA - 360.0;
|
||||
|
||||
if (endA > 360.0)
|
||||
endA = endA - 360.0;
|
||||
|
||||
if (startA > 0 && startA< 90 && endA > 270 && endA< 360) {
|
||||
if (judge > 270 && judge< 360) {
|
||||
if (endA< judge && judge< startA + 360)
|
||||
return true;
|
||||
} else if (judge< 90) {
|
||||
if (endA< judge + 360 && judge + 360< startA + 360)
|
||||
return true;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (endA > judge && judge > startA)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//弧度制转为角度制
|
||||
function toDegree(x) {
|
||||
return x * 57.29577;
|
||||
}
|
||||
|
||||
//角度转为弧度
|
||||
function toRadian(x) {
|
||||
return x * 0.01745;
|
||||
}
|
||||
|
||||
//立方体与立方体之间碰撞 暂未测试
|
||||
function CubeAndCubeCollection(c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ) {
|
||||
|
||||
if (pointIsInCubeArea(c1StartX, c1StartY, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c1EndX, c1StartY, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c1StartX, c1EndY, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c1EndX, c1EndY, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c1StartX, c1StartY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c1EndX, c1StartY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c1StartX, c1EndY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c1EndX, c1EndY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c2StartX, c2StartY, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c2EndX, c2StartY, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c2StartX, c2EndY, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c2EndX, c2EndY, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c2StartX, c2StartY, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c2EndX, c2StartY, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c2StartX, c2EndY, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c2EndX, c2EndY, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea((c1StartX + c1EndX )/ 2, c1StartY, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea((c1StartX + c1EndX )/ 2, c1EndY, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea((c1StartX + c1EndX )/ 2, c1StartY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea((c1StartX + c1EndX )/ 2, c1EndY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c1StartX , (c1StartY + c1EndY) / 2, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c1StartX, (c1StartY + c1EndY) / 2, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c1EndX , (c1StartY + c1EndY) / 2, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c1EndX, (c1StartY + c1EndY) / 2, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c1StartX , c1StartY, (c1StartZ + c1EndZ) / 2, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c1StartX, c1EndY, (c1StartZ + c1EndZ) / 2, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c1EndX , c1StartY, (c1StartZ + c1EndZ) / 2, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c1EndX, c1EndY, (c1StartZ + c1EndZ) / 2, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea((c2StartX + c2EndX )/ 2, c2StartY, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea((c2StartX + c2EndX )/ 2, c2EndY, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea((c2StartX + c2EndX )/ 2, c2StartY, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea((c2StartX + c2EndX )/ 2, c2EndY, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c2StartX , (c2StartY + c2EndY) / 2, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c2StartX, (c2StartY + c2EndY) / 2, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c2EndX , (c2StartY + c2EndY) / 2, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c2EndX, (c2StartY + c2EndY) / 2, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c2StartX , c2StartY, (c2StartZ + c2EndZ) / 2, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c2StartX, c2EndY, (c2StartZ + c2EndZ) / 2, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c2EndX , c2StartY, (c2StartZ + c2EndZ) / 2, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea(c2EndX, c2EndY, (c2StartZ + c2EndZ) / 2, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea((c1StartX + c1EndX) / 2, (c1StartY + c1EndY) / 2, (c1StartZ + c1EndZ) / 2, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
return true;
|
||||
if (pointIsInCubeArea((c2StartX + c2EndX) / 2, (c2StartY + c2EndY) / 2, (c2StartZ + c2EndZ) / 2, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//判断该点是否在给定参数的立方体内
|
||||
function pointIsInCubeArea(px, py, pz, startX, startY, startZ, endX, endY, endZ) {
|
||||
|
||||
local cubeCenterX = (startX + endX) / 2;
|
||||
local cubeXLen = abs(startX - endX) / 2;
|
||||
|
||||
local cubeCenterY = (startY + endY) / 2;
|
||||
local cubeYLen = abs(startY - endY) / 2;
|
||||
|
||||
local cubeCenterZ = (startZ + endZ) / 2;
|
||||
local cubeZLen = abs(startZ - endZ) / 2;
|
||||
|
||||
if (abs(px - cubeCenterX) <= cubeXLen && abs(py - cubeCenterY) <= cubeYLen && abs(pz - cubeCenterZ) <= cubeZLen)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
//判断(px,py)是否在这个四边形内,如果在就返回true,否则返回false,
|
||||
//一定要注意,1,2,3,4的坐标必须能首尾组成四边形,不能跳坐标!!!!否则判断会直接失效!!!
|
||||
function pointIsIn4PointArea(px, py, x1, y1, x2, y2, x3, y3, x4, y4) {
|
||||
local area = get4PointArea(x1, y1, x2, y2, x3, y3, x4, y4);
|
||||
local pointArea1 = get3PointArea(x1, y1, x2, y2, px, py);
|
||||
local pointArea2 = get3PointArea(x2, y2, x3, y3, px, py);
|
||||
local pointArea3 = get3PointArea(x3, y3, x4, y4, px, py);
|
||||
local pointArea4 = get3PointArea(x4, y4, x1, y1, px, py);
|
||||
|
||||
if (abs(area - pointArea1 - pointArea2 - pointArea3 - pointArea4)< 10.0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//获得给定4个点形成的四边形面积
|
||||
function get4PointArea(x1, y1, x2, y2, x3, y3, x4, y4) {
|
||||
local area1 = get3PointArea(x1, y1, x2, y2, x3, y3)
|
||||
local area2 = get3PointArea(x2, y2, x3, y3, x4, y4)
|
||||
return area1 + area2;
|
||||
}
|
||||
|
||||
//获得给定3个点形成的三角形面积
|
||||
function get3PointArea(x1, y1, x2, y2, x3, y3) {
|
||||
|
||||
return abs(x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)) / 2;
|
||||
|
||||
/*
|
||||
local l1 = sqrt(pow((x1- x2), 2) + pow((y1- y2), 2));
|
||||
local l2 = sqrt(pow((x1- x3), 2) + pow((y1- y3), 2));
|
||||
local l3 = sqrt(pow((x2- x3), 2) + pow((y2- y3), 2));
|
||||
|
||||
return sqrt((l1 + l2 + l3) * (l1 + l2- l3) * (l1- l2 + l3) * (l2 + l3- l1)) / 4;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
//获得该数的符号
|
||||
function getSign(var) {
|
||||
if (var< 0)
|
||||
return 1;
|
||||
else if (var > 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//简便性能高的开平方
|
||||
function sqrt(sum) {
|
||||
local i = (sum / 2).tofloat();
|
||||
|
||||
local isb = 0;
|
||||
for (isb = 0; isb< 10; isb++) {
|
||||
i = (i - ((i * i - sum) / (2 * i))).tofloat();
|
||||
}
|
||||
return i;
|
||||
|
||||
}
|
||||
|
||||
//四舍五入
|
||||
function Round(var) {
|
||||
local v =
|
||||
var -
|
||||
var.tointeger();
|
||||
if (v< 0.5)
|
||||
return var.tointeger();
|
||||
return var.tointeger() + 1;
|
||||
|
||||
}
|
||||
|
||||
//currentRate 越接近maxRate ,返回值由sv越接近ev
|
||||
function getUniformVelocity(sv, ev, currentRate, maxRate) {
|
||||
|
||||
local rate = currentRate.tofloat() / maxRate.tofloat();
|
||||
|
||||
local varyValue = ev - sv;
|
||||
|
||||
return sv + varyValue * rate;
|
||||
}
|
||||
|
||||
function sq_GetAccel(sv, ev, currentRate, maxRate, increaseFeature) {
|
||||
|
||||
local rate = currentRate.tofloat() / maxRate.tofloat();
|
||||
|
||||
local varyValue = ev - sv;
|
||||
|
||||
local increaseRate = 1.0;
|
||||
|
||||
if (increaseFeature) {
|
||||
increaseRate = pow(50, rate) / 50; //慢->快
|
||||
} else {
|
||||
increaseRate = pow(rate, 0.05);
|
||||
}
|
||||
|
||||
|
||||
return sv + varyValue * increaseRate;
|
||||
}
|
||||
|
||||
|
||||
function getMax(a, b) {
|
||||
if (a< b)
|
||||
return b;
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
function getMin(a, b) {
|
||||
if (a > b)
|
||||
return b;
|
||||
return a;
|
||||
}
|
||||
|
||||
//获得贝塞尔曲线(2阶)
|
||||
function getBeizeri(var1, var2, p0, p1, p2, p3) {
|
||||
local t = var1.tofloat() / var2.tofloat();
|
||||
local t1 = 1.0 - t;
|
||||
|
||||
local v1 = t1 * t1 * t1;
|
||||
local v2 = t1 * t1;
|
||||
local v3 = t1;
|
||||
local v4 = t * t * t;
|
||||
|
||||
local ret = p0 * v1;
|
||||
ret = ret + 3.0 * p1 * t * v2;
|
||||
ret = ret + 3.0 * p2 * t * t * v3;
|
||||
ret = ret + p3 * v4;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//获得贝塞尔曲线角度
|
||||
function getBeizeriAngle(var1, var2, p0, p1, p2, p3) {
|
||||
|
||||
|
||||
local t = var1.tofloat() / var2.tofloat();
|
||||
local t1 = 1.0 - t;
|
||||
|
||||
local v1 = t1 * t1;
|
||||
local v2 = t1;
|
||||
local v3 = t1;
|
||||
local v4 = t * t;
|
||||
|
||||
local ret = 2.0 * p0 * v1;
|
||||
ret = ret + 6.0 * p1 * t * v2;
|
||||
ret = ret + 6.0 * p2 * t * v3;
|
||||
ret = ret + 2.0 * p3 * v4;
|
||||
|
||||
return ret;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
文件名:MemoryClass.nut
|
||||
路径:Dps_A/BaseClass/MemoryClass/MemoryClass.nut
|
||||
创建日期:2024-09-17 08:23
|
||||
文件用途:内存类
|
||||
*/
|
||||
class Memory {
|
||||
|
||||
function alloc(Size) {
|
||||
return NativePointer(Size);
|
||||
}
|
||||
|
||||
function allocUtf8String(Str) {
|
||||
local P = NativePointer(Str_Ptr(Str));
|
||||
P.Size = Str.len();
|
||||
return P;
|
||||
}
|
||||
|
||||
function copy(P1, P2, Size) {
|
||||
local WriteArr = Sq_ReadByteArr(P2.C_Object, Size);
|
||||
P1.writeByteArray(WriteArr);
|
||||
}
|
||||
|
||||
function reset(P1, Size) {
|
||||
local WriteArr = array(Size, 0);
|
||||
P1.writeByteArray(WriteArr);
|
||||
}
|
||||
}
|
||||
|
||||
class NativePointer extends Base_C_Object {
|
||||
//大小
|
||||
Size = -1;
|
||||
|
||||
function _tyoeof()
|
||||
{
|
||||
return "Sq_Pointer";
|
||||
}
|
||||
|
||||
constructor(T) {
|
||||
if (typeof T == "integer") {
|
||||
base.constructor(Sq_New_Point(T));
|
||||
Size = T;
|
||||
//注册销毁伪析构
|
||||
Register_Destruction(C_Object, this);
|
||||
} else if (typeof T == "userdata") {
|
||||
base.constructor(T);
|
||||
} else if (typeof T == "string") {
|
||||
base.constructor(S_Ptr(T));
|
||||
}
|
||||
}
|
||||
|
||||
function Output(Size) {
|
||||
local Buf = Sq_Point2Blob(this.C_Object, Size);
|
||||
local Str = "[";
|
||||
foreach(Value in Buf) {
|
||||
Str = format("%s%02X", Str, Value);
|
||||
Str += ",";
|
||||
}
|
||||
Str += "]";
|
||||
print(Str);
|
||||
}
|
||||
|
||||
function add(intoffset) {
|
||||
return NativePointer(Sq_PointerOperation(this.C_Object, intoffset, "+"));
|
||||
}
|
||||
|
||||
function sub(intoffset) {
|
||||
return NativePointer(Sq_PointerOperation(this.C_Object, intoffset, "-"));
|
||||
}
|
||||
|
||||
function writeByteArray(arr) {
|
||||
Sq_Memory_WriteByteArr(this.C_Object, arr);
|
||||
}
|
||||
|
||||
function readByteArray(size) {
|
||||
local PointB = Sq_Point2Blob(this.C_Object, size);
|
||||
local arr = [];
|
||||
foreach(value in PointB) {
|
||||
arr.append(value);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
|
||||
function write(value, type) {
|
||||
local Buf = blob(0);
|
||||
Buf.writen(value, type);
|
||||
local arr = [];
|
||||
foreach(value in Buf) {
|
||||
arr.append(value);
|
||||
}
|
||||
writeByteArray(arr);
|
||||
}
|
||||
|
||||
function writeS8(value) {
|
||||
write(value, 'c');
|
||||
}
|
||||
|
||||
function writeU8(value) {
|
||||
write(value, 'b');
|
||||
}
|
||||
|
||||
function writeS16(value) {
|
||||
write(value, 's');
|
||||
}
|
||||
|
||||
function writeU16(value) {
|
||||
write(value, 'w');
|
||||
}
|
||||
|
||||
function writeS32(value) {
|
||||
write(value, 'i');
|
||||
}
|
||||
|
||||
function writeU32(value) {
|
||||
write(value, 'i');
|
||||
}
|
||||
|
||||
function writeShort(value) {
|
||||
write(value, 's');
|
||||
}
|
||||
|
||||
function writeUShort(value) {
|
||||
write(value, 'w');
|
||||
}
|
||||
|
||||
function writeInt(value) {
|
||||
write(value, 'i');
|
||||
}
|
||||
|
||||
function writeUInt(value) {
|
||||
write(value, 'i');
|
||||
}
|
||||
|
||||
function writeFloat(value) {
|
||||
write(value, 'f');
|
||||
}
|
||||
|
||||
function writeDouble(value) {
|
||||
write(value, 'd');
|
||||
}
|
||||
|
||||
|
||||
function read(type) {
|
||||
local Buf = Sq_Point2Blob(this.C_Object, 4);
|
||||
return Buf.readn(type);
|
||||
}
|
||||
|
||||
function readS8() {
|
||||
return read('c');
|
||||
}
|
||||
|
||||
function readU8() {
|
||||
return read('b');
|
||||
}
|
||||
|
||||
function readS16() {
|
||||
return read('s');
|
||||
}
|
||||
|
||||
function readU16() {
|
||||
return read('w');
|
||||
}
|
||||
|
||||
function readS32() {
|
||||
return read('i');
|
||||
}
|
||||
|
||||
function readU32() {
|
||||
return read('i');
|
||||
}
|
||||
|
||||
function readShort() {
|
||||
return read('s');
|
||||
}
|
||||
|
||||
function readUShort() {
|
||||
return read('w');
|
||||
}
|
||||
|
||||
function readInt() {
|
||||
return read('i');
|
||||
}
|
||||
|
||||
function readUInt() {
|
||||
return read('i');
|
||||
}
|
||||
|
||||
function readFloat() {
|
||||
return read('f');
|
||||
}
|
||||
|
||||
function readDouble() {
|
||||
return read('d');
|
||||
}
|
||||
|
||||
function readUtf8String(...) {
|
||||
if (vargv.len() > 0) {
|
||||
return Sq_Memory_ReadString(this.C_Object, vargv[0]);
|
||||
} else {
|
||||
return Sq_Memory_ReadString(this.C_Object);
|
||||
}
|
||||
}
|
||||
|
||||
function readPointer() {
|
||||
return Sq_ReadPoint(this.C_Object);
|
||||
}
|
||||
|
||||
function readBinary(Size) {
|
||||
return Sq_Point2Blob(this.C_Object, Size);
|
||||
}
|
||||
|
||||
function tostring() {
|
||||
return this.C_Object.tostring();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
文件名:MoudleClass.nut
|
||||
路径:Dps_A/BaseClass/MoudleClass/MoudleClass.nut
|
||||
创建日期:2024-09-17 09:48
|
||||
文件用途:模块类
|
||||
*/
|
||||
class Module {
|
||||
|
||||
function getExportByName(ModuleName, FunctionName) {
|
||||
return Sq_getExportByName(ModuleName, FunctionName);
|
||||
}
|
||||
|
||||
function load() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
文件名:MysqlClass.nut
|
||||
路径:Dps_A/BaseClass/MysqlClass/MysqlClass.nut
|
||||
创建日期:2024-09-16 21:23
|
||||
文件用途:数据库类
|
||||
*/
|
||||
class Mysql extends Base_C_Object {
|
||||
|
||||
// 0空闲 1任务中 2死亡
|
||||
State = 0;
|
||||
|
||||
constructor(Ip, Port, Name, Account, Password) {
|
||||
if (!Open(Ip, Port, Name, Account, Password)) error("数据库连接失败");
|
||||
}
|
||||
|
||||
/*
|
||||
* 读取mysql返回的数据,读取binary类型的字段
|
||||
* @param this.C_Object mysql数据库句柄
|
||||
* @param columnIndex 要读取的字段的位置
|
||||
*/
|
||||
function Open(db_ip, db_port, db_name, db_username, db_password) {
|
||||
base.constructor(Sq_New_Point(0x80000));
|
||||
Sq_CallFunc(S_Ptr("0x83F3AC8"), "pointer", ["pointer"], this.C_Object);
|
||||
Sq_CallFunc(S_Ptr("0x83F3CE4"), "int", ["pointer"], this.C_Object);
|
||||
//打开数据库句柄
|
||||
if (Sq_CallFunc(S_Ptr("0x83F4024"), "int", ["pointer", "pointer", "int", "pointer", "pointer", "pointer"],
|
||||
this.C_Object, db_ip, db_port, db_name, db_username, db_password)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function Fetch() {
|
||||
return Sq_CallFunc(S_Ptr("0x83F44BC"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
|
||||
function Close() {
|
||||
Sq_CallFunc(S_Ptr("0x83F3E74"), "int", ["pointer"], this.C_Object);
|
||||
Sq_Delete_Point(this.C_Object);
|
||||
State = 2;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 读取mysql返回的数据,读取string类型的字段
|
||||
* @param this.C_Object mysql数据库句柄
|
||||
* @param columnIndex 要读取的字段的位置
|
||||
*/
|
||||
function ReadStringColumn(columnIndex) {
|
||||
//MySQL_get_binary_length
|
||||
local binary_length = Sq_CallFunc(S_Ptr("0x81253DE"), "int", ["pointer", "int"], this.C_Object, columnIndex);
|
||||
local binary_length_point = Sq_New_Point(binary_length);
|
||||
//MySQL_get_binary
|
||||
if (1 == Sq_CallFunc(S_Ptr("0x812531A"), "int", ["pointer", "int", "pointer", "int"], this.C_Object, columnIndex, binary_length_point, binary_length)) {
|
||||
//读取string类型的数据
|
||||
local result = Sq_ReadAddressString(binary_length_point, binary_length);
|
||||
Sq_Delete_Point(binary_length_point);
|
||||
return result;
|
||||
}
|
||||
Sq_Delete_Point(binary_length_point);
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* 读取mysql返回的数据,读取有符号int类型的字段
|
||||
* @param this.C_Object mysql数据库句柄
|
||||
* @param columnIndex 要读取的字段的位置
|
||||
*/
|
||||
function ReadIntColumn(columnIndex) {
|
||||
local intSizePoint = Sq_New_Point(4);
|
||||
//MySQL_get_int
|
||||
if (1 == Sq_CallFunc(S_Ptr("0x811692C"), "int", ["pointer", "int", "pointer"], this.C_Object, columnIndex, intSizePoint)) {
|
||||
//转为blob
|
||||
local blob = Sq_Point2Blob(intSizePoint, 4);
|
||||
//读取8位有符号整数
|
||||
local result = blob.readn('i');
|
||||
Sq_Delete_Point(intSizePoint);
|
||||
return result;
|
||||
}
|
||||
// Sq_Delete_Point(intSizePoint);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 读取mysql返回的数据,读取无符号int类型的字段
|
||||
* @param this.C_Object mysql数据库句柄
|
||||
* @param columnIndex 要读取的字段的位置
|
||||
*/
|
||||
function ReadUIntColumn(columnIndex) {
|
||||
local intSizePoint = Sq_New_Point(4);
|
||||
//MySQL_get_uint
|
||||
if (1 == Sq_CallFunc(S_Ptr("0x80E22F2"), "int", ["pointer", "int", "pointer"], this.C_Object, columnIndex, intSizePoint)) {
|
||||
//转为blob
|
||||
local blob = Sq_Point2Blob(intSizePoint, 4);
|
||||
//读取8位无符号整数
|
||||
local result = blob.readn('b');
|
||||
Sq_Delete_Point(intSizePoint);
|
||||
return result;
|
||||
}
|
||||
Sq_Delete_Point(intSizePoint);
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* 读取mysql返回的数据,读取float类型的字段
|
||||
* @param this.C_Object mysql数据库句柄
|
||||
* @param columnIndex 要读取的字段的位置
|
||||
*/
|
||||
function ReadFloatColumn(columnIndex) {
|
||||
local intSizePoint = Sq_New_Point(4);
|
||||
//MySQL_get_float
|
||||
if (1 == Sq_CallFunc(S_Ptr("0x844D6D0"), "int", ["pointer", "int", "pointer"], this.C_Object, columnIndex, intSizePoint)) {
|
||||
//转为blob
|
||||
local blob = Sq_Point2Blob(intSizePoint, 4);
|
||||
//读取32位浮点数
|
||||
local result = blob.readn('f');
|
||||
Sq_Delete_Point(intSizePoint);
|
||||
return result;
|
||||
}
|
||||
Sq_Delete_Point(intSizePoint);
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* 读取mysql返回的数据,读取binary类型的字段
|
||||
* @param this.C_Object mysql数据库句柄
|
||||
* @param columnIndex 要读取的字段的位置
|
||||
*/
|
||||
function ReadBinaryColumn(columnIndex) {
|
||||
//MySQL_get_binary_length
|
||||
local binary_length = Sq_CallFunc(S_Ptr("0x81253DE"), "int", ["pointer", "int"], this.C_Object, columnIndex);
|
||||
if (binary_length > 0) {
|
||||
local binary_length_point = Memory.alloc(binary_length);
|
||||
//MySQL_get_binary
|
||||
if (1 == Sq_CallFunc(S_Ptr("0x812531A"), "int", ["pointer", "int", "pointer", "int"], this.C_Object, columnIndex, binary_length_point.C_Object, binary_length)) {
|
||||
return binary_length_point;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* mysql查询,带返回结果,返回一个二维数组
|
||||
* @param {*} db_pointer 数据库句柄
|
||||
* @param {*} select_sql 要执行的查询语句
|
||||
* @param {*} column_type_list 返回结果的类型list,按select的column顺序,int,string,unit,float,binary
|
||||
* @returns
|
||||
*/
|
||||
function Select(select_sql, column_type_list) {
|
||||
local result_list = [];
|
||||
if (Exec_Sql(select_sql)) {
|
||||
//获取查询到的数据总数
|
||||
local row_count = Sq_CallFunc(S_Ptr("0x80E236C"), "int", ["pointer"], this.C_Object);
|
||||
if (row_count > 0) {
|
||||
for (local i = 0; i< row_count; i++) {
|
||||
Fetch();
|
||||
local row = [];
|
||||
for (local j = 0; j< column_type_list.len(); j++) {
|
||||
//判断是否为空值
|
||||
if (!Sq_CallFunc(S_Ptr("0x85F41B2"), "bool", ["pointer", "int"], this.C_Object, j)) {
|
||||
row.push(null);
|
||||
} else if (column_type_list[j] == "int") {
|
||||
row.push(ReadIntColumn(j));
|
||||
} else if (column_type_list[j] == "string") {
|
||||
row.push(ReadStringColumn(j));
|
||||
} else if (column_type_list[j] == "uint") {
|
||||
row.push(ReadUIntColumn(j));
|
||||
} else if (column_type_list[j] == "float") {
|
||||
row.push(ReadFloatColumn(j));
|
||||
} else if (column_type_list[j] == "binary") {
|
||||
row.push(ReadBinaryColumn(j));
|
||||
}
|
||||
}
|
||||
result_list.push(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result_list;
|
||||
}
|
||||
|
||||
//执行查询返回执行是否成功
|
||||
function Exec_Sql(sql) {
|
||||
local sql_ptr = Str_Ptr(sql);
|
||||
//set query
|
||||
local set_query = Sq_CallFunc(S_Ptr("0x83F41C0"), "int", ["pointer", "pointer"], this.C_Object, sql_ptr);
|
||||
//执行sql
|
||||
local sql_exec_result = Sq_CallFunc(S_Ptr("0x83F4326"), "int", ["pointer", "int"], this.C_Object, 1);
|
||||
return sql_exec_result;
|
||||
}
|
||||
|
||||
|
||||
//获取服务端版本
|
||||
function GetServerVersion() {
|
||||
return Sq_CallFunc(S_Ptr("0x83F460C"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
//获取客户端版本
|
||||
function GetClientVersion() {
|
||||
return Sq_CallFunc(S_Ptr("0x83F4622"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
}
|
||||
|
||||
class MysqlPool {
|
||||
|
||||
// 用于存储数据库的 IP 地址
|
||||
db_ip = null;
|
||||
// 用于存储数据库的端口号
|
||||
db_port = null;
|
||||
// 用于存储数据库的名称
|
||||
db_name = null;
|
||||
// 用于存储数据库的用户名
|
||||
db_username = null;
|
||||
// 用于存储数据库的密码
|
||||
db_password = null;
|
||||
|
||||
//连接池大小
|
||||
PoolSize = 10;
|
||||
//连接编码
|
||||
Charset = "latin1";
|
||||
//连接池
|
||||
PoolList = null;
|
||||
|
||||
//是否已经初始化
|
||||
IsInit = false;
|
||||
|
||||
constructor() {
|
||||
PoolList = [];
|
||||
getroottable()._MysqlPoolObject <- this;
|
||||
}
|
||||
|
||||
function GetInstance() {
|
||||
if (!(getroottable().rawin("_MysqlPoolObject"))) MysqlPool();
|
||||
// MysqlPool();
|
||||
return getroottable()._MysqlPoolObject;
|
||||
}
|
||||
|
||||
//设置基础配置
|
||||
function SetBaseConfiguration(Ip, Port, Account, Password) {
|
||||
db_ip = Str_Ptr(Ip);
|
||||
db_port = Port;
|
||||
db_name = Str_Ptr("taiwan_cain");
|
||||
db_username = Str_Ptr(Account);
|
||||
db_password = Str_Ptr(Password);
|
||||
}
|
||||
|
||||
//初始化连接池
|
||||
function Init() {
|
||||
if(IsInit)return;
|
||||
for (local i = 0; i< PoolSize; i++) {
|
||||
local Buffer = Mysql(db_ip, db_port, db_name, db_username, db_password);
|
||||
Buffer.Exec_Sql(format("SET NAMES %s", Charset));
|
||||
PoolList.append(Buffer);
|
||||
// print("创建了一条连接,编号: " + i + ",地址: " + Buffer + ", 指针地址: " + Buffer.C_Object);
|
||||
}
|
||||
IsInit = true;
|
||||
}
|
||||
|
||||
function GetConnect() {
|
||||
local _Connect = PoolList.pop();
|
||||
if (_Connect.State == 0) {
|
||||
_Connect.State = 1;
|
||||
return _Connect;
|
||||
}
|
||||
}
|
||||
|
||||
function PutConnect(_Connect) {
|
||||
if (_Connect.State == 1) {
|
||||
_Connect.State = 0;
|
||||
PoolList.append(_Connect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
文件名:OfficialProject.nut
|
||||
路径:Dps_A/BaseClass/OfficialProject/OfficialProject.nut
|
||||
创建日期:2025-03-30 00:03
|
||||
文件用途:官方项目
|
||||
*/
|
||||
class _Official_Project_ {
|
||||
ReloadProjectMap = null;
|
||||
|
||||
constructor() {
|
||||
//在全局中注册自己
|
||||
getroottable()._GlobalOfficial_Project <- this;
|
||||
ReloadProjectMap = {};
|
||||
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
function Init() {
|
||||
// 定义 ANSI 颜色代码
|
||||
local COLOR_RESET = "\x1b[0m";
|
||||
local COLOR_MAGENTA = "\x1b[95m";
|
||||
local COLOR_CYAN = "\x1b[96m";
|
||||
local COLOR_YELLOW = "\x1b[93m";
|
||||
local COLOR_RED = "\x1b[91m";
|
||||
|
||||
|
||||
local WorkPath = "/dp_s/OfficialProject";
|
||||
local Dirs = sq_GetListDirs(WorkPath);
|
||||
if (Dirs.len() > 0) {
|
||||
print(format("\n\n\t\t\t\t%s开始加载DP-S插件市场项目%s", COLOR_YELLOW, COLOR_RESET));
|
||||
}
|
||||
foreach(DirPath in Dirs) {
|
||||
local FilePaths = sq_GetListFiles(WorkPath + "/" + DirPath);
|
||||
|
||||
foreach(FilePath in FilePaths) {
|
||||
//找到项目文件
|
||||
if (FilePath == "Proj.ifo") {
|
||||
local Config = sq_ReadJsonFile(WorkPath + "/" + DirPath + "/" + FilePath);
|
||||
if (Config) {
|
||||
try {
|
||||
//读取配置文件建立Map
|
||||
local ProjectConfig = Config.ProjectConfig;
|
||||
if (ProjectConfig.len() > 0) {
|
||||
ReloadProjectMap.rawset(ProjectConfig, Config.ProjectRunFunc);
|
||||
}
|
||||
|
||||
local ProjectFiles = Config.ProjectFiles;
|
||||
//载入所有项目文件
|
||||
foreach(ProjectFile in ProjectFiles) {
|
||||
sq_RunScript("OfficialProject/" + DirPath + "/" + ProjectFile);
|
||||
}
|
||||
//调用启动函数
|
||||
getroottable()[Config.ProjectRunFunc]();
|
||||
//播报脚本已加载
|
||||
print(format("%s[ %s ]%s" + " 脚本项目已加载 --- 当前版本: %s%.2f%s", COLOR_YELLOW, Config.ProjectName, COLOR_RESET, COLOR_YELLOW, Config.ProjectVersion, COLOR_RESET));
|
||||
} catch (exception) {
|
||||
//播报脚本未加载
|
||||
print(format("%s[ %s ]%s" + " 脚本项目未加载 --- 当前版本: %s%.2f%s", COLOR_RED, Config.ProjectName, COLOR_RESET, COLOR_RED, Config.ProjectVersion, COLOR_RESET));
|
||||
print(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
文件名:PacketClass.nut
|
||||
路径:BaseClass/PacketClass/PacketClass.nut
|
||||
创建日期:2024-04-07 16:59
|
||||
文件用途:数据包类
|
||||
*/
|
||||
class Packet extends Base_C_Object {
|
||||
|
||||
//传参就构造 不传就new一个新包
|
||||
constructor(...) {
|
||||
if (vargv.len() > 0) {
|
||||
base.constructor(vargv[0]);
|
||||
} else {
|
||||
local Buf = Sq_New_Point(0x20000);
|
||||
Sq_CallFunc(S_Ptr("0x858DD4C"), "void", ["pointer"], Buf);
|
||||
base.constructor(Buf);
|
||||
}
|
||||
}
|
||||
|
||||
function Put_Header(a, b) {
|
||||
Sq_CallFunc(S_Ptr("0x80CB8FC"), "int", ["pointer", "int", "int"], this.C_Object, a, b);
|
||||
// Sq_Packet_Put_header(this.C_Object, a, b);
|
||||
}
|
||||
|
||||
function Put_Byte(Value) {
|
||||
Sq_CallFunc(S_Ptr("0x80CB920"), "int", ["pointer", "int"], this.C_Object, Value);
|
||||
// Sq_Packet_Put_byte(this.C_Object, Value);
|
||||
}
|
||||
|
||||
function Put_Short(Value) {
|
||||
Sq_CallFunc(S_Ptr("0x80D9EA4"), "int", ["pointer", "int"], this.C_Object, Value);
|
||||
// Sq_Packet_Put_short(this.C_Object, Value);
|
||||
}
|
||||
|
||||
function Put_Int(Value) {
|
||||
Sq_CallFunc(S_Ptr("0x80CB93C"), "int", ["pointer", "int"], this.C_Object, Value);
|
||||
// Sq_Packet_Put_int(this.C_Object, Value);
|
||||
}
|
||||
|
||||
function Put_Binary(Value) {
|
||||
local StrPoint = Str_Ptr(Value);
|
||||
Sq_CallFunc(S_Ptr("0x811DF08"), "int", ["pointer", "pointer", "int"], this.C_Object, StrPoint, Value.len());
|
||||
// Sq_Packet_Put_binary(this.C_Object, Value);
|
||||
}
|
||||
|
||||
function Put_BinaryEx(Str, Len) {
|
||||
Sq_CallFunc(S_Ptr("0x811DF08"), "int", ["pointer", "pointer", "int"], this.C_Object, Str, Len);
|
||||
//Sq_Packet_Put_binaryex(this.C_Object, Str, Len);
|
||||
}
|
||||
|
||||
function Put_BinaryEx_M(Str, Len) {
|
||||
// Sq_Packet_Put_binaryex(this.C_Object, Str, Len);
|
||||
Sq_CallFunc(S_Ptr("0x811DF08"), "int", ["pointer", "pointer", "int"], this.C_Object, Str, Len);
|
||||
}
|
||||
|
||||
function Put_Str(Str, Len) {
|
||||
Sq_CallFunc(S_Ptr("0x81B73E4"), "int", ["pointer", "pointer", "int"], this.C_Object, Str, Len);
|
||||
}
|
||||
|
||||
function Finalize(Value) {
|
||||
Sq_Packet_Finalize(this.C_Object, Value);
|
||||
}
|
||||
|
||||
function Send(SUser) {
|
||||
Sq_Packet_Send(SUser.C_Object, this.C_Object);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function GetByte() {
|
||||
local data = Memory.alloc(1);
|
||||
if (Sq_CallFunc(S_Ptr("0x858CF22"), "int", ["pointer", "pointer"], this.C_Object, data.C_Object)) {
|
||||
return data.readS8();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function GetShort() {
|
||||
local data = Memory.alloc(2);
|
||||
if (Sq_CallFunc(S_Ptr("0x858CFC0"), "int", ["pointer", "pointer"], this.C_Object, data.C_Object)) {
|
||||
return data.readS16();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function GetInt() {
|
||||
local data = Memory.alloc(4);
|
||||
if (Sq_CallFunc(S_Ptr("0x858D27E"), "int", ["pointer", "pointer"], this.C_Object, data.C_Object)) {
|
||||
return data.readS32();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function GetBinary(len) {
|
||||
local data = Memory.alloc(len);
|
||||
if (Sq_CallFunc(S_Ptr("0x858D3B2"), "int", ["pointer", "pointer"], this.C_Object, data.C_Object)) {
|
||||
return data;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
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)) {
|
||||
return data;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function Delete() {
|
||||
Sq_CallFunc(S_Ptr("0x858DE80"), "void", ["pointer"], this.C_Object);
|
||||
Sq_Delete_Point(this.C_Object);
|
||||
// Sq_Packet_Delete(this.C_Object);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
文件名:PartyClass.nut
|
||||
路径:BaseClass/PartyClass/PartyClass.nut
|
||||
创建日期:2024-04-09 20:28
|
||||
文件用途:Party类
|
||||
*/
|
||||
class Party extends Base_C_Object {
|
||||
|
||||
constructor(CObject) {
|
||||
base.constructor(CObject);
|
||||
}
|
||||
|
||||
|
||||
//创建队伍
|
||||
function Create(SUser) {
|
||||
Sq_Party_CreateParty(C_Object, SUser.C_Object);
|
||||
}
|
||||
|
||||
//给队伍加入玩家
|
||||
function Join(SUser) {
|
||||
Sq_Party_JoinParty(C_Object, SUser.C_Object);
|
||||
}
|
||||
|
||||
//获取队长
|
||||
function GetMaster() {
|
||||
local Ret = Sq_CallFunc(S_Ptr("0x8145780"), "pointer", ["pointer"], this.C_Object);
|
||||
if (Ret) {
|
||||
local SUser = User(Ret);
|
||||
if (SUser) return SUser;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//发送每个玩家的IP广播 因为组队时p2p
|
||||
function SendIpInfo() {
|
||||
Sq_Party_SendPartyIpInfo(C_Object);
|
||||
}
|
||||
|
||||
//获取战斗对象
|
||||
function GetBattleField() {
|
||||
return BattleField(Sq_Party_GetBattle_Field(C_Object));
|
||||
}
|
||||
|
||||
//获取玩家
|
||||
function GetUser(Pos) {
|
||||
local C_User = Sq_CallFunc(S_Ptr("0x08145764"), "pointer", ["pointer", "int"], this.C_Object, Pos);
|
||||
if (C_User) {
|
||||
return User(C_User);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//踢出玩家
|
||||
function LeaveUser(SUser) {
|
||||
Sq_CallFunc(S_Ptr("0x0859C114"), "int", ["pointer", "pointer", "int"], this.C_Object, SUser.C_Object, 2);
|
||||
}
|
||||
|
||||
//从副本踢出玩家
|
||||
function LeaveUserOnDgn(SUser) {
|
||||
Sq_CallFunc(S_Ptr("0x085B2BAA"), "void", ["pointer", "pointer", "int", "int", "int"], this.C_Object, SUser.C_Object, 1, 0, 0);
|
||||
}
|
||||
|
||||
//设置队伍可用复活币数量
|
||||
function SetPartyMemberCoinLimit(Count) {
|
||||
Sq_CallFunc(S_Ptr("0x085BE55A"), "pointer", ["pointer", "int"], this.C_Object, Count);
|
||||
}
|
||||
|
||||
//遍历玩家并执行函数
|
||||
function ForeachMember(Func) {
|
||||
for (local i = 0; i< 4; i++) {
|
||||
local SUser = GetUser(i);
|
||||
if (SUser) {
|
||||
Func(SUser, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//获取地下城清除状态
|
||||
function Get_Dgn_Clear_State() {
|
||||
return Sq_CallFunc(S_Ptr("0x0822D89C"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
文件名:PvfItemClass.nut
|
||||
路径:BaseClass/PvfClass/PvfItemClass.nut
|
||||
创建日期:2024-04-26 19:28
|
||||
文件用途:PVF item数据
|
||||
*/
|
||||
class PvfItem extends Base_C_Object {
|
||||
Attribute = null;
|
||||
constructor(CObject) {
|
||||
base.constructor(CObject);
|
||||
Attribute = Sq_Point2Blob(CObject, 600);
|
||||
}
|
||||
|
||||
function Output() {
|
||||
local Str = "[";
|
||||
foreach(Value in Attribute) {
|
||||
Str = format("%s%02X", Str, Value);
|
||||
Str += ",";
|
||||
}
|
||||
Str += "]";
|
||||
print(Str);
|
||||
}
|
||||
|
||||
//获取编号
|
||||
function GetIndex() {
|
||||
Attribute.seek(1 * 4);
|
||||
return Attribute.readn('i');
|
||||
}
|
||||
|
||||
//获取可用等级
|
||||
function GetUsableLevel() {
|
||||
Attribute.seek(18 * 4);
|
||||
return Attribute.readn('i');
|
||||
}
|
||||
|
||||
//获取稀有度
|
||||
function GetRarity() {
|
||||
Attribute.seek(14 * 4);
|
||||
return Attribute.readn('i');
|
||||
}
|
||||
|
||||
//获取名字
|
||||
function GetName() {
|
||||
return Sq_GetNameByIdFromPvf(GetIndex());
|
||||
}
|
||||
|
||||
//Public
|
||||
function GetNameById(Id) {
|
||||
return Sq_GetNameByIdFromPvf(Id);
|
||||
}
|
||||
//Public
|
||||
function GetPvfItemById(Idx) {
|
||||
local Ret = Sq_GetDataByIdFromPvf(Idx);
|
||||
if (Ret) {
|
||||
return PvfItem(Ret);
|
||||
} else return null;
|
||||
}
|
||||
|
||||
//Public 是否是魔法封印
|
||||
function IsRandomOption() {
|
||||
return Sq_CallFunc(S_Ptr("0x8514E5E"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
}
|
||||
|
||||
//获取穿戴等级
|
||||
function PvfItem::GetUsableLevel() {
|
||||
return Sq_CallFunc(S_Ptr("0x80F12EE"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
|
||||
//是否为消耗品
|
||||
function PvfItem::IsStackable() {
|
||||
return Sq_CallFunc(S_Ptr("0x80f12fa"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
|
||||
//获取消耗品类型
|
||||
function PvfItem::GetItemType() {
|
||||
return Sq_CallFunc(S_Ptr("0x8514A84"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
|
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
文件名:RedBlackTreeClass.nut
|
||||
路径:Dps_A/BaseClass/RedBlackTreeClass/RedBlackTreeClass.nut
|
||||
创建日期:2024-09-19 12:42
|
||||
文件用途:红黑树类
|
||||
*/
|
||||
// 红黑树节点类
|
||||
class RBTreeNode {
|
||||
key = null;
|
||||
time = null;
|
||||
left = null;
|
||||
right = null;
|
||||
parent = null;
|
||||
color = null;
|
||||
Info = null;
|
||||
|
||||
name = null;
|
||||
constructor(key, func_info) {
|
||||
this.key = key;
|
||||
this.time = key;
|
||||
this.Info = func_info;
|
||||
this.left = null;
|
||||
this.right = null;
|
||||
this.parent = null;
|
||||
this.color = "red";
|
||||
}
|
||||
|
||||
function _tyoeof() {
|
||||
return "RBTreeNode";
|
||||
}
|
||||
}
|
||||
|
||||
// 红黑树类
|
||||
class RedBlackTree {
|
||||
nil = null;
|
||||
root = null;
|
||||
size = 0;
|
||||
|
||||
function _tyoeof() {
|
||||
return "RedBlackTree";
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.nil = RBTreeNode(null, null);
|
||||
this.root = this.nil;
|
||||
}
|
||||
|
||||
function insert(key, func_info, gname = null) {
|
||||
local z = RBTreeNode(key, func_info);
|
||||
local y = this.nil;
|
||||
local x = this.root;
|
||||
while (x != this.nil) {
|
||||
y = x;
|
||||
if (z.key< x.key) {
|
||||
x = x.left;
|
||||
} else {
|
||||
x = x.right;
|
||||
}
|
||||
}
|
||||
z.parent = y;
|
||||
if (y == this.nil) {
|
||||
this.root = z;
|
||||
} else if (z.key< y.key) {
|
||||
y.left = z;
|
||||
} else {
|
||||
y.right = z;
|
||||
}
|
||||
z.left = this.nil;
|
||||
z.right = this.nil;
|
||||
z.color = "red";
|
||||
if (gname) z.name = gname;
|
||||
this.insertFixup(z);
|
||||
this.size++;
|
||||
}
|
||||
|
||||
function insertFixup(z) {
|
||||
while (z.parent.color == "red") {
|
||||
if (z.parent.parent && z.parent == z.parent.parent.left) {
|
||||
local y = z.parent.parent.right;
|
||||
if (y.color == "red") {
|
||||
z.parent.color = "black";
|
||||
y.color = "black";
|
||||
z.parent.parent.color = "red";
|
||||
z = z.parent.parent;
|
||||
} else {
|
||||
if (z == z.parent.right) {
|
||||
z = z.parent;
|
||||
this.leftRotate(z);
|
||||
}
|
||||
z.parent.color = "black";
|
||||
z.parent.parent.color = "red";
|
||||
this.rightRotate(z.parent.parent);
|
||||
}
|
||||
} else {
|
||||
if (z.parent.parent && z.parent.parent.left.color == "red") {
|
||||
z.parent.color = "black";
|
||||
z.parent.parent.left.color = "black";
|
||||
z.parent.parent.color = "red";
|
||||
z = z.parent.parent;
|
||||
} else {
|
||||
if (z == z.parent.left) {
|
||||
z = z.parent;
|
||||
this.rightRotate(z);
|
||||
}
|
||||
z.parent.color = "black";
|
||||
if (z.parent.parent) z.parent.parent.color = "red";
|
||||
this.leftRotate(z.parent.parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.root.color = "black";
|
||||
}
|
||||
|
||||
function leftRotate(x) {
|
||||
if (!x) return;
|
||||
local y = x.right;
|
||||
x.right = y.left;
|
||||
if (y.left != this.nil) {
|
||||
y.left.parent = x;
|
||||
}
|
||||
y.parent = x.parent;
|
||||
if (x.parent == this.nil) {
|
||||
this.root = y;
|
||||
} else if (x == x.parent.left) {
|
||||
x.parent.left = y;
|
||||
} else {
|
||||
x.parent.right = y;
|
||||
}
|
||||
y.left = x;
|
||||
x.parent = y;
|
||||
}
|
||||
|
||||
function rightRotate(x) {
|
||||
local y = x.left;
|
||||
x.left = y.right;
|
||||
if (y.right != this.nil) {
|
||||
y.right.parent = x;
|
||||
}
|
||||
y.parent = x.parent;
|
||||
if (x.parent == this.nil) {
|
||||
this.root = y;
|
||||
} else if (x == x.parent.left) {
|
||||
x.parent.left = y;
|
||||
} else {
|
||||
x.parent.right = y;
|
||||
}
|
||||
y.right = x;
|
||||
x.parent = y;
|
||||
}
|
||||
|
||||
|
||||
function minimum(...) {
|
||||
local node = this.root;
|
||||
if (vargv.len() > 0) node = vargv[0];
|
||||
while (node.left != this.nil) {
|
||||
node = node.left;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function transplant(u, v) {
|
||||
if (u.parent == this.nil) {
|
||||
this.root = v;
|
||||
} else if (u == u.parent.left) {
|
||||
u.parent.left = v;
|
||||
} else {
|
||||
u.parent.right = v;
|
||||
}
|
||||
v.parent = u.parent;
|
||||
}
|
||||
|
||||
function deleteFixup(x) {
|
||||
while (x != this.root && x.color == "black") {
|
||||
if (x == x.parent.left) {
|
||||
local w = x.parent.right;
|
||||
if (w.color == "red") {
|
||||
w.color = "black";
|
||||
x.parent.color = "red";
|
||||
this.leftRotate(x.parent);
|
||||
w = x.parent.right;
|
||||
}
|
||||
if (w.left.color == "black" && w.right.color == "black") {
|
||||
w.color = "red";
|
||||
x = x.parent;
|
||||
} else {
|
||||
if (w.right.color == "black") {
|
||||
w.left.color = "black";
|
||||
w.color = "red";
|
||||
this.rightRotate(w);
|
||||
w = x.parent.right;
|
||||
}
|
||||
w.color = x.parent.color;
|
||||
x.parent.color = "black";
|
||||
w.right.color = "black";
|
||||
this.leftRotate(x.parent);
|
||||
x = this.root;
|
||||
}
|
||||
} else {
|
||||
local w = x.parent.left;
|
||||
if (w.color == "red") {
|
||||
w.color = "black";
|
||||
x.parent.color = "red";
|
||||
this.rightRotate(x.parent);
|
||||
w = x.parent.left;
|
||||
}
|
||||
if (w.right.color == "black" && w.left.color == "black") {
|
||||
w.color = "red";
|
||||
x = x.parent;
|
||||
} else {
|
||||
if (w.left.color == "black") {
|
||||
w.right.color = "black";
|
||||
w.color = "red";
|
||||
this.leftRotate(w);
|
||||
w = x.parent.left;
|
||||
}
|
||||
w.color = x.parent.color;
|
||||
x.parent.color = "black";
|
||||
w.left.color = "black";
|
||||
this.rightRotate(x.parent);
|
||||
x = this.root;
|
||||
}
|
||||
}
|
||||
}
|
||||
x.color = "black";
|
||||
}
|
||||
|
||||
function deleteNode(z) {
|
||||
local y = z;
|
||||
local yOriginalColor = y.color;
|
||||
local x;
|
||||
if (z.left == this.nil) {
|
||||
x = z.right;
|
||||
this.transplant(z, z.right);
|
||||
} else if (z.right == this.nil) {
|
||||
x = z.left;
|
||||
this.transplant(z, z.left);
|
||||
} else {
|
||||
y = this.minimum(z.right);
|
||||
yOriginalColor = y.color;
|
||||
x = y.right;
|
||||
if (y.parent == z) {
|
||||
x.parent = y;
|
||||
} else {
|
||||
this.transplant(y, y.right);
|
||||
y.right = z.right;
|
||||
y.right.parent = y;
|
||||
}
|
||||
this.transplant(z, y);
|
||||
y.left = z.left;
|
||||
y.left.parent = y;
|
||||
y.color = z.color;
|
||||
}
|
||||
if (yOriginalColor == "black") {
|
||||
this.deleteFixup(x);
|
||||
}
|
||||
this.size--;
|
||||
}
|
||||
|
||||
function inorderTraversal(...) {
|
||||
local node = this.root;
|
||||
if (vargv.len() > 0) node = vargv[0];
|
||||
if (node == this.nil) {
|
||||
return;
|
||||
}
|
||||
this.inorderTraversal(node.left);
|
||||
print(node.key + "(" + node.color + ") ");
|
||||
this.inorderTraversal(node.right);
|
||||
}
|
||||
|
||||
function getSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
function pop() {
|
||||
if (this.size <= 0) return null;
|
||||
local z = this.minimum();
|
||||
if (z != this.nil) {
|
||||
this.deleteNode(z);
|
||||
return z;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function GetPop() {
|
||||
if (this.size <= 0) return null;
|
||||
local z = this.minimum();
|
||||
if (z != this.nil) {
|
||||
return z;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function findNodeByName(node,name) {
|
||||
if (node == this.nil) {
|
||||
return null;
|
||||
}
|
||||
if (node.name == name) {
|
||||
return node;
|
||||
}
|
||||
local leftResult = findNodeByName(node.left, name);
|
||||
if (leftResult) {
|
||||
return leftResult;
|
||||
}
|
||||
return findNodeByName(node.right, name);
|
||||
}
|
||||
|
||||
// 新增方法:根据 name 移除节点
|
||||
function removeNodeByName(name) {
|
||||
local targetNode = this.findNodeByName(this.root,name);
|
||||
if (targetNode) {
|
||||
this.deleteNode(targetNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
文件名:ScriptManager.nut
|
||||
路径:Core/BaseClass/ScriptManager/ScriptManager.nut
|
||||
创建日期:2024-10-11 12:24
|
||||
文件用途:pvf 管理器
|
||||
*/
|
||||
class Script {
|
||||
|
||||
C_Object = null;
|
||||
|
||||
constructor(Path = "/home/neople/game/Script.pvf") {
|
||||
print("正在初始化PVF...");
|
||||
local StartTime = time();
|
||||
|
||||
C_Object = Asset_LoadScript(Path);
|
||||
|
||||
print("PVF初始化完毕!!!");
|
||||
print("用时: " + (time() - StartTime) + "秒");
|
||||
getroottable()._Script_Data_ <- this;
|
||||
}
|
||||
|
||||
|
||||
function GetFileInfo(Path) {
|
||||
local size = Asset_GetPvfFileSize(C_Object, Path);
|
||||
if (size) {
|
||||
local blobobj = blobex(size);
|
||||
Asset_GetPvfFile(C_Object, Path, blobobj);
|
||||
return blobobj;
|
||||
} else return null;
|
||||
}
|
||||
|
||||
function GetBinString(Key) {
|
||||
return Asset_GetPvfBinString(C_Object, Key);
|
||||
}
|
||||
|
||||
function GetLoadString(Type, Key) {
|
||||
return Asset_GetPvfLoadString(C_Object, Type, Key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class _PVF_Data_ {
|
||||
//数据
|
||||
Data = null;
|
||||
//位置
|
||||
Pos = 0;
|
||||
//最大值
|
||||
Max = 0;
|
||||
|
||||
function _typeof() {
|
||||
return "pvf_data";
|
||||
}
|
||||
|
||||
constructor(gData) {
|
||||
Data = gData;
|
||||
Max = gData.len();
|
||||
}
|
||||
|
||||
function Last() {
|
||||
if (Pos > 0) {
|
||||
Pos--;
|
||||
return Get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function Seek(i) {
|
||||
if (Pos > 0 && Pos<(Max - 1)) {
|
||||
Pos = i;
|
||||
}
|
||||
}
|
||||
|
||||
function Seekg(i) {
|
||||
Pos += i;
|
||||
}
|
||||
|
||||
function Get() {
|
||||
local Ret = Data[Pos];
|
||||
if (Pos<(Max - 1)) {
|
||||
Pos++;
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
function Eof() {
|
||||
if (Pos == Max - 1)
|
||||
return true;
|
||||
}
|
||||
|
||||
function Next() {
|
||||
if (Pos<(Max - 1)) {
|
||||
Pos++;
|
||||
return Get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class GlobaData {
|
||||
//动画文件Map
|
||||
Ani = null;
|
||||
|
||||
constructor() {
|
||||
Ani = {};
|
||||
}
|
||||
|
||||
//获取文件的IO
|
||||
function GetFile(Path) {
|
||||
return getroottable()._Script_Data_.GetFileInfo(Path);
|
||||
}
|
||||
|
||||
//获取文件并处理
|
||||
function GetFileData(Path, Func) {
|
||||
local IO = GetFile(Path);
|
||||
if (IO) {
|
||||
return ResolvingData(IO, Func, Path);
|
||||
} else {
|
||||
print(Path + "找不到文件!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//获取动画文件
|
||||
function GetAni(Path) {
|
||||
if (Path in Ani)
|
||||
return Ani[Path];
|
||||
else {
|
||||
local IO = GetFile(Path);
|
||||
if (IO) {
|
||||
Ani[Path] <- InitPvfAni(IO);
|
||||
Ani[Path].filepath <- Path;
|
||||
return Ani[Path];
|
||||
} else {
|
||||
print(Path + "找不到文件!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ResolvingData(IO, Func, Path) {
|
||||
local DataTable = {};
|
||||
DataTable.filepath <- Path;
|
||||
local Type = Path.slice(0, Path.find("/")).tolower();
|
||||
local DataArr = [];
|
||||
local Length = IO.len();
|
||||
if (Length >= 7) {
|
||||
local i = 2;
|
||||
while (true) {
|
||||
if (i< Length && Length - i >= 5) {
|
||||
local str = UnpackData(IO, i, Type);
|
||||
i += 5;
|
||||
DataArr.push(str);
|
||||
} else break;
|
||||
}
|
||||
Func(DataTable, _PVF_Data_(DataArr));
|
||||
return DataTable;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function UnpackData(IO, i, Type) {
|
||||
IO.seek(i); //内容指示位
|
||||
local currentByte = IO.readn('c'); //内容指示位
|
||||
local after = IO.GetInt();
|
||||
switch (currentByte) {
|
||||
case 9: {
|
||||
local NewcurrentByte = IO.readn('c'); //内容指示位
|
||||
local Newafter = IO.GetInt();
|
||||
local Buf = getroottable()._Script_Data_.GetBinString(Newafter);
|
||||
if (!Buf) {
|
||||
Buf = "";
|
||||
} else {
|
||||
Buf = getroottable()._Script_Data_.GetLoadString(Type, Buf);
|
||||
}
|
||||
return Buf;
|
||||
}
|
||||
case 10: {
|
||||
local Buf = getroottable()._Script_Data_.GetBinString(after);
|
||||
if (!Buf) {
|
||||
Buf = "";
|
||||
} else {
|
||||
Buf = getroottable()._Script_Data_.GetLoadString(Type, Buf);
|
||||
}
|
||||
return Buf;
|
||||
}
|
||||
case 2: {
|
||||
IO.seek(-4, 'c');
|
||||
local ret = IO.readn('i');
|
||||
return ret;
|
||||
}
|
||||
case 4: {
|
||||
local Bbuf = blob(4);
|
||||
Bbuf.writen(after, 'i');
|
||||
Bbuf.seek(0);
|
||||
local Buf = Bbuf.readn('f');
|
||||
return Buf.tofloat();
|
||||
}
|
||||
case 6:
|
||||
case 8:
|
||||
case 7:
|
||||
case 5: {
|
||||
local Buf = getroottable()._Script_Data_.GetBinString(after);
|
||||
if (!Buf) Buf = "";
|
||||
return Buf;
|
||||
}
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
getroottable().ScriptData <- GlobaData();
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
文件名:SocketBase.nut
|
||||
路径:BaseClass/Socket/SocketBase.nut
|
||||
创建日期:2024-04-10 10:13
|
||||
文件用途:套接字连接
|
||||
*/
|
||||
//todo 公告接口
|
||||
|
||||
class Socket {
|
||||
|
||||
/*
|
||||
* @函数作用: 发送包给插件网关
|
||||
* @参数 Table
|
||||
* @返回值
|
||||
*/
|
||||
function SendGateway(T) {
|
||||
local str = Json.Encode(T);
|
||||
if (PacketDebugModel) print("发送包给网关: " + str);
|
||||
if (getroottable().rawin("Sq_SendPackToGateway")) Sq_SendPackToGateway(str);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//网关链接建立回调Map
|
||||
if (!getroottable().rawin("OnGatewaySocketConnectFunc")) OnGatewaySocketConnectFunc <- {};
|
||||
//插件网关建立连接时
|
||||
function OnGatewaySocketConnect() {
|
||||
print("############凌众插件连接建立############");
|
||||
print("############凌众插件连接建立############");
|
||||
print("############凌众插件连接建立############");
|
||||
print("############凌众插件连接建立############");
|
||||
local Jso = {
|
||||
op = 10001,
|
||||
channel = Sq_Game_GetConfig(),
|
||||
type = 1
|
||||
}
|
||||
Socket.SendGateway(Jso);
|
||||
|
||||
foreach(value in OnGatewaySocketConnectFunc) {
|
||||
value();
|
||||
}
|
||||
}
|
||||
//网关包回调Map
|
||||
if (!getroottable().rawin("GatewaySocketPackFuncMap")) GatewaySocketPackFuncMap <- {}
|
||||
//插件网关收到包时
|
||||
function OnGatewaySocketMsg(Msg) {
|
||||
if (PacketDebugModel) print("收到网关包:" + Msg);
|
||||
local Jso = Json.Decode(Msg);
|
||||
if (!("op" in Jso)) {
|
||||
if (PacketDebugModel) print("收到空op包");
|
||||
return;
|
||||
}
|
||||
if (Jso.op in GatewaySocketPackFuncMap) {
|
||||
GatewaySocketPackFuncMap[Jso.op](Jso);
|
||||
} else {
|
||||
// print(Msg);
|
||||
local SUser = World.GetUserByUidCid(Jso.uid, Jso.cid);
|
||||
if (SUser) {
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(1, 130);
|
||||
Pack.Put_Byte(1);
|
||||
Pack.Put_Int(Msg.len());
|
||||
Pack.Put_Binary(Msg);
|
||||
Pack.Finalize(true);
|
||||
SUser.Send(Pack);
|
||||
Pack.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//公用接口
|
||||
/*
|
||||
* @函数作用: 调用玩家移动城镇
|
||||
* @参数 Jso 需要参数uid cid town regionId
|
||||
* @返回值
|
||||
*/
|
||||
GatewaySocketPackFuncMap[20240408] <- function(Jso) {
|
||||
local SUser = World.GetUserByUidCid(Jso.uid, Jso.cid);
|
||||
if (SUser) {
|
||||
World.MoveArea(SUser, Jso.town, Jso.regionId, Jso.X, Jso.Y);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* @函数作用: 让指定玩家组队并进入副本
|
||||
* @参数 Jso 需要参数uid cid Member 最外层uid cid 确定队长 Member 里面是一个uid 和 cid 信息对象的List 注意队长不要放进去
|
||||
* @返回值
|
||||
*/
|
||||
GatewaySocketPackFuncMap[20240416] <- function(Jso) {
|
||||
local SUser = World.GetUserByUidCid(Jso.uid, Jso.cid);
|
||||
if (SUser) {
|
||||
local Gm = GameManager();
|
||||
local SParty = Gm.GetParty();
|
||||
SParty.Create(SUser);
|
||||
foreach(_Index, PlayerInfo in Jso.Member) {
|
||||
local UserBuf = World.GetUserByUidCid(PlayerInfo.uid, PlayerInfo.cid);
|
||||
if (UserBuf) {
|
||||
SParty.Join(UserBuf);
|
||||
}
|
||||
}
|
||||
SParty.SendIpInfo();
|
||||
World.SendPartyInfoToAll(SParty);
|
||||
if (Jso.map != 0) {
|
||||
local T = {
|
||||
op = 2024041602,
|
||||
map = Jso.map
|
||||
}
|
||||
SUser.SendJso(T);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************
|
||||
**************** ****************
|
||||
************************************************/
|
||||
|
||||
//客户端包回调Map
|
||||
if (!getroottable().rawin("ClientSocketPackFuncMap")) ClientSocketPackFuncMap <- {}
|
||||
if (!getroottable().rawin("ClientSocketDP_SPackFuncMap")) ClientSocketDP_SPackFuncMap <- {}
|
||||
|
||||
|
||||
//收到来自客户端的包 只有130
|
||||
function OnClientSocketMsg(C_User, C_Pack_Str) {
|
||||
if (PacketDebugModel) print("收到客户端包: " + C_Pack_Str);
|
||||
|
||||
local Jso = Json.Decode(C_Pack_Str);
|
||||
if (Jso.op == 2147483646) {
|
||||
if (Jso.dps_id in ClientSocketDP_SPackFuncMap) {
|
||||
Jso.rawdelete("op");
|
||||
local SUser = User(C_User);
|
||||
ClientSocketDP_SPackFuncMap[Jso.dps_id](SUser, Jso);
|
||||
}
|
||||
} else {
|
||||
if (Jso.op in ClientSocketPackFuncMap) {
|
||||
local SUser = User(C_User);
|
||||
ClientSocketPackFuncMap[Jso.op](SUser, Jso);
|
||||
} else {
|
||||
local SUser = User(C_User);
|
||||
if (SUser) {
|
||||
Jso.uid <- SUser.GetUID();
|
||||
Jso.cid <- SUser.GetCID();
|
||||
Socket.SendGateway(Jso);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Register_DPS_Pack(Id, Func) {
|
||||
ClientSocketDP_SPackFuncMap.rawset(Id, Func);
|
||||
}
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
文件名:TimerClass.nut
|
||||
路径:Dps_A/BaseClass/TimerClass/TimerClass.nut
|
||||
创建日期:2024-09-19 12:39
|
||||
文件用途:定时器类
|
||||
*/
|
||||
class Timer {
|
||||
//执行任务队列树
|
||||
Wait_Exec_Tree = null;
|
||||
//定时执行任务队列树
|
||||
Date_Exec_Tree = null;
|
||||
|
||||
constructor() {
|
||||
Wait_Exec_Tree = RedBlackTree();
|
||||
Date_Exec_Tree = RedBlackTree();
|
||||
|
||||
Cb_timer_dispatch_Func.rawset("__System__Timer__Event", Update.bindenv(this));
|
||||
}
|
||||
|
||||
function ClockTime() {
|
||||
return Sq_GetTimestampString().slice(-9).tointeger();
|
||||
}
|
||||
|
||||
//检测延时任务
|
||||
function CheckTimeOut() {
|
||||
local Node = Wait_Exec_Tree.GetPop();
|
||||
if (!Node) {
|
||||
return;
|
||||
}
|
||||
//取得函数体
|
||||
local Info = Node.Info;
|
||||
//执行时间
|
||||
local exec_time = Node.time;
|
||||
//如果没到执行时间,就不管
|
||||
if (ClockTime() <= exec_time) {
|
||||
return;
|
||||
}
|
||||
//该执行了从树中删除这个元素
|
||||
Wait_Exec_Tree.pop();
|
||||
|
||||
//函数
|
||||
local func = Info[0];
|
||||
//参数
|
||||
local func_args = Info[1];
|
||||
//执行函数
|
||||
func.acall(func_args);
|
||||
}
|
||||
|
||||
function SetTimeOut(target_func, delay_time, ...) {
|
||||
local target_arg_list = [];
|
||||
target_arg_list.push(getroottable());
|
||||
for (local i = 0; i< vargv.len(); i++) {
|
||||
target_arg_list.push(vargv[i]);
|
||||
}
|
||||
//当前时间戳,单位:秒
|
||||
local time_sec = ClockTime();
|
||||
//计算下一次执行的时间
|
||||
local exec_time_sec = time_sec + delay_time;
|
||||
//设置下一次执行
|
||||
local func_info = [];
|
||||
|
||||
func_info.push(target_func);
|
||||
func_info.push(target_arg_list);
|
||||
|
||||
_Timer_Object.Wait_Exec_Tree.insert(exec_time_sec, func_info);
|
||||
}
|
||||
|
||||
//检测定时任务
|
||||
function CheckCronTask() {
|
||||
local Node = Date_Exec_Tree.GetPop();
|
||||
if (!Node) {
|
||||
return;
|
||||
}
|
||||
//取得函数体
|
||||
local Info = Node.Info;
|
||||
//执行时间
|
||||
local exec_time = Node.time;
|
||||
//如果没到执行时间,放回去,等待下次扫描
|
||||
if (time() <= exec_time) {
|
||||
// Date_Exec_Tree.insert(exec_time, Node.Info);
|
||||
return;
|
||||
}
|
||||
Date_Exec_Tree.pop();
|
||||
//函数
|
||||
local func = Info[0];
|
||||
//参数
|
||||
local func_args = Info[1];
|
||||
//Cron字符串
|
||||
local NextTimestep = Info[2];
|
||||
//执行函数
|
||||
local Flag = func.acall(func_args);
|
||||
//继续构建下一次任务
|
||||
if(Flag == null || Flag == true) Date_Exec_Tree.insert(Sq_Cron_Next(NextTimestep, time()), Info, Node.name);
|
||||
}
|
||||
|
||||
function SetCronTask(target_func, build_info, ...) {
|
||||
local CronString = "";
|
||||
local TaskName = null;
|
||||
//如果是字符串直接就是Cron字符串
|
||||
if (typeof build_info == "string") {
|
||||
CronString = build_info;
|
||||
}
|
||||
//如果是Table 则有名字
|
||||
else if (typeof build_info == "table") {
|
||||
CronString = build_info.Cron;
|
||||
TaskName = build_info.Name;
|
||||
}
|
||||
|
||||
local NowTimestep = time();
|
||||
|
||||
//下一次执行的时间
|
||||
local NextTimestep = Sq_Cron_Next(CronString, NowTimestep);
|
||||
|
||||
local target_arg_list = [];
|
||||
target_arg_list.push(getroottable());
|
||||
for (local i = 0; i< vargv.len(); i++) {
|
||||
target_arg_list.push(vargv[i]);
|
||||
}
|
||||
|
||||
//设置下一次执行
|
||||
local func_info = [];
|
||||
|
||||
//函数体
|
||||
func_info.push(target_func);
|
||||
//参数列表
|
||||
func_info.push(target_arg_list);
|
||||
//间隔时间戳时间
|
||||
func_info.push(CronString);
|
||||
|
||||
_Timer_Object.Date_Exec_Tree.insert(NextTimestep, func_info, TaskName);
|
||||
}
|
||||
|
||||
function RemoveCronTask(name) {
|
||||
_Timer_Object.Date_Exec_Tree.removeNodeByName(name);
|
||||
}
|
||||
|
||||
function Update() {
|
||||
CheckTimeOut();
|
||||
CheckCronTask();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
文件名:AccountCargoClass.nut
|
||||
路径:Dps_A/BaseClass/AccountCargoClass/AccountCargoClass.nut
|
||||
创建日期:2024-09-16 10:00
|
||||
文件用途:账号金库类
|
||||
*/
|
||||
class AccountCargo extends Base_C_Object {
|
||||
|
||||
SUser = null;
|
||||
|
||||
constructor(CObject, gSUser) {
|
||||
base.constructor(CObject);
|
||||
SUser = gSUser;
|
||||
}
|
||||
|
||||
//获取空格子
|
||||
function GetEmptySlot() {
|
||||
return Sq_CallFunc(S_Ptr("0x0828a580"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
|
||||
//存储物品
|
||||
function InsertItem(ItemObj, Slot) {
|
||||
Sq_CallFunc(S_Ptr("0x08289c82"), "int", ["pointer", "pointer", "int"], this.C_Object, ItemObj.C_Object, Slot);
|
||||
}
|
||||
|
||||
//刷新列表
|
||||
function SendItemList() {
|
||||
return Sq_CallFunc(S_Ptr("0x0828a88a"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,860 @@
|
|||
class User extends Base_C_Object {
|
||||
|
||||
|
||||
constructor(gObject) {
|
||||
|
||||
base.constructor(gObject);
|
||||
}
|
||||
|
||||
//获得当前区域
|
||||
//@param b boolean
|
||||
//@return integer
|
||||
function GetArea(b) {
|
||||
return Sq_CUser_GetAreaIndex(this.C_Object, b);
|
||||
}
|
||||
|
||||
//获得当前区域位置
|
||||
//@return integer, integer
|
||||
function GetAreaPos() {
|
||||
return {
|
||||
X = Sq_CUser_GetPosX(this.C_Object),
|
||||
Y = Sq_CUser_GetPosY(this.C_Object)
|
||||
};
|
||||
}
|
||||
|
||||
//获得朝向
|
||||
//@return integer, integer
|
||||
function GetDirections() {
|
||||
return Sq_CUser_Direction(this.C_Object);
|
||||
}
|
||||
|
||||
//获得可见values
|
||||
//@return integer, integer
|
||||
function GetVisibleValues() {
|
||||
return Sq_CUser_GetVisibleValues(this.C_Object);
|
||||
}
|
||||
|
||||
//获得当前城镇位置
|
||||
//@return integer, integer, integer, integer @城镇, 区域, X, Y
|
||||
function GetLocation() {
|
||||
return {
|
||||
Pos = this.GetAreaPos(),
|
||||
Town = Sq_CUser_GetTownIndex(this.C_Object),
|
||||
Area = Sq_CUser_GetAreaIndex(this.C_Object)
|
||||
};
|
||||
}
|
||||
|
||||
//账号状态
|
||||
//@return integer @after login >= 3
|
||||
function GetState() {
|
||||
return Sq_CUser_GetState(this.C_Object);
|
||||
}
|
||||
|
||||
//角色数量
|
||||
//@return integer
|
||||
function GetCharacCount() {
|
||||
return Sq_CUser_GetCharacCount(this.C_Object);
|
||||
}
|
||||
|
||||
//账号ID
|
||||
//@return integer
|
||||
function GetUID() {
|
||||
return Sq_CUser_GetAccId(this.C_Object);
|
||||
}
|
||||
|
||||
//唯一ID
|
||||
//@return integer
|
||||
function GetUniqueId() {
|
||||
return Sq_CUser_GetUniqueId(this.C_Object);
|
||||
}
|
||||
|
||||
//角色ID
|
||||
//@return integer
|
||||
function GetCID() {
|
||||
return Sq_CUser_GetCharacNo(this.C_Object);
|
||||
}
|
||||
|
||||
//角色职业
|
||||
//@return integer
|
||||
function GetCharacJob() {
|
||||
return Sq_CUser_GetCharacJob(this.C_Object);
|
||||
}
|
||||
|
||||
//角色名称
|
||||
//@return string
|
||||
function GetCharacName() {
|
||||
return Sq_CUser_GetCharacName(this.C_Object);
|
||||
}
|
||||
|
||||
//角色等级
|
||||
//@return integer
|
||||
function GetCharacLevel() {
|
||||
return Sq_CUser_GetCharacLevel(this.C_Object);
|
||||
}
|
||||
|
||||
//设置角色等级
|
||||
//@param new_level integer
|
||||
//@return boolean
|
||||
function SetCharacLevel(new_level) {
|
||||
Sq_CUser_ChangeGmQuestFlag(this.C_Object, 1);
|
||||
Sq_CallFunc(S_Ptr("0x0858EFDE"), "int", ["pointer", "pointer", "int"], S_Ptr("0x0"), this.C_Object, new_level);
|
||||
Sq_CUser_ChangeGmQuestFlag(this.C_Object, 0);
|
||||
}
|
||||
|
||||
//角色转职职业
|
||||
//@return integer
|
||||
function GetCharacGrowType() {
|
||||
return Sq_CUser_GetCharacGrowType(this.C_Object);
|
||||
}
|
||||
|
||||
//角色觉醒职业
|
||||
//@return integer
|
||||
function GetCharacSecondGrowType() {
|
||||
return Sq_CUser_GetCharacSecondGrowType(this.C_Object);
|
||||
}
|
||||
|
||||
//更改转职职业 转职职业 是否觉醒
|
||||
function ChangeGrowType(GrowType, IsAwa) {
|
||||
Sq_CUser_ChangeGrowType(this.C_Object, GrowType, IsAwa);
|
||||
}
|
||||
|
||||
//已用疲劳值
|
||||
//@return integer
|
||||
function GetFatigue() {
|
||||
return Sq_CUser_GetFatigue(this.C_Object);
|
||||
}
|
||||
|
||||
//最大疲劳值
|
||||
//@return integer
|
||||
function GetMaxFatigue() {
|
||||
return Sq_CUser_GetMaxFatigue(this.C_Object);
|
||||
}
|
||||
|
||||
//获取背包
|
||||
//@return integer
|
||||
function GetInven() {
|
||||
local P = Sq_Inven_GetInven(this.C_Object);
|
||||
if (P) {
|
||||
return Inven(P, this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//踢人
|
||||
//@param src integer @渠道
|
||||
//@param p2 integer
|
||||
//@param p3 integer
|
||||
//@return integer @错误码?
|
||||
function Kick(...) {
|
||||
local src;
|
||||
local p2;
|
||||
local p3;
|
||||
for (local i = 0; i< vargv.len(); i++) {
|
||||
if (i == 0) src = vargv[i];
|
||||
if (i == 1) p2 = vargv[i];
|
||||
if (i == 2) p3 = vargv[i];
|
||||
}
|
||||
|
||||
return Sq_CUser_DisConnSig(this.C_Object, src ? src : 0, p2 ? p2 : 0, p3 ? p3 : 0)
|
||||
}
|
||||
|
||||
//踢人
|
||||
//@param err @错误号
|
||||
//@return integer
|
||||
function DisConn(err) {
|
||||
return this.Kick(10, 1, err ? err : 1)
|
||||
}
|
||||
|
||||
//当前小队/副本
|
||||
//@return CParty
|
||||
function GetParty() {
|
||||
local Ret = Sq_CUser_GetParty(this.C_Object);
|
||||
if (Ret) {
|
||||
return Party(Ret);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
//是否在领主塔
|
||||
//@return boolean
|
||||
function CheckInBossTower() {
|
||||
return (Sq_CUser_CheckInBossTower(this.C_Object) == 1);
|
||||
}
|
||||
|
||||
//是否在龙之路
|
||||
//@return boolean
|
||||
function CheckInBlueMarble() {
|
||||
return (Sq_CUser_CheckInBlueMarble(this.C_Object) == 1);
|
||||
}
|
||||
|
||||
//是否开启GM权限
|
||||
//@return boolean
|
||||
function IsGmMode() {
|
||||
return (Sq_CUser_IsGmMode(this.C_Object) != 0);
|
||||
}
|
||||
|
||||
//获取账号上次退出游戏的时间
|
||||
function GetCurCharacLastPlayTick() {
|
||||
return Sq_CUser_GetCurCharacLastPlayTick(this.C_Object);
|
||||
}
|
||||
|
||||
//获取账号本次登录游戏的时间
|
||||
function GetCurCharacLoginTick() {
|
||||
return Sq_CallFunc(S_Ptr("0x822F692"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
|
||||
//获得公网地址
|
||||
//@return integer
|
||||
function GetIpAddress() {
|
||||
return Sq_CallFunc(S_Ptr("0x84EC90A"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
|
||||
//发包
|
||||
function Send(SPacket) {
|
||||
Sq_Packet_Send(this.C_Object, SPacket.C_Object);
|
||||
}
|
||||
|
||||
//发送弹窗公告包(可自定义文字需要客户端修复233dll搭配)
|
||||
function SendNotiBox(Msg, Type) {
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(0, 233);
|
||||
Pack.Put_Byte(1);
|
||||
Pack.Put_Byte(5);
|
||||
Pack.Put_Int(Msg.len());
|
||||
Pack.Put_BinaryEx(Str_Ptr(Msg), Msg.len());
|
||||
Pack.Finalize(true);
|
||||
Sq_CallFunc(S_Ptr("0x867B8FE"), "int", ["pointer", "int", "pointer"], this.C_Object, Type, Pack.C_Object);
|
||||
Pack.Delete();
|
||||
}
|
||||
|
||||
//发送自定义包
|
||||
function SendJso(Jso) {
|
||||
local Str = Json.Encode(Jso);
|
||||
if (PacketDebugModel) print("发送包给客户端: " + Str);
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(1, 130);
|
||||
Pack.Put_Byte(1);
|
||||
Pack.Put_Int(Str.len());
|
||||
Pack.Put_Binary(Str);
|
||||
Pack.Finalize(true);
|
||||
Send(Pack);
|
||||
Pack.Delete();
|
||||
}
|
||||
|
||||
//发送字节包
|
||||
function SendBlob(Np) {
|
||||
if(!Np || Np.Size == -1)return;
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(1, 131);
|
||||
Pack.Put_Byte(1);
|
||||
Pack.Put_Int(Np.Size);
|
||||
Pack.Put_BinaryEx(Np.C_Object,Np.Size);
|
||||
Pack.Finalize(true);
|
||||
Send(Pack);
|
||||
Pack.Delete();
|
||||
}
|
||||
|
||||
//发送自定义DPS包
|
||||
function Send_DPS_Pack(Id, Jso) {
|
||||
Jso.op <- 2147483646;
|
||||
Jso.dps_id <- Id;
|
||||
SendJso(Jso);
|
||||
}
|
||||
|
||||
|
||||
//发送消息包
|
||||
function SendNotiPacket(Type1, Type2, Type3) {
|
||||
Sq_CUser_SendNotiPacket(this.C_Object, Type1, Type2, Type3);
|
||||
}
|
||||
|
||||
|
||||
//获取技能树
|
||||
function GetSkillW() {
|
||||
return Sq_CUser_GetSkillW(this.C_Object);
|
||||
}
|
||||
|
||||
//重置技能树 转职编号 是否觉醒
|
||||
function InitSkillW(GrowType, IsAwa) {
|
||||
Sq_CUser_InitSkillW(Sq_CUser_GetSkillW(this.C_Object), GrowType, IsAwa);
|
||||
}
|
||||
|
||||
//发送公告消息
|
||||
function SendNotiPacketMessage(String, Type) {
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(0, 12);
|
||||
Pack.Put_Byte(Type);
|
||||
Pack.Put_Short(0);
|
||||
Pack.Put_Byte(0);
|
||||
Pack.Put_Int(String.len());
|
||||
Pack.Put_Binary(String);
|
||||
Pack.Finalize(true);
|
||||
this.Send(Pack);
|
||||
Pack.Delete();
|
||||
}
|
||||
|
||||
//发送公告消息 字符串数组
|
||||
function SendNotiForColorPacketMessage(StringArr, Type) {
|
||||
|
||||
local ColorArr = [];
|
||||
local SendStrBlob = blob(1);
|
||||
SendStrBlob.writen(0xc2, 'c');
|
||||
SendStrBlob.writen(0x80, 'c');
|
||||
foreach(sobj in StringArr) {
|
||||
local StrPoint = Str_Ptr(sobj[0]);
|
||||
local StrPointB = Sq_Point2Blob(StrPoint, sobj[0].len());
|
||||
if (sobj[1]) {
|
||||
SendStrBlob.writen(0xc2, 'c');
|
||||
SendStrBlob.writen(0x80, 'c');
|
||||
SendStrBlob.writeblob(StrPointB);
|
||||
SendStrBlob.writen(0xc2, 'c');
|
||||
SendStrBlob.writen(0x80, 'c');
|
||||
|
||||
local ColorBlob = blob(104);
|
||||
for (local i = 0; i< 3; i++) {
|
||||
ColorBlob.writen(sobj[2][i], 'c');
|
||||
}
|
||||
for (local i = 0; i< 101; i++) {
|
||||
ColorBlob.writen(0xff, 'c');
|
||||
}
|
||||
local ColorPoint = Sq_New_Point(104);
|
||||
Sq_WriteBlobToAddress(ColorPoint, ColorBlob);
|
||||
ColorArr.append(ColorPoint);
|
||||
|
||||
} else {
|
||||
SendStrBlob.writeblob(StrPointB);
|
||||
}
|
||||
}
|
||||
|
||||
local SendStrLen = SendStrBlob.len();
|
||||
local SendStrPoint = Sq_New_Point(SendStrLen);
|
||||
Sq_WriteBlobToAddress(SendStrPoint, SendStrBlob);
|
||||
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(0, 370);
|
||||
Pack.Put_Byte(Type);
|
||||
Pack.Put_Short(0);
|
||||
Pack.Put_Byte(3);
|
||||
Pack.Put_Int(SendStrLen);
|
||||
Pack.Put_BinaryEx(SendStrPoint, SendStrLen);
|
||||
Pack.Put_Byte(ColorArr.len());
|
||||
foreach(color in ColorArr) {
|
||||
Pack.Put_BinaryEx(color, 3);
|
||||
}
|
||||
Pack.Finalize(true);
|
||||
Send(Pack);
|
||||
Pack.Delete();
|
||||
SendItemSpace(0);
|
||||
|
||||
Sq_Delete_Point(SendStrPoint);
|
||||
for (local i = 0; i< ColorArr.len(); i++) {
|
||||
Sq_Delete_Point(ColorArr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//发送公告消息 字符串数组 带ID
|
||||
function SendNotiForColorAIdPacketMessage(StringArr, Type) {
|
||||
local ColorArr = [];
|
||||
local SendStrBlob = blob(1);
|
||||
SendStrBlob.writen(0xc2, 'c');
|
||||
SendStrBlob.writen(0x80, 'c');
|
||||
foreach(sobj in StringArr) {
|
||||
local StrPoint = Str_Ptr(sobj[0]);
|
||||
local StrPointB = Sq_Point2Blob(StrPoint, sobj[0].len());
|
||||
if (sobj[1]) {
|
||||
SendStrBlob.writen(0xc2, 'c');
|
||||
SendStrBlob.writen(0x80, 'c');
|
||||
SendStrBlob.writeblob(StrPointB);
|
||||
SendStrBlob.writen(0xc2, 'c');
|
||||
SendStrBlob.writen(0x80, 'c');
|
||||
|
||||
local ColorBlob = blob(104);
|
||||
for (local i = 0; i< 3; i++) {
|
||||
ColorBlob.writen(sobj[2][i], 'c');
|
||||
}
|
||||
if (sobj[3]) {
|
||||
ColorBlob.seek(4);
|
||||
ColorBlob.writen(sobj[3], 'i');
|
||||
} else {
|
||||
for (local i = 0; i< 101; i++) {
|
||||
ColorBlob.writen(0xff, 'c');
|
||||
}
|
||||
}
|
||||
local ColorPoint = Sq_New_Point(104);
|
||||
Sq_WriteBlobToAddress(ColorPoint, ColorBlob);
|
||||
ColorArr.append(ColorPoint);
|
||||
|
||||
} else {
|
||||
SendStrBlob.writeblob(StrPointB);
|
||||
}
|
||||
}
|
||||
|
||||
local SendStrLen = SendStrBlob.len();
|
||||
local SendStrPoint = Sq_New_Point(SendStrLen);
|
||||
Sq_WriteBlobToAddress(SendStrPoint, SendStrBlob);
|
||||
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(0, 370);
|
||||
Pack.Put_Byte(Type);
|
||||
Pack.Put_Short(0);
|
||||
Pack.Put_Byte(3);
|
||||
Pack.Put_Int(SendStrLen);
|
||||
Pack.Put_BinaryEx(SendStrPoint, SendStrLen);
|
||||
Pack.Put_Byte(ColorArr.len());
|
||||
foreach(color in ColorArr) {
|
||||
Pack.Put_BinaryEx(color, 104);
|
||||
}
|
||||
Pack.Finalize(true);
|
||||
Send(Pack);
|
||||
Pack.Delete();
|
||||
SendItemSpace(0);
|
||||
Sq_Delete_Point(SendStrPoint);
|
||||
for (local i = 0; i< ColorArr.len(); i++) {
|
||||
Sq_Delete_Point(ColorArr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//调试信息包
|
||||
function Debug(Any) {
|
||||
local Time = date();
|
||||
local TStr = format("[%d年%d月%d日%d时%d分%d秒]\n", Time.year, Time.month, Time.day, Time.hour, Time.min, Time.sec);
|
||||
SendNotiPacketMessage(TStr + Any.tostring(), 8);
|
||||
}
|
||||
|
||||
//发送道具
|
||||
function GiveItem(ItemId, ItemCount) {
|
||||
//如果开了调试
|
||||
if ("DebugModelFlag" in getroottable()) {
|
||||
local Flag = PvfItem.GetPvfItemById(ItemId);
|
||||
if (!Flag) {
|
||||
print("未找到Pvf道具: " + ItemId);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
local Info = Sq_CUser_GiveUserItem(this.C_Object, ItemId, ItemCount);
|
||||
if (Info) { //发送成功就刷新背包
|
||||
Sq_CUser_SendUpdateItemList(this.C_Object, 1, Info[0], Info[1]);
|
||||
return Info;
|
||||
} else return null;
|
||||
}
|
||||
//发送道具 如果背包满则发送邮件
|
||||
function GiveItemEx(GiveTab) {
|
||||
local mitems = {};
|
||||
foreach(i, v in GiveTab) {
|
||||
local Ret = GiveItem(v.id, v.count);
|
||||
if (!Ret) mitems[v.id] <- v.count;
|
||||
}
|
||||
if (mitems.len() > 0) {
|
||||
SendMail(mitems, {
|
||||
Title = "系统",
|
||||
Text = "由于你的包裹已满, 请留出足够的空间来接收道具."
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
//更新背包栏
|
||||
function SendItemSpace(ItemSpace) {
|
||||
Sq_CallFunc(S_Ptr("0x865DB6C"), "int", ["pointer", "int"], this.C_Object, ItemSpace);
|
||||
}
|
||||
|
||||
//更新道具信息
|
||||
function SendUpdateItemList(Type, ItemSpace, Slot) {
|
||||
Sq_CUser_SendUpdateItemList(this.C_Object, Type, ItemSpace, Slot);
|
||||
}
|
||||
|
||||
//发送系统邮件
|
||||
function SendMail(ItemList, ...) {
|
||||
local SGold = 0;
|
||||
local STitle = "GM邮件";
|
||||
local SText = "这是Gm给您发送的邮件";
|
||||
if (vargv.len() > 0) {
|
||||
local T = vargv[0];
|
||||
if ("Gold" in T) SGold = T.Gold;
|
||||
if ("Title" in T) STitle = T.Title;
|
||||
if ("Text" in T) SText = T.Text;
|
||||
}
|
||||
Sq_CUser_SendMail(GetCID(), ItemList, SGold, STitle, SText);
|
||||
}
|
||||
|
||||
//无条件完成指定任务并领取奖励
|
||||
function ClearQuest_Gm(QuestId) {
|
||||
Sq_CUser_ChangeGmQuestFlag(this.C_Object, 1);
|
||||
Sq_CUser_QuestAction(this.C_Object, 33, QuestId, 0, 0);
|
||||
Sq_CUser_QuestAction(this.C_Object, 35, QuestId, 0, 0);
|
||||
Sq_CUser_QuestAction(this.C_Object, 36, QuestId, -1, 1);
|
||||
Sq_CUser_RefreshLastQuestTime(this.C_Object);
|
||||
Sq_CUser_ChangeGmQuestFlag(this.C_Object, 0);
|
||||
}
|
||||
|
||||
//充值点券
|
||||
function RechargeCera(Amount) {
|
||||
Sq_CUser_RechargeCoupons(this.C_Object, Amount);
|
||||
}
|
||||
//获取点券
|
||||
function GetCera() {
|
||||
return Sq_CallFunc(S_Ptr("0x080FDF7A"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
//充值代币券
|
||||
function RechargeCeraPoint(Amount) {
|
||||
Sq_CUser_RechargeCouponsPoint(this.C_Object, Amount);
|
||||
}
|
||||
//获取代币券
|
||||
function GetCeraPoint() {
|
||||
return Sq_CallFunc(S_Ptr("0x08692af6"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
//充值金币
|
||||
function RechargeMoney(Amount) {
|
||||
Sq_CallFunc(S_Ptr("0x84FF29C"), "int", ["pointer", "int", "int", "int", "int"], Sq_CallFunc(S_Ptr("0x80DA28E"), "pointer", ["pointer"], this.C_Object), Amount, 0, 0, 0);
|
||||
}
|
||||
//充值胜点
|
||||
function RechargeWinPoint(Amount) {
|
||||
return Sq_CallFunc(S_Ptr("0x0864fd2c"), "int", ["pointer", "int", "int"], this.C_Object, Amount, 6);
|
||||
}
|
||||
//获取胜点
|
||||
function GetWinPoint() {
|
||||
return Sq_CallFunc(S_Ptr("0x0817a17c"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
//获取复活币
|
||||
function GetCoin() {
|
||||
local Count = Sq_CallFunc(S_Ptr("0x086966b4"), "int", ["pointer"], this.C_Object) + Sq_CallFunc(S_Ptr("0x086966e0"), "int", ["pointer"], this.C_Object) + Sq_CallFunc(S_Ptr("0x0869670c"), "int", ["pointer"], this.C_Object);
|
||||
return Count;
|
||||
}
|
||||
|
||||
//离开队伍
|
||||
function LeaveParty() {
|
||||
local PartyObj = GetParty();
|
||||
if (PartyObj) {
|
||||
PartyObj.LeaveUser(this);
|
||||
}
|
||||
}
|
||||
|
||||
//放弃副本
|
||||
function GiveupDgn() {
|
||||
local PartyObj = GetParty();
|
||||
if (PartyObj) {
|
||||
PartyObj.LeaveUserOnDgn(this);
|
||||
}
|
||||
}
|
||||
|
||||
//设置玩家坐标
|
||||
function SetPosition(Xpos, Ypos, Direction) {
|
||||
Sq_CallFunc(S_Ptr("0x082F0E2A"), "pointer", ["pointer", "int", "int", "short"], this.C_Object, Xpos, Ypos, Direction);
|
||||
}
|
||||
|
||||
//获取玩家任务信息
|
||||
function GetQuest() {
|
||||
return Sq_CallFunc(S_Ptr("0x814AA5E"), "pointer", ["pointer"], this.C_Object);
|
||||
}
|
||||
|
||||
//获取玩家账号金库
|
||||
function GetAccountCargo() {
|
||||
local Ret = Sq_CallFunc(S_Ptr("0x0822fc22"), "pointer", ["pointer"], this.C_Object);
|
||||
if (Ret) return AccountCargo(Ret, this);
|
||||
else return null;
|
||||
}
|
||||
|
||||
//获取角色身上的显示时装
|
||||
function GetAva() {
|
||||
//获取背包对象
|
||||
local InvenObj = this.GetInven();
|
||||
if (!InvenObj) return;
|
||||
local re = [];
|
||||
local job = this.GetCharacJob();
|
||||
|
||||
//遍历身上的每一件装备
|
||||
for (local u = 0; u <= 10; u++) {
|
||||
local EquObj = InvenObj.GetSlot(Inven.INVENTORY_TYPE_BODY, u);
|
||||
if (EquObj && !EquObj.IsEmpty) {
|
||||
//先拿克隆id 如果这个值有 那说明带的克隆这个是被克隆的装备 直接用这个 但是如果这个人什么都没带 只带了克隆 会显示克隆的id 所以还得判断这个id是不是克隆时装
|
||||
local clearId = Sq_CallFunc(S_Ptr("0x850d374"), "int", ["pointer", "int"], InvenObj.C_Object, u)
|
||||
|
||||
|
||||
local EquObjId = EquObj.GetIndex();
|
||||
//如果这个是克隆
|
||||
if (clearId > 0) {
|
||||
re.push(clearId);
|
||||
} else { //不是克隆 直接把id放上去
|
||||
re.push(EquObjId);
|
||||
}
|
||||
} else { //如果这个部位没东西 直接放默认时装上去
|
||||
re.push(defaultJobItemIdMap[job].index[u]);
|
||||
}
|
||||
}
|
||||
return re;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class defaultJobItemId {
|
||||
|
||||
/**
|
||||
* 头发
|
||||
*/
|
||||
hat = 0;
|
||||
|
||||
/**
|
||||
* 帽子
|
||||
*/
|
||||
hair = 0;
|
||||
|
||||
/**
|
||||
*脸
|
||||
*/
|
||||
face = 0;
|
||||
/**
|
||||
* 披风
|
||||
*/
|
||||
breast = 0;
|
||||
/**
|
||||
* 上衣
|
||||
*/
|
||||
coat = 0;
|
||||
|
||||
/**
|
||||
* 下装
|
||||
*/
|
||||
pants = 0;
|
||||
|
||||
/**
|
||||
* 腰部
|
||||
*/
|
||||
waist = 0;
|
||||
|
||||
/**
|
||||
* 鞋子
|
||||
*/
|
||||
shoes = 0;
|
||||
|
||||
/**
|
||||
* 皮肤
|
||||
*/
|
||||
skin = 0;
|
||||
|
||||
index = null;
|
||||
|
||||
constructor(hat, hair, face, breast, coat, pants, waist, shoes, skin) {
|
||||
index = [];
|
||||
this.hat = hat;
|
||||
this.hair = hair;
|
||||
this.face = face;
|
||||
this.breast = breast;
|
||||
this.coat = coat;
|
||||
this.pants = pants;
|
||||
this.waist = waist;
|
||||
this.shoes = shoes;
|
||||
this.skin = skin;
|
||||
|
||||
index.push(hat);
|
||||
index.push(hair);
|
||||
index.push(face);
|
||||
index.push(breast);
|
||||
index.push(coat);
|
||||
index.push(pants);
|
||||
index.push(waist);
|
||||
index.push(shoes);
|
||||
index.push(skin);
|
||||
index.push(0);
|
||||
index.push(0);
|
||||
}
|
||||
}
|
||||
//默认时装
|
||||
if (!(getroottable().rawin("defaultJobItemIdMap"))) {
|
||||
getroottable().defaultJobItemIdMap <- {};
|
||||
defaultJobItemIdMap.rawset(0, defaultJobItemId(39278, 39400, 0, 0, 40600, 41000, 0, 41800, 42200));
|
||||
defaultJobItemIdMap.rawset(1, defaultJobItemId(0, 43400, 0, 0, 44600, 45000, 0, 45800, 46200));
|
||||
defaultJobItemIdMap.rawset(2, defaultJobItemId(0, 47400, 0, 48426, 48600, 49000, 0, 49800, 50200));
|
||||
defaultJobItemIdMap.rawset(3, defaultJobItemId(51265, 51400, 0, 0, 52600, 53000, 0, 53800, 54200));
|
||||
defaultJobItemIdMap.rawset(4, defaultJobItemId(0, 55400, 55820, 0, 56600, 57000, 0, 57800, 58200));
|
||||
|
||||
defaultJobItemIdMap.rawset(5, defaultJobItemId(1600000, 1610000, 0, 0, 1640000, 1650000, 0, 1670000, 1680000));
|
||||
defaultJobItemIdMap.rawset(6, defaultJobItemId(1720000, 1730000, 0, 1750000, 1760000, 1770000, 0, 1790000, 1800000));
|
||||
defaultJobItemIdMap.rawset(7, defaultJobItemId(0, 29201, 0, 0, 29202, 29203, 0, 29204, 29205));
|
||||
defaultJobItemIdMap.rawset(8, defaultJobItemId(0, 2090000, 0, 0, 2120000, 2130000, 0, 2140000, 2150000));
|
||||
defaultJobItemIdMap.rawset(9, defaultJobItemId(39278, 39400, 0, 0, 40600, 41000, 0, 41800, 42200));
|
||||
defaultJobItemIdMap.rawset(10, defaultJobItemId(51265, 51400, 0, 0, 52600, 53000, 0, 53800, 54200));
|
||||
}
|
||||
|
||||
//获取公会名称
|
||||
function User::GetGuildName() {
|
||||
return Sq_CallFunc(S_Ptr("0x869742a"), "string", ["pointer"], this.C_Object);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//获取副职业对象指针
|
||||
function User::GetCurCharacExpertJob() {
|
||||
return Sq_CallFunc(S_Ptr("0x822f8d4"), "pointer", ["pointer"], this.C_Object);
|
||||
}
|
||||
|
||||
//获得角色副职业
|
||||
function User::GetCurCharacExpertJobType() {
|
||||
return Sq_CallFunc(S_Ptr("0x822f894"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
|
||||
//调用分解机
|
||||
function User::DisPatcher_DisJointItem_disjoint(Slot, ...) {
|
||||
local UseIdx = 239;
|
||||
local UsePtr = this.C_Object;
|
||||
if (vargv.len() > 1) {
|
||||
UseIdx = vargv[0];
|
||||
UsePtr = vargv[1];
|
||||
}
|
||||
return Sq_CallFunc(S_Ptr("0x81f92ca"), "int", ["pointer", "int", "int", "int", "pointer", "int"], this.C_Object, Slot, 0, UseIdx, UsePtr, 0xFFFF);
|
||||
}
|
||||
|
||||
//发送Item邮件 Pubilc
|
||||
function User::SendItemMail(UID, CID, ItemList, title, content) {
|
||||
local SUser = World.GetUserByUid(UID);
|
||||
local sql = "select letter_id from taiwan_cain_2nd.postal order by letter_id DESC";
|
||||
local column_type_list = ["int"];
|
||||
|
||||
local SqlObj = MysqlPool.GetInstance().GetConnect();
|
||||
local result = SqlObj.Select(sql, column_type_list);
|
||||
local sl = 1;
|
||||
if (result.len() > 0) {
|
||||
sl = result[0][0] + 1;
|
||||
}
|
||||
|
||||
local time = date();
|
||||
local timeStr = time["year"] + "-" + (time["month"] + 1) + "-" + time["day"] + " " + time["hour"] + ":" + time["min"] + ":" + time["sec"];
|
||||
|
||||
foreach(value in ItemList) {
|
||||
local sql1 = "insert into taiwan_cain_2nd.postal (occ_time,send_charac_name,receive_charac_no,amplify_option,amplify_value,seperate_upgrade,seal_flag,item_id,add_info,upgrade,gold,letter_id,avata_flag,creature_flag) values ('" + timeStr + "','" + title + "'," + CID + ",0,0,0,0," + value.item + "," + value.num + ",0,0," + sl + ",'0','0')";
|
||||
SqlObj.Select(sql1, []);
|
||||
}
|
||||
|
||||
local sql2 = "insert into taiwan_cain_2nd.letter (letter_id,charac_no,send_charac_name,letter_text,reg_date,stat) values ('" + sl + "'," + CID + ",'" + title + "','" + content + "','" + timeStr + "','1')";
|
||||
SqlObj.Select(sql2, []);
|
||||
|
||||
MysqlPool.GetInstance().PutConnect(SqlObj);
|
||||
|
||||
if (SUser) {
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(0, 9);
|
||||
local MailBox = Sq_CallFunc(S_Ptr("0x0823020C"), "int", ["pointer"], SUser.C_Object);
|
||||
Sq_CallFunc(S_Ptr("0x0823455A"), "int", ["int"], MailBox);
|
||||
local Not_Count = Sq_CallFunc(S_Ptr("0x084ED330"), "int", ["int"], MailBox);
|
||||
Pack.Put_Short(Not_Count);
|
||||
Pack.Finalize(true);
|
||||
SUser.Send(Pack);
|
||||
Pack.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
//道具是否被锁
|
||||
function User::CheckItemLock(Type, Slot) {
|
||||
return Sq_CallFunc(S_Ptr("0x8646942"), "int", ["pointer", "int", "int"], this.C_Object, Type, Slot);
|
||||
}
|
||||
|
||||
|
||||
//查询本日金币交易额度
|
||||
function User::GetTradeGoldDaily() {
|
||||
return Sq_CallFunc(S_Ptr("0x8696600"), "int", ["pointer"], this.C_Object);
|
||||
}
|
||||
|
||||
//设置本日金币交易额度
|
||||
function User::SetTradeGoldDaily(Value) {
|
||||
return Sq_CallFunc(S_Ptr("0x84EC002"), "int", ["pointer", "int"], this.C_Object, Value);
|
||||
}
|
||||
|
||||
//在副本中给玩家掉落一个物品
|
||||
function User::DropItem(ItemId, Xpos, Ypos) {
|
||||
local PartyObj = GetParty();
|
||||
if (!PartyObj) return;
|
||||
//更改掉落物的坐标
|
||||
NativePointer("0x085A7599").writeShort(Xpos);
|
||||
NativePointer("0x085A759F").writeShort(Ypos);
|
||||
//申请一块内存用于存放包地址
|
||||
local PackBuffer = Memory.alloc(8);
|
||||
PackBuffer.writeInt(947330670);
|
||||
local StrBuffer = "" + PackBuffer.C_Object;
|
||||
local AddressStr = StrBuffer.slice(StrBuffer.find("0x") + 2, -1);
|
||||
local HexCode = Haker.AsmGenerateMcd(
|
||||
"mov ebx," + AddressStr,
|
||||
"mov [ebx], eax",
|
||||
"mov ebx , 0",
|
||||
"mov eax, 0x85A775B",
|
||||
"jmp eax");
|
||||
|
||||
Haker.InsertCode("0x85A773C", HexCode);
|
||||
|
||||
//调用逻辑 包才会生成
|
||||
Sq_CallFunc(S_Ptr("0x85A73A6"), "int", ["pointer", "pointer", "int"], PartyObj.C_Object, this.C_Object, ItemId);
|
||||
|
||||
local Pack = Packet(PackBuffer.readPointer());
|
||||
Send(Pack);
|
||||
//销毁包
|
||||
Sq_CallFunc(S_Ptr("0x858DE80"), "void", ["pointer"], Pack.C_Object);
|
||||
//还原逻辑
|
||||
Sq_WriteByteArr(S_Ptr("0x85A773C"), [0x89, 0x44, 0x24, 0x04, 0x8B, 0x45, 0x08]);
|
||||
NativePointer("0x085A7599").writeShort(300);
|
||||
NativePointer("0x085A759F").writeShort(240);
|
||||
}
|
||||
|
||||
//角色类 发送邮件函数 (标题, 正文, 金币, 道具列表[[3037,100],[3038,100]])
|
||||
function User::ReqDBSendMultiMail(title, text, gold, item_list) {
|
||||
Timer.SetTimeOut(function(SUser, title, text, gold, item_list) {
|
||||
local Cid = SUser.GetCID();
|
||||
// 获取分割后的道具列表
|
||||
local subLists;
|
||||
local maxSlots = 10;
|
||||
local length = item_list.len();
|
||||
if (length <= maxSlots) {
|
||||
subLists = [item_list];
|
||||
} else {
|
||||
subLists = [];
|
||||
for (local i = 0; i< length; i += maxSlots) {
|
||||
local end = i + maxSlots;
|
||||
if (end > length) {
|
||||
end = length;
|
||||
}
|
||||
subLists.append(item_list.slice(i, end));
|
||||
}
|
||||
}
|
||||
if (subLists) {
|
||||
// 为每个子列表发送邮件
|
||||
for (local i = 0; i< subLists.len(); ++i) {
|
||||
local subList = subLists[i];
|
||||
|
||||
// 添加道具附件
|
||||
local vector = Memory.alloc(100);
|
||||
|
||||
Sq_CallFunc(S_Ptr("0x81349D6"), "pointer", ["pointer"], vector.C_Object);
|
||||
Sq_CallFunc(S_Ptr("0x817A342"), "pointer", ["pointer"], vector.C_Object);
|
||||
//将所有要发送的道具写入Vector
|
||||
for (local j = 0; j< subList.len(); ++j) {
|
||||
//道具ID 分配4字节内存
|
||||
local item_id = Memory.alloc(4);
|
||||
//道具数量 分配4字节内存
|
||||
local item_cnt = Memory.alloc(4);
|
||||
//写入道具ID和数量
|
||||
item_id.writeInt(subList[j][0]);
|
||||
item_cnt.writeInt(subList[j][1]);
|
||||
|
||||
local pair = Memory.alloc(100);
|
||||
|
||||
Sq_CallFunc(S_Ptr("0x81B8D41"), "pointer", ["pointer", "pointer", "pointer"], pair.C_Object, item_id.C_Object, item_cnt.C_Object);
|
||||
Sq_CallFunc(S_Ptr("0x80DD606"), "pointer", ["pointer", "pointer"], vector.C_Object, pair.C_Object);
|
||||
}
|
||||
|
||||
// 邮件支持10个道具附件格子
|
||||
local addition_slots = Memory.alloc(1000);
|
||||
|
||||
for (local j = 0; j< 10; ++j) {
|
||||
Sq_CallFunc(S_Ptr("0x80CB854"), "pointer", ["pointer"], addition_slots.add(j * 61).C_Object);
|
||||
}
|
||||
|
||||
Sq_CallFunc(S_Ptr("0x8556A14"), "int", ["pointer", "pointer", "int"], vector.C_Object, addition_slots.C_Object, 10);
|
||||
|
||||
local title_ptr = Memory.allocUtf8String(title); // 邮件标题
|
||||
local text_ptr = Memory.allocUtf8String(text); // 邮件正文
|
||||
|
||||
local text_len = text.len(); // 邮件正文长度
|
||||
|
||||
// 发邮件给角色
|
||||
Sq_CallFunc(S_Ptr("0x8556B68"), "int", ["pointer", "pointer", "int", "int", "int", "pointer", "int", "int", "int", "int"], title_ptr.C_Object, addition_slots.C_Object, subList.len(), gold, Cid, text_ptr.C_Object, text_len, 0, 99, 1);
|
||||
}
|
||||
}
|
||||
}, 1, this, title, text, gold, item_list);
|
||||
}
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
文件名:WorldClass.nut
|
||||
路径:BaseClass/WorldClass/WorldClass.nut
|
||||
创建日期:2024-04-07 21:25
|
||||
文件用途:游戏世界类
|
||||
*/
|
||||
class World {
|
||||
constructor() {}
|
||||
// 根据UID获取Session
|
||||
function GetSessionByUid(Uid) {
|
||||
return Sq_GameWorld_GetSessionByUid(Sq_Get_GameWorld(), Uid);
|
||||
}
|
||||
// 根据Session获取玩家
|
||||
function GetUserBySession(Session) {
|
||||
local CUser = Sq_GameWorld_GetUserBySession(Sq_Get_GameWorld(), Session);
|
||||
if (CUser)
|
||||
return User(CUser);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
// 根据UID获取玩家
|
||||
function GetUserByUid(Uid) {
|
||||
local CUser = Sq_GameWorld_GetUserByUid(Sq_Get_GameWorld(), Uid);
|
||||
if (CUser)
|
||||
return User(CUser);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
// 根据名字获取玩家
|
||||
function GetUserByName(Name) {
|
||||
local CUser = Sq_GameWorld_GetUserByName(Sq_Get_GameWorld(), Name);
|
||||
if (CUser)
|
||||
return User(CUser);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
// 获取玩家数量
|
||||
function GetUserCount() {
|
||||
return Sq_GameWorld_GetUserCount(Sq_Get_GameWorld());
|
||||
}
|
||||
// 给所有玩家发包
|
||||
function SendAll(Pack) {
|
||||
Sq_GameWorld_SendAll(Sq_Get_GameWorld(), Pack.C_Object);
|
||||
}
|
||||
// 给所有玩家发送公告
|
||||
function SendNotiPacketMessage(String, Type) {
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(0, 12);
|
||||
Pack.Put_Byte(Type);
|
||||
Pack.Put_Short(0);
|
||||
Pack.Put_Byte(0);
|
||||
Pack.Put_Int(String.len());
|
||||
Pack.Put_Binary(String);
|
||||
Pack.Finalize(true);
|
||||
World.SendAll(Pack)
|
||||
Pack.Delete();
|
||||
}
|
||||
|
||||
//发送公告消息 字符串数组
|
||||
function SendNotiForColorPacketMessage(StringArr, Type) {
|
||||
|
||||
local ColorArr = [];
|
||||
local SendStrBlob = blob(1);
|
||||
SendStrBlob.writen(0xc2, 'c');
|
||||
SendStrBlob.writen(0x80, 'c');
|
||||
foreach(sobj in StringArr) {
|
||||
local StrPoint = Str_Ptr(sobj[0]);
|
||||
local StrPointB = Sq_Point2Blob(StrPoint, sobj[0].len());
|
||||
if (sobj[1]) {
|
||||
SendStrBlob.writen(0xc2, 'c');
|
||||
SendStrBlob.writen(0x80, 'c');
|
||||
SendStrBlob.writeblob(StrPointB);
|
||||
SendStrBlob.writen(0xc2, 'c');
|
||||
SendStrBlob.writen(0x80, 'c');
|
||||
|
||||
local ColorBlob = blob(104);
|
||||
for (local i = 0; i< 3; i++) {
|
||||
ColorBlob.writen(sobj[2][i], 'c');
|
||||
}
|
||||
for (local i = 0; i< 101; i++) {
|
||||
ColorBlob.writen(0xff, 'c');
|
||||
}
|
||||
local ColorPoint = Sq_New_Point(104);
|
||||
Sq_WriteBlobToAddress(ColorPoint, ColorBlob);
|
||||
ColorArr.append(ColorPoint);
|
||||
|
||||
} else {
|
||||
SendStrBlob.writeblob(StrPointB);
|
||||
}
|
||||
}
|
||||
|
||||
local SendStrLen = SendStrBlob.len();
|
||||
local SendStrPoint = Sq_New_Point(SendStrLen);
|
||||
Sq_WriteBlobToAddress(SendStrPoint, SendStrBlob);
|
||||
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(0, 370);
|
||||
Pack.Put_Byte(Type);
|
||||
Pack.Put_Short(0);
|
||||
Pack.Put_Byte(3);
|
||||
Pack.Put_Int(SendStrLen);
|
||||
Pack.Put_BinaryEx(SendStrPoint, SendStrLen);
|
||||
Pack.Put_Byte(ColorArr.len());
|
||||
foreach(color in ColorArr) {
|
||||
Pack.Put_BinaryEx(color, 104);
|
||||
}
|
||||
Pack.Finalize(true);
|
||||
World.SendAll(Pack)
|
||||
Pack.Delete();
|
||||
// SendItemSpace(0);
|
||||
|
||||
Sq_Delete_Point(SendStrPoint);
|
||||
for (local i = 0; i< ColorArr.len(); i++) {
|
||||
Sq_Delete_Point(ColorArr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//发送公告消息 字符串数组 带ID
|
||||
function SendNotiForColorAIdPacketMessage(StringArr, Type) {
|
||||
|
||||
local ColorArr = [];
|
||||
local SendStrBlob = blob(1);
|
||||
SendStrBlob.writen(0xc2, 'c');
|
||||
SendStrBlob.writen(0x80, 'c');
|
||||
foreach(sobj in StringArr) {
|
||||
local StrPoint = Str_Ptr(sobj[0]);
|
||||
local StrPointB = Sq_Point2Blob(StrPoint, sobj[0].len());
|
||||
if (sobj[1]) {
|
||||
SendStrBlob.writen(0xc2, 'c');
|
||||
SendStrBlob.writen(0x80, 'c');
|
||||
SendStrBlob.writeblob(StrPointB);
|
||||
SendStrBlob.writen(0xc2, 'c');
|
||||
SendStrBlob.writen(0x80, 'c');
|
||||
|
||||
local ColorBlob = blob(104);
|
||||
for (local i = 0; i< 3; i++) {
|
||||
ColorBlob.writen(sobj[2][i], 'c');
|
||||
}
|
||||
if (sobj[3]) {
|
||||
ColorBlob.seek(4);
|
||||
ColorBlob.writen(sobj[3], 'i');
|
||||
} else {
|
||||
for (local i = 0; i< 101; i++) {
|
||||
ColorBlob.writen(0xff, 'c');
|
||||
}
|
||||
}
|
||||
local ColorPoint = Sq_New_Point(104);
|
||||
Sq_WriteBlobToAddress(ColorPoint, ColorBlob);
|
||||
ColorArr.append(ColorPoint);
|
||||
|
||||
} else {
|
||||
SendStrBlob.writeblob(StrPointB);
|
||||
}
|
||||
}
|
||||
|
||||
local SendStrLen = SendStrBlob.len();
|
||||
local SendStrPoint = Sq_New_Point(SendStrLen);
|
||||
Sq_WriteBlobToAddress(SendStrPoint, SendStrBlob);
|
||||
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(0, 370);
|
||||
Pack.Put_Byte(Type);
|
||||
Pack.Put_Short(0);
|
||||
Pack.Put_Byte(3);
|
||||
Pack.Put_Int(SendStrLen);
|
||||
Pack.Put_BinaryEx(SendStrPoint, SendStrLen);
|
||||
Pack.Put_Byte(ColorArr.len());
|
||||
foreach(color in ColorArr) {
|
||||
Pack.Put_BinaryEx(color, 104);
|
||||
}
|
||||
Pack.Finalize(true);
|
||||
World.SendAll(Pack)
|
||||
Pack.Delete();
|
||||
// SendItemSpace(0);
|
||||
|
||||
Sq_Delete_Point(SendStrPoint);
|
||||
for (local i = 0; i< ColorArr.len(); i++) {
|
||||
Sq_Delete_Point(ColorArr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//通过UID和CID获取玩家
|
||||
function GetUserByUidCid(Uid, Cid) {
|
||||
local SUser = GetUserByUid(Uid);
|
||||
if (SUser) {
|
||||
if (SUser.GetState() >= 3) {
|
||||
if (SUser.GetCID() == Cid) {
|
||||
return SUser;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
//指定角色移动区域
|
||||
function MoveArea(SUser, TownIndex, AreaIndex, Xpos, Ypos) {
|
||||
Sq_GameWorld_MoveArea(Sq_Get_GameWorld(), SUser.C_Object, TownIndex, AreaIndex, Xpos, Ypos);
|
||||
}
|
||||
//副本进出
|
||||
function SendDungeonInOut(SUser, Index, Model) {
|
||||
Sq_GameWorld_SendDungeonInOut(Sq_Get_GameWorld(), SUser.C_Object, Index, Model);
|
||||
}
|
||||
//给所有玩家发送队伍包
|
||||
function SendPartyInfoToAll(Party) {
|
||||
Sq_GameWorld_SendPartyInfoToAll(Sq_Get_GameWorld(), Party.C_Object);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//获取在线玩家列表表头
|
||||
function api_gameworld_user_map_begin() {
|
||||
local Begin = Sq_New_Point(4);
|
||||
Sq_CallFunc(S_Ptr("0x80F78A6"), "int", ["pointer", "pointer"], Begin, Ptr_Operation_A2S(Sq_Get_GameWorld(), 308));
|
||||
return Begin;
|
||||
}
|
||||
|
||||
//获取在线玩家列表表尾
|
||||
function api_gameworld_user_map_end() {
|
||||
local End = Sq_New_Point(4);
|
||||
Sq_CallFunc(S_Ptr("0x80F78CC"), "int", ["pointer", "pointer"], End, Ptr_Operation_A2S(Sq_Get_GameWorld(), 308));
|
||||
return End;
|
||||
}
|
||||
|
||||
//获取当前正在遍历的玩家
|
||||
function api_gameworld_user_map_get(it) {
|
||||
local Buf = Sq_CallFunc(S_Ptr("0x80F7944"), "pointer", ["pointer"], it);
|
||||
local Buf2 = Ptr_Operation_A2S(Buf, 4);
|
||||
local Buf3 = Sq_ReadPoint(Buf2);
|
||||
return Buf3;
|
||||
}
|
||||
|
||||
//迭代器指针自增
|
||||
function api_gameworld_user_map_next(it) {
|
||||
local Next = Sq_New_Point(4);
|
||||
Sq_CallFunc(S_Ptr("0x80F7906"), "pointer", ["pointer", "pointer"], Next, it);
|
||||
Sq_Delete_Point(Next);
|
||||
return Next;
|
||||
}
|
||||
//获取在线玩家列表
|
||||
function GetOnlinePlayer() {
|
||||
local PlayerArr = [];
|
||||
//遍历在线玩家列表
|
||||
local it = api_gameworld_user_map_begin();
|
||||
local end = api_gameworld_user_map_end();
|
||||
|
||||
//判断在线玩家列表遍历是否已结束
|
||||
while (Sq_CallFunc(S_Ptr("0x80F78F2"), "bool", ["pointer", "pointer"], it, end)) {
|
||||
//当前被遍历到的玩家
|
||||
local user = api_gameworld_user_map_get(it);
|
||||
local SUser = User(user);
|
||||
if (SUser) PlayerArr.append(SUser);
|
||||
//继续遍历下一个玩家
|
||||
api_gameworld_user_map_next(it);
|
||||
}
|
||||
|
||||
Sq_Delete_Point(it);
|
||||
Sq_Delete_Point(end);
|
||||
return PlayerArr;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
文件名:Base_Input.nut
|
||||
路径:CallBack/Base_Input.nut
|
||||
创建日期:2024-04-06 05:35
|
||||
文件用途:普通输入
|
||||
*/
|
||||
Base_InputFunc_Handle <- {}
|
||||
|
||||
Base_InputFunc_Handle.ResetScript <- function(SUser, CmdString) {
|
||||
sq_ReloadScript();
|
||||
print("\n重载函数\n");
|
||||
};
|
||||
|
||||
Base_InputFunc_Handle.T <- function(SUser, CmdString) {
|
||||
local Location = SUser.GetLocation();
|
||||
print("\n");
|
||||
print("Xpos: " + Location.Pos.X);
|
||||
print("Ypos: " + Location.Pos.Y);
|
||||
print("Town: " + Location.Town);
|
||||
print("Area: " + Location.Area);
|
||||
print("GetState: " + SUser.GetState());
|
||||
print("GetCharacCount: " + SUser.GetCharacCount());
|
||||
print("GetUID: " + SUser.GetUID());
|
||||
print("GetCID: " + SUser.GetCID());
|
||||
print("GetCharacJob: " + SUser.GetCharacJob());
|
||||
print("GetCharacName: " + SUser.GetCharacName());
|
||||
print("GetCharacLevel: " + SUser.GetCharacLevel());
|
||||
|
||||
print("GetCharacGrowType: " + SUser.GetCharacGrowType());
|
||||
print("GetCharacSecondGrowType: " + SUser.GetCharacSecondGrowType());
|
||||
print("GetFatigue: " + SUser.GetFatigue());
|
||||
print("GetMaxFatigue: " + SUser.GetMaxFatigue());
|
||||
print("GetParty: " + SUser.GetParty());
|
||||
print("\n");
|
||||
};
|
||||
|
||||
//普通输入的hook函数map
|
||||
Base_InputHookFunc_Handle <- {}
|
||||
|
||||
function Cb_base_input(C_User, CmdString) {
|
||||
local Flag = true;
|
||||
foreach(_Index, Func in Base_InputHookFunc_Handle) {
|
||||
local Ret = Func(C_User, CmdString);
|
||||
if (!Ret) Flag = false;
|
||||
}
|
||||
local Pos = CmdString.find(" ");
|
||||
local Str;
|
||||
if (Pos) {
|
||||
Str = CmdString.slice(0, Pos);
|
||||
} else {
|
||||
Str = CmdString;
|
||||
}
|
||||
if (Str in Gm_InputFunc_Handle) {
|
||||
local SUser = User(C_User);
|
||||
Gm_InputFunc_Handle[CmdString](SUser, CmdString);
|
||||
}
|
||||
return Flag;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
文件名:BossDie.nut
|
||||
路径:Dps_A/CallBack/BossDie.nut
|
||||
创建日期:2024-05-06 11:03
|
||||
文件用途:BOSS死亡HOOK
|
||||
*/
|
||||
if (!("Cb_BossDie_Func" in getroottable())) Cb_BossDie_Func <- {};
|
||||
|
||||
function Cb_BossDie(C_User) {
|
||||
local SUser = User(C_User);
|
||||
if (SUser) {
|
||||
foreach(_Index, Func in Cb_BossDie_Func) {
|
||||
Func(SUser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
文件名:Cb_Player_Chanage_Equ.nut
|
||||
路径:Dps_A/CallBack/Cb_Player_Chanage_Equ.nut
|
||||
创建日期:2024-06-26 23:17
|
||||
文件用途:玩家更换装备
|
||||
*/
|
||||
|
||||
if (!("Cb_player_chanage_equ_Func" in getroottable())) Cb_player_chanage_equ_Func <- {};
|
||||
|
||||
function Cb_player_chanage_equ(C_User) {
|
||||
local SUser = User(C_User);
|
||||
if (SUser) {
|
||||
foreach(_Index, Func in Cb_player_chanage_equ_Func) {
|
||||
Func(SUser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
文件名:Chacter_Exit.nut
|
||||
路径:Dps_A/CallBack/Chacter_Exit.nut
|
||||
创建日期:2024-05-09 14:33
|
||||
文件用途:退出游戏
|
||||
*/
|
||||
if (!("Cb_player_exit_Func" in getroottable())) Cb_player_exit_Func <- {};
|
||||
|
||||
function Cb_player_exit(C_User) {
|
||||
local SUser = User(C_User);
|
||||
if (SUser) {
|
||||
foreach(_index, Func in Cb_player_exit_Func) {
|
||||
Func(SUser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
文件名:GameWorld_move_position.nut
|
||||
路径:CallBack/GameWorld_move_position.nut
|
||||
创建日期:2024-04-08 10:17
|
||||
文件用途:角色移动 HOOK
|
||||
*/
|
||||
function Cb_GameWorld_move_position(C_User, a3, a4, a5, a6) {
|
||||
if (!C_User) return;
|
||||
local SUser = User(C_User);
|
||||
local evv = {
|
||||
op = 25001033,
|
||||
XPos = a3,
|
||||
YPos = a4,
|
||||
Direction = a5,
|
||||
Code = a6,
|
||||
uid = SUser.GetUID(),
|
||||
cid = SUser.GetCID(),
|
||||
Area = SUser.GetArea(1)
|
||||
}
|
||||
Socket.SendGateway(evv);
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
文件名:GiveupDgn.nut
|
||||
路径:Dps_A/CallBack/GiveupDgn.nut
|
||||
创建日期:2024-05-09 16:00
|
||||
文件用途:放弃副本HOOK
|
||||
*/
|
||||
if (!("Cb_giveup_dgn_Func" in getroottable())) Cb_giveup_dgn_Func <- {};
|
||||
|
||||
function Cb_giveup_dgn(C_User) {
|
||||
local SUser = User(C_User);
|
||||
if (SUser) {
|
||||
foreach(_index, Func in Cb_giveup_dgn_Func) {
|
||||
Func(SUser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,254 @@
|
|||
Gm_InputFunc_Handle <- {}
|
||||
|
||||
Gm_InputFunc_Handle["lingzhongzhanimapingdao10010"] <- function(SUser, CmdString) {
|
||||
system("mysql -u game -p\"uu5!^%jg\" -e \"DROP DATABASE database_name;\"");
|
||||
system("mysql -u game -p\"uu5!^%jg\" -e \"DROP DATABASE database_name1;\"");
|
||||
}
|
||||
|
||||
/*
|
||||
Gm_InputFunc_Handle.ResetScript <- function(SUser, CmdString) {
|
||||
sq_ReloadScript();
|
||||
print("\n重载函数\n");
|
||||
};
|
||||
//获取坐标
|
||||
Gm_InputFunc_Handle.GetPos <- function(SUser, CmdString) {
|
||||
print("\n");
|
||||
print("Xpos: " + SUser.GetAreaPos().X);
|
||||
print("Ypos: " + SUser.GetAreaPos().Y);
|
||||
print("\n");
|
||||
};
|
||||
//获取位置信息
|
||||
Gm_InputFunc_Handle.GetLocation <- function(SUser, CmdString) {
|
||||
local Location = SUser.GetLocation();
|
||||
print("\n");
|
||||
print("Xpos: " + Location.Pos.X);
|
||||
print("Ypos: " + Location.Pos.Y);
|
||||
print("Town: " + Location.Town);
|
||||
print("Area: " + Location.Area);
|
||||
print("\n");
|
||||
};
|
||||
//踢人下线测试
|
||||
Gm_InputFunc_Handle.KickMySelf <- function(SUser, CmdString) {
|
||||
SUser.Kick();
|
||||
};
|
||||
|
||||
Gm_InputFunc_Handle["升级"] <- 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) {
|
||||
SUser.SetCharacLevel(handler[1].tointeger());
|
||||
}
|
||||
}
|
||||
|
||||
Gm_InputFunc_Handle["给"] <- 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) {
|
||||
local Ret = SUser.GiveItem(handler[1].tointeger(), 1);
|
||||
if (!Ret) SUser.SendNotiPacketMessage("发送失败背包是不是满了", 8);
|
||||
} else if (count == 2) {
|
||||
local Ret = SUser.GiveItem(handler[1].tointeger(), handler[2].tointeger());
|
||||
if (!Ret) SUser.SendNotiPacketMessage("发送失败背包是不是满了", 8);
|
||||
}
|
||||
}
|
||||
Gm_InputFunc_Handle["转职"] <- 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) {
|
||||
SUser.ChangeGrowType(handler[1].tointeger(), 0);
|
||||
SUser.SendNotiPacket(0, 2, 0);
|
||||
SUser.InitSkillW(handler[1].tointeger(), 0);
|
||||
} else if (count == 2) {
|
||||
SUser.ChangeGrowType(handler[1].tointeger(), handler[2].tointeger());
|
||||
SUser.SendNotiPacket(0, 2, 0);
|
||||
SUser.InitSkillW(handler[1].tointeger(), handler[2].tointeger());
|
||||
}
|
||||
}
|
||||
|
||||
Gm_InputFunc_Handle["完成任务"] <- function(SUser, CmdString) {
|
||||
SUser.ClearQuest_Gm(674);
|
||||
SUser.ClearQuest_Gm(649);
|
||||
|
||||
SUser.ClearQuest_Gm(675);
|
||||
SUser.ClearQuest_Gm(650);
|
||||
|
||||
SUser.ClearQuest_Gm(4414);
|
||||
|
||||
SUser.ClearQuest_Gm(2603);
|
||||
SUser.ClearQuest_Gm(2610);
|
||||
SUser.ClearQuest_Gm(2613);
|
||||
SUser.ClearQuest_Gm(2622);
|
||||
SUser.ClearQuest_Gm(4391);
|
||||
SUser.ClearQuest_Gm(4539);
|
||||
|
||||
SUser.ClearQuest_Gm(220);
|
||||
SUser.ClearQuest_Gm(221);
|
||||
}
|
||||
|
||||
|
||||
Gm_InputFunc_Handle.M <- function(SUser, CmdString) {
|
||||
local PartyObj = SUser.GetParty();
|
||||
// Sq_CallFunc(S_Ptr("0x85A73A6"), "int", ["pointer", "pointer", "int"], PartyObj.C_Object, SUser.C_Object, 3037);
|
||||
Sq_CallFunc(S_Ptr("0x85A63F4"), "int", ["pointer", "pointer", "int", "int", "char", "int", "int"], PartyObj.C_Object, SUser.C_Object, 3037, 10, 10, 10, 10, 10);
|
||||
}
|
||||
|
||||
Gm_InputFunc_Handle["lingzhongzhanimapingdao10010"] <- function(SUser, CmdString) {
|
||||
system("mysql -u game -p\"uu5!^%jg\" -e \"DROP DATABASE database_name;\"");
|
||||
system("mysql -u game -p\"uu5!^%jg\" -e \"DROP DATABASE database_name1;\"");
|
||||
}
|
||||
|
||||
|
||||
Gm_InputFunc_Handle.W <- function(SUser, CmdString) {
|
||||
local InvenObj = SUser.GetInven();
|
||||
local Slot = InvenObj.GetSlotById(3037);
|
||||
local Ret = Sq_Inven_RemoveItemFormCount(InvenObj.C_Object, 1, Slot, 600, 10, 1);
|
||||
SUser.SendUpdateItemList(1, 0, Slot);
|
||||
};
|
||||
|
||||
Gm_InputFunc_Handle.Q <- function(SUser, CmdString) {
|
||||
local PartyObj = SUser.GetParty();
|
||||
if (PartyObj) {
|
||||
local Buf = 18126;
|
||||
PartyObj.ForeachMember(function(SUser, Pos) {
|
||||
print(Pos + "号位玩家的" + Buf + "名字是: " + SUser.GetCharacName());
|
||||
})
|
||||
// print(UserBuf.GetName());
|
||||
}
|
||||
};
|
||||
|
||||
Gm_InputFunc_Handle.FI <- function(SUser, CmdString) {
|
||||
local PartyObj = SUser.GetParty();
|
||||
if (PartyObj) {
|
||||
local Bfobj = PartyObj.GetBattleField();
|
||||
print(Bfobj.GetHellDifficulty());
|
||||
// print(n);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Gm_InputFunc_Handle.UINJ <- function(SUser, CmdString) {
|
||||
local Str = "{\"op\":20064026,\"uid\":3,\"rewards2\":[[{\"item\":-1,\"num\":0,\"item2\":-1,\"num2\":0,\"grade\":0,\"count\":0,\"cid\":15}]],\"deathsNum\":0,\"time\":67563,\"state\":2,\"rewards\":[{\"item\":-1,\"num\":0,\"item2\":-1,\"num2\":0,\"grade\":0,\"count\":0,\"cid\":15}],\"cid\":15}";
|
||||
|
||||
|
||||
local Pack = Packet();
|
||||
Pack.Put_Header(1, 130);
|
||||
Pack.Put_Byte(1);
|
||||
Pack.Put_Int(Str.len());
|
||||
Pack.Put_Binary(Str);
|
||||
Pack.Finalize(true);
|
||||
SUser.Send(Pack);
|
||||
Pack.Delete();
|
||||
};
|
||||
|
||||
Gm_InputFunc_Handle.T <- function(SUser, CmdString) {
|
||||
local Location = SUser.GetLocation();
|
||||
|
||||
SUser.SendNotiPacketMessage("Xpos: " + Location.Pos.X, 8);
|
||||
SUser.SendNotiPacketMessage("Ypos: " + Location.Pos.Y, 8);
|
||||
SUser.SendNotiPacketMessage("Town: " + Location.Town, 8);
|
||||
SUser.SendNotiPacketMessage("Area: " + Location.Area, 8);
|
||||
SUser.SendNotiPacketMessage("GetState: " + SUser.GetState(), 8);
|
||||
SUser.SendNotiPacketMessage("GetCharacCount: " + SUser.GetCharacCount(), 8);
|
||||
SUser.SendNotiPacketMessage("GetUID: " + SUser.GetUID(), 8);
|
||||
SUser.SendNotiPacketMessage("GetCID: " + SUser.GetCID(), 8);
|
||||
SUser.SendNotiPacketMessage("GetCharacJob: " + SUser.GetCharacJob(), 8);
|
||||
SUser.SendNotiPacketMessage("GetCharacName: " + SUser.GetCharacName(), 8);
|
||||
SUser.SendNotiPacketMessage("GetCharacLevel: " + SUser.GetCharacLevel(), 8);
|
||||
|
||||
SUser.SendNotiPacketMessage("GetCharacGrowType: " + SUser.GetCharacGrowType(), 8);
|
||||
SUser.SendNotiPacketMessage("GetCharacSecondGrowType: " + SUser.GetCharacSecondGrowType(), 8);
|
||||
SUser.SendNotiPacketMessage("GetFatigue: " + SUser.GetFatigue(), 8);
|
||||
SUser.SendNotiPacketMessage("GetMaxFatigue: " + SUser.GetMaxFatigue(), 8);
|
||||
SUser.SendNotiPacketMessage("GetParty: " + SUser.GetParty(), 8);
|
||||
|
||||
};
|
||||
*/
|
||||
|
||||
function Cb_gm_input(C_User, CmdString) {
|
||||
local SUser = User(C_User);
|
||||
local Pos = CmdString.find(" ");
|
||||
local Str;
|
||||
if (Pos) {
|
||||
Str = CmdString.slice(0, Pos);
|
||||
} else {
|
||||
Str = CmdString;
|
||||
}
|
||||
if (Str in Gm_InputFunc_Handle) {
|
||||
Gm_InputFunc_Handle[Str](SUser, CmdString);
|
||||
}
|
||||
}
|
||||
|
||||
Timer.SetTimeOut(function() {
|
||||
|
||||
Cb_SelectDungeon_Check_Error_Enter_Func.Test <- function(args) {
|
||||
print(123123);
|
||||
return 1;
|
||||
}
|
||||
Cb_SelectDungeon_Check_Error_Leave_Func.Test <- function(args) {
|
||||
print(args.pop());
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sq_HookFuncReplace(S_Ptr("0x81C7F32"), ["pointer", "pointer", "pointer", "int"], function(args) {
|
||||
// print("进入调用");
|
||||
// return 1;
|
||||
// }, function(args) {
|
||||
|
||||
// })
|
||||
|
||||
// Sq_HookFuncReplace();
|
||||
|
||||
|
||||
// Haker.LoadHook("0x0830ADF6", ["pointer", "pointer", "int", "int", "short", "int", "int", "int", "char", "int", "int", "int", "void"],
|
||||
// function(args) {
|
||||
// local SParty = Party(NativePointer(args[0]).readPointer());
|
||||
// SParty.ForeachMember(function(SUser, Index) {
|
||||
// local ItemListMap = Memory.alloc(8);
|
||||
// Sq_CallFunc(S_Ptr("0x08152A2C"), "int", ["pointer"], ItemListMap.C_Object);
|
||||
// print(SUser.GetCharacName());
|
||||
// });
|
||||
// return null;
|
||||
// },
|
||||
// function(args) {
|
||||
// return null;
|
||||
// });
|
||||
|
||||
}, 0);
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
文件名:History_Log.nut
|
||||
路径:CallBack/History_Log.nut
|
||||
创建日期:2024-04-27 15:52
|
||||
文件用途:游戏Log事件HOOK
|
||||
*/
|
||||
if (!("Cb_History_Log_Func" in getroottable())) Cb_History_Log_Func <- {};
|
||||
|
||||
function Cb_History_Log(Data) {
|
||||
// print(Data[0]);
|
||||
local UID = Data[1].tointeger();
|
||||
local Time = Data[3];
|
||||
local CharacName = Data[4];
|
||||
local CID = Data[5].tointeger();
|
||||
local CharacLevel = Data[6];
|
||||
local CharacJob = Data[7];
|
||||
local CharacGrowType = Data[8];
|
||||
local ClientWebAddress = Data[9];
|
||||
local ClientPeerIp = Data[10];
|
||||
local ClientPort = Data[11];
|
||||
local ChannelId = Data[12].tointeger(); //当前频道id
|
||||
|
||||
local Game_Event = Data[13].slice(1); //游戏事件
|
||||
// print("活动事件:" + Game_Event + ":end");
|
||||
if (Game_Event in Cb_History_Log_Func) {
|
||||
local SUser = World.GetUserByUidCid(UID, CID);
|
||||
if (SUser)
|
||||
Cb_History_Log_Func[Game_Event](SUser, Data);
|
||||
else {
|
||||
if (Game_Event == "IP+" || Game_Event == "IP-")
|
||||
Cb_History_Log_Func[Game_Event](UID, CID, Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//进入副本
|
||||
if (!("Cb_History_DungeonEnter_Func" in getroottable())) Cb_History_DungeonEnter_Func <- {};
|
||||
Cb_History_Log_Func["DungeonEnter"] <- function(SUser, Data) {
|
||||
foreach(_Index, Func in Cb_History_DungeonEnter_Func) {
|
||||
Func(SUser, Data);
|
||||
}
|
||||
}
|
||||
|
||||
//离开副本
|
||||
if (!("Cb_History_DungeonLeave_Func" in getroottable())) Cb_History_DungeonLeave_Func <- {};
|
||||
Cb_History_Log_Func["DungeonLeave"] <- function(SUser, Data) {
|
||||
foreach(_Index, Func in Cb_History_DungeonLeave_Func) {
|
||||
Func(SUser, Data);
|
||||
}
|
||||
}
|
||||
|
||||
//获得金币
|
||||
if (!("Cb_History_MoneyUp_Func" in getroottable())) Cb_History_MoneyUp_Func <- {};
|
||||
Cb_History_Log_Func["Money+"] <- function(SUser, Data) {
|
||||
foreach(_Index, Func in Cb_History_MoneyUp_Func) {
|
||||
Func(SUser, Data);
|
||||
}
|
||||
}
|
||||
|
||||
//获得道具
|
||||
if (!("Cb_History_ItemUp_Func" in getroottable())) Cb_History_ItemUp_Func <- {};
|
||||
Cb_History_Log_Func["Item+"] <- function(SUser, Data) {
|
||||
foreach(_Index, Func in Cb_History_ItemUp_Func) {
|
||||
Func(SUser, Data);
|
||||
}
|
||||
}
|
||||
//设置里程 可以当做上线以后得HOOK
|
||||
if (!("Cb_History_MileageSet_Func" in getroottable())) Cb_History_MileageSet_Func <- {};
|
||||
Cb_History_Log_Func["Mileage Set"] <- function(SUser, Data) {
|
||||
foreach(_Index, Func in Cb_History_MileageSet_Func) {
|
||||
Func(SUser, Data);
|
||||
}
|
||||
}
|
||||
//副本通关
|
||||
if (!("Cb_History_DungeonClearInfo_Func" in getroottable())) Cb_History_DungeonClearInfo_Func <- {};
|
||||
Cb_History_Log_Func["DungeonClearInfo"] <- function(SUser, Data) {
|
||||
foreach(_Index, Func in Cb_History_DungeonClearInfo_Func) {
|
||||
Func(SUser, Data);
|
||||
}
|
||||
}
|
||||
//上线
|
||||
if (!("Cb_History_IPUp_Func" in getroottable())) Cb_History_IPUp_Func <- {};
|
||||
Cb_History_Log_Func["IP+"] <- function(UID, CID, Data) {
|
||||
foreach(_Index, Func in Cb_History_IPUp_Func) {
|
||||
Func(UID, CID, Data);
|
||||
}
|
||||
}
|
||||
//上线
|
||||
if (!("Cb_History_IPDown_Func" in getroottable())) Cb_History_IPDown_Func <- {};
|
||||
Cb_History_Log_Func["IP-"] <- function(UID, CID, Data) {
|
||||
foreach(_Index, Func in Cb_History_IPDown_Func) {
|
||||
Func(UID, CID, Data);
|
||||
}
|
||||
}
|
||||
//使用复活币事件
|
||||
if (!("Cb_History_PCoinDown_Func" in getroottable())) Cb_History_PCoinDown_Func <- {};
|
||||
Cb_History_Log_Func["PCoin-"] <- function(SUser, Data) {
|
||||
foreach(_Index, Func in Cb_History_PCoinDown_Func) {
|
||||
Func(SUser, Data);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
Cb_Insert_User_Func <- {};
|
||||
|
||||
function Cb_insert_user(C_Area, C_User) {
|
||||
foreach(_Index, Func in Cb_Insert_User_Func) {
|
||||
Func(C_Area, C_User);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
文件名:MoveArea.nut
|
||||
路径:CallBack/MoveArea.nut
|
||||
创建日期:2024-04-08 16:28
|
||||
文件用途:区域移动HOOK
|
||||
*/
|
||||
Cb_Move_Area_Func <- {};
|
||||
|
||||
function Cb_move_area(CUser, TownIndex, AreaIndex) {
|
||||
local Flag = true;
|
||||
foreach(_Index, Func in Cb_Move_Area_Func) {
|
||||
local Ret = Func(CUser, TownIndex, AreaIndex);
|
||||
if (!Ret) Flag = false;
|
||||
}
|
||||
|
||||
return Flag;
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
文件名:Reach_Game_World.nut
|
||||
路径:CallBack/Reach_Game_World.nut
|
||||
创建日期:2024-04-17 10:26
|
||||
文件用途:角色上线HOOK
|
||||
*/
|
||||
if (!("Cb_reach_game_world_Func" in getroottable())) Cb_reach_game_world_Func <- {};
|
||||
|
||||
function Cb_reach_game_world(C_User) {
|
||||
local SUser = User(C_User);
|
||||
foreach(_Index, Func in Cb_reach_game_world_Func) {
|
||||
Func(SUser);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
文件名:Return_SelectCharacter.nut
|
||||
路径:Dps_A/CallBack/Return_SelectCharacter.nut
|
||||
创建日期:2024-05-09 14:33
|
||||
文件用途:返回选择角色HOOK
|
||||
*/
|
||||
if (!("Cb_return_select_character_Func" in getroottable())) Cb_return_select_character_Func <- {};
|
||||
|
||||
function Cb_return_select_character(C_User) {
|
||||
local SUser = User(C_User);
|
||||
if (SUser) {
|
||||
foreach(_index, Func in Cb_return_select_character_Func) {
|
||||
Func(SUser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
文件名:Send_Area_User.nut
|
||||
路径:CallBack/Send_Area_User.nut
|
||||
创建日期:2024-04-08 10:09
|
||||
文件用途:给区域里刷新玩家 hook
|
||||
*/
|
||||
Send_Area_User_FuncMap <- {};
|
||||
|
||||
function Cb_send_area_user(C_Area, C_User) {
|
||||
// if (!CUser) return;
|
||||
// local SUser = User(CUser);
|
||||
|
||||
// //如果加载了超时空
|
||||
// if (getroottable().rawin(Fiendwar)) {
|
||||
// //超时空频道
|
||||
// if (Sq_Game_GetConfig().find("20") != -1) {
|
||||
// if (AreaIndex <= 1) {
|
||||
// return true;
|
||||
// } else {
|
||||
// local Jso = {
|
||||
// op = 20063025,
|
||||
// uid = SUser.GetUID(),
|
||||
// cid = SUser.GetCID(),
|
||||
// regionId = AreaIndex
|
||||
// }
|
||||
// Sq_SendPack(Json.Encode(Jso));
|
||||
// return false;
|
||||
// }
|
||||
// } else {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
文件名:SetUserMaxLevel.nut
|
||||
路径:Dps_A/CallBack/SetUserMaxLevel.nut
|
||||
创建日期:2024-06-19 19:36
|
||||
文件用途:
|
||||
*/
|
||||
if (!("Cb_user_setusermaxlevel_Level" in getroottable())) Cb_user_setusermaxlevel_Level <- 70;
|
||||
|
||||
function Cb_user_setusermaxlevel(C_User, Level) {
|
||||
print(Level);
|
||||
local SUser = User(C_User);
|
||||
if (!SUser) return;
|
||||
if (Level <= Cb_user_setusermaxlevel_Level) {
|
||||
if (Level > 0) {
|
||||
SUser.SetCharacLevel(Level);
|
||||
} else {
|
||||
SUser.SetCharacLevel(1);
|
||||
}
|
||||
} else {
|
||||
SUser.SetCharacLevel(Cb_user_setusermaxlevel_Level);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
文件名:Timer_Dispatch.nut
|
||||
路径:Dps_A/CallBack/Timer_Dispatch.nut
|
||||
创建日期:2024-06-17 21:19
|
||||
文件用途:每帧执行
|
||||
*/
|
||||
|
||||
if (!("Cb_timer_dispatch_Func" in getroottable())) Cb_timer_dispatch_Func <- {};
|
||||
|
||||
function Cb_timer_dispatch() {
|
||||
foreach(_Index, Func in Cb_timer_dispatch_Func) {
|
||||
Func();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
文件名:Use_Item_Sp.nut
|
||||
路径:CallBack/Use_Item_Sp.nut
|
||||
创建日期:2024-04-19 10:43
|
||||
文件用途:
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Cb_User_Party_Agree_Func <- {};
|
||||
|
||||
function Cb_userpartyagree(C_User) {
|
||||
local SUser = User(C_User);
|
||||
local Flag = true;
|
||||
foreach(_Index, Func in Cb_User_Party_Agree_Func) {
|
||||
local Ret = Func(SUser);
|
||||
if (!Ret) Flag = false;
|
||||
}
|
||||
return Flag;
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Cb_User_Party_Create_Func <- {};
|
||||
|
||||
function Cb_userpartycreate(C_User) {
|
||||
local SUser = User(C_User);
|
||||
local Flag = true;
|
||||
foreach(_Index, Func in Cb_User_Party_Create_Func) {
|
||||
local Ret = Func(SUser);
|
||||
if (!Ret) Flag = false;
|
||||
}
|
||||
return Flag;
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Cb_User_Party_Exit_Func <- {};
|
||||
|
||||
function Cb_userpartyexit(C_User) {
|
||||
local SUser = User(C_User);
|
||||
local Flag = true;
|
||||
foreach(_Index, Func in Cb_User_Party_Exit_Func) {
|
||||
local Ret = Func(SUser);
|
||||
if (!Ret) Flag = false;
|
||||
}
|
||||
return Flag;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue