/* 文件名:MarrySystem.nut 路径:Dps_A/ProjectClass/MarrySystem/MarrySystem.nut 创建日期:2024-10-01 10:02 文件用途:结婚系统 */ class Marry { //当前频道 Channel = null; //配置 Config = null; //包头 OP = 20078000; //请求结婚的列表 RequestMarryList = {}; //进入礼堂前的位置信息 EnterAuditoriumPosList = {}; //礼堂id 对应的用户信息 结构为Map> AuditoriumUserInfo = {}; //角色时装信息 UserAvaList = {}; //数据库操作集 Mysql_Operate_Func = { //查询结婚状态 CheckMarryState = function(Cid) { local CheckSql = format(MARRY_SQL_LIST.CheckMarryState, Cid); //从池子拿连接 local SqlObj = MysqlPool.GetInstance().GetConnect(); local Ret = SqlObj.Select(CheckSql, ["int"]); //把连接还池子 MysqlPool.GetInstance().PutConnect(SqlObj); //没结婚要返回false if (Ret.len()< 1 || Ret[0][0] == null) { return 0; } else { return Ret[0][0]; } } //新增结婚信息 InseartMarryInfo = function(Cid, Name, TargerCid, Job, Level, Experience, Equip, State) { local sql = format(MARRY_SQL_LIST.InseartMarryInfo, Cid, Name, TargerCid, Job, Level, Experience, Equip, State, TargerCid, Equip, State); //从池子拿连接 local SqlObj = MysqlPool.GetInstance().GetConnect(); SqlObj.Exec_Sql(sql); //把连接还池子 MysqlPool.GetInstance().PutConnect(SqlObj); } //查询结婚对象CID CheckMarryTarget = function(Cid) { local CheckSql = format(MARRY_SQL_LIST.CheckMarryTarget, Cid); //从池子拿连接 local SqlObj = MysqlPool.GetInstance().GetConnect(); local Ret = SqlObj.Select(CheckSql, ["int"]); //把连接还池子 MysqlPool.GetInstance().PutConnect(SqlObj); //没结婚要返回false if (Ret.len()< 1 || Ret[0][0] == null) { return null; } else { return Ret[0][0]; } } //删除结婚信息 DeleteMarryInfo = function(Cid) { local delete_sql = format(MARRY_SQL_LIST.DeleteMarryInfo, Cid); //从池子拿连接 local SqlObj = MysqlPool.GetInstance().GetConnect(); SqlObj.Exec_Sql(delete_sql); //把连接还池子 MysqlPool.GetInstance().PutConnect(SqlObj); } //查询结婚对象名字 CheckMarryTargetName = function(Cid) { local CheckSql = format(MARRY_SQL_LIST.CheckMarryTargetName, Cid); //从池子拿连接 local SqlObj = MysqlPool.GetInstance().GetConnect(); local Ret = SqlObj.Select(CheckSql, ["string"]); //把连接还池子 MysqlPool.GetInstance().PutConnect(SqlObj); //没结婚要返回false if (Ret.len()< 1 || Ret[0][0] == null) { return null; } else { return Ret[0][0]; } } //修改结婚状态 ChangeMarryState = function(Cid, State) { local Sql = format(MARRY_SQL_LIST.ChangeMarryState, State, Cid); //从池子拿连接 local SqlObj = MysqlPool.GetInstance().GetConnect(); SqlObj.Exec_Sql(Sql); //把连接还池子 MysqlPool.GetInstance().PutConnect(SqlObj); } //新增礼堂信息 InsertMarryRoom = function(Cid, Name, Time, Level, Target_CId, Target_Name, State, Index) { local Sql = format(MARRY_SQL_LIST.InsertMarryRoom, Cid, Name, Time, Level, Target_CId, Target_Name, State, Index); //从池子拿连接 local SqlObj = MysqlPool.GetInstance().GetConnect(); SqlObj.Exec_Sql(Sql); //把连接还池子 MysqlPool.GetInstance().PutConnect(SqlObj); } //查询礼堂信息 GetAuditoriumList = function() { local Sql = format(MARRY_SQL_LIST.GetAuditoriumList); //从池子拿连接 local SqlObj = MysqlPool.GetInstance().GetConnect(); local Ret = SqlObj.Select(Sql, ["int", "string", "int", "int", "int", "string", "int", "int"]); //把连接还池子 MysqlPool.GetInstance().PutConnect(SqlObj); return Ret; } //根据cid查询自己的礼堂编号 GetAuditoriumIndexById = function(cid) { local Sql = format(MARRY_SQL_LIST.GetAuditoriumIndexById, cid); //从池子拿连接 local SqlObj = MysqlPool.GetInstance().GetConnect(); local Ret = SqlObj.Select(Sql, ["int"]); //把连接还池子 MysqlPool.GetInstance().PutConnect(SqlObj); if (Ret.len()< 1 || Ret[0][0] == null) { return null; } else { return Ret[0][0]; } } //根据cid查询婚礼开始时间 GetAuditoriumTimeById = function(cid) { local Sql = format(MARRY_SQL_LIST.GetAuditoriumTimeById, cid); //从池子拿连接 local SqlObj = MysqlPool.GetInstance().GetConnect(); local Ret = SqlObj.Select(Sql, ["int"]); //把连接还池子 MysqlPool.GetInstance().PutConnect(SqlObj); if (Ret.len()< 1 || Ret[0][0] == null) { return null; } else { return Ret[0][0]; } } } //查看是否结婚包 function CheckMarryStateCallBack(SUser, Jso) { local T = { op = OP + 10, Flag = Mysql_Operate_Func.CheckMarryState(SUser.GetCID()) } SUser.SendJso(T); } //申请订婚包 function RequestMarry(SUser, Jso) { local PSUser = World.GetUserByName(Jso.Name); //判断对象角色是否在线 if (!PSUser) { //没找到这个角色要返回一个错误包 local T = { op = OP + 90, str = "未找到角色,请检查角色名或查看玩家是否在线" } SUser.SendNotiBox("未找到角色,请检查角色名或查看玩家是否在线", 1); } //判断是否是自己 if (SUser.GetCID() == PSUser.GetCID()) { SUser.SendNotiBox("不能和自己结婚!", 1); return; } //查询两人状态必须都为未结婚 local SUserState = Mysql_Operate_Func.CheckMarryState(SUser.GetCID()); local PSUserState = Mysql_Operate_Func.CheckMarryState(PSUser.GetCID()); if (SUserState) { SUser.SendNotiBox("抱歉,您已经结婚了!", 1); return; } if (PSUserState) { SUser.SendNotiBox("抱歉,对方已经结婚了...", 1); return; } local T = { op = OP + 4, applicantCid = SUser.GetCID(), applicantUid = SUser.GetUID(), applicantName = SUser.GetCharacName(), } PSUser.SendJso(T); //把请求加入到请求列表 RequestMarryList.rawset(SUser.GetCID(), PSUser.GetCID()); } //订婚答复包 function ResponseMarry(SUser, Jso) { local Flag = Jso.Flag; local applicantUser = World.GetUserByUidCid(Jso.applicantUid, Jso.applicantCid); if (Flag) { if (applicantUser) { //在请求列表里查看是否有请求 if (!(RequestMarryList.rawin(Jso.applicantCid)) || RequestMarryList[Jso.applicantCid] != SUser.GetCID()) { SUser.SendNotiBox("抱歉,对方未发送请求!", 1); return; } applicantUser.SendNotiBox("恭喜您!\n对方同意了您的请求。\n请寻找大司祭制定结婚的详细事宜。", 1); Mysql_Operate_Func.InseartMarryInfo(Jso.applicantCid, applicantUser.GetCharacName(), SUser.GetCID(), applicantUser.GetCharacJob(), 0, 0, "no", 1); Mysql_Operate_Func.InseartMarryInfo(SUser.GetCID(), SUser.GetCharacName(), Jso.applicantCid, SUser.GetCharacJob(), 0, 0, "no", 1); //刷新客户端的订婚状态 local T = { op = OP + 10, Flag = 1 }; applicantUser.SendJso(T); SUser.SendJso(T); } } else { if (applicantUser) applicantUser.SendNotiBox("很遗憾!\n对方拒绝了您的请求", 1); } } //退婚包 function CancelMarry(SUser, Jso) { //加判断 必须两人都在订婚状态才能退婚 local DeleteArr = []; DeleteArr.push(SUser.GetCID()); local Target_CId = Mysql_Operate_Func.CheckMarryTarget(SUser.GetCID()); if (Target_CId) { DeleteArr.push(Target_CId); //如果对象存在则判断两人是否都在订婚状态 local SUserState = Mysql_Operate_Func.CheckMarryState(SUser.GetCID()) local TargetState = Mysql_Operate_Func.CheckMarryTarget(Target_CId); if (SUserState != 1 || TargetState != 1) return; } foreach(s_cid in DeleteArr) { Mysql_Operate_Func.DeleteMarryInfo(s_cid); } //刷新客户端的订婚状态 local T = { op = OP + 10, Flag = 0 }; SUser.SendJso(T); //如果需要通知被退婚的对象 if (DeleteArr.len() > 1) { local WorldMap = World.GetOnlinePlayer(); foreach(W_User in WorldMap) { if (W_User.GetCID() == DeleteArr[1]) { W_User.SendJso(T); } } } } //打开准备婚礼窗口 function OpenPreparationWindow(SUser, Jso) { local Target_CId = Mysql_Operate_Func.CheckMarryTarget(SUser.GetCID()); if (!Target_CId) { SUser.SendNotiBox("没有婚礼信息!", 1); return; } local Target_Name = Mysql_Operate_Func.CheckMarryTargetName(Target_CId); if (!Target_Name) { SUser.SendNotiBox("没有婚礼信息!", 1); return; } local T = { op = OP + 12, MyName = SUser.GetCharacName(), TargetName = Target_Name, }; SUser.SendJso(T); } //确认婚礼 function ConfirmMarry(SUser, Jso) { local Target_CId = Mysql_Operate_Func.CheckMarryTarget(SUser.GetCID()); if (!Target_CId) { SUser.SendNotiBox("没有婚礼信息!", 1); return; } local Time = Jso.Time; local Level = Jso.Level; local NeedItem = Config[("结婚等级" + (Level + 1) + "道具ID")]; //获取背包对象 local InvenObj = SUser.GetInven(); local SlotIdx = InvenObj.GetSlotById(NeedItem); if (SlotIdx == -1) { SUser.SendNotiBox("没有足够的道具!", 1); return; } else { InvenObj.DeleteItemCount(NeedItem, 1); //获得婚礼仪式开始时间 local Index = time() + (Time + 1) * 10 * 60; //注册婚礼礼堂信息 Mysql_Operate_Func.InsertMarryRoom(SUser.GetCID(), SUser.GetCharacName(), Time, Level, Target_CId, Mysql_Operate_Func.CheckMarryTargetName(Target_CId), 1, Index); Mysql_Operate_Func.InsertMarryRoom(Target_CId, Mysql_Operate_Func.CheckMarryTargetName(Target_CId), Time, Level, SUser.GetCID(), SUser.GetCharacName(), 1, Index); AuditoriumUserInfo.rawset(SUser.GetCID(), {}); Mysql_Operate_Func.ChangeMarryState(SUser.GetCID(), 2); Mysql_Operate_Func.ChangeMarryState(Target_CId, 2); local T = { op = OP + 10, Flag = 2 } local WorldMap = World.GetOnlinePlayer(); foreach(W_User in WorldMap) { if (W_User.GetCID() == Target_CId) { W_User.SendJso(T); W_User.SendNotiBox(format("婚礼将在%d分钟后举行!\n点击大司祭可进入礼堂。", (Time + 1) * 10), 1); } } SUser.SendJso(T); SUser.SendNotiBox(format("婚礼将在%d分钟后举行!\n点击大司祭可进入礼堂。", (Time + 1) * 10), 1); } } //开启婚礼 参数为礼堂编号 也就是其中一个人的cid function OpenAuditorium(index) { //通知所有在这个礼堂里的人 婚礼开始了 local userlist = AuditoriumUserInfo[RoomId]; local dxcid = Mysql_Operate_Func.CheckMarryTarget(index); foreach(uid in userlist) { local user = World.GetUserByUid(uid); //发包通知 如果是2个结婚的人的cid 下发另外的包 if (user.GetCID() == index || user.GetCID() == dxcid) { local T = { op = OP + 32, userlist = userlist } } else { //发包通知 普通宾客的包 local T = { op = OP + 34, userlist = userlist } } user.SendJso(T); } //删除礼堂信息 AuditoriumUserInfo.rawdelete(RoomId); //删除数据库信息 Mysql_Operate_Func.DeleteMarryInfo(index); Mysql_Operate_Func.DeleteMarryInfo(dxcid); } //进入礼堂 function EnterAuditorium(SUser, Jso) { local RoomId = Jso.room; local location = SUser.GetLocation(); //进入自己的礼堂 if (RoomId == -1) { local MyState = Mysql_Operate_Func.CheckMarryState(SUser.GetCID()); if (MyState != 2) { SUser.SendNotiBox("您访问的礼堂不存在!", 1); return; } RoomId = SUser.GetCID(); //如果根据自己的cid不能拿到礼堂信息 说明这个礼堂的key是对象的 if (!(AuditoriumUserInfo.rawin(RoomId))) { //对象的cid RoomId = Mysql_Operate_Func.GetAuditoriumIndexById(SUser.GetCID()); } location.rawset("所在礼堂编号", RoomId); //向缓存写入进入时的坐标 EnterAuditoriumPosList.rawset(SUser.GetCID(), location); //移动到礼堂 World.MoveArea(SUser, Config["礼堂城镇编号"], Config["礼堂区域编号"], 55, 349); } else { location.rawset("所在礼堂编号", RoomId); //向缓存写入进入时的坐标 EnterAuditoriumPosList.rawset(SUser.GetCID(), location); //移动到礼堂 World.MoveArea(SUser, Config["礼堂城镇编号"], Config["礼堂区域编号"], 55, 349); } AuditoriumUserInfo[RoomId].rawset(SUser.GetUID(), GetAva(SUser)); local UserCanSee = []; foreach(cid in AuditoriumUserInfo[RoomId]) { UserCanSee.push(cid); } local T = { op = OP + 22, time = Mysql_Operate_Func.GetAuditoriumTimeById(RoomId) - time() } SUser.SendJso(T); } //离开礼堂 function LeaveAuditorium(SUser, Jso) { if (EnterAuditoriumPosList.rawin(SUser.GetCID())) { local Info = EnterAuditoriumPosList[SUser.GetCID()]; //离开礼堂回到进入时的位置 World.MoveArea(SUser, Info.Town, Info.Area, Info.Pos.X, Info.Pos.Y); AuditoriumUserInfo[Info["所在礼堂编号"]].rawdelete(SUser.GetUID()); } } //获得礼堂列表 function GetAuditoriumList(SUser, Jso) { local re = Mysql_Operate_Func.GetAuditoriumList(); local SendArr = []; //判断用的 local SelectMap = {}; foreach(v in re) { local TimeBuf = v.pop(); local id = v[0]; //不存在时PUSH if (!(SelectMap.rawin(v[4]))) { v.push(AuditoriumUserInfo.rawget(id).len()); v.push(Channel); v.push(TimeBuf); SendArr.push(v); SelectMap.rawset(id, 1); } } local T = { op = OP + 20, info = SendArr } SUser.SendJso(T); } function GetConfig(SUser, Jso) { local T = { op = OP + 778, town = Config["礼堂城镇编号"], area = Config["礼堂区域编号"], } SUser.SendJso(T); } //表示是否可见 参数为用户数组 function MarryUserCallBack(RealList, MUser) { foreach(_Index, Value in RealList) { local SUser = Value; if (!SUser || !SUser.GetState() >= 3) continue; if (SUser.GetUID() == MUser.GetUID()) continue; 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 MarryUserDeleteCallBack(RealList, MUser) { foreach(_Index, Value in RealList) { local SUser = Value; if (!SUser || !(SUser.GetState() >= 3) || !MUser || !(MUser.GetState() >= 3)) continue; if (SUser.GetUID() == MUser.GetUID()) continue; local Pack = Packet(); Pack.Put_Header(0, 23); Pack.Put_Short(MUser.GetUniqueId()); //唯一id Pack.Put_Byte(MUser.GetLocation().Town); //城镇 Pack.Put_Byte(99); //区域 Pack.Put_Short(MUser.GetAreaPos().X); Pack.Put_Short(MUser.GetAreaPos().Y); Pack.Put_Byte(MUser.GetDirections()); //朝向 Pack.Put_Byte(MUser.GetVisibleValues()); //是否可见 Pack.Finalize(true); print(111); SUser.Send(Pack); Pack.Delete(); } } constructor() { Config = dofile("/root/娱心插件配置/结婚系统配置.dat"); local ConfigPath = Sq_Game_GetConfig(); Channel = ConfigPath.slice(-6).slice(0, 2); //注册来自客户端的收包 ClientSocketPackFuncMap.rawset(OP + 9, CheckMarryStateCallBack.bindenv(this)); ClientSocketPackFuncMap.rawset(OP + 3, RequestMarry.bindenv(this)); ClientSocketPackFuncMap.rawset(OP + 5, ResponseMarry.bindenv(this)); ClientSocketPackFuncMap.rawset(OP + 7, CancelMarry.bindenv(this)); ClientSocketPackFuncMap.rawset(OP + 11, OpenPreparationWindow.bindenv(this)); ClientSocketPackFuncMap.rawset(OP + 13, ConfirmMarry.bindenv(this)); ClientSocketPackFuncMap.rawset(OP + 15, EnterAuditorium.bindenv(this)); ClientSocketPackFuncMap.rawset(OP + 17, LeaveAuditorium.bindenv(this)); ClientSocketPackFuncMap.rawset(OP + 19, GetAuditoriumList.bindenv(this)); ClientSocketPackFuncMap.rawset(OP + 777, GetConfig.bindenv(this)); //每次加载的时候都注册礼堂信息 AuditoriumUserInfo.rawset(1, {}); //玩家重新上线的时候自动给他退出礼堂 Cb_reach_game_world_Func.Auditorium <- function(SUser) { if (EnterAuditoriumPosList.rawin(SUser.GetUID())) { local Info = EnterAuditoriumPosList[SUser.GetCID()]; AuditoriumUserInfo[Info["所在礼堂编号"]].rawdelete(SUser.GetUID()); } }.bindenv(this); // local RealList = []; // RealList.push(World.GetUserByUid(1)); // RealList.push(World.GetUserByUid(2)); // Timer.SetTimeOut(function() { // // Sq_CallFunc(S_Ptr("0x850d374"), "int", ["pointer", "int"], S_Ptr("0x1"), "sss") // // local S = Memory.alloc(100); // // Sq_Delete_Point(S.C_Object); // Sq_CallFunc(S_Ptr("0x08692af6"), "int", ["pointer", "int", "int"], 1, 1, 1); // }, 3000); // local Suser = World.GetUserByUid(2); // //获取背包对象 // local InvenObj = Suser.GetInven(); // //遍历身上的每一件装备 // for (local u = 0; u <= 10; u++) { // //如果装备存在 并且存在于 加成表中 就给提升率加上对应的值 // local EquObj = InvenObj.GetSlot(Inven.INVENTORY_TYPE_BODY, u); // if (EquObj && !EquObj.IsEmpty) { // local EquObjId = EquObj.GetIndex(); // print(EquObj.Output()); // } // } //从池子拿连接 local SqlObj = MysqlPool.GetInstance().GetConnect(); local query = "SELECT COUNT(*) AS table_exists FROM information_schema.tables WHERE table_schema = 'zyk' AND table_name = 'marry';" local Res = SqlObj.Select(query, ["int"]); //需要建库 if (Res.len() > 0 && Res[0][0] == 0) { local CreateSql = "CREATE TABLE IF NOT EXISTS zyk.marry (cid INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), target_cid INT(11), job INT(11), level INT(11), experience INT(11), equip VARCHAR(255), state INT(11));" local CreateSql2 = "CREATE TABLE IF NOT EXISTS zyk.marry_room (cid INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), time INT(11), level INT(11), target_cid INT(11), target_name VARCHAR(255), state INT(11), index INT(11));" SqlObj.Exec_Sql(CreateSql); SqlObj.Exec_Sql(CreateSql2); } //把连接还池子 MysqlPool.GetInstance().PutConnect(SqlObj); defaultJobItemIdMap.rawset(0, defaultJobItemId(39278, 39400, 0, 0, 40600, 41000, 41800, 42200)); defaultJobItemIdMap.rawset(1, defaultJobItemId(0, 43400, 0, 0, 44600, 45000, 45800, 46200)); defaultJobItemIdMap.rawset(2, defaultJobItemId(0, 47400, 0, 48426, 48600, 49000, 49800, 50200)); defaultJobItemIdMap.rawset(3, defaultJobItemId(51265, 51400, 0, 0, 52600, 53000, 53800, 54200)); defaultJobItemIdMap.rawset(4, defaultJobItemId(0, 55400, 55820, 0, 56600, 57000, 57800, 58200)); defaultJobItemIdMap.rawset(5, defaultJobItemId(1600000, 1610000, 0, 0, 1640000, 1650000, 1670000, 1680000)); defaultJobItemIdMap.rawset(6, defaultJobItemId(1720000, 1730000, 0, 1750000, 1760000, 1770000, 1790000, 1800000)); defaultJobItemIdMap.rawset(7, defaultJobItemId(0, 29201, 0, 0, 29202, 29203, 29204, 29205)); defaultJobItemIdMap.rawset(8, defaultJobItemId(0, 2090000, 0, 0, 2120000, 2130000, 2140000, 2150000)); defaultJobItemIdMap.rawset(9, defaultJobItemId(39278, 39400, 0, 0, 40600, 41000, 41800, 42200)); defaultJobItemIdMap.rawset(10, defaultJobItemId(51265, 51400, 0, 0, 52600, 53000, 53800, 54200)); } } //获取角色身上的显示时装 function GetAva(SUser) { //获取背包对象 local InvenObj = SUser.GetInven(); local re = []; local job = SUser.GetCharacJob(); //遍历身上的每一件装备 for (local u = 0; u <= 2; u++) { local EquObj = InvenObj.GetSlot(Inven.INVENTORY_TYPE_BODY, u); if (EquObj && !EquObj.IsEmpty) { //先拿克隆id 如果这个值有 那说明带的克隆 直接用这个 local clearId = Sq_CallFunc(S_Ptr("0x850d374"), "int", ["pointer", "int"], 1, u) // print(clearId); local EquObjId = EquObj.GetIndex(); // print(EquObjId); //如果这个是克隆 if (clearId > 0) { re.push(clearId); } else { //不是克隆 直接把id放上去 re.push(EquObjId); } } else { //如果这个部位没东西 直接放默认时装上去 re.push(defaultJobItemIdMap[job].index[u]); } } return re; } //默认时装 defaultJobItemIdMap <- {}; class defaultJobItemId { /** * 头发 */ hat = 0; /** * 帽子 */ hair = 0; /** *脸 */ face = 0; /** * 披风 */ breast = 0; /** * 上衣 */ coat = 0; /** * 下装 */ pants = 0; /** * 鞋子 */ shoes = 0; /** * 皮肤 */ skin = 0; index = []; constructor(hat, hair, face, breast, coat, pants, shoes, skin) { this.hat = hat; this.hair = hair; this.face = face; this.breast = breast; this.coat = coat; this.pants = pants; 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(shoes); index.push(skin); } } ProjectInitFuncMap.P_Marry <- Marry();