From 167f1018e83452c601f84fa12e0d42fa47cf7ae4 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期五, 28 十二月 2018 11:55:22 +0800
Subject: [PATCH] 5424 【后端】【1.4】跨服竞技场开发(未同步的PK信息增加存储DB,防止服务器维护后数据丢失)

---
 ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py            |  157 +++++++++++++++++++++++++++++++
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py |   87 ++++++++++++++++-
 ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py               |    7 +
 3 files changed, 246 insertions(+), 5 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py
index 238badb..611fc5c 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py
@@ -1634,6 +1634,44 @@
         
     return
 
+#跨服竞技场未通知玩家的比赛结果,注意该类只处理数据逻辑,功能相关逻辑不要写在该类,不然重读脚本不会生效
+class CrossPKUnNotifyOverInfoManager(object):
+    
+    def __init__(self):
+        self.__unNotifyOverInfoDict = {} # {playerID:tagDBCrossPKUnNotifyOverInfo, ...}
+        return
+    
+    def AddUnNotifyOverInfo(self, playerID, overInfoData):
+        self.__unNotifyOverInfoDict[playerID] = overInfoData
+        return
+    
+    def GetPlayerUnNotifyOverInfo(self, playerID): return self.__unNotifyOverInfoDict.pop(playerID, None)
+    
+    # 保存数据 存数据库和realtimebackup
+    def GetSaveData(self):
+        savaData = ""
+        cntData = ""
+        cnt = 0
+        for overInfoData in self.__unNotifyOverInfoDict.values():
+            cnt += 1
+            savaData += overInfoData.getBuffer()
+                
+        GameWorld.Log("SaveDBCrossPKUnNotifyOverInfo cnt :%s" % cnt)
+        return CommFunc.WriteDWORD(cntData, cnt) + savaData
+    
+    # 从数据库载入数据
+    def LoadPyGameData(self, datas, pos, dataslen):
+        cnt, pos = CommFunc.ReadDWORD(datas, pos)
+        GameWorld.Log("LoadDBCrossPKUnNotifyOverInfo cnt :%s" % cnt)
+        
+        for _ in xrange(cnt):
+            overInfoData = PyGameDataStruct.tagDBCrossPKUnNotifyOverInfo()
+            overInfoData.clear()
+            pos += overInfoData.readData(datas, pos, dataslen)
+            self.__unNotifyOverInfoDict[overInfoData.PlayerID] = overInfoData
+            
+        return pos
+    
 def CrossServerMsg_PKOverInfo(playerOverDict):
     ## 子服接收跨服PK结果信息
     
@@ -1651,7 +1689,24 @@
         player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
         if not player or PlayerControl.GetIsTJG(player):
             GameWorld.Log("    玩家不在线 或脱机中,先缓存,玩家上线后再同步,playerID=%s" % (playerID))
-            PyGameData.g_crossPKUnNotifyOverInfo[playerID] = sendMapOverInfo
+            overInfoData = PyGameDataStruct.tagDBCrossPKUnNotifyOverInfo()
+            overInfoData.clear()
+            overInfoData.ZoneID = zoneID
+            overInfoData.SeasonID = seasonID
+            overInfoData.RoomID = roomID
+            overInfoData.TimeStr = timeStr
+            overInfoData.OverType = overType
+            overInfoData.PlayerID = playerID
+            overInfoData.WinnerID = winnerID
+            overInfoData.RoundWinnerInfo = str(roundWinnerIDList)
+            overInfoData.RoundWinnerLen = len(overInfoData.RoundWinnerInfo)
+            overInfoData.PKScore = pkScore
+            overInfoData.DanLV = danLV
+            overInfoData.CWinCount = cWinCount
+            overInfoData.AddScore = addScore
+            overInfoData.TagPlayerID = tagPlayerID
+            overInfoData.TagPlayerName = tagPlayerName
+            PyDataManager.GetCrossPKUnNotifyOverInfoManager().AddUnNotifyOverInfo(playerID, overInfoData)
             continue
         
         PlayerControl.SetVsRoomId(player, 0)
@@ -1663,14 +1718,36 @@
 
 def __OnLoginNotifyPKOverInfo(curPlayer):
     playerID = curPlayer.GetPlayerID()
-    if playerID not in PyGameData.g_crossPKUnNotifyOverInfo:
+    overInfoData = PyDataManager.GetCrossPKUnNotifyOverInfoManager().GetPlayerUnNotifyOverInfo(playerID)
+    if not overInfoData:
         return
-    overInfo = PyGameData.g_crossPKUnNotifyOverInfo.pop(playerID)
     PlayerControl.SetCrossRealmState(curPlayer, 0)
     PlayerControl.SetVsRoomId(curPlayer, 0)
-    sysMsg = str(overInfo)
+    
+    zoneID = overInfoData.ZoneID
+    seasonID = overInfoData.SeasonID
+    roomID = overInfoData.RoomID
+    timeStr = overInfoData.TimeStr
+    overType = overInfoData.OverType
+    #playerID = overInfoData.PlayerID
+    winnerID = overInfoData.WinnerID
+    roundWinnerIDList = []
+    try:
+        roundWinnerIDList = eval(overInfoData.RoundWinnerInfo)
+    except:
+        GameWorld.ErrLog("__OnLoginNotifyPKOverInfo roundWinnerIDList eval error! RoundWinnerInfo=%s" % overInfoData.RoundWinnerInfo, playerID)
+    pkScore = overInfoData.PKScore
+    danLV = overInfoData.DanLV
+    cWinCount = overInfoData.CWinCount
+    addScore = overInfoData.AddScore
+    tagPlayerID = overInfoData.TagPlayerID
+    tagPlayerName = overInfoData.TagPlayerName
+    notifyState = 0 # 登录才通知的默认未通知
+    sendMapOverInfo = [roomID, zoneID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState]
+    sysMsg = str(sendMapOverInfo)
     curPlayer.MapServer_QueryPlayerResult(0, 0, "CrossPKOverInfo", sysMsg, len(sysMsg))
-    GameWorld.Log("玩家上线通知地图未结算的跨服PK结算: mapID=%s,overInfo=%s" % (curPlayer.GetMapID(), overInfo), playerID)
+    GameWorld.Log("玩家上线通知地图未结算的跨服PK结算: roomID=%s,zoneID=%s,seasonID=%s,timeStr=%s,overType=%s,winnerID=%s,roundWinnerIDList=%s, pkScore=%s,danLV=%s,cWinCount=%s,addScore=%s,tagPlayerID=%s,notifyState=%s,mapID=%s" 
+                  % (roomID, zoneID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, notifyState, curPlayer.GetMapID()), playerID)
     return
 
 
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py b/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
index f0c6132..23be71f 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
@@ -44,6 +44,7 @@
 
 class PyGameDataManager(object):
     def __init__(self):
+        self.crossPKUnNotifyOverInfo = CrossRealmPK.CrossPKUnNotifyOverInfoManager()
         self.crossPKBillboard = CrossRealmPK.CrossPKBillboardManager()
         self.XMZZManager = PlayerXMZZ.XMZZManager()
         self.sealDemonManager = PlayerSealDemon.SealDemonManager()
@@ -60,6 +61,7 @@
 
     def GetSaveData(self):
         buff = ""
+        buff += self.crossPKUnNotifyOverInfo.GetSaveData()
         buff += self.crossPKBillboard.GetSaveData()
         buff += self.XMZZManager.GetSaveData()
         buff += self.sealDemonManager.GetSaveData()
@@ -75,6 +77,7 @@
         return buff
     
     def LoadGameData(self, gameBuffer, pos):
+        pos = self.crossPKUnNotifyOverInfo.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
         pos = self.crossPKBillboard.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
         pos = self.XMZZManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
         pos = self.sealDemonManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
@@ -89,6 +92,10 @@
         pos = self.socialInfoManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
         return pos
 
+# 跨服竞技场未通知玩家的比赛结果
+def GetCrossPKUnNotifyOverInfoManager():
+    return PyGameData.g_pyGameDataManager.crossPKUnNotifyOverInfo
+
 # 跨服竞技场排行榜管理
 def GetCrossPKBillboardManager():
     return PyGameData.g_pyGameDataManager.crossPKBillboard
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py b/ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py
index aa2cd6e..a5a2017 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py
@@ -15,6 +15,163 @@
 from ctypes import (Structure, memset, memmove, sizeof, addressof, create_string_buffer, string_at)
 import CommFunc
 
+# 跨服竞技场未通知玩家的比赛结果表 #tagDBCrossPKUnNotifyOverInfo
+class tagDBCrossPKUnNotifyOverInfo(Structure):
+    _pack_ = 1
+    _fields_ = [
+        ('ZoneID', ctypes.c_ubyte),
+        ('SeasonID', ctypes.c_ubyte),
+        ('RoomID', ctypes.c_ushort),
+        ('TimeStr', ctypes.c_char * 19),
+        ('OverType', ctypes.c_ubyte),
+        ('PlayerID', ctypes.c_ulong),
+        ('WinnerID', ctypes.c_ulong),
+        ('RoundWinnerLen', ctypes.c_ubyte),
+        ('RoundWinnerInfo', ctypes.c_char_p),
+        ('PKScore', ctypes.c_ulong),
+        ('DanLV', ctypes.c_ubyte),
+        ('CWinCount', ctypes.c_ushort),
+        ('AddScore', ctypes.c_ushort),
+        ('TagPlayerID', ctypes.c_ulong),
+        ('TagPlayerName', ctypes.c_char * 33),
+        ('ADOResult', ctypes.c_ulong),
+    ]
+
+    def __init__(self):
+        Structure.__init__(self)
+        self.clear()
+
+    def clear(self):
+        self.ZoneID = 0
+        self.SeasonID = 0
+        self.RoomID = 0
+        self.TimeStr = ''
+        self.OverType = 0
+        self.PlayerID = 0
+        self.WinnerID = 0
+        self.RoundWinnerLen = 0
+        self.RoundWinnerInfo = ''
+        self.PKScore = 0
+        self.DanLV = 0
+        self.CWinCount = 0
+        self.AddScore = 0
+        self.TagPlayerID = 0
+        self.TagPlayerName = ''
+
+    def readData(self, buf, pos = 0, length = 0):
+        if not pos <= length:
+            return -1
+        if len(buf) < pos + self.getLength():
+            return -1
+        self.clear()
+        self.ZoneID, pos = CommFunc.ReadBYTE(buf, pos)
+        self.SeasonID, pos = CommFunc.ReadBYTE(buf, pos)
+        self.RoomID, pos = CommFunc.ReadWORD(buf, pos)
+        self.TimeStr, pos = CommFunc.ReadString(buf, pos, 19)
+        self.OverType, pos = CommFunc.ReadBYTE(buf, pos)
+        self.PlayerID, pos = CommFunc.ReadDWORD(buf, pos)
+        self.WinnerID, pos = CommFunc.ReadDWORD(buf, pos)
+        self.RoundWinnerLen, pos = CommFunc.ReadBYTE(buf, pos)
+        tmp, pos = CommFunc.ReadString(buf, pos, self.RoundWinnerLen)
+        self.RoundWinnerInfo = ctypes.c_char_p(tmp)
+        self.PKScore, pos = CommFunc.ReadDWORD(buf, pos)
+        self.DanLV, pos = CommFunc.ReadBYTE(buf, pos)
+        self.CWinCount, pos = CommFunc.ReadWORD(buf, pos)
+        self.AddScore, pos = CommFunc.ReadWORD(buf, pos)
+        self.TagPlayerID, pos = CommFunc.ReadDWORD(buf, pos)
+        self.TagPlayerName, pos = CommFunc.ReadString(buf, pos, 33)
+        return self.getLength()
+
+    def getBuffer(self):
+        buf = ''
+        buf = CommFunc.WriteBYTE(buf, self.ZoneID)
+        buf = CommFunc.WriteBYTE(buf, self.SeasonID)
+        buf = CommFunc.WriteWORD(buf, self.RoomID)
+        buf = CommFunc.WriteString(buf, sizeof(ctypes.c_char) * 19, self.TimeStr)
+        buf = CommFunc.WriteBYTE(buf, self.OverType)
+        buf = CommFunc.WriteDWORD(buf, self.PlayerID)
+        buf = CommFunc.WriteDWORD(buf, self.WinnerID)
+        buf = CommFunc.WriteBYTE(buf, self.RoundWinnerLen)
+        buf = CommFunc.WriteString(buf, self.RoundWinnerLen, self.RoundWinnerInfo)
+        buf = CommFunc.WriteDWORD(buf, self.PKScore)
+        buf = CommFunc.WriteBYTE(buf, self.DanLV)
+        buf = CommFunc.WriteWORD(buf, self.CWinCount)
+        buf = CommFunc.WriteWORD(buf, self.AddScore)
+        buf = CommFunc.WriteDWORD(buf, self.TagPlayerID)
+        buf = CommFunc.WriteString(buf, sizeof(ctypes.c_char) * 33, self.TagPlayerName)
+        return buf
+
+    def getLength(self):
+        length = 0
+        length += sizeof(ctypes.c_ubyte)
+        length += sizeof(ctypes.c_ubyte)
+        length += sizeof(ctypes.c_ushort)
+        length += sizeof(ctypes.c_char) * 19
+        length += sizeof(ctypes.c_ubyte)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ubyte)
+        length += self.RoundWinnerLen
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ubyte)
+        length += sizeof(ctypes.c_ushort)
+        length += sizeof(ctypes.c_ushort)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_char) * 33
+        return length
+
+    def outputString(self):
+        output = '''// 跨服竞技场未通知玩家的比赛结果表 #tagDBCrossPKUnNotifyOverInfo:
+            ZoneID = %s,
+            SeasonID = %s,
+            RoomID = %s,
+            TimeStr = %s,
+            OverType = %s,
+            PlayerID = %s,
+            WinnerID = %s,
+            RoundWinnerLen = %s,
+            RoundWinnerInfo = %s,
+            PKScore = %s,
+            DanLV = %s,
+            CWinCount = %s,
+            AddScore = %s,
+            TagPlayerID = %s,
+            TagPlayerName = %s,
+            ADOResult = %s,
+            '''%(
+                self.ZoneID,
+                self.SeasonID,
+                self.RoomID,
+                self.TimeStr,
+                self.OverType,
+                self.PlayerID,
+                self.WinnerID,
+                self.RoundWinnerLen,
+                self.RoundWinnerInfo,
+                self.PKScore,
+                self.DanLV,
+                self.CWinCount,
+                self.AddScore,
+                self.TagPlayerID,
+                self.TagPlayerName,
+                self.ADOResult,
+            )
+        return output
+
+    #Char数组类型Set接口,使用该接口对此类型数据赋值,防止赋值的数据过长报错
+    def SetTimeStr(self,Str):
+        if len(Str)<=19:
+            self.TimeStr = Str
+        else:
+            self.TimeStr = Str[:19]
+            
+    def SetTagPlayerName(self,Str):
+        if len(Str)<=33:
+            self.TagPlayerName = Str
+        else:
+            self.TagPlayerName = Str[:33]
+            
+
 # 跨服竞技场PK排行榜 #tagDBCrossPKBillboard
 class tagDBCrossPKBillboard(Structure):
     _pack_ = 1

--
Gitblit v1.8.0