From ffa8a645ed6a92a3c723bbf5c7f1eb4d5425c826 Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期三, 17 十一月 2021 15:15:34 +0800 Subject: [PATCH] 9341 【BT5】【主干】【后端】情缘系统(优化情缘系统) --- ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerLove.py | 756 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 567 insertions(+), 189 deletions(-) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerLove.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerLove.py index 01bc4aa..96c5995 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerLove.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerLove.py @@ -21,12 +21,14 @@ import ChPyNetSendPack import PlayerCompensation import PlayerFamilyRedPacket -import PlayerBillboard +import PyGameDataStruct import NetPackCommon import IpyGameDataPY import PlayerSocial +import PlayerCharm import ShareDefine import PyGameData +import CommFunc import operator import time @@ -58,6 +60,227 @@ self.playerFreeEatCountDict = {} # 玩家免费吃喜糖次数 {playerID:次数, ...} self.fireworksCountDict = {} # 烟花次数信息 {playerID:次数, ...} return + +class PlayerCouple(): + + def __init__(self, coupleData): + self.coupleData = coupleData # PyGameDataStruct.tagDBPyCouple() + + # 更新最大聘礼ID + self.BridePriceMaxID = 0 + maxCount = IpyGameDataPY.IPY_Data().GetMarryCount() + for index in range(maxCount)[::-1]: + ipyData = IpyGameDataPY.IPY_Data().GetMarryByIndex(index) + priceID = ipyData.GetBridePriceID() + if self.GetBridePriceBuyCount(priceID): + self.BridePriceMaxID = priceID + break + return + + def GetCoupleID(self, playerID): + return self.coupleData.PlayerIDA if (playerID == self.coupleData.PlayerIDB) else self.coupleData.PlayerIDB + def GetCoupleName(self, playerID): return PlayerSocial.GetSocialPlayerName(self.GetCoupleID(playerID)) + def GetCoupleJob(self, playerID): return PlayerSocial.GetSocialPlayerJob(self.GetCoupleID(playerID)) + def GetNewMarryTime(self): return self.coupleData.NewMarryTime + def GetMarryTime(self): return self.coupleData.MarryTime + def GetBridePriceState(self): return self.coupleData.BridePriceState + def GetBridePriceBuyCount(self, priceID): return GameWorld.GetDataByDigitPlace(self.coupleData.BridePriceState, priceID - 1) + def SetBridePriceBuyCount(self, priceID, buyCount): + self.coupleData.BridePriceState = GameWorld.ChangeDataByDigitPlace(self.coupleData.BridePriceState, priceID - 1, min(buyCount, 9)) + return self.coupleData.BridePriceState + def GetBreakRequestID(self): return self.coupleData.BreakRequestID + def GetBreakRequestTime(self): return self.coupleData.BreakRequestTime + def SetBreakRequestID(self, reqID): + self.coupleData.BreakRequestID = reqID + self.coupleData.BreakRequestTime = 0 + if reqID > 0: + curTime = int(time.time()) + self.coupleData.BreakRequestTime = curTime + if reqID == self.coupleData.PlayerIDA: + self.coupleData.BreakRequestTimeA = curTime + else: + self.coupleData.BreakRequestTimeB = curTime + return + def GetPlayerBreakRequestTime(self, playerID): + return self.coupleData.BreakRequestTimeA if (playerID == self.coupleData.PlayerIDA) else self.coupleData.BreakRequestTimeB + def GetSendMapServerCoupleInfo(self, playerID): + coupleID = self.GetCoupleID(playerID) + coupleName = self.GetCoupleName(playerID) + coupleJob = self.GetCoupleJob(playerID) + bridePriceMaxID = self.BridePriceMaxID + return coupleID, coupleName, coupleJob, bridePriceMaxID + +class DBPyCoupleManager(object): + ## 伴侣数据管理 + + def __init__(self): + self.coupleDict = {} # {(playerIDA, playerIDB):PlayerCouple, ...} + self.coupleIDDict = {} # {playerID:(playerIDA, playerIDB), ...} # 伴侣对应关系 + return + + def DelCouple(self, playerIDA, playerIDB): + ## 删除伴侣数据,如果已离婚且均已通知,则可直接删除 + key = (playerIDA, playerIDB) + if key in self.coupleDict: + self.coupleDict.pop(key) + + if playerIDA in self.coupleIDDict and self.coupleIDDict[playerIDA] == key: + self.coupleIDDict.pop(playerIDA) + + if playerIDB in self.coupleIDDict and self.coupleIDDict[playerIDB] == key: + self.coupleIDDict.pop(playerIDB) + return + + def AddCouple(self, playerIDA, playerIDB, coupleData): + ## 添加新伴侣 + coupleKey = (playerIDA, playerIDB) + couple = PlayerCouple(coupleData) + self.coupleDict[coupleKey] = couple + self.coupleIDDict[playerIDA] = coupleKey + self.coupleIDDict[playerIDB] = coupleKey + return couple + + def GetCouple(self, playerID): + ## 获取伴侣 + coupleData = None + # 不可能成立的条件,只是为了. 能出代码提示指向 PlayerCouple 类 + if False: + coupleData = PlayerCouple(None) + if playerID not in self.coupleIDDict: + return coupleData + coupleKey = self.coupleIDDict[playerID] + if coupleKey not in self.coupleDict: + return coupleData + coupleData = self.coupleDict[coupleKey] + return coupleData + + def SendMapServerCoupleInfo(self, syncPlayerIDList=None): + ## 同步地图伴侣信息 + syncCoupleInfo = {} + if syncPlayerIDList == None: + syncPlayerIDList = self.coupleIDDict.keys() + for playerID in syncPlayerIDList: + couple = self.GetCouple(playerID) + if not couple: + syncCoupleInfo[playerID] = [] + else: + syncCoupleInfo[playerID] = couple.GetSendMapServerCoupleInfo(playerID) + GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CoupleInfo, syncCoupleInfo) + return + + # 保存数据 存数据库和realtimebackup + def GetSaveData(self): + savaData = "" + cntData = "" + cnt = 0 + + for couple in self.coupleDict.values(): + cnt += 1 + savaData += couple.coupleData.getBuffer() + + GameWorld.Log("Save DBPyMarry count :%s len=%s" % (cnt, len(savaData))) + return CommFunc.WriteDWORD(cntData, cnt) + savaData + + # 从数据库载入数据 + def LoadPyGameData(self, datas, pos, dataslen): + cnt, pos = CommFunc.ReadDWORD(datas, pos) + GameWorld.Log("Load DBPyMarry count :%s" % cnt) + + for _ in xrange(cnt): + coupleData = PyGameDataStruct.tagDBPyCouple() + coupleData.clear() + pos += coupleData.readData(datas, pos, dataslen) + + playerIDA = coupleData.PlayerIDA + playerIDB = coupleData.PlayerIDB + + couple = self.AddCouple(playerIDA, playerIDB, coupleData) + if couple.GetBreakRequestTime() > 0: + PyGameData.g_marryBreakInfo[(playerIDA, playerIDB)] = couple + + SortMarryBreak() + return pos + +class DBPyUnNotifyLoveGiftRecManager(object): + ## 未通知的赠送礼物记录管理 + + def __init__(self): + self.unNotifyLoveGiftDict = {} # {playerID:[PyGameDataStruct.tagDBPyUnNotifyLoveGiftRec, ...], ...} + return + + def AddUnNotifyGiftRec(self, receivePlayerID, givePlayerID, giftNum, giftCount, sendTime): + ''' 添加未通知的赠送礼物记录 + @param receivePlayerID: 未通知的受赠方玩家ID + @param givePlayerID: 赠送方玩家ID + ''' + recData = PyGameDataStruct.tagDBPyUnNotifyLoveGiftRec() + recData.PlayerID = receivePlayerID + recData.GivePlayerID = givePlayerID + recData.GiftNum = giftNum + recData.GiftCount = giftCount + recData.SendTime = sendTime + + if receivePlayerID not in self.unNotifyLoveGiftDict: + self.unNotifyLoveGiftDict[receivePlayerID] = [] + giftList = self.unNotifyLoveGiftDict[receivePlayerID] + giftList.append(recData) + return + + def LoginNotify(self, curPlayer): + receivePlayerID = curPlayer.GetPlayerID() + if receivePlayerID not in self.unNotifyLoveGiftDict: + return + giftList = self.unNotifyLoveGiftDict.pop(receivePlayerID, []) + + sendGiftList = [] + for recData in giftList: + giftOK = ChPyNetSendPack.tagGCSendGiftsOK() + giftOK.PlayerID = recData.GivePlayerID + giftOK.Name = PlayerSocial.GetSocialPlayerName(recData.GivePlayerID) + giftOK.NameLen = len(giftOK.Name) + giftOK.GiftNum = recData.GiftNum + giftOK.GiftCount = recData.GiftCount + giftOK.SendTime = recData.SendTime + sendGiftList.append(giftOK) + + clientPack = ChPyNetSendPack.tagGCSendGiftsOKList() + clientPack.SendGiftsOKList = sendGiftList + clientPack.Count = len(clientPack.SendGiftsOKList) + NetPackCommon.SendFakePack(curPlayer, clientPack) + return + + # 保存数据 存数据库和realtimebackup + def GetSaveData(self): + savaData = "" + cntData = "" + cnt = 0 + + for recDataList in self.unNotifyLoveGiftDict.values(): + for recData in recDataList: + cnt += 1 + savaData += recData.getBuffer() + + GameWorld.Log("Save DBPyUnNotifyLoveGiftRec count :%s len=%s" % (cnt, len(savaData))) + return CommFunc.WriteDWORD(cntData, cnt) + savaData + + # 从数据库载入数据 + def LoadPyGameData(self, datas, pos, dataslen): + cnt, pos = CommFunc.ReadDWORD(datas, pos) + GameWorld.Log("Load DBPyUnNotifyLoveGiftRec count :%s" % cnt) + + for _ in xrange(cnt): + recData = PyGameDataStruct.tagDBPyUnNotifyLoveGiftRec() + recData.clear() + pos += recData.readData(datas, pos, dataslen) + + playerID = recData.PlayerID + + if playerID not in self.unNotifyLoveGiftDict: + self.unNotifyLoveGiftDict[playerID] = [] + recDataList = self.unNotifyLoveGiftDict[playerID] + recDataList.append(recData) + + return pos def AddProsperity(candyObj, addValue): candyObj.prosperity += addValue @@ -100,11 +323,42 @@ return def DoOnDay(): - PlayerBillboard.ClearBillboardByIndex(ShareDefine.Def_BT_CharmDay) + + # 重置每日聘礼状态 + syncPlayerIDList = [] + coupleMgr = PyDataManager.GetDBPyCoupleManager() + ipyDataMgr = IpyGameDataPY.IPY_Data() + for index in range(ipyDataMgr.GetMarryCount()): + ipyData = ipyDataMgr.GetMarryByIndex(index) + if not ipyData.GetIsDayReset(): + continue + bridePriceID = ipyData.GetBridePriceID() + + for couple in coupleMgr.coupleDict.values(): + bridePriceState = couple.GetBridePriceState() + buyCount = couple.GetBridePriceBuyCount(bridePriceID) + if not buyCount: + continue + coupleIDInfo = [couple.coupleData.PlayerIDA, couple.coupleData.PlayerIDB] + updBridePriceState = couple.SetBridePriceBuyCount(bridePriceID, 0) + GameWorld.DebugLog("重置每日聘礼次数: coupleIDInfo=%s,bridePriceState=%s,bridePriceID=%s,updBridePriceState=%s" + % (coupleIDInfo, bridePriceState, bridePriceID, updBridePriceState)) + syncPlayerIDList.extend(coupleIDInfo) + + if syncPlayerIDList: + playerMgr = GameWorld.GetPlayerManager() + syncPlayerIDList = list(set(syncPlayerIDList)) + for playerID in syncPlayerIDList: + curPlayer = playerMgr.FindPlayerByID(playerID) + if not curPlayer or PlayerControl.GetIsTJG(curPlayer): + continue + Sync_CoupleInfo(curPlayer) + return def OnPlayerLogin(curPlayer): - __LoginCheckCouple(curPlayer) + PyDataManager.GetDBPyUnNotifyLoveGiftRecManager().LoginNotify(curPlayer) + Sync_CoupleInfo(curPlayer) Sync_CandyList(curPlayer) return @@ -123,6 +377,22 @@ PyGameData.g_marryCandyInfo.pop((candyObj.playerIDA, candyObj.playerIDB), None) __DoMarryCandyOver(candyObj) + + # 检查和离 + breakWaitTimes = IpyGameDataPY.GetFuncCfg("LoveMarryBreak", 5) + doCount = len(PyGameData.g_marryBreakSortList) + while doCount > 0 and PyGameData.g_marryBreakSortList: + doCount -= 1 + couple = PyGameData.g_marryBreakSortList[0] + if curTime <= (couple.GetBreakRequestTime() + breakWaitTimes): + break + playerIDA, playerIDB = couple.coupleData.PlayerIDA, couple.coupleData.PlayerIDB + PyGameData.g_marryBreakSortList.pop(0) + PyGameData.g_marryBreakInfo.pop((playerIDA, playerIDB), None) + + GameWorld.Log("和离提交请求到期,系统自动和离! playerIDA=%s,playerIDB=%s, len(g_marryBreakSortList)=%s" + % (playerIDA, playerIDB, len(PyGameData.g_marryBreakSortList))) + __DoMarryBreakLogic(couple, 0) return @@ -167,7 +437,6 @@ return playerID = curPlayer.GetPlayerID() - curTime = int(time.time()) if reqPlayerID not in PyGameData.g_marryReqInfo: GameWorld.DebugLog("提亲请求不存在! reqPlayerID=%s" % reqPlayerID, playerID) PlayerControl.NotifyCode(curPlayer, "MarryReqInvalid") @@ -180,21 +449,31 @@ PlayerControl.NotifyCode(curPlayer, "MarryReqInvalid") return - reqData = PyGameData.g_marryReqInfo.pop(reqPlayerID) - - bridePriceID = reqData.bridePriceID - passSeconds = curTime - reqData.reqTime - reqSecondCD = IpyGameDataPY.GetFuncCfg("LoveMarry", 1) - if passSeconds > reqSecondCD: + if __CheckMarryReqTimeout(reqData): GameWorld.DebugLog("提亲请求已超时! reqPlayerID=%s" % reqPlayerID, playerID) PlayerControl.NotifyCode(curPlayer, "MarryReqInvalid") + PyGameData.g_marryReqInfo.pop(reqPlayerID, None) return + __DoMarryResponse(curPlayer, reqPlayer, reqPlayerID, isOK) + return + +def __DoMarryResponse(curPlayer, reqPlayer, reqPlayerID, isOK): + ''' 提亲回应 + @param curPlayer: 回应玩家 + @param reqPlayer: 提亲玩家 + @param isOK: 是否统一 + ''' + reqData = PyGameData.g_marryReqInfo.pop(reqPlayerID, None) + if not reqData: + return + bridePriceID = reqData.bridePriceID ipyData = IpyGameDataPY.GetIpyGameData("Marry", bridePriceID) if not ipyData: return - reqPlayerName = reqPlayer.GetName() + playerID = curPlayer.GetPlayerID() + reqPlayerName = reqPlayer.GetName() if reqPlayer else PlayerSocial.GetSocialPlayerName(reqPlayerID) playerName = curPlayer.GetName() responsePack = ChPyNetSendPack.tagGCMarryResponseRet() @@ -205,13 +484,17 @@ responsePack.PlayerNameB = playerName responsePack.NameBLen = len(responsePack.PlayerNameB) responsePack.IsOK = isOK - NetPackCommon.SendFakePack(reqPlayer, responsePack) # 必回复提亲方 + if reqPlayer: + NetPackCommon.SendFakePack(reqPlayer, responsePack) # 必回复提亲方 # 拒绝 if not isOK: return NetPackCommon.SendFakePack(curPlayer, responsePack) # 回应方仅同意时同步 # ===================== 以下执行成亲逻辑 ===================== + GameWorld.Log("执行成亲: reqPlayerID=%s,playerID=%s,bridePriceID=%s" % (reqPlayerID, playerID, bridePriceID), playerID) + + curTime = int(time.time()) prosperity = ipyData.GetProsperity() candyTimes = ipyData.GetCandyTimes() brideGiftItemInfo = ipyData.GetBrideGiftItemInfo() @@ -222,26 +505,49 @@ paramList.extend([itemID, itemCount]) PlayerControl.WorldNotify(0, worldNotifyKey, paramList) - for player, coupleID, coupleName in [[reqPlayer, playerID, playerName], [curPlayer, reqPlayerID, reqPlayerName]]: - PlayerControl.SetCoupleID(player, coupleID) + coupleMgr = PyDataManager.GetDBPyCoupleManager() + couple = coupleMgr.GetCouple(playerID) + if not couple: + GameWorld.Log(" 新婚: reqPlayerID=%s,playerID=%s,bridePriceID=%s" % (reqPlayerID, playerID, bridePriceID), playerID) + coupleData = PyGameDataStruct.tagDBPyCouple() + coupleData.PlayerIDA = reqPlayerID + coupleData.PlayerNameA = reqPlayerName + coupleData.PlayerIDB = playerID + coupleData.PlayerNameB = playerName + coupleData.NewMarryTime = curTime + couple = coupleMgr.AddCouple(reqPlayerID, playerID, coupleData) - # 更新社交关系 - socialPlayer = PyDataManager.GetPersonalSocialManager().GetSocialPlayer(player.GetPlayerID()) - if socialPlayer: - socialPlayer.SetCoupleInfo(coupleID, coupleName) - socialPlayer.CheckUpdCouplePriceMaxID(bridePriceID) - - # 通知地图玩家 - dataMsg = [reqPlayerID, coupleID, curTime, bridePriceID] + # 通知给相关社交人员 + PlayerSocial.NotifySocialCoupleChange(reqPlayerID, playerID) + PlayerSocial.NotifySocialCoupleChange(playerID, reqPlayerID) + + # 通知地图全局伴侣信息 + PyDataManager.GetDBPyCoupleManager().SendMapServerCoupleInfo([playerID, reqPlayerID]) + else: + GameWorld.Log(" 已婚,再次提亲: PlayerIDA=%s,PlayerIDB=%s, cur reqPlayerID=%s,playerID=%s,bridePriceID=%s" + % (couple.coupleData.PlayerIDA, couple.coupleData.PlayerIDB, reqPlayerID, playerID, bridePriceID), playerID) + + couple.coupleData.MarryTime = curTime + updBuyCountValue = couple.SetBridePriceBuyCount(bridePriceID, couple.GetBridePriceBuyCount(bridePriceID) + 1) + GameWorld.Log(" updBuyCountValue=%s" % updBuyCountValue, playerID) + + if bridePriceID > couple.BridePriceMaxID: + couple.BridePriceMaxID = bridePriceID + GameWorld.Log(" update BridePriceMaxID=%s" % couple.BridePriceMaxID, playerID) + + # 通知玩家 + for player in [reqPlayer, curPlayer]: + if not player: + continue + mapServerCoupleInfo = couple.GetSendMapServerCoupleInfo(player.GetPlayerID()) + dataMsg = [reqPlayerID, bridePriceID, mapServerCoupleInfo] MapServer_QueryPlayer_DoLogic_Love(player, "MarrySuccess", dataMsg, playerID) + Sync_CoupleInfo(player) # 聘礼奖励发邮件 playerIDList = [reqPlayerID, playerID] paramList = [reqPlayerName, playerName] PlayerCompensation.SendMailByKey("MarrySuccess", playerIDList, brideGiftItemInfo, paramList) - - # 通知地图全局伴侣信息 - PlayerSocial.SendMapServerCoupleInfo([playerID, reqPlayerID]) # 新增喜糖 candyObj = MarryCandy() @@ -255,11 +561,27 @@ AddProsperity(candyObj, prosperity) PyGameData.g_marryCandyInfo[(reqPlayerID, playerID)] = candyObj + __SortCandy() + Sync_CandyList(None, [candyObj]) + return True + +def __SortCandy(): PyGameData.g_marryCandySortList = PyGameData.g_marryCandyInfo.values() PyGameData.g_marryCandySortList.sort(key=operator.attrgetter("endTime")) - - Sync_CandyList(None, [candyObj]) return + +def SortMarryBreak(): + PyGameData.g_marryBreakSortList = PyGameData.g_marryBreakInfo.values() + PyGameData.g_marryBreakSortList.sort(key=operator.attrgetter("coupleData.BreakRequestTime")) + #GameWorld.DebugLog("SortMarryBreak count=%s" % len(PyGameData.g_marryBreakSortList)) + return + +def __CheckMarryReqTimeout(reqData): + ## 检查提亲是否超时 + curTime = int(time.time()) + passSeconds = curTime - reqData.reqTime + reqSecondCD = IpyGameDataPY.GetFuncCfg("LoveMarry", 1) + return passSeconds > reqSecondCD #// B3 16 和平离婚回应 #tagGCMarryBreakResponse # @@ -273,103 +595,89 @@ isOK = clientData.IsOK playerID = curPlayer.GetPlayerID() - coupleID = PlayerControl.GetCoupleID(curPlayer) - if not coupleID: + couple = PyDataManager.GetDBPyCoupleManager().GetCouple(playerID) + if not couple: + GameWorld.Log("没有伴侣,无法回应和离! ", playerID) + return + coupleID = couple.GetCoupleID(playerID) + breakRequestID = couple.GetBreakRequestID() + if not breakRequestID or coupleID != breakRequestID: + GameWorld.Log("伴侣没有提出和离,无法回应和离! coupleID=%s,breakRequestID=%s" + % (coupleID, breakRequestID), playerID) return - if coupleID not in PyGameData.g_marryBreakReqInfo: - GameWorld.DebugLog("对方没有请求和离,回应无效! coupleID=%s" % coupleID, playerID) - return + playerIDA, playerIDB = couple.coupleData.PlayerIDA, couple.coupleData.PlayerIDB + if (playerIDA, playerIDB) in PyGameData.g_marryBreakInfo: + PyGameData.g_marryBreakInfo.pop((playerIDA, playerIDB), None) + SortMarryBreak() - if playerID != PyGameData.g_marryBreakReqInfo[coupleID]: - GameWorld.DebugLog("非对方没有请求和离对象,回应无效! reqPlayerID=%s,tagPlayerID=%s" - % (coupleID, PyGameData.g_marryBreakReqInfo[coupleID]), playerID) - return - PyGameData.g_marryBreakReqInfo.pop(coupleID, None) - if not isOK: + GameWorld.Log("拒绝和离! coupleID=%s" % coupleID, playerID) + couple.SetBreakRequestID(0) # 清除和离请求ID + + Sync_CoupleInfo(curPlayer) + tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(coupleID) + if tagPlayer and not PlayerControl.GetIsTJG(tagPlayer): + Sync_CoupleInfo(tagPlayer) PlayerCompensation.SendMailByKey("MarryBreakRefuse", [coupleID], [], [curPlayer.GetName()]) return GameWorld.Log("同意和离: coupleID=%s" % coupleID, playerID) - __DoMarryBreak(curPlayer, coupleID) + __DoMarryBreakLogic(couple, playerID) return -def __DoMarryBreak(curPlayer, coupleID): +def __DoMarryBreakLogic(couple, playerID=0): ## 执行离婚 - playerID = curPlayer.GetPlayerID() - - __ClearCoupleSocial(curPlayer) - - tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(coupleID) - if tagPlayer: - __ClearCoupleSocial(tagPlayer) - - # 未在线,标记离婚状态,等下次玩家上线处理 - else: - socialPlayer = PyDataManager.GetPersonalSocialManager().GetSocialPlayer(coupleID) - if socialPlayer: - socialPlayer.SetCoupleBreakOffline() - GameWorld.Log("离婚时伴侣不在线,标记伴侣社交关系已离婚!等下次上线处理! coupleID=%s" % coupleID, playerID) - - # 通知地图全局伴侣信息 - PlayerSocial.SendMapServerCoupleInfo([playerID, coupleID]) - return - -def __LoginCheckCouple(curPlayer): - ## 登录检查是否已被离婚 - playerID = curPlayer.GetPlayerID() - coupleID = PlayerControl.GetCoupleID(curPlayer) - if not coupleID: + if not couple: return - socialPlayer = PyDataManager.GetPersonalSocialManager().GetSocialPlayer(playerID) - if socialPlayer == None or socialPlayer.GetCoupleBreakOffline(): - GameWorld.Log("玩家上线检测到已被离婚,执行解除伴侣关系!coupleID=%s" % coupleID, playerID) - __ClearCoupleSocial(curPlayer) - - # 上线未同步过地图全局伴侣信息的则同步 - if socialPlayer and not socialPlayer.syncMapCouple and socialPlayer.GetCoupleID(): - PlayerSocial.SendMapServerCoupleInfo([playerID]) - - return - -def __ClearCoupleSocial(curPlayer): - ## 清除伴侣社交关系 + playerIDA = couple.coupleData.PlayerIDA + playerIDB = couple.coupleData.PlayerIDB - coupleID = PlayerControl.GetCoupleID(curPlayer) - coupleName = "" + coupleMgr = PyDataManager.GetDBPyCoupleManager() - playerID = curPlayer.GetPlayerID() - GameWorld.Log("玩家执行解除伴侣关系! coupleID=%s" % coupleID, playerID) - - if coupleID: - # 亲密度减少 - curFriends = PyDataManager.GetFriendManager().GetFriends(playerID) - if curFriends != None: - decIntimacyPer = IpyGameDataPY.GetFuncCfg("LoveMarryBreak", 3) - updIntimacy = curFriends.AddIntimacyByPer(curPlayer, coupleID, -decIntimacyPer) - GameWorld.Log(" 更新自身与对方亲密度: tagPlayerID=%s,decIntimacyPer=%s,updIntimacy=%s" % (coupleID, decIntimacyPer, updIntimacy), playerID) - - # 通知地图 - dataMsg = [] - MapServer_QueryPlayer_DoLogic_Love(curPlayer, "ClearCoupleSocial", dataMsg, playerID) - - # 清社交关系 - 由地图清除后同步更新 - PlayerControl.SetCoupleID(curPlayer, 0) - socialPlayer = PyDataManager.GetPersonalSocialManager().GetSocialPlayer(playerID) - if socialPlayer: - coupleName = socialPlayer.playerInfo.CoupleName - socialPlayer.SetCoupleInfo(0, "") - socialPlayer.CheckUpdCouplePriceMaxID(0) + # 亲密度减少 + decIntimacyPer = IpyGameDataPY.GetFuncCfg("LoveMarryBreak", 4) + if decIntimacyPer: + PyDataManager.GetIntimacyManager().DelIntimacyBothPer(playerIDA, playerIDB, decIntimacyPer) # 邮件通知离婚 - playerIDList = [playerID] - paramList = [coupleName] - PlayerCompensation.SendMailByKey("MarryBreakOK", playerIDList, [], paramList) - return + for pid in [playerIDA, playerIDB]: + coupleName = couple.GetCoupleName(pid) + playerIDList = [pid] + paramList = [coupleName] + PlayerCompensation.SendMailByKey("MarryBreakOK", playerIDList, [], paramList) + + coupleMgr.DelCouple(playerIDA, playerIDB) + # 通知地图全局伴侣信息 + PyDataManager.GetDBPyCoupleManager().SendMapServerCoupleInfo([playerIDA, playerIDB]) + + # 通知玩家 + dataMsg = [] + for pid in [playerIDA, playerIDB]: + tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(pid) + if tagPlayer and not PlayerControl.GetIsTJG(tagPlayer): + MapServer_QueryPlayer_DoLogic_Love(tagPlayer, "ClearCoupleSocial", dataMsg, playerID) + Sync_CoupleInfo(tagPlayer) + + # 通知给相关社交人员 + PlayerSocial.NotifySocialCoupleChange(playerIDA, 0) + PlayerSocial.NotifySocialCoupleChange(playerIDB, 0) + + if (playerIDA, playerIDB) in PyGameData.g_marryCandyInfo: + GameWorld.Log("离婚时同步清除喜糖宴会: playerIDA=%s, playerIDB=%s" % (playerIDA, playerIDB), playerID) + PyGameData.g_marryCandyInfo.pop((playerIDA, playerIDB)) + __SortCandy() + Sync_CandyList(None) + + if (playerIDA, playerIDB) in PyGameData.g_marryBreakInfo: + GameWorld.Log("离婚时同步清除和离请求: playerIDA=%s, playerIDB=%s" % (playerIDA, playerIDB), playerID) + PyGameData.g_marryBreakInfo.pop((playerIDA, playerIDB), None) + SortMarryBreak() + + return True def MapServer_Love(curPlayer, msgList): mapID = curPlayer.GetRealMapID() @@ -379,13 +687,13 @@ msgType, dataMsg = msgList - # 送花请求 - if msgType == "SendFlowersReq": - ret = __CheckSendFlowers(curPlayer, dataMsg) + # 送礼物请求 + if msgType == "SendGiftsReq": + ret = __SendGiftsReq(curPlayer, dataMsg) - # 送花OK - elif msgType == "SendFlowersOK": - __DoSendFlowersOK(curPlayer, dataMsg) + # 送礼物 + elif msgType == "SendGiftsOK": + __DoSendGiftsOK(curPlayer, dataMsg) return # 提亲 @@ -409,63 +717,70 @@ return return msgList + [ret] -def __CheckSendFlowers(curPlayer, dataMsg): - ## 在线好友可赠送 +def __SendGiftsReq(curPlayer, dataMsg): + ## 送礼物请求 tagPlayerID = dataMsg[0] playerID = curPlayer.GetPlayerID() - curFriends = PyDataManager.GetFriendManager().GetFriends(playerID) - if curFriends == None: - return - curFriend = curFriends.Find(tagPlayerID) - if curFriend == None: - PlayerControl.NotifyCode(curPlayer, "NotFriend") - return - tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(tagPlayerID) - if not tagPlayer or PlayerControl.GetIsTJG(tagPlayer): - PlayerControl.NotifyCode(curPlayer, "LoveOffline") + # 黑名单检查 + if PyDataManager.GetBlacklistManager().CheckBlacklistBoth(playerID, tagPlayerID, curPlayer): return return True -def __DoSendFlowersOK(curPlayer, dataMsg): - ## 送花OK +def __DoSendGiftsOK(curPlayer, dataMsg): + ## 送礼物 playerID = curPlayer.GetPlayerID() playerName = curPlayer.GetName() - tagPlayerID, flowerID, flowerCount, addCharm, addCharmTag, addIntimacy, isWorldNotify = dataMsg + tagPlayerID, giftNum, giftItemID, giftCount, isAutoBuy = dataMsg - GameWorld.Log("赠送鲜花OK: tagPlayerID=%s,flowerCount=%s,addCharm=%s,addCharmTag=%s,addIntimacy=%s" - % (tagPlayerID, flowerCount, addCharm, addCharmTag, addIntimacy), playerID) - - curFriends = PyDataManager.GetFriendManager().GetFriends(playerID) - if curFriends != None: - updIntimacy = curFriends.AddIntimacy(curPlayer, tagPlayerID, addIntimacy) - GameWorld.Log(" 增加自身与对方亲密度: tagPlayerID=%s,updIntimacy=%s" % (tagPlayerID, updIntimacy), playerID) - - tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(tagPlayerID) - if not tagPlayer or PlayerControl.GetIsTJG(tagPlayer): + ipyData = IpyGameDataPY.GetIpyGameData("LoveGift", giftNum) + if not ipyData: return - tagPlayerName = tagPlayer.GetName() - tagFriends = PyDataManager.GetFriendManager().GetFriends(tagPlayerID) - if tagFriends != None: - updIntimacy = tagFriends.AddIntimacy(tagPlayer, playerID, addIntimacy) - GameWorld.Log(" 增加对方与自身亲密度: tagPlayerID=%s,updIntimacy=%s" % (tagPlayerID, updIntimacy), playerID) + addCharmSelf = ipyData.GetAddCharmSelf() * giftCount + addCharmTag = ipyData.GetAddCharmTag() * giftCount + addIntimacy = ipyData.GetAddIntimacy() * giftCount + worldNotifyKey = ipyData.GetWorldNotifyKey() + + GameWorld.Log("赠送礼物: tagPlayerID=%s,giftNum=%s,giftItemID=%s,giftCount=%s,addCharmSelf=%s,addCharmTag=%s,addIntimacy=%s,isAutoBuy=%s" + % (tagPlayerID, giftNum, giftItemID, giftCount, addCharmSelf, addCharmTag, addIntimacy, isAutoBuy), playerID) + + tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(tagPlayerID) + + PyDataManager.GetIntimacyManager().AddIntimacyBoth(playerID, tagPlayerID, addIntimacy) + PlayerCharm.AddCharm(curPlayer, playerID, playerID, addCharmSelf) + PlayerCharm.AddCharm(tagPlayer, tagPlayerID, playerID, addCharmTag) + + tagPlayerName = "" + isOnline = tagPlayer and not PlayerControl.GetIsTJG(tagPlayer) + if isOnline: + tagPlayerName = tagPlayer.GetName() + else: + tagPlayerName = PlayerSocial.GetSocialPlayerName(tagPlayerID) - if isWorldNotify: - PlayerControl.WorldNotify(0, "SendFlowers%s" % flowerCount, [playerName, tagPlayerName, flowerCount, flowerID]) + if worldNotifyKey: + PlayerControl.WorldNotify(0, worldNotifyKey, [playerName, tagPlayerName, giftItemID, giftCount]) - dataMsg = [addCharmTag] - MapServer_QueryPlayer_DoLogic_Love(tagPlayer, "AddCharm", dataMsg, playerID) - + sendTime = int(time.time()) + if not isOnline: + PyDataManager.GetDBPyUnNotifyLoveGiftRecManager().AddUnNotifyGiftRec(tagPlayerID, playerID, giftNum, giftCount, sendTime) + return + # 通知目标前端送花成功 - clientPack = ChPyNetSendPack.tagGCSendFlowersOK() - clientPack.PlayerID = playerID - clientPack.Name = playerName - clientPack.NameLen = len(clientPack.Name) - clientPack.FlowerCount = flowerCount + giftOK = ChPyNetSendPack.tagGCSendGiftsOK() + giftOK.PlayerID = playerID + giftOK.Name = playerName + giftOK.NameLen = len(giftOK.Name) + giftOK.GiftNum = giftNum + giftOK.GiftCount = giftCount + giftOK.SendTime = sendTime + + clientPack = ChPyNetSendPack.tagGCSendGiftsOKList() + clientPack.SendGiftsOKList = [giftOK] + clientPack.Count = len(clientPack.SendGiftsOKList) NetPackCommon.SendFakePack(tagPlayer, clientPack) return @@ -485,33 +800,30 @@ ## 成亲通用检查 playerID = curPlayer.GetPlayerID() - curFriends = PyDataManager.GetFriendManager().GetFriends(playerID) - if curFriends == None: - PlayerControl.NotifyCode(curPlayer, "NotFriend") # 非好友 - return - curFriend = curFriends.Find(tagPlayerID) - if curFriend == None: - PlayerControl.NotifyCode(curPlayer, "NotFriend") # 非好友 + + # 黑名单检查 + if PyDataManager.GetBlacklistManager().CheckBlacklistBoth(playerID, tagPlayerID, curPlayer): return if not tagPlayer or PlayerControl.GetIsTJG(tagPlayer): PlayerControl.NotifyCode(curPlayer, "LoveOffline") # 离线 return - coupleID = PlayerControl.GetCoupleID(curPlayer) - if coupleID and coupleID != tagPlayerID: - PlayerControl.NotifyCode(curPlayer, "TagHaveCouple") # 已经有其他伴侣了 + curCouple = PyDataManager.GetDBPyCoupleManager().GetCouple(playerID) + if curCouple and curCouple.GetCoupleID(playerID) != tagPlayerID: + PlayerControl.NotifyCode(curPlayer, "HaveCouple") # 已经有其他伴侣了 return - tagCoupleID = PlayerControl.GetCoupleID(tagPlayer) - if tagCoupleID and tagCoupleID != playerID: - PlayerControl.NotifyCode(curPlayer, "TagHaveCouple") # 已经有其他伴侣了 + tagCouple = PyDataManager.GetDBPyCoupleManager().GetCouple(tagPlayerID) + if tagCouple and tagCouple.GetCoupleID(tagPlayerID) != playerID: + PlayerControl.NotifyCode(curPlayer, "TagHaveCouple") # 对方已经有其他伴侣了 return # 回应方可不检查亲密度 if checkIntimacy: needIntimacy = IpyGameDataPY.GetFuncCfg("LoveMarry", 2) - if curFriend.Intimacy < needIntimacy: + curIntimacys = PyDataManager.GetIntimacyManager().GetIntimacys(playerID) + if not curIntimacys or curIntimacys.GetTagIntimacy(tagPlayerID) < needIntimacy: PlayerControl.NotifyCode(curPlayer, "IntimacyLack", [needIntimacy]) # 亲密度不足 return @@ -519,7 +831,7 @@ def __DoMarryReq(curPlayer, dataMsg): ## 提亲 - + tagPlayerID, bridePriceID = dataMsg tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(tagPlayerID) @@ -533,6 +845,34 @@ PlayerControl.NotifyCode(curPlayer, "MarryReqLimitByCandy") # 喜宴中无法操作 return + couple = PyDataManager.GetDBPyCoupleManager().GetCouple(playerID) + if couple: + coupleID = couple.GetCoupleID(playerID) + if coupleID != tagPlayerID: + GameWorld.Log("已成亲伴侣ID不一致,无法提亲! tagPlayerID(%s) != coupleID(%s)" % (tagPlayerID, coupleID), playerID) + return + + ipyData = IpyGameDataPY.GetIpyGameData("Marry", bridePriceID) + if not ipyData: + return + + canBuyMax = ipyData.GetCanBuyCount() + buyCount = couple.GetBridePriceBuyCount(bridePriceID) + GameWorld.DebugLog("bridePriceID=%s,buyCount=%s,canBuyMax=%s %s" % (bridePriceID, buyCount, canBuyMax, couple.coupleData.BridePriceState)) + if canBuyMax and buyCount >= canBuyMax: + GameWorld.Log("聘礼提亲次数不足,无法提亲! bridePriceID=%s,buyCount(%s) >= canBuyMax(%s)" + % (bridePriceID, buyCount, canBuyMax), playerID) + return + + if tagPlayerID in PyGameData.g_marryReqInfo: + tagReqData = PyGameData.g_marryReqInfo[tagPlayerID] + if playerID == tagReqData.playerIDB and not __CheckMarryReqTimeout(tagReqData): + GameWorld.Log("玩家提亲时,目标刚好已经先提过亲,且在有效期内,直接成亲!tagPlayerID=%s" % tagPlayerID, playerID) + if __DoMarryResponse(curPlayer, tagPlayer, tagPlayerID, 1): + return + else: + GameWorld.DebugLog("对方有提亲,但是对象不一样或已超时! tagPlayerID=%s, timeout=%s" % (tagReqData.playerIDB, __CheckMarryReqTimeout(tagReqData)), playerID) + curTime = int(time.time()) if playerID not in PyGameData.g_marryReqInfo: reqData = MarryReq() @@ -631,44 +971,82 @@ def __DoMarryBreakReq(curPlayer, dataMsg): ## 离婚请求 - playerID, coupleID, breakType, moneyType, moneyValue = dataMsg + playerID, breakType, moneyType, moneyValue = dataMsg - gameServerCoupleID = PlayerControl.GetCoupleID(curPlayer) - socialPlayer = PyDataManager.GetPersonalSocialManager().GetSocialPlayer(playerID) - socialCoupleID = 0 if not socialPlayer else socialPlayer.GetCoupleID() + couple = PyDataManager.GetDBPyCoupleManager().GetCouple(playerID) + if not couple: + GameWorld.Log("没有伴侣,不需要离婚! ", playerID) + return + coupleID = couple.GetCoupleID(playerID) - if not gameServerCoupleID or coupleID != gameServerCoupleID or not socialCoupleID or coupleID != socialCoupleID: - GameWorld.ErrLog("地图玩家伴侣数据与GameServer不一致,离婚请求时直接通过! gameServerCoupleID=%s,socialCoupleID=%s,mapCoupleID=%s" - % (gameServerCoupleID, socialCoupleID, coupleID), playerID) - __ClearCoupleSocial(curPlayer) - PlayerSocial.SendMapServerCoupleInfo([playerID]) + curTime = int(time.time()) + + # 公共CD + marryTime = couple.GetMarryTime() + passTime = curTime - marryTime + marryBreakCD = IpyGameDataPY.GetFuncCfg("LoveMarryBreak", 1) + if marryBreakCD and passTime < marryBreakCD: + GameWorld.Log("距离最近一次成亲离婚等待时间未到,无法请求离婚! marryTime=%s,passTime(%s) < %s" + % (GameWorld.ChangeTimeNumToStr(marryTime), passTime, marryBreakCD), playerID) return - if (playerID, coupleID) in PyGameData.g_marryCandyInfo or (coupleID, playerID) in PyGameData.g_marryCandyInfo: - PlayerControl.NotifyCode(curPlayer, "MarryReqLimitByCandy") # 喜宴中无法操作 + # 和离额外限制个人CD + playerBreakRequestTime = couple.GetPlayerBreakRequestTime(playerID) + if breakType == 0 and playerBreakRequestTime: + passTime = curTime - playerBreakRequestTime + breakReqCD = IpyGameDataPY.GetFuncCfg("LoveMarryBreak", 2) + if breakReqCD and passTime < breakReqCD: + GameWorld.Log("距离最近一次请求和离等待时间未到,无法请求离婚! playerBreakRequestTime=%s,passTime(%s) < %s" + % (GameWorld.ChangeTimeNumToStr(playerBreakRequestTime), passTime, breakReqCD), playerID) + return + + if couple.GetBreakRequestID() == coupleID: + GameWorld.Log("请求离婚时对方已经提出和离了,直接离婚! coupleID=%s,breakRequestID=%s" + % (coupleID, couple.GetBreakRequestID()), playerID) + __DoMarryBreakLogic(couple, playerID) return # 0-和平离婚;1-强制离婚 if breakType == 0: + if couple.GetBreakRequestID() != playerID: + playerIDA, playerIDB = couple.coupleData.PlayerIDA, couple.coupleData.PlayerIDB + GameWorld.Log("新增提交和离! coupleID=%s" % coupleID, playerID) + couple.SetBreakRequestID(playerID) + PyGameData.g_marryBreakInfo[(playerIDA, playerIDB)] = couple + SortMarryBreak() + playerBreakRequestTime = couple.GetPlayerBreakRequestTime(playerID) + else: + GameWorld.Log("重复提交和离! coupleID=%s" % coupleID, playerID) + + Sync_CoupleInfo(curPlayer) tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(coupleID) - if not tagPlayer or PlayerControl.GetIsTJG(tagPlayer): - PlayerControl.NotifyCode(curPlayer, "LoveOffline") # 离线 - return - - clientPack = ChPyNetSendPack.tagGCMarryBreakInfo() - clientPack.PlayerID = playerID - clientPack.PlayerName = curPlayer.GetName() - clientPack.NameLen = len(clientPack.PlayerName) - NetPackCommon.SendFakePack(tagPlayer, clientPack) - - PyGameData.g_marryBreakReqInfo[playerID] = coupleID + if tagPlayer and not PlayerControl.GetIsTJG(tagPlayer): + Sync_CoupleInfo(tagPlayer) return GameWorld.Log("强制离婚: coupleID=%s" % coupleID, playerID) - __DoMarryBreak(curPlayer, coupleID) + __DoMarryBreakLogic(couple, playerID) return moneyType, moneyValue +def Sync_CoupleInfo(curPlayer): + ## 同步伴侣信息 + playerID = curPlayer.GetPlayerID() + clientPack = ChPyNetSendPack.tagGCCoupleInfo() + curCouple = PyDataManager.GetDBPyCoupleManager().GetCouple(playerID) + if curCouple: + clientPack.CoupleID = curCouple.GetCoupleID(playerID) + clientPack.CoupleName = curCouple.GetCoupleName(playerID) + clientPack.NameLen = len(clientPack.CoupleName) + clientPack.NewMarryTime = curCouple.GetNewMarryTime() + clientPack.MarryTime = curCouple.GetMarryTime() + clientPack.BridePriceState = curCouple.GetBridePriceState() + clientPack.BreakRequestID = curCouple.GetBreakRequestID() + clientPack.BreakRequestTime = curCouple.GetBreakRequestTime() + clientPack.PlayerBreakRequestTime = curCouple.GetPlayerBreakRequestTime(playerID) + NetPackCommon.SendFakePack(curPlayer, clientPack) + return + def Sync_CandyList(curPlayer, syncCandyList=None): if syncCandyList == None: syncCandyList = PyGameData.g_marryCandySortList -- Gitblit v1.8.0