604 lines
18 KiB
Plaintext
604 lines
18 KiB
Plaintext
/*
|
|
文件名:FatalismStone.nut
|
|
路径:Dps_A/ProjectClass/FatalismStone/FatalismStone.nut
|
|
创建日期:2025-06-22 12:54
|
|
文件用途:
|
|
*/
|
|
|
|
|
|
class FatalismStone_Stone {
|
|
//编号
|
|
Id = null;
|
|
//唯一ID
|
|
Uuid = null;
|
|
//类型
|
|
StoneType = null;
|
|
//洗练度
|
|
CultivationDegree = null;
|
|
|
|
|
|
constructor() {
|
|
|
|
}
|
|
|
|
|
|
//反序列化构造
|
|
function Deserialize(StoneId, StoneUuid) {
|
|
this.Id = StoneId;
|
|
this.Uuid = StoneUuid;
|
|
this.StoneType = ProjectInitFuncMap.P_FatalismStone.GetStoneData(this.Id)["stone type"];
|
|
}
|
|
|
|
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(Uuid, 'i'); //写入Uuid
|
|
return Blob2Hex(B);
|
|
}
|
|
}
|
|
|
|
//魂石背包类
|
|
class FatalismStone_BackPack {
|
|
|
|
//背包总格子数
|
|
GridCount = 77;
|
|
//穿戴总格子数
|
|
WearCount = 6;
|
|
StoneArr = null;
|
|
|
|
constructor() {
|
|
StoneArr = [];
|
|
}
|
|
|
|
//通过数据构造背包 反序列化
|
|
function Deserialize(N_Data) {
|
|
local BackpackData = N_Data[0][0];
|
|
local WearData = N_Data[0][1];
|
|
|
|
//转换背包数据
|
|
local BackPackArr = [];
|
|
for (local i = 0; i<(GridCount * 3); i++) {
|
|
local StoneId = BackpackData.add(i * 8).readInt();
|
|
local StoneUuid = BackpackData.add(i * 8 + 4).readInt();
|
|
if (StoneId != 0 && StoneUuid != 0) {
|
|
local StoneObj = FatalismStone_Stone();
|
|
StoneObj.Deserialize(StoneId, StoneUuid)
|
|
BackPackArr.push(StoneObj);
|
|
} else {
|
|
BackPackArr.push(null);
|
|
}
|
|
}
|
|
//转化穿戴数据
|
|
local WearArr = [];
|
|
for (local i = 0; i< WearCount; i++) {
|
|
local StoneId = WearData.add(i * 8).readInt();
|
|
local StoneUuid = WearData.add(i * 8 + 4).readInt();
|
|
if (StoneId != 0 && StoneUuid != 0) {
|
|
local StoneObj = FatalismStone_Stone();
|
|
StoneObj.Deserialize(StoneId, StoneUuid)
|
|
WearArr.push(StoneObj);
|
|
} else {
|
|
WearArr.push(null);
|
|
}
|
|
}
|
|
|
|
//两段数据放入总数据
|
|
StoneArr.extend(BackPackArr);
|
|
StoneArr.extend(WearArr);
|
|
}
|
|
|
|
//序列化
|
|
function Serialize() {
|
|
//背包数据
|
|
local BackpackArr = StoneArr.slice(0, GridCount * 3);
|
|
local BackpackHex = "0x";
|
|
foreach(Pos, StoneObject in BackpackArr) {
|
|
if (StoneObject) BackpackHex += StoneObject.Serialize();
|
|
else BackpackHex += "0000000000000000";
|
|
}
|
|
//穿戴数据
|
|
local WearArr = StoneArr.slice(GridCount * 3, GridCount * 3 + WearCount);
|
|
local WearHex = "0x";
|
|
foreach(Pos, StoneObject in WearArr) {
|
|
if (StoneObject) WearHex += StoneObject.Serialize();
|
|
else WearHex += "0000000000000000";
|
|
}
|
|
//返回
|
|
return {
|
|
inventory = BackpackHex,
|
|
wear = WearHex
|
|
};
|
|
}
|
|
|
|
//获取魂石的列表 3为身上穿戴的
|
|
function GetList(Page) {
|
|
local SliceLength = GridCount;
|
|
if (Page == 3) SliceLength = WearCount;
|
|
return StoneArr.slice(Page * 77, Page * 77 + SliceLength);
|
|
}
|
|
}
|
|
|
|
class FatalismStone {
|
|
|
|
//总格子数
|
|
GridCount = 77;
|
|
//总穿戴数
|
|
WearCount = 6;
|
|
|
|
//属性数据位数
|
|
AttrCount = 2;
|
|
|
|
//魂石Lst
|
|
FatalismStoneLst = null;
|
|
//魂石配置
|
|
FatalismStoneConfig = null;
|
|
|
|
constructor() {
|
|
Script();
|
|
local PoolObj = MysqlPool.GetInstance();
|
|
PoolObj.SetBaseConfiguration("127.0.0.1", 3306, "game", "uu5!^%jg");
|
|
//连接池大小
|
|
PoolObj.PoolSize = 10;
|
|
//初始化
|
|
PoolObj.Init();
|
|
|
|
//读取pvf的魂石相关数据
|
|
InitFatalismStoneData();
|
|
|
|
//创建新架构表
|
|
SelectSql("CREATE TABLE `zyk`.`f_user_info` ( `cid` int(250) NOT NULL, `inventory` varbinary(1848) NULL, `wear` varbinary(48) NULL, PRIMARY KEY (`cid`));", []);
|
|
SelectSql("CREATE TABLE `zyk`.`f_stone_map` ( `uuid` int(250) NOT NULL AUTO_INCREMENT, `cultivation` float NULL DEFAULT NULL, PRIMARY KEY (`uuid`) USING BTREE);", []);
|
|
// UpdateNewMysqlData();
|
|
|
|
|
|
|
|
//注册客户端收包
|
|
RegisterClient();
|
|
//注册调试命令
|
|
RegisterDebugCmd();
|
|
}
|
|
|
|
|
|
//查询单个魂石的属性
|
|
function GetStoneAttr(Uuid) {
|
|
local Ret = SelectSql("select cultivation from zyk.f_stone_map where uuid = " + Uuid, ["float"]);
|
|
if (Ret.len() == 0) {
|
|
return null;
|
|
} else {
|
|
return Ret[0];
|
|
}
|
|
}
|
|
|
|
//查询多个魂石的属性
|
|
function GetStoneAttrArr(UuidArr) {
|
|
local SqlStr = "select uuid,cultivation from zyk.f_stone_map where uuid in (";
|
|
for (local i = 0; i< UuidArr.len(); i++) {
|
|
SqlStr += UuidArr[i];
|
|
if (i != UuidArr.len() - 1) {
|
|
SqlStr += ",";
|
|
}
|
|
}
|
|
SqlStr += ")";
|
|
local Ret = SelectSql(SqlStr, ["int", "float"]);
|
|
if (Ret.len() == 0) {
|
|
return null;
|
|
} else {
|
|
return Ret;
|
|
}
|
|
}
|
|
|
|
|
|
function RegisterClient() {
|
|
|
|
//查询魂石背包数据
|
|
ClientSocketPackFuncMap.rawset(21000001, function(SUser, Jso) {
|
|
local Ret = GetInvenData(SUser);
|
|
//没查到东西说明没有背包 第一次创建背包
|
|
if (!Ret || Ret.len() == 0) {
|
|
local SqlStr = format("INSERT INTO zyk.f_user_info (cid, inventory, wear) VALUES (%d,REPEAT(0x00, 1848),REPEAT(0x00, 48))", SUser.GetCID());
|
|
SelectSql(SqlStr, []);
|
|
}
|
|
//有数据的读取
|
|
else {
|
|
local BackPackData = Ret[0][0];
|
|
local WearData = Ret[0][1];
|
|
local PackSize = 4 + 4 + BackPackData.Size + 4 + WearData.Size;
|
|
local Pack = Packet();
|
|
Pack.Put_Header(1, 131);
|
|
Pack.Put_Byte(1);
|
|
Pack.Put_Int(PackSize);
|
|
Pack.Put_Int(21000002);
|
|
Pack.Put_Int(BackPackData.Size);
|
|
Pack.Put_BinaryEx(BackPackData.C_Object, BackPackData.Size);
|
|
Pack.Put_Int(WearData.Size);
|
|
Pack.Put_BinaryEx(WearData.C_Object, WearData.Size);
|
|
Pack.Finalize(true);
|
|
SUser.Send(Pack);
|
|
Pack.Delete();
|
|
|
|
//查询身上穿戴的魂石属性
|
|
local BackPack = FatalismStone_BackPack();
|
|
BackPack.Deserialize(Ret);
|
|
local WearArr = BackPack.GetList(3);
|
|
local UuidArr = [];
|
|
for (local i = 0; i< WearArr.len(); i++) {
|
|
if (WearArr[i] != null) {
|
|
UuidArr.push(WearArr[i].Uuid);
|
|
}
|
|
}
|
|
if (UuidArr.len() > 0) {
|
|
local Attr = GetStoneAttrArr(UuidArr);
|
|
if (Attr) {
|
|
local PackSize = 4 + 4 + (Attr.len() * 4 * Attr[0].len());
|
|
local Pack = Packet();
|
|
Pack.Put_Header(1, 131);
|
|
Pack.Put_Byte(1);
|
|
Pack.Put_Int(PackSize);
|
|
Pack.Put_Int(21000014);
|
|
Pack.Put_Int(Attr.len());
|
|
for (local i = 0; i< Attr.len(); i++) {
|
|
for (local z = 0; z< Attr[i].len(); z++) {
|
|
Pack.Put_Int(Attr[i][z]);
|
|
}
|
|
}
|
|
Pack.Finalize(true);
|
|
SUser.Send(Pack);
|
|
Pack.Delete();
|
|
}
|
|
}
|
|
}
|
|
}.bindenv(this));
|
|
|
|
//查询魂石唯一属性
|
|
ClientSocketPackFuncMap.rawset(21000011, function(SUser, Jso) {
|
|
local Uuid = Jso.uuid;
|
|
SendFatalismStoneData(SUser, Uuid);
|
|
}.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 BackPack = GetInven(SUser);
|
|
if (!BackPack) return;
|
|
|
|
//直接去交换位置
|
|
local Buffer = BackPack.StoneArr[OldType * 77 + OldIndex];
|
|
BackPack.StoneArr[OldType * 77 + OldIndex] = BackPack.StoneArr[NewType * 77 + NewIndex];
|
|
BackPack.StoneArr[NewType * 77 + NewIndex] = Buffer;
|
|
|
|
SaveInven(BackPack, SUser);
|
|
}.bindenv(this));
|
|
|
|
//魂石洗练
|
|
ClientSocketPackFuncMap.rawset(21000005, function(SUser, Jso) {
|
|
local Uuid = Jso.uuid;
|
|
local rarity = Jso.rarity;
|
|
//获取背包对象
|
|
local InvenObj = SUser.GetInven();
|
|
local Flag = InvenObj.DeleteItemCount(FatalismStoneConfig["wash_item"], FatalismStoneConfig["wash_cost"][rarity]);
|
|
//扣除不成功
|
|
if (!Flag) {
|
|
SUser.SendNotiPacketMessage("精炼魂石所需的材料不足!", 8);
|
|
return;
|
|
}
|
|
|
|
local Rand = MathClass.Rand(1, 105);
|
|
if (Rand > 100) Rand = 100;
|
|
|
|
//将新的精炼值写入数据库
|
|
local Sql = "update zyk.f_stone_map set cultivation = " + Rand + " where uuid = " + Uuid;
|
|
SelectSql(Sql, []);
|
|
SendFatalismStoneData(SUser, Uuid)
|
|
}.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);
|
|
}, 1000);
|
|
//如果满了就发邮件
|
|
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 GetInvenData(SUser) {
|
|
local Ret = SelectSql("select inventory,wear from zyk.f_user_info where cid = " + SUser.GetCID(), ["binary", "binary"]);
|
|
if (!Ret || Ret.len() == 0) return null;
|
|
else return Ret;
|
|
}
|
|
|
|
//获取玩家背包
|
|
function GetInven(SUser) {
|
|
local Ret = GetInvenData(SUser);
|
|
if (Ret) {
|
|
local BackPack = FatalismStone_BackPack();
|
|
BackPack.Deserialize(Ret);
|
|
return BackPack;
|
|
} else return null;
|
|
}
|
|
|
|
//固化背包数据到数据库
|
|
function SaveInven(Inven, SUser) {
|
|
//获取背包整体信息并储存
|
|
local Hex = Inven.Serialize();
|
|
//更新数据库
|
|
local Sql = "update zyk.f_user_info set inventory = " + Hex.inventory + ",wear = " + Hex.wear + " where cid = " + SUser.GetCID();
|
|
SelectSql(Sql, []);
|
|
}
|
|
|
|
//发送uuid的魂石数据给客户端
|
|
function SendFatalismStoneData(SUser, Uuid) {
|
|
local Attr = GetStoneAttr(Uuid);
|
|
if (!Attr) {
|
|
SUser.SendNotiPacketMessage("魂石属性异常,请联系管理员!", 8);
|
|
} else {
|
|
local Cultivation = Attr[0];
|
|
local PackSize = 4 + 4 + 4;
|
|
local Pack = Packet();
|
|
Pack.Put_Header(1, 131);
|
|
Pack.Put_Byte(1);
|
|
Pack.Put_Int(PackSize);
|
|
Pack.Put_Int(21000012);
|
|
Pack.Put_Int(Uuid);
|
|
Pack.Put_Int(Cultivation);
|
|
Pack.Finalize(true);
|
|
SUser.Send(Pack);
|
|
Pack.Delete();
|
|
}
|
|
}
|
|
|
|
//给指定玩家新增魂石
|
|
function AddFatalismStone(SUser, FatalismStoneID) {
|
|
local CID = SUser.GetCID();
|
|
|
|
|
|
}
|
|
|
|
|
|
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));
|
|
|
|
FatalismStoneConfig = ScriptData.GetFileData("fatalismstone/fatalismstone.etc", function(DataTable, Data) {
|
|
while (!Data.Eof()) {
|
|
local Str = Data.Get();
|
|
if (Str == "[wash item]") {
|
|
DataTable.wash_item <- Data.Get();
|
|
} else if (Str == "[wash cost]") {
|
|
DataTable.wash_cost <- [Data.Get(), Data.Get(), Data.Get(), Data.Get(), Data.Get(), Data.Get(), Data.Get()];
|
|
}
|
|
}
|
|
}.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;
|
|
}
|
|
|
|
|
|
//UpdateNewMysqlData
|
|
function UpdateNewMysqlData() {
|
|
|
|
local Ret = SelectSql("select * from zyk.fatalismstone", ["int", "binary", "binary"]);
|
|
|
|
foreach(Index, Info in Ret) {
|
|
local cid = Info[0];
|
|
local inventory = Info[1];
|
|
local wear = Info[2];
|
|
|
|
//处理背包里的魂石
|
|
local NewBlob = blob();
|
|
for (local i = 0; i< 462; i += 2) {
|
|
local item_id = inventory.add(i * 4).readInt();
|
|
local cultivation = inventory.add(i * 4 + 4).readInt();
|
|
if (item_id > 0) {
|
|
//在新表中建立这件装备的uuid
|
|
local Sql = "insert into zyk.f_stone_map (cultivation) values (" + cultivation + ")";
|
|
SelectSql(Sql, []);
|
|
//查询最后新增条目的uuid
|
|
Sql = "select LAST_INSERT_ID() as uuid";
|
|
local uuid = SelectSql(Sql, ["int"])[0][0];
|
|
|
|
NewBlob.writen(item_id, 'i');
|
|
NewBlob.writen(uuid, 'i');
|
|
} else {
|
|
NewBlob.writen(0, 'i');
|
|
NewBlob.writen(0, 'i');
|
|
}
|
|
}
|
|
local inventoryBinary = "0x" + Blob2Hex(NewBlob);
|
|
|
|
//处理身上穿戴的魂石
|
|
NewBlob.resize(0);
|
|
for (local i = 0; i< 12; i += 2) {
|
|
local item_id = wear.add(i * 4).readInt();
|
|
print(item_id);
|
|
|
|
local cultivation = wear.add(i * 4 + 4).readInt();
|
|
if (item_id > 0) {
|
|
//在新表中建立这件装备的uuid
|
|
local Sql = "insert into zyk.f_stone_map (cultivation) values (" + cultivation + ")";
|
|
SelectSql(Sql, []);
|
|
//查询最后新增条目的uuid
|
|
Sql = "select LAST_INSERT_ID() as uuid";
|
|
local uuid = SelectSql(Sql, ["int"])[0][0];
|
|
|
|
NewBlob.writen(item_id, 'i');
|
|
NewBlob.writen(uuid, 'i');
|
|
} else {
|
|
NewBlob.writen(0, 'i');
|
|
NewBlob.writen(0, 'i');
|
|
}
|
|
}
|
|
local wearBinary = "0x" + Blob2Hex(NewBlob);
|
|
|
|
local Sql = "insert into zyk.f_user_info (cid,inventory, wear) values (" + cid + "," + inventoryBinary + "," + wearBinary + ")";
|
|
SelectSql(Sql, []);
|
|
}
|
|
}
|
|
|
|
function Blob2Hex(buf) {
|
|
local str = "";
|
|
for (local i = 0; i< buf.len(); i++) {
|
|
str += format("%02X", buf[i]);
|
|
}
|
|
return str;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
ProjectInitFuncMap.P_FatalismStone <- FatalismStone(); |