--------------------------------------------------------------------- -- 公会模块 -- db.unionSignIn 最近一次公会签到的0点时间戳 --------------------------------------------------------------------- local Lang = require("common.Lang") local FilterUtil = require("common.FilterUtil") local UnionDBLogic = require("union.UnionDBLogic") local UnionExcel = require("excel.union") local MailManager = require("mail.MailManager") local MailExcel = require("excel.mail") local RoleDBLogic = require("role.RoleDBLogic") local Msg = require("core.Msg") local Broadcast = require("broadcast.Broadcast") local ObjHuman = require("core.ObjHuman") local Util = require("common.Util") local BagLogic = require("bag.BagLogic") local ItemDefine = require("bag.ItemDefine") local CombatLogic = require("combat.CombatLogic") local CombatDefine = require("combat.CombatDefine") local HeroGrid = require("hero.HeroGrid") local ChatUnion = require("chat.ChatUnion") local ChatHandler = require("chat.Handler") local Grid = require("bag.Grid") local UnionEctypeLogic = require("union.UnionEctypeLogic") local UnionWarLogic = require("union.UnionWarLogic") local UnionWarDBLogic = require("union.UnionWarDBLogic") local LuaMongo = _G.lua_mongo local DB = require("common.DB") local RoleLogic = require("role.RoleLogic") local UnionDefine = require("union.UnionDefine") local MonsterExcel = require("excel.monster") local VipLogic = require("vip.VipLogic") local RoleSystemLogic = require("roleSystem.RoleSystemLogic") local RoleSystemDefine = require("roleSystem.RoleSystemDefine") local ChengjiuLogic = require("chengjiu.ChengjiuLogic") local UnionDonateLogic = require("union.UnionDonateLogic") local UnionLivenessLogic = require("union.UnionLivenessLogic") local MailDefine = require("mail.MailIdDefine") local RoleAttr = require("role.RoleAttr") local Timer = require("core.Timer") local BillboardDB = require("billboard.BillboardDB") local InnerMsg = require("core.InnerMsg") local FieldsMember = {lastLoginTime = 1} local FieldsUnionOffline = {presidentUuid = 1} local FieldsRoleOffline = {lastLogoutTime = 1, lv = 1,identity = 1, name = 1} local FakeHuman = {} local CREATEUNION_NEED_VIPLV = 2 -- 创建公会需要VIP等级 local CREATEUNION_NEED_LV = 35 -- 创建公会需要等级 local CREATEUNION_NEED_ZUANSHI = 100 -- 创建公会花费 local EXPEL_CNT_MAX = 10 -- 每日踢人上限 local POST_OFFICIAL_MAXCNT = 3 -- 官员上限 local UNION_CHANGE_CD = 86400 -- 公告修改CD local SIGNIN_GIVE_UNIONCOIN = 50 -- 签到给与公会币 local CHANGENAME_NEED_ZUANSHI = 500 -- 改名花费 local UNION_NAME_LEN_MAX = 18 -- 公会名字最大长度 local UNION_NAME_LEN_MIN = 3 -- 公会名字最小长度 local UNION_ALL_MAIL_MAX_CNT = 10 -- 每日邮件上限 local UNION_AUTO_PRESIDENT_TIME = 3 * 86400 -- 会长离线x秒自动转让位置 local RECRUIT_COST_VALUE = 18 -- 招募花费 local UNION_OP_IMPEACH_PRESIDENT = 300 -- 弹劾会长操作花费 -- 公会成员管理 local UNION_MEM_EXPEL = 1 -- 踢出玩家 local UNION_MEM_SET_POST = 2 -- 设置管理员 local UNION_MEM_CHANGE_PRESIDENT = 3 -- 转让会长 UNION_CHANGE_OP_1 = 1 -- 离开公会 UNION_CHANGE_OP_2 = 2 -- 加入公会 UNION_CHANGE_OP_3 = 3 -- 解散公会 -------------------------------------- db ----------------------------------------------------- -- 插入公会日志 function addUnionLog(unionUuid, logType, name,classify,param) if not logType then return end local cf = UnionExcel.log[logType] if not cf then return end local now = os.time() local date = os.date("*t", now) local content = Util.format(cf.content, date.month, date.day, date.hour, date.min, name,param) UnionDBLogic.addLog(unionUuid, content,classify) end -- 发送到公会 function send2Union(msg, union,eUuid) if not union then return end for uuid in pairs(union.member) do local human = ObjHuman.onlineUuid[uuid] if human and human.fd and uuid ~= eUuid then Msg.send(msg, human.fd) end end end ------------------------------------------ msg ----------------------------------------------- local function getUnionConfig(unionLv) local unionLv = math.min(unionLv, #UnionExcel.union) return UnionExcel.union[unionLv] end -- 封装公会基础信息结构体 function fontUnionMsg(net, union, uuid) local lv = math.min(union.lv, #UnionExcel.union) local config = UnionExcel.union[lv] net.unionIdentity = union.id net.unionUuid = union._id net.name = union.name or "" net.maxCnt = config.maxCnt net.curCnt = union.curCnt net.bannerID = union.bannerID net.needLv = union.needLv or 0 net.notice = union.notice net.lv = lv net.exp = union.exp net.maxExp = config.exp local presidentDB = RoleDBLogic.getDb(union.presidentUuid, "name") net.presidentName = presidentDB and presidentDB.name or "" net.isApply = 0 if uuid and UnionDBLogic.isApply(union, uuid) then net.isApply = 1 end end -- 封装公会成员信息结构体 function fontUnionMember(net, uuid, member) local FieldsMember = {unionDonate = 1,unionLiveness = 1,lastLogoutTime = 1,dailyBanggong = 1,totalBanggong = 1} RoleLogic.makeRoleBaseFields(FieldsMember) local db, online = RoleDBLogic.getDb(uuid, FieldsMember) RoleLogic.makeRoleBase(db, net.roleBase) net.post = member.post net.inUnionWar = 0 --UnionWarDBLogic.isCommonSign(uuid) and 1 or 0 net.lastLogoutTime = 0 -- 成员捐赠 net.todayDonate = db.dailyBanggong or 0 net.totalDonate = db.totalBanggong or 0 -- 成员活跃度 if db.unionLiveness == nil then net.liveLv = 0 else net.liveLv = db.unionLiveness.lv end if not online then if db.lastLogoutTime == nil then -- 刚刚离线,未保存离线时间 net.lastLogoutTime = 1 else net.lastLogoutTime = os.time() - (db and db.lastLogoutTime or 0) end end end -- 发送公会信息 function sendUnionQuery(human) local union = UnionDBLogic.getUnion(human.db.unionUuid) if not union then return end local member = UnionDBLogic.getUnionMember(union, human.db._id) if not member then return end -- 因为客户端要知道会长信息,为了客户端方便,把会长放在首位 local presidentMember = union.member[union.presidentUuid] -- 由于逻辑错误导致副会长将会长踢出公会,这里做个判断修复数据 -- 如果会长数据为nil,设置第一个成员为会长 if not presidentMember then for k,v in pairs(union.member) do UnionDBLogic.setPresident(union, k) union = UnionDBLogic.getUnion(human.db.unionUuid) presidentMember = union.member[union.presidentUuid] break end end local msgRet = Msg.gc.GC_UNION_QUERY msgRet.post = member.post msgRet.logDot = hasLog(human, union) and 1 or 0 msgRet.leaveUnion = human.db.leaveUnionLimit and 1 or 0 fontUnionMsg(msgRet.unionMsg, union) msgRet.unionMember[0] = 1 fontUnionMember(msgRet.unionMember[1], union.presidentUuid, presidentMember) for uuid, member in pairs(union.member) do if uuid ~= union.presidentUuid then if msgRet.unionMember[0] >= #msgRet.unionMember then break end msgRet.unionMember[0] = msgRet.unionMember[0] + 1 fontUnionMember(msgRet.unionMember[msgRet.unionMember[0]], uuid, member) end end msgRet.hasApply = dot(human) and 1 or 0 Msg.send(msgRet, human.fd) return true end -- 发送公会变更 function sendUnionChange(union, uuid) local msgRet = Msg.gc.GC_UNION_CHANGE_MSG fontUnionMsg(msgRet.unionMsg, union) if uuid then local human = ObjHuman.onlineUuid[uuid] if human and human.fd then Msg.send(msgRet, human.fd) end else send2Union(msgRet, union) end end -- 公推推荐列表/查询返回列表 function sendRecommandList(human, rtype, list) local msgRet = Msg.gc.GC_UNION_RECOMMEND msgRet.type = rtype msgRet.unionMsg[0] = math.min(list and #list or 0, #msgRet.unionMsg) for i = 1, msgRet.unionMsg[0] do fontUnionMsg(msgRet.unionMsg[i], list[i], human.db._id) end Msg.send(msgRet, human.fd) end -- 给加入公会的成员返回公会信息(考虑删除) function sendUnionMsg(uuid, union) if not union then return end local human = ObjHuman.onlineUuid[uuid] if not human or not human.fd then return end local msgRet = Msg.gc.GC_UNION_MSG msgRet.unionIdentity = union.id msgRet.unionUuid = union._id msgRet.unionName = union.name msgRet.bannerID = union.bannerID Msg.send(msgRet, human.fd) end -- 成员信息变化 function sendMemberUpdate(union, uuid) local msgRet = Msg.gc.GC_UNION_AGREE_JOIN_UPDATE_MEMBER msgRet.unionMember[0] = 0 for uuid, member in pairs(union.member) do if msgRet.unionMember[0] >= #msgRet.unionMember then break end msgRet.unionMember[0] = msgRet.unionMember[0] + 1 fontUnionMember(msgRet.unionMember[msgRet.unionMember[0]], uuid, member) end if uuid then local human = ObjHuman.onlineUuid[uuid] if human and human.fd then Msg.send(msgRet, human.fd) end else send2Union(msgRet, union) end end -- 申请列表 function sendApplyMsg(human, union) if not union then return end local msgRet = Msg.gc.GC_UNION_APPLY_MSG msgRet.applyMsg[0] = 0 if union.apply then for uuid in pairs(union.apply) do if msgRet.applyMsg[0] >= #msgRet.applyMsg then break end local applyNet = msgRet.applyMsg[msgRet.applyMsg[0] + 1] if RoleLogic.getRoleBaseByUuid(uuid, applyNet.roleBase) then applyNet.flag = 1 msgRet.applyMsg[0] = msgRet.applyMsg[0] + 1 end end end Msg.send(msgRet, human.fd) end -- 查询公会,有公会返回公会信息,没公会返回推荐列表 function unionQuery(human) if not RoleSystemLogic.isOpen(human, RoleSystemDefine.ROLE_SYS_ID_1001, true) then return end if sendUnionQuery(human) then -- 公会基础信息 return end -- 推荐列表 local recommandList = UnionDBLogic.getRecommendList() sendRecommandList(human, UnionDefine.RECOMMEND_TYPE_RANDOM, recommandList) end -- 查找公会 function findUnion(human, unionName) if not RoleSystemLogic.isOpen(human, RoleSystemDefine.ROLE_SYS_ID_1001, true) then return false end if UnionDBLogic.getUnion(human.db.unionUuid) then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_ONE) end local unionList = UnionDBLogic.getUnionByNameRegex(unionName) local union = UnionDBLogic.getUnion(unionName) if union then unionList = unionList or {} table.insert(unionList, 1, union) end sendRecommandList(human, UnionDefine.RECOMMEND_TYPE_FIND, unionList) if not unionList or #unionList < 1 then Broadcast.sendErr(human, Lang.UNION_IS_UNREAL) end end -- 判断公会名是否合法 local function checkUnionName(human, unionName) -- 如果unionName是nil 公会名不能为空 if not unionName then return Broadcast.sendErr(human, Lang.UNION_FAIL_NAME_NIL) end local nameLen = string.len(unionName) -- 如果公会名长度小于公会名最小长度 公会名过短 if nameLen < UNION_NAME_LEN_MIN then return Broadcast.sendErr(human, Lang.UNION_FAIL_NAME_LEN1) end -- 如果公会名长度大于公会名最小长度 公会名过长 if nameLen > UNION_NAME_LEN_MAX then return Broadcast.sendErr(human, Lang.UNION_FAIL_NAME_LEN2) end -- 如果公会名中包含非法字符 公会名中有非法字符 if unionName ~= FilterUtil.filterName(unionName) then return Broadcast.sendErr(human, Lang.UNION_FAIL_NAME_FILTER) end -- 公会名已经存在 if UnionDBLogic.isNameExistInDB(unionName) then return Broadcast.sendErr(human, Lang.UNION_FAIL_NAME_DUPLICATE) end return true end -- 创建工会 function createUnion(human, unionName, bannerID, notice, needLv, needAgree) if not RoleSystemLogic.isOpen(human, RoleSystemDefine.ROLE_SYS_ID_1001, true) then return end -- 需要VIP等级 --[[ local vipLv = VipLogic.getVipLv(human) if vipLv < CREATEUNION_NEED_VIPLV and human.db.lv < CREATEUNION_NEED_LV then return Broadcast.sendErr(human, Util.format(Lang.ROLE_VIP_ERROR, CREATEUNION_NEED_VIPLV, CREATEUNION_NEED_LV)) end ]] if UnionDBLogic.getUnion(human.db.unionUuid) then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_ONE) end if not checkUnionName(human, unionName) then return end if not ObjHuman.checkRMB(human, CREATEUNION_NEED_ZUANSHI) then return end local now = os.time() if human.db.leaveUnionLimit ~= nil and now < human.db.leaveUnionLimit then return Broadcast.sendErr(human, Lang.UNION_LEAVE_TIME_NO_ENOUGH) end ObjHuman.decZuanshi(human, -CREATEUNION_NEED_ZUANSHI, "createUnion") bannerID = bannerID or 1 notice = notice or "" local union = UnionDBLogic.addUnion(human, unionName, bannerID, notice, needLv, needAgree) if not union then return end human.db.unionUuid = union._id ObjHuman.save(human) addUnionLog(union._id, 1, human.db.name,UnionDefine.UNION_LOG_CLASSIFY_BASE) sendUnionQuery(human) Broadcast.sendErr(human, Lang.UNION_CREATE_SUCCESS) RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1001) unionChangeOp(UNION_CHANGE_OP_2, human.db._id, union._id) end -- 离开公会回调 function onLeaveUnion(unionUuid, uuid, logType, mailId) local db = RoleDBLogic.getDb(uuid) if db then FakeHuman.db = db db.unionUuid = nil RoleDBLogic.saveRole(db) addUnionLog(unionUuid, 4, db.name,UnionDefine.UNION_LOG_CLASSIFY_BASE) db.dailyBanggong = 0 db.totalBanggong = 0 if mailId then local title = MailExcel.mail[mailId].title local content = MailExcel.mail[mailId].content local senderName = MailExcel.mail[mailId].senderName MailManager.add(MailManager.SYSTEM, uuid, title, content, nil, senderName) end end local human = ObjHuman.onlineUuid[uuid] if human and human.fd then Msg.send(Msg.gc.GC_UNION_LEAVE, human.fd) RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1001) end if mailId and mailId == MailDefine.MAIL_ID_UNION_DISMISS then unionChangeOp(UNION_CHANGE_OP_3, uuid, unionUuid) else unionChangeOp(UNION_CHANGE_OP_1, uuid, unionUuid) end end -- 解散公会 function dismissUnion(human) local union = UnionDBLogic.getUnion(human.db.unionUuid) local unionUuid = human.db.unionUuid if not union then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_NO) end if union.presidentUuid ~= human.db._id then return Broadcast.sendErr(human, Lang.UNION_HAVE_NO_POWER) end if union.curCnt > 1 then return Broadcast.sendErr(human, Lang.UNION_HAS_MEMBER) end local warState = UnionWarLogic.getState() if warState > UnionWarLogic.STATE1 then -- 公会战期间 return Broadcast.sendErr(human, Lang.UNION_IS_WARRING) end UnionDBLogic.delUnion(union._id) onLeaveUnion(union._id, human.db._id, nil, MailDefine.MAIL_ID_UNION_DISMISS) if not human.db.leaveUnionLimit then human.db.leaveUnionLimit = 0 else human.db.leaveUnionLimit = os.time() + 8*60*60 end Broadcast.sendErr(human, Lang.UNION_DISMISS_SUCCESS) BillboardDB.dismissUnion(unionUuid) UnionWarDBLogic.dismissUnion(unionUuid) end -- 申请加入公会 function applyJoinUnion(human, unionUuid) if not RoleSystemLogic.isOpen(human, RoleSystemDefine.ROLE_SYS_ID_1001, true) then return end local now = os.time() if human.db.leaveUnionLimit ~= nil and now < human.db.leaveUnionLimit then return Broadcast.sendErr(human, Lang.UNION_LEAVE_TIME_NO_ENOUGH) end if UnionDBLogic.getUnion(human.db.unionUuid) then return Broadcast.sendErr(human, Lang.UNION_PLAYER_JOIN_OTHER) end local union = UnionDBLogic.getUnion(unionUuid) if not union then return Broadcast.sendErr(human, Lang.UNION_IS_UNREAL) end if (union.needLv or 0) > human.db.lv then return Broadcast.sendErr(human, Lang.UNION_IS_NEED_LV) end local config = getUnionConfig(union.lv) -- if union.curCnt >= config.maxCnt then -- 人数满了 -- return Broadcast.sendErr(human, Lang.UNION_IS_FULL) -- end local isJoin = false if union.needAgree == 1 or union.curCnt >= config.maxCnt then UnionDBLogic.addApply(union, human.db._id) local msgRet = Msg.gc.GC_UNION_APPLY_JOIN msgRet.unionUuid = unionUuid Msg.send(msgRet, human.fd) for _,tpHuman in pairs(ObjHuman.onlineUuid) do if isPost(tpHuman) and tpHuman.db.unionUuid == unionUuid then RoleSystemLogic.onDot(tpHuman, RoleSystemDefine.ROLE_SYS_ID_1005) end end else -- 自动同意 human.db.unionUuid = union._id isJoin = true ObjHuman.save(human) UnionDBLogic.addUnionMember(union, human.db._id) addUnionLog(union._id, 3, human.db.name,UnionDefine.UNION_LOG_CLASSIFY_BASE) sendUnionMsg(human.db._id, union) -- 邮件 local mailID = MailDefine.MAIL_ID_UNION_JOIN local title = MailExcel.mail[mailID].title local content = Util.format(MailExcel.mail[mailID].content, union.name) local senderName = MailExcel.mail[mailID].senderName MailManager.add(MailManager.SYSTEM, human.db._id, title, content, nil, senderName) --unionQuery(human) sendMemberUpdate(union) end Broadcast.sendErr(human, Lang.UNION_APPLY_OK) if isJoin then unionChangeOp(UNION_CHANGE_OP_2, human.db._id, union._id) end end -- 会长同意/拒绝加入公会 function agreeJoinUnion(human, uuid, isArgee) local union = UnionDBLogic.getUnion(human.db.unionUuid) if not union then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_NO) end local member = UnionDBLogic.getUnionMember(union, human.db._id) if not member or (member.post ~= UnionDefine.POST_PRESIDENT and member.post ~= UnionDefine.POST_OFFICIAL) then return Broadcast.sendErr(human, Lang.UNION_HAVE_NO_POWER) end -- 申请不存在 if not UnionDBLogic.isApply(union, uuid) then return Broadcast.sendErr(human, Lang.UNION_APPLY_AGREE_ERR_NONE) end local isJoin = false if isArgee == 1 then local config = getUnionConfig(union.lv) if union.curCnt >= config.maxCnt then -- 人数满了 return Broadcast.sendErr(human, Lang.UNION_CNT_IS_OVER) end UnionDBLogic.delApply(union, uuid) local db = RoleDBLogic.getDb(uuid) if db == nil then -- 不存在 return Broadcast.sendErr(human, Lang.UNION_HAVE_NO_ID) end if UnionDBLogic.getUnion(db.unionUuid) then -- 有公会 return Broadcast.sendErr(human, Lang.UNION_PLAYER_JOIN_OTHER) end db.unionUuid = union._id RoleDBLogic.saveRole(db) UnionDBLogic.addUnionMember(union, uuid) addUnionLog(union._id, 3, db.name,UnionDefine.UNION_LOG_CLASSIFY_BASE) sendUnionMsg(uuid, union) -- 邮件 local mailID = MailDefine.MAIL_ID_UNION_JOIN local title = MailExcel.mail[mailID].title local content = Util.format(MailExcel.mail[mailID].content, union.name) local senderName = MailExcel.mail[mailID].senderName MailManager.add(MailManager.SYSTEM, db._id, title, content, nil, senderName) sendMemberUpdate(union,uuid) sendMemberUpdate(union,human.db._id) isJoin = true else UnionDBLogic.delApply(union, uuid) end sendApplyMsg(human, union) RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1005) if isJoin then unionChangeOp(UNION_CHANGE_OP_2, uuid, union._id) end end -- 一键拒绝 function oneKeyDisagree(human) local union = UnionDBLogic.getUnion(human.db.unionUuid) if not union then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_NO) end local member = UnionDBLogic.getUnionMember(union, human.db._id) if not member or (member.post ~= UnionDefine.POST_PRESIDENT and member.post ~= UnionDefine.POST_OFFICIAL) then return Broadcast.sendErr(human, Lang.UNION_HAVE_NO_POWER) end UnionDBLogic.resetApply(union) sendApplyMsg(human, union) RoleSystemLogic.onDot(tpHuman, RoleSystemDefine.ROLE_SYS_ID_1005) end -- 会长踢玩家出公会 function expelPlayer(human, uuid) if human.db._id == uuid then --不能踢自己 return Broadcast.sendErr(human, Lang.UNION_OPERATE_FAIL) end local union = UnionDBLogic.getUnion(human.db.unionUuid) if not union then return Broadcast.sendErr(human, Lang.UNION_IS_UNREAL) end local member = UnionDBLogic.getUnionMember(union, uuid) if not member or member.post == UnionDefine.POST_PRESIDENT then return Broadcast.sendErr(human, Lang.UNION_HAVE_NO_POWER) end member = UnionDBLogic.getUnionMember(union, human.db._id) if not member or (member.post ~= UnionDefine.POST_PRESIDENT and member.post ~= UnionDefine.POST_OFFICIAL) then return Broadcast.sendErr(human, Lang.UNION_HAVE_NO_POWER) end if UnionDBLogic.getKickCntToday(union) >= EXPEL_CNT_MAX then return Broadcast.sendErr(human, Lang.UNION_EXPEL_NUM_MAX_ERROR) end local tmember = UnionDBLogic.getUnionMember(union, uuid) if not tmember then --该玩家不在本公会 return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_OTHER) end UnionDBLogic.delUnionMember(union, uuid, true) onLeaveUnion(union._id, uuid, 2, MailDefine.MAIL_ID_UNION_LEAVE) sendMemberUpdate(union) Broadcast.sendErr(human, Lang.UNION_OPERATE_SUCCESS) local fakeHuman = ObjHuman.onlineUuid[uuid] if fakeHuman and fakeHuman.db then RoleAttr.cleanHeroAttrCache(fakeHuman) end end -- 玩家自己离开公会 function leaveUnion(human) local union = UnionDBLogic.getUnion(human.db.unionUuid) if not union then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_NO) end if union.presidentUuid == human.db._id then return Broadcast.sendErr(human, Lang.UNION_LEVEL_ERR_LEADER) end UnionDBLogic.delUnionMember(union, human.db._id) onLeaveUnion(union._id, human.db._id) if not human.db.leaveUnionLimit then human.db.leaveUnionLimit = 0 else human.db.leaveUnionLimit = os.time() + 8*60*60 end sendMemberUpdate(union) Broadcast.sendErr(human, Lang.UNION_LEVEL_SUCCESS) if human.db.roleDot and human.db.roleDot.unionLog then human.db.roleDot.unionLog = nil end RoleAttr.cleanHeroAttrCache(human) end -- 玩家公会变化 function unionChangeOp(op, uuid, unionUuid) local msgInner = InnerMsg.lw.LW_ROLE_UNION_OP msgInner.op = op msgInner.uuid = uuid msgInner.unionUuid = unionUuid InnerMsg.sendMsg(0, msgInner) end -- 设置工会官员 function setPost(human, uuid) if human.db._id == uuid then return Broadcast.sendErr(human, Lang.UNION_OPERATE_FAIL) end local union = UnionDBLogic.getUnion(human.db.unionUuid) if not union then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_NO) end if union.presidentUuid ~= human.db._id then return Broadcast.sendErr(human, Lang.UNION_HAVE_NO_POWER) end local member = UnionDBLogic.getUnionMember(union, uuid) if not member then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_OTHER) end local postCnt = UnionExcel.union[union.lv].postCnt local db = RoleDBLogic.getDb(uuid, "name") if member.post == UnionDefine.POST_OFFICIAL then -- 取消官员 UnionDBLogic.setPost(union, uuid, UnionDefine.POST_MEMBER) addUnionLog(union._id, 7, db and db.name or "",UnionDefine.UNION_LOG_CLASSIFY_BASE) local mailID = MailDefine.MAIL_ID_UNION_BE_MEMBER local title = MailExcel.mail[mailID].title local content = MailExcel.mail[mailID].content local senderName = MailExcel.mail[mailID].senderName MailManager.add(MailManager.SYSTEM, uuid, title, content, nil, senderName) else if UnionDBLogic.getPostCnt(union, UnionDefine.POST_OFFICIAL) >= postCnt then return Broadcast.sendErr(human, Lang.UNION_POST_IS_MAX) end -- 设置为官员 UnionDBLogic.setPost(union, uuid, UnionDefine.POST_OFFICIAL) addUnionLog(union._id, 5, db and db.name or "",UnionDefine.UNION_LOG_CLASSIFY_BASE) local mailID = MailDefine.MAIL_ID_UNION_BE_POST local title = MailExcel.mail[mailID].title local content = MailExcel.mail[mailID].content local senderName = MailExcel.mail[mailID].senderName MailManager.add(MailManager.SYSTEM, uuid, title, content, nil, senderName) end sendMemberUpdate(union) Broadcast.sendErr(human, Lang.UNION_OPERATE_SUCCESS) end -- 更换会长 function changePresident(human, uuid) if human.db._id == uuid then return Broadcast.sendErr(human, Lang.UNION_OPERATE_FAIL) end local union = UnionDBLogic.getUnion(human.db.unionUuid) if not union then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_NO) end if union.presidentUuid ~= human.db._id then return Broadcast.sendErr(human, Lang.UNION_HAVE_NO_POWER) end local member = UnionDBLogic.getUnionMember(union, uuid) if not member then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_OTHER) end UnionDBLogic.setPresident(union, uuid) local db = RoleDBLogic.getDb(uuid, "name") addUnionLog(union._id, 6, db.name,UnionDefine.UNION_LOG_CLASSIFY_BASE) sendMemberUpdate(union) Broadcast.sendErr(human, Lang.UNION_OPERATE_SUCCESS) -- 发送邮件 for uuid in pairs(union.member) do local mailID = MailDefine.MAIL_ID_UNION_CHANGE_PRE1 local title = MailExcel.mail[mailID].title local content = Util.format(MailExcel.mail[mailID].content, db.name) local senderName = MailExcel.mail[mailID].senderName MailManager.add(MailManager.SYSTEM, uuid, title, content, nil, senderName) end end -- 成员管理 function memberMam(human, uuid, mamType) if mamType == UNION_MEM_EXPEL then return expelPlayer(human, uuid) elseif mamType == UNION_MEM_SET_POST then return setPost(human, uuid) elseif mamType == UNION_MEM_CHANGE_PRESIDENT then return changePresident(human, uuid) else return Broadcast.sendErr(human, Lang.UNION_OPERATE_FAIL) end end -- 设置公告 function setNotice(human, notice) local union = UnionDBLogic.getUnion(human.db.unionUuid) if not union then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_NO) end local member = UnionDBLogic.getUnionMember(union, human.db._id) if not member or (member.post ~= UnionDefine.POST_PRESIDENT and member.post ~= UnionDefine.POST_OFFICIAL) then return Broadcast.sendErr(human, Lang.UNION_HAVE_NO_POWER) end if notice == union.notice then return Broadcast.sendErr(human, Lang.UNION_OPERATE_SUCCESS) end if union.noticeTime and (os.time() - union.noticeTime < UNION_CHANGE_CD) then local hour = math.floor((UNION_CHANGE_CD - (os.time() - union.noticeTime)) / 60/60) local min = math.floor((UNION_CHANGE_CD - (os.time() - union.noticeTime)) / 60) - (hour*60) return Broadcast.sendErr(human, Util.format(Lang.UNION_CHANGE_CD_ERROR, hour,min)) end if notice ~= FilterUtil.filter(notice) then return Broadcast.sendErr(human, Lang.UNION_NOTICE_IS_FAIL) end UnionDBLogic.setNotice(union, notice) sendUnionChange(union) Broadcast.sendErr(human, Lang.UNION_OPERATE_SUCCESS) end -- 查询入会设置 function sendJoinLimitQuery(human) local union = UnionDBLogic.getUnion(human.db.unionUuid) if not union then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_NO) end local member = UnionDBLogic.getUnionMember(union, human.db._id) if not member or (member.post ~= UnionDefine.POST_PRESIDENT and member.post ~= UnionDefine.POST_OFFICIAL) then return Broadcast.sendErr(human, Lang.UNION_HAVE_NO_POWER) end local msgRet = Msg.gc.GC_UNION_CHANGE_LIMIT_QUERY msgRet.needLv = union.needLv or 0 msgRet.needAgree = union.needAgree or 0 Msg.send(msgRet, human.fd) end -- 修改入会设置 function setJoinLimit(human, needLv, needAgree) local union = UnionDBLogic.getUnion(human.db.unionUuid) if not union then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_NO) end local member = UnionDBLogic.getUnionMember(union, human.db._id) if not member or (member.post ~= UnionDefine.POST_PRESIDENT and member.post ~= UnionDefine.POST_OFFICIAL) then return Broadcast.sendErr(human, Lang.UNION_HAVE_NO_POWER) end UnionDBLogic.setJoinLimit(union, needLv, needAgree) Broadcast.sendErr(human, Lang.UNION_OPERATE_SUCCESS) end function addUnionExpByItem(human, add) if not human.db.unionUuid or human.db.unionUuid == "" then return end local union = UnionDBLogic.getUnion(human.db.unionUuid) if not union then return end addUnionExp(union, add) UnionDBLogic.updateUnionData(union) end -- 添加公会经验 function addUnionExp(union, exp) local oldLv = union.lv union.exp = union.exp + exp while true do local config = UnionExcel.union[union.lv] if not config then break end if config.exp < 1 then -- 满级 union.exp = 0 break end if union.exp < config.exp then break end union.exp = union.exp - config.exp union.lv = union.lv + 1 end end -- 公会申请查询 function applyQuery(human) local union = UnionDBLogic.getUnion(human.db.unionUuid) if not union then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_NO) end sendApplyMsg(human, union) end -- 获取改名价格 local function getChangeNameCost(union) if not union.nameTime then return 0 -- 首次改名免费 end return CHANGENAME_NEED_ZUANSHI end -- 改名相关查询 例如改名价格 function sendChangeNameQuery(human) local union = UnionDBLogic.getUnion(human.db.unionUuid) if not union then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_NO) end if union.presidentUuid ~= human.db._id then return Broadcast.sendErr(human, Lang.UNION_HAVE_NO_POWER) end local msgRet = Msg.gc.GC_UNION_CHANGE_NAME_QUERY msgRet.needCost = getChangeNameCost(union) Msg.send(msgRet, human.fd) end -- 公会改名 function changeUnionName(human, name, bannerID) local union = UnionDBLogic.getUnion(human.db.unionUuid) if not union then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_NO) end if union.presidentUuid ~= human.db._id then return Broadcast.sendErr(human, Lang.UNION_HAVE_NO_POWER) end if union.nameTime and (os.time() - union.nameTime < UNION_CHANGE_CD) then local leftTime = math.ceil((UNION_CHANGE_CD - (os.time() - union.nameTime)) / 60) return Broadcast.sendErr(human, Util.format(Lang.UNION_CHANGE_CD_ERROR, leftTime)) end if not checkUnionName(human, name) and name ~= union.name then return Broadcast.sendErr(human, Lang.CREATE_UNION_FAIL_NAME) end local needCost = getChangeNameCost(union) if not ObjHuman.checkRMB(human, needCost) then return end ObjHuman.decZuanshi(human, -needCost, "changeUnionName") UnionDBLogic.setUnionName(union, name) sendUnionChange(union) Broadcast.sendErr(human, Lang.UNION_CHANGE_NAME_SUCCESS) end -- 公会改旗帜 function changeUnionBannerID(human,bannerID) local union = UnionDBLogic.getUnion(human.db.unionUuid) if not union then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_NO) end if union.presidentUuid ~= human.db._id then return Broadcast.sendErr(human, Lang.UNION_HAVE_NO_POWER) end if not UnionExcel.banner[bannerID] then return Broadcast.sendErr(human, Lang.UNION_BANNER_ID_ILL) end UnionDBLogic.setBannerID(union, bannerID) sendUnionChange(union) Broadcast.sendErr(human, Lang.UNION_OPERATE_SUCCESS) end -- 发送邮件 function sendUnionMail(human, content) local msgRet = Msg.gc.GC_UNION_MAIL msgRet.flag = 0 local union = UnionDBLogic.getUnion(human.db.unionUuid) if not union then Msg.send(msgRet, human.fd) return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_NO) end local member = UnionDBLogic.getUnionMember(union, human.db._id) if not member or (member.post ~= UnionDefine.POST_PRESIDENT and member.post ~= UnionDefine.POST_OFFICIAL) then Msg.send(msgRet, human.fd) return Broadcast.sendErr(human, Lang.UNION_HAVE_NO_POWER) end local mailCnt = UnionDBLogic.getMailCnt(union) if mailCnt >= UNION_ALL_MAIL_MAX_CNT then Msg.send(msgRet, human.fd) return Broadcast.sendErr(human, Lang.UNION_MAIL_CNT_MAX) end if content == "" or content ~= FilterUtil.filter(content) then return Broadcast.sendErr(human, Lang.MAIL_CONTENT_ERROR) end union.mailCnt = mailCnt + 1 union.mailTs = union.mailTs or os.time() UnionDBLogic.updateUnionData(union) for uuid in pairs(union.member) do MailManager.add(MailManager.SYSTEM, uuid, Lang.UNION_MAIL, content, nil, human.db.name, human) end Broadcast.sendErr(human, Lang.UNION_SEND_SUCCESS) msgRet.flag = 1 Msg.send(msgRet, human.fd) end function hasLog(human, union) local time = 0 if human.db.roleDot and human.db.roleDot.unionLog then time = human.db.roleDot.unionLog end for i = 1, #union.logs do local log = union.logs[i] if log.time > time then return true end end return false end -- 公会日志 function getLog(human,classify) local union = UnionDBLogic.getUnion(human.db.unionUuid) if not union then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_NO) end local msgRet = Msg.gc.GC_UNION_GET_LOG local cnt = 0 for i = 1, #union.logs do local log = union.logs[i] if log.classify == classify or classify == 0 then cnt = cnt + 1 msgRet.logMsg[cnt].logMsg = log.content end if cnt >= #msgRet.logMsg then break end end msgRet.logMsg[0] = cnt --Msg.trace(msgRet) Msg.send(msgRet, human.fd) human.db.roleDot = human.db.roleDot or {} human.db.roleDot.unionLog = os.time() RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1005) end local function getRecruitCost(union) if not union.recruit then return 0 end return RECRUIT_COST_VALUE end -- 招募查询 function sendRecruitQuery(human) local union = UnionDBLogic.getUnion(human.db.unionUuid) if not union then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_NO) end local member = UnionDBLogic.getUnionMember(union, human.db._id) if not member or (member.post ~= UnionDefine.POST_PRESIDENT and member.post ~= UnionDefine.POST_OFFICIAL) then return Broadcast.sendErr(human, Lang.UNION_HAVE_NO_POWER) end local msgRet = Msg.gc.GC_UNION_RECRUIT_QUERY msgRet.costValue = getRecruitCost(union) Msg.send(msgRet, human.fd) end -- 招募宣言 function unionRecruit(human,str) local union = UnionDBLogic.getUnion(human.db.unionUuid) if not union then return Broadcast.sendErr(human, Lang.UNION_PLAYER_IN_NO) end local member = UnionDBLogic.getUnionMember(union, human.db._id) if not member or (member.post ~= UnionDefine.POST_PRESIDENT and member.post ~= UnionDefine.POST_OFFICIAL) then return Broadcast.sendErr(human, Lang.UNION_HAVE_NO_POWER) end -- 检查花费 local costValue = getRecruitCost(union) if not ObjHuman.checkRMB(human, costValue) then Msg.send(msgRet, human.fd) return end human.chatTime = human.chatTime or {} local chatTime = human.chatTime[ChatHandler.CHAT_TYPE_WORLD] or 0 if chatTime + ChatHandler.CHAT_CD >= Timer.now then local cdLeftSec = math.ceil((ChatHandler.CHAT_CD - (Timer.now - chatTime))/1000) Broadcast.sendDown(human, Util.format(Lang.CHAT_TIME_SHORT, cdLeftSec)) return end human.worldChatLast = human.worldChatLast or {} if human.worldChatLast[ChatHandler.CHAT_TYPE_WORLD] == str then Broadcast.sendDown(human, Lang.CHAT_TIME_DUPLICATE) return end ObjHuman.decZuanshi(human, -costValue, "union_recruit") if not union.recruit then union.recruit = 1 UnionDBLogic.updateUnionData(union) end local dec = Util.format(Lang.UNION_RECRUIT_BC, union.lv, union.name) ChatUnion.chatUnion(human, ChatHandler.CHAT_TYPE_UNION, str) Broadcast.sendErr(human, Lang.UNION_SEND_SUCCESS) end -- 是否有红点 申请 function dot(human) local union = UnionDBLogic.getUnion(human.db.unionUuid) if union == nil then return end local member = UnionDBLogic.getUnionMember(union, human.db._id) if not member then return end if member.post ~= UnionDefine.POST_PRESIDENT and member.post ~= UnionDefine.POST_OFFICIAL then return end if union.apply == nil then return end return next(union.apply) ~= nil end -- 用于显示红点 function isDot(human) local union = UnionDBLogic.getUnion(human.db.unionUuid) if union == nil then -- 没加入公会 不显示红点 return end if dot(human) then return true end if hasLog(human, union) then return true end return nil end -- 0点后自动让位 function onHour() PRESIDENT_CHECK_FLAG = true end -- 自动让位 PRESIDENT_AUTO_LIST = PRESIDENT_AUTO_LIST or nil -- 自动让位列表 PRESIDENT_CHECK_FLAG = PRESIDENT_CHECK_FLAG or nil -- 自动让位标记 function checkPresidentOffline() if PRESIDENT_AUTO_LIST then return end PRESIDENT_CHECK_FLAG = nil PRESIDENT_AUTO_LIST = {} local lastSevenDays = os.time() - UNION_AUTO_PRESIDENT_TIME LuaMongo.find(DB.db_union, nil, FieldsUnionOffline) local union2president = {} while true do local union = {} if not LuaMongo.next(union) then break end union2president[union._id] = union.presidentUuid end for unionUuid, presidentUuid in pairs(union2president) do local db, online = RoleDBLogic.getDb(presidentUuid, FieldsRoleOffline) if not db or (not online and (db.lastLogoutTime or 0) < lastSevenDays) then PRESIDENT_AUTO_LIST[#PRESIDENT_AUTO_LIST + 1] = unionUuid end end end -- 是否可继承会长 local function canBeNewPresident(db, lastSevenDays, online) if not db then return end if not online and db.lastLogoutTime < lastSevenDays then return end return true end -- 比较 local function cmpBeNewMember(db1, db2) if not db1 then return end if not db2 then return true end if db1.lastLogoutTime ~= db2.lastLogoutTime then return db1.lastLogoutTime > db2.lastLogoutTime end return db1.lv > db2.lv end -- 自动转让会长 function autoPresidentChange() local unionUuid = PRESIDENT_AUTO_LIST[#PRESIDENT_AUTO_LIST] if not unionUuid then PRESIDENT_AUTO_LIST = nil return end PRESIDENT_AUTO_LIST[#PRESIDENT_AUTO_LIST] = nil local union = UnionDBLogic.getUnion(unionUuid) if not union then return end local lastSevenDays = os.time() - UNION_AUTO_PRESIDENT_TIME local newdb = nil for uuid, member in pairs(union.member) do -- 优先挑选管理 if member.post == UnionDefine.POST_OFFICIAL then local db, online = RoleDBLogic.getDb(uuid, FieldsRoleOffline) if canBeNewPresident(db, lastSevenDays, online) then newdb = db break end end end if not newdb then for uuid, member in pairs(union.member) do -- 再挑普通成员 if member.post == UnionDefine.POST_MEMBER then local db, online = RoleDBLogic.getDb(uuid, FieldsRoleOffline) if canBeNewPresident(db, lastSevenDays, online) and not cmpBeNewMember(newdb, db) then newdb = db break end end end end if not newdb then return end -- 设置新会长 UnionDBLogic.setPresident(union, newdb._id) addUnionLog(union._id, 6, newdb.name,UnionDefine.UNION_LOG_CLASSIFY_BASE) end -- 定时检测 function onTimer() if PRESIDENT_CHECK_FLAG then checkPresidentOffline() end if PRESIDENT_AUTO_LIST then autoPresidentChange() end end -- 弹劾会长 function impeachPresident(human) -- 判断玩家是否有工会 -- 判断玩家公会是否存在 local union = UnionDBLogic.getUnion(human.db.unionUuid) if union == nil then return end local db,online = RoleDBLogic.getDb(union.presidentUuid,FieldsRoleOffline) local lastSevenDays = os.time() - UNION_AUTO_PRESIDENT_TIME if online ~= nil or db.lastLogoutTime >= lastSevenDays then return -- 弹劾失败 end -- 扣除花费 local cost = UNION_OP_IMPEACH_PRESIDENT if not ObjHuman.checkRMB(human, cost) then return end ObjHuman.decZuanshi(human, -cost, "abs_answer") -- 设置新会长 UnionDBLogic.setPresident(union, human.db._id) addUnionLog(union._id, 14, human.db.name,UnionDefine.UNION_LOG_CLASSIFY_BASE,db.name) sendMemberUpdate(union) -- 发送系统消息 -- todo -- 发送邮件 local mailID = MailDefine.MAIL_ID_UNION_CHANGE_PRE2 local title = MailExcel.mail[mailID].title local content = Util.format(MailExcel.mail[mailID].content, human.db.name) local senderName = MailExcel.mail[mailID].senderName MailManager.add(MailManager.SYSTEM, db._id, title, content, nil, senderName) end function getUnionLogMemberDetail(human,type) local msgRet = Msg.gc.GC_UNION_LOG_DETAIL_QUERY if type == 2 then return -- 临时 --getCanUnionWarMember(human.db.unionUuid,msgRet) elseif type == 3 then getCanBossMember(human.db.unionUuid,msgRet) elseif type == 4 then getCanDonateMember(human.db.unionUuid,msgRet) end Msg.send(msgRet,human.fd) end -- 获得还有挑战工会战次数的玩家 -- todo 等全谈写完工会战,再完成 function getCanUnionWarMember(unionUuid) local union = UnionDBLogic.getUnion(unionUuid) if not union then return end for uuid, member in pairs(union.member) do if uuid ~= union.presidentUuid then if msgRet.memberDetail[0] >= #msgRet.memberDetail then break end msgRet.memberDetail[0] = msgRet.memberDetail[0] + 1 fontUnionMember(msgRet.memberDetail[msgRet.memberDetail[0]], uuid, member) end end end -- 获得还有捐献次数的玩家 function getCanDonateMember(unionUuid,net) local union = UnionDBLogic.getUnion(unionUuid) if not union then return end local maxCnt = 0 local leftCnt = 0 local len = 0 local maxLen = #net.memberDetail for uuid, member in pairs(union.member) do maxCnt= maxCnt + 1 local db = RoleDBLogic.getDb(uuid) if db.todayDonate ~= 0 then if len >= maxLen then break end leftCnt = leftCnt + 1 len = len + 1 fontUnionMember(net.memberDetail[len], uuid, member) end end net.memberDetail[0] = len net.maxCnt = maxCnt net.leftCnt = leftCnt end -- 获得还有挑战工会boss次数的玩家 -- todo 等全谈写完工会boss,再完成 function getCanBossMember(unionUuid,net) local union = UnionDBLogic.getUnion(unionUuid) if not union then return end local maxCnt = 0 local leftCnt = 0 local len = 0 local maxLen = #net.memberDetail for uuid, member in pairs(union.member) do maxCnt= maxCnt + 1 local db = RoleDBLogic.getDb(uuid) if db.ectypeCnt == nil or db.ectypeCnt < UnionEctypeLogic.FIGHT_MAX_CNT then if len >= maxLen then break end leftCnt = leftCnt + 1 len = len + 1 fontUnionMember(net.memberDetail[len], uuid, member) end end net.memberDetail[0] = len net.maxCnt = maxCnt net.leftCnt = leftCnt end function isPost(human) local union = UnionDBLogic.getUnion(human.db.unionUuid) if union == nil then return end local member = UnionDBLogic.getUnionMember(union, human.db._id) if not member then return end if member.post == UnionDefine.POST_PRESIDENT or member.post == UnionDefine.POST_OFFICIAL then return true end return nil end function cancelApply(human,unionUuid) if not RoleSystemLogic.isOpen(human, RoleSystemDefine.ROLE_SYS_ID_1001, true) then return end if UnionDBLogic.getUnion(human.db.unionUuid) then return end local union = UnionDBLogic.getUnion(unionUuid) if not union then return Broadcast.sendErr(human, Lang.UNION_IS_UNREAL) end UnionDBLogic.delApply(union, human.db._id) for _,tpHuman in pairs(ObjHuman.onlineUuid) do if isPost(tpHuman) and tpHuman.db.unionUuid == unionUuid then RoleSystemLogic.onDot(tpHuman, RoleSystemDefine.ROLE_SYS_ID_1005) end end end