From a9039a33299cc764fb4225a9d49b15d10414cfb8 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期三, 03 七月 2024 15:14:39 +0800
Subject: [PATCH] 10195 【香港】【越南】【主干】【砍树】新增消耗记录(代币获得、消耗记录;后台扣除货币支持扣代币;)

---
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerRecData.py                                               |  107 ++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py                                   |    7 
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py                                                 |    8 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py                               |  184 ++++++++++++++++
 ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py                                                    |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameServerRefresh.py                      |    3 
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py                                                    |  184 ++++++++++++++++
 ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py                                                           |    8 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCoin.py                             |    6 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_GMTDelPlayerMoney.py |    2 
 ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/ClearPlayerRec.py                                         |   58 +++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py                                     |   12 +
 ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py                                                        |    7 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py                          |   16 +
 14 files changed, 580 insertions(+), 25 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py b/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
index 8653068..bb2fa2c 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
@@ -527,6 +527,14 @@
 Def_QueryNoLimit_ActionTypeList = [ShareDefine.Def_ActionType_OfficerModelEquip]
 #------------------------------------------------------------------------------ 
 
+#玩家记录上线需要直接同步给前端的类型
+Def_PlayerRecLoginNotifyList = [ShareDefine.Def_PlayerRecType_PayCoin]
+
+#玩家记录类型每人限制条数,没有配置的类型不限制,由功能自行控制
+Def_PlayerRecCountDict = {
+                          ShareDefine.Def_PlayerRecType_PayCoin:100,
+                          }
+
 #玩家通用信息记录类型保存的条数
 UniversalGameRecTypeSaveCnt = {
                                 ShareDefine.Def_UniversalGameRecType_BossDropGoodItemInfo:100,    #boss掉落好物品信息
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
index 7b77e7d..a78b626 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -424,6 +424,190 @@
 
 
 #------------------------------------------------------
+# A0 08 玩家记录信息 #tagGCPlayerRecInfo
+
+class  tagGCPlayerRec(Structure):
+    Time = 0    #(DWORD Time)//时间
+    Value1 = 0    #(DWORD Value1)//值1
+    Value2 = 0    #(DWORD Value2)//值2
+    Value3 = 0    #(DWORD Value3)//值3
+    Value4 = 0    #(DWORD Value4)//值4
+    Value5 = 0    #(DWORD Value5)//值5
+    Value6 = 0    #(DWORD Value6)//值6
+    Value7 = 0    #(DWORD Value7)//值7
+    Value8 = 0    #(DWORD Value8)//值8
+    UserDataLen = 0    #(WORD UserDataLen)//扩展数据长度
+    UserData = ""    #(String UserData)//扩展数据
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.Time,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value1,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value3,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value4,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value5,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value6,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value7,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value8,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.UserDataLen,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.UserData,_pos = CommFunc.ReadString(_lpData, _pos,self.UserDataLen)
+        return _pos
+
+    def Clear(self):
+        self.Time = 0
+        self.Value1 = 0
+        self.Value2 = 0
+        self.Value3 = 0
+        self.Value4 = 0
+        self.Value5 = 0
+        self.Value6 = 0
+        self.Value7 = 0
+        self.Value8 = 0
+        self.UserDataLen = 0
+        self.UserData = ""
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 2
+        length += len(self.UserData)
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteDWORD(data, self.Time)
+        data = CommFunc.WriteDWORD(data, self.Value1)
+        data = CommFunc.WriteDWORD(data, self.Value2)
+        data = CommFunc.WriteDWORD(data, self.Value3)
+        data = CommFunc.WriteDWORD(data, self.Value4)
+        data = CommFunc.WriteDWORD(data, self.Value5)
+        data = CommFunc.WriteDWORD(data, self.Value6)
+        data = CommFunc.WriteDWORD(data, self.Value7)
+        data = CommFunc.WriteDWORD(data, self.Value8)
+        data = CommFunc.WriteWORD(data, self.UserDataLen)
+        data = CommFunc.WriteString(data, self.UserDataLen, self.UserData)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Time:%d,
+                                Value1:%d,
+                                Value2:%d,
+                                Value3:%d,
+                                Value4:%d,
+                                Value5:%d,
+                                Value6:%d,
+                                Value7:%d,
+                                Value8:%d,
+                                UserDataLen:%d,
+                                UserData:%s
+                                '''\
+                                %(
+                                self.Time,
+                                self.Value1,
+                                self.Value2,
+                                self.Value3,
+                                self.Value4,
+                                self.Value5,
+                                self.Value6,
+                                self.Value7,
+                                self.Value8,
+                                self.UserDataLen,
+                                self.UserData
+                                )
+        return DumpString
+
+
+class  tagGCPlayerRecInfo(Structure):
+    Head = tagHead()
+    Type = 0    #(BYTE Type)//类型
+    Count = 0    #(WORD Count)//数量
+    PlayerRecList = list()    #(vector<tagGCPlayerRec> PlayerRecList)
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xA0
+        self.Head.SubCmd = 0x08
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.Type,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.Count,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        for i in range(self.Count):
+            temPlayerRecList = tagGCPlayerRec()
+            _pos = temPlayerRecList.ReadData(_lpData, _pos)
+            self.PlayerRecList.append(temPlayerRecList)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xA0
+        self.Head.SubCmd = 0x08
+        self.Type = 0
+        self.Count = 0
+        self.PlayerRecList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 1
+        length += 2
+        for i in range(self.Count):
+            length += self.PlayerRecList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.Type)
+        data = CommFunc.WriteWORD(data, self.Count)
+        for i in range(self.Count):
+            data = CommFunc.WriteString(data, self.PlayerRecList[i].GetLength(), self.PlayerRecList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                Type:%d,
+                                Count:%d,
+                                PlayerRecList:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.Type,
+                                self.Count,
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagGCPlayerRecInfo=tagGCPlayerRecInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCPlayerRecInfo.Head.Cmd,m_NAtagGCPlayerRecInfo.Head.SubCmd))] = m_NAtagGCPlayerRecInfo
+
+
+#------------------------------------------------------
 # A0 06 服务器地图线路人数状态 #tagGCPyServerMapState
 
 class  tagGCPyServerMapLineState(Structure):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/ClearPlayerRec.py b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/ClearPlayerRec.py
new file mode 100644
index 0000000..e2fc233
--- /dev/null
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/ClearPlayerRec.py
@@ -0,0 +1,58 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package GM.Commands.ClearPlayerRec
+#
+# @todo:清除玩家记录数据
+# @author hxp
+# @date 2024-07-03
+# @version 1.0
+#
+# 详细描述: 清除玩家记录数据
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2024-07-03 15:30"""
+#-------------------------------------------------------------------------------
+
+import ShareDefine
+import PyDataManager
+import GameWorld
+
+## 执行逻辑
+#  @param curPlayer 当前玩家
+#  @param gmList []
+#  @return None
+def OnExec(curPlayer, gmList):
+    if not gmList:
+        GameWorld.DebugAnswer(curPlayer, "清除类型记录: ClearPlayerRec 记录类型")
+        GameWorld.DebugAnswer(curPlayer, "清除玩家记录: ClearPlayerRec 记录类型 玩家ID")
+        GameWorld.DebugAnswer(curPlayer, "清除指定记录: ClearPlayerRec 记录类型 玩家ID value1 [可选value2~8]")
+        GameWorld.DebugAnswer(curPlayer, "玩家ID为1代表自己,大于1代表指定ID,0为无")
+        GameWorld.DebugAnswer(curPlayer, "2-膜拜记录,3-代币记录")
+        return
+    
+    recType = gmList[0]
+    if recType not in ShareDefine.Def_PlayerRecTypeList:
+        GameWorld.DebugAnswer(curPlayer, "类型不存在")
+        return
+    
+    paramCount = len(gmList)
+    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
+    if paramCount == 1:
+        delCount = playerRecMgr.DelRecDataByType(recType)
+        GameWorld.DebugAnswer(curPlayer, "清除所有玩家记录类型:%s, 条数:%s" % (recType, delCount))
+    elif paramCount == 2:
+        delPlayerID = curPlayer.GetPlayerID() if gmList[1] == 1 else gmList[1]
+        playerRecMgr.DelRecDataByTypePlayer(recType, delPlayerID)
+        GameWorld.DebugAnswer(curPlayer, "清除指定玩家记录类型:%s, ID:%s, 条数:%s" % (recType, delPlayerID, delCount))
+    else:
+        delPlayerID = curPlayer.GetPlayerID() if gmList[1] == 1 else gmList[1]
+        valueList = gmList[2:]
+        playerRecMgr.DelRecDataByTypeValue(recType, valueList, delPlayerID)
+        GameWorld.DebugAnswer(curPlayer, "清除指定玩家记录类型:%s, ID:%s, Value:%s, 条数:%s" % (recType, delPlayerID, valueList, delCount))
+        
+    return
+
+
+
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
index a77a7c1..a274864 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
@@ -75,6 +75,7 @@
 import CrossActAllRecharge
 import CrossYaomoBoss
 import GameWorldMineArea
+import PlayerRecData
 import GameWorship
 #---------------------------------------------------------------------
 
@@ -246,6 +247,8 @@
         CrossActAllRecharge.OnPlayerLogin(curPlayer)
         #跨服妖魔boss
         CrossYaomoBoss.OnPlayerLogin(curPlayer)
+        #玩家记录
+        PlayerRecData.OnPlayerLogin(curPlayer)
         
     if isMixServerFirstLogin:
         PlayerCharm.OnMixServerFirstLogin(curPlayer)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
index 1de01c2..2c85108 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
@@ -87,6 +87,7 @@
 import PlayerTurnFight
 import GameWorldArena
 import GameWorldItem
+import PlayerRecData
 import PlayerAssist
 import PlayerLove
 
@@ -723,6 +724,13 @@
         GameWorldFamilyWar.MapServer_FamilyWarOver(eval(resultName))
         return
     
+    # 增加玩家Rec数据
+    if callName == "AddPlayerRec":
+        curPlayer = None if not srcPlayerID else GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID)
+        recType, valueList, userData, notifyType = eval(resultName)
+        PlayerRecData.MapServer_AddPlayerRec(curPlayer, recType, valueList, userData, notifyType)
+        return
+    
     # 删除通用玩家Rec数据
     if callName == "AddUniversalGameRec":
         curPlayer = None if not srcPlayerID else GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerRecData.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerRecData.py
index 683b67e..a471d0b 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerRecData.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerRecData.py
@@ -15,9 +15,14 @@
 #"""Version = 2024-07-02 16:30"""
 #-------------------------------------------------------------------------------
 
-import CommFunc
+import ChConfig
+import ShareDefine
+import PyDataManager
 import PyGameDataStruct
+import ChPyNetSendPack
+import NetPackCommon
 import GameWorld
+import CommFunc
 
 import time
 
@@ -58,8 +63,8 @@
     def GetUserData(self): return self.dbRecData.UserData
     def SetUserData(self, userData):
         if type(userData) != str:
-            userData = str(userData).replace(" ", "")
-        self.dbRecData.UserData = userData
+            userData = str(userData)
+        self.dbRecData.UserData = userData.replace(" ", "")
         self.dbRecData.UserDataLen = len(self.dbRecData.UserData)
         if self.evalUserData != None:
             self.evalUserData = None
@@ -117,9 +122,12 @@
     
     def DelRecDataByType(self, recType):
         ## 删除某个记录类型所有玩家记录
-        GameWorld.DebugLog("删除所有玩家指定记录类型: recType=%s" % recType)
-        self.recTypeDict.pop(recType, None)
-        return
+        recDict = self.recTypeDict.pop(recType, {})
+        delCount = 0
+        for recList in recDict.values():
+            delCount += len(recList)
+        GameWorld.DebugLog("删除所有玩家指定记录类型: recType=%s,delCount=%s" % (recType, delCount))
+        return delCount
     
     def DelRecDataByTypePlayer(self, recType, delPlayerID):
         ## 删除玩家某个类型记录
@@ -223,17 +231,22 @@
     def GetPlayerRecDataList(self, recType, playerID):
         ## 获取玩家记录类型对应记录列表 [recData, ...]
         if recType not in self.recTypeDict:
-            return []
+            self.recTypeDict[recType] = {}
         playerRecDataDict = self.recTypeDict[recType]
         if playerID not in playerRecDataDict:
-            return []
-        return playerRecDataDict[playerID]
+            playerRecDataDict[playerID] = []
+        playerRecDataList = playerRecDataDict[playerID]
+        return playerRecDataList
     
     def GetPlayerRecDataDict(self, recType):
         ## 获取记录类型对应所有玩家的记录字典 {playerID:[recData, ...], ...}
         if recType not in self.recTypeDict:
             return {}
         return self.recTypeDict[recType]
+    
+    def SortRecDataList(self, recDataList):
+        recDataList.sort(key=lambda r: (r.GetTime()), reverse=False)
+        return
     
     # 保存数据 存数据库和realtimebackup
     def GetSaveData(self):
@@ -269,3 +282,79 @@
         return pos
     
 PlayerRecDataTemp = PlayerRecData()
+
+def OnPlayerLogin(curPlayer):
+    playerID = curPlayer.GetPlayerID()
+    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
+    for recType in ChConfig.Def_PlayerRecLoginNotifyList:
+        recDataList = playerRecMgr.GetPlayerRecDataList(recType, playerID)
+        if not recDataList:
+            continue
+        SyncPlayerRecInfo(curPlayer, recType, recDataList)
+    return
+
+def MapServer_AddPlayerRec(curPlayer, recType, valueList, userData="", notifyType=0):
+    '''
+    @todo: 添加玩家记录
+    @param recType: 通用记录类型, 对应 ShareDefine.Def_PlayerRecTypeList
+    @param valueList: 数值列表[value1, value2, ...], 按顺序, 支持value1 ~ value8
+    @param userData: 自定义字符信息
+    @param notifyType: 0-不通知; 1-通知单条; 2-通知全部
+    '''
+    playerID = curPlayer.GetPlayerID()
+    if recType not in ShareDefine.Def_PlayerRecTypeList:
+        GameWorld.ErrLog("玩家记录类型错误: recType=%s" % recType, playerID)
+        return
+    
+    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
+    recDataList = playerRecMgr.GetPlayerRecDataList(recType, playerID)
+    if recDataList and len(recDataList) >= ChConfig.Def_PlayerRecCountDict.get(recType, 50):
+        playerRecMgr.SortRecDataList(recDataList)
+        recDataList.pop(0) # 删除第一个
+        
+    recData = playerRecMgr.AddPlayerRecData(recType, playerID)
+    
+    for num, value in enumerate(valueList, 1):
+        if num > 8:
+            break
+        getattr(recData, "SetValue%s" % num)(min(ChConfig.Def_UpperLimit_DWord, value))
+        
+    if userData:
+        recData.SetUserData(userData)
+        
+    if notifyType == 1:
+        SyncPlayerRecInfo(curPlayer, recType, [recData])
+    elif notifyType == 2:
+        SyncPlayerRecInfo(curPlayer, recType, recDataList)
+        
+    return recData
+
+def SyncPlayerRecInfo(curPlayer, recType, recDataList):
+    if not recDataList:
+        return
+    
+    playerRecList = []
+    for recData in recDataList:
+        if not recData:
+            continue
+        rec = ChPyNetSendPack.tagGCPlayerRec()
+        rec.Time = recData.GetTime()
+        rec.Value1 = recData.GetValue1()
+        rec.Value2 = recData.GetValue2()
+        rec.Value3 = recData.GetValue3()
+        rec.Value4 = recData.GetValue4()
+        rec.Value5 = recData.GetValue5()
+        rec.Value6 = recData.GetValue6()
+        rec.Value7 = recData.GetValue7()
+        rec.Value8 = recData.GetValue8()
+        rec.UserData = recData.GetUserData()
+        rec.UserDataLen = len(rec.UserData)
+        playerRecList.append(rec)
+        
+    clientPack = ChPyNetSendPack.tagGCPlayerRecInfo()
+    clientPack.Clear()
+    clientPack.Type = recType
+    clientPack.PlayerRecList = playerRecList
+    clientPack.Count = len(clientPack.PlayerRecList)
+    NetPackCommon.SendFakePack(curPlayer, clientPack)
+    return
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
index b0348e2..5158df0 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -1310,11 +1310,8 @@
 Def_PlayerRecTypeList = (
                          Def_PlayerRecType_WorshipPlayer, # 被膜拜的玩家 1
                          Def_PlayerRecType_WorshipDaily, # 玩家每日膜拜记录 2
-                         ) = range(1, 1 + 2)
-
-#玩家记录类型每人限制条数,没有配置的类型不限制,由功能自行控制
-Def_PlayerRecCountDict = {
-                          }
+                         Def_PlayerRecType_PayCoin, # 代币记录 3
+                         ) = range(1, 1 + 3)
 
 #通用信息记录类型
 Def_UniversalGameRecTypeList = (
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index 7b77e7d..a78b626 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -424,6 +424,190 @@
 
 
 #------------------------------------------------------
+# A0 08 玩家记录信息 #tagGCPlayerRecInfo
+
+class  tagGCPlayerRec(Structure):
+    Time = 0    #(DWORD Time)//时间
+    Value1 = 0    #(DWORD Value1)//值1
+    Value2 = 0    #(DWORD Value2)//值2
+    Value3 = 0    #(DWORD Value3)//值3
+    Value4 = 0    #(DWORD Value4)//值4
+    Value5 = 0    #(DWORD Value5)//值5
+    Value6 = 0    #(DWORD Value6)//值6
+    Value7 = 0    #(DWORD Value7)//值7
+    Value8 = 0    #(DWORD Value8)//值8
+    UserDataLen = 0    #(WORD UserDataLen)//扩展数据长度
+    UserData = ""    #(String UserData)//扩展数据
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.Time,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value1,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value3,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value4,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value5,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value6,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value7,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.Value8,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.UserDataLen,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.UserData,_pos = CommFunc.ReadString(_lpData, _pos,self.UserDataLen)
+        return _pos
+
+    def Clear(self):
+        self.Time = 0
+        self.Value1 = 0
+        self.Value2 = 0
+        self.Value3 = 0
+        self.Value4 = 0
+        self.Value5 = 0
+        self.Value6 = 0
+        self.Value7 = 0
+        self.Value8 = 0
+        self.UserDataLen = 0
+        self.UserData = ""
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 4
+        length += 2
+        length += len(self.UserData)
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteDWORD(data, self.Time)
+        data = CommFunc.WriteDWORD(data, self.Value1)
+        data = CommFunc.WriteDWORD(data, self.Value2)
+        data = CommFunc.WriteDWORD(data, self.Value3)
+        data = CommFunc.WriteDWORD(data, self.Value4)
+        data = CommFunc.WriteDWORD(data, self.Value5)
+        data = CommFunc.WriteDWORD(data, self.Value6)
+        data = CommFunc.WriteDWORD(data, self.Value7)
+        data = CommFunc.WriteDWORD(data, self.Value8)
+        data = CommFunc.WriteWORD(data, self.UserDataLen)
+        data = CommFunc.WriteString(data, self.UserDataLen, self.UserData)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Time:%d,
+                                Value1:%d,
+                                Value2:%d,
+                                Value3:%d,
+                                Value4:%d,
+                                Value5:%d,
+                                Value6:%d,
+                                Value7:%d,
+                                Value8:%d,
+                                UserDataLen:%d,
+                                UserData:%s
+                                '''\
+                                %(
+                                self.Time,
+                                self.Value1,
+                                self.Value2,
+                                self.Value3,
+                                self.Value4,
+                                self.Value5,
+                                self.Value6,
+                                self.Value7,
+                                self.Value8,
+                                self.UserDataLen,
+                                self.UserData
+                                )
+        return DumpString
+
+
+class  tagGCPlayerRecInfo(Structure):
+    Head = tagHead()
+    Type = 0    #(BYTE Type)//类型
+    Count = 0    #(WORD Count)//数量
+    PlayerRecList = list()    #(vector<tagGCPlayerRec> PlayerRecList)
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xA0
+        self.Head.SubCmd = 0x08
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.Type,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.Count,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        for i in range(self.Count):
+            temPlayerRecList = tagGCPlayerRec()
+            _pos = temPlayerRecList.ReadData(_lpData, _pos)
+            self.PlayerRecList.append(temPlayerRecList)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xA0
+        self.Head.SubCmd = 0x08
+        self.Type = 0
+        self.Count = 0
+        self.PlayerRecList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 1
+        length += 2
+        for i in range(self.Count):
+            length += self.PlayerRecList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.Type)
+        data = CommFunc.WriteWORD(data, self.Count)
+        for i in range(self.Count):
+            data = CommFunc.WriteString(data, self.PlayerRecList[i].GetLength(), self.PlayerRecList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                Type:%d,
+                                Count:%d,
+                                PlayerRecList:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.Type,
+                                self.Count,
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagGCPlayerRecInfo=tagGCPlayerRecInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCPlayerRecInfo.Head.Cmd,m_NAtagGCPlayerRecInfo.Head.SubCmd))] = m_NAtagGCPlayerRecInfo
+
+
+#------------------------------------------------------
 # A0 06 服务器地图线路人数状态 #tagGCPyServerMapState
 
 class  tagGCPyServerMapLineState(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
index f93743b..ec0ed88 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
@@ -2122,6 +2122,18 @@
     showLV = serverLV if transCnt <= 0 else serverLV - curTransRealLV + curNewLV - curTransTotalSplitLV + curTransAddSplitLV
     return transCnt, showLV
 
+def AddPlayerRec(playerID, recType, valueList, userData="", notifyType=0):
+    '''
+    @todo: 添加玩家记录
+    @param recType: 通用记录类型, 对应 ShareDefine.Def_PlayerRecTypeList
+    @param valueList: 数值列表[value1, value2, ...], 按顺序, 支持value1 ~ value8
+    @param userData: 自定义字符信息
+    @param notifyType: 0-不通知; 1-通知单条; 2-通知全部
+    '''
+    msgStr = str([recType, valueList, userData, notifyType])
+    GetPlayerManager().GameServer_QueryPlayerResult(playerID, 0, 0, "AddPlayerRec", msgStr, len(msgStr))
+    return
+
 def AddUniversalGameRec(playerID, recType, valueList, strValueList, notifyType=0, isSort=1):
     '''
     @todo: 添加GameServer存储通用记录
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameServerRefresh.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameServerRefresh.py
index 00976bb..e078916 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameServerRefresh.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameServerRefresh.py
@@ -719,6 +719,9 @@
 # DB推送过来的充值信息
 def PushRecharge(index, tick):
     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    if not curPlayer or curPlayer.IsEmpty():
+        #可能刚好下线导致玩家对象为空
+        return
     cPlayerCoin = PlayerCoin.CPY_PlayerCoinToGold()
     cPlayerCoin.useCoin = curPlayer.GetOrderAmount()
     cPlayerCoin.orderID = curPlayer.GetOrderID()
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCoin.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCoin.py
index 138af15..ba3e704 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCoin.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCoin.py
@@ -294,7 +294,7 @@
     eventName = addDRDict.get("eventName", "ExchangePayCoin")
     playerID = curPlayer.GetPlayerID()
     befPayCoin = PlayerControl.GetPayCoin(curPlayer)
-    drDict = {ChConfig.Def_Give_Reason_SonKey:orderInfo, "payOrderType":payOrderType}
+    drDict = {ChConfig.Def_Give_Reason_SonKey:orderInfo, "payOrderType":payOrderType, "orderInfo":orderInfo}
     PlayerControl.GiveMoney(curPlayer, ShareDefine.TYPE_Price_PayCoin, orderCoin, eventName, drDict)
     aftPayCoin = PlayerControl.GetPayCoin(curPlayer)
     GameWorld.Log("充值转化为代币: orderInfo=%s,orderCoin=%s,payOrderType=%s,eventName=%s,befPayCoin=%s,aftPayCoin=%s,errorInfo=%s" 
@@ -427,7 +427,7 @@
                     GameWorld.ErrLog("代币可不用于支付代币充值!appID=%s,orderInfo=%s" % (appID, orderInfo), curPlayer.GetPlayerID())
                     return
         #直接扣,类似充值扣钱,这里是发放物品,可能会有发放失败的当做 CTGError 处理
-        if not PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_PayCoin, orderCoin, eventName, {ChConfig.Def_Cost_Reason_SonKey:orderInfo}):
+        if not PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_PayCoin, orderCoin, eventName, {ChConfig.Def_Cost_Reason_SonKey:orderInfo, "orderInfo":orderInfo}):
             GameWorld.ErrLog("代币不足! appID=%s,orderInfo=%s,orderCoin=%s,curPayCoin=%s" 
                              % (appID, orderInfo, orderCoin, PlayerControl.GetPayCoin(curPlayer)), curPlayer.GetPlayerID())
             return
@@ -591,7 +591,7 @@
         playerID = curPlayer.GetPlayerID()
         befPayCoin = PlayerControl.GetPayCoin(curPlayer)
         if addGold and moneyType == ShareDefine.TYPE_Price_PayCoin:
-            drDict = {ChConfig.Def_Give_Reason_SonKey:orderInfo, "payOrderType":payOrderType}
+            drDict = {ChConfig.Def_Give_Reason_SonKey:orderInfo, "payOrderType":payOrderType, "orderInfo":orderInfo}
             PlayerControl.GiveMoney(curPlayer, moneyType, addGold, eventName, drDict)
         aftPayCoin = PlayerControl.GetPayCoin(curPlayer)
         GameWorld.Log("充值代币: orderInfo=%s,orderCoin=%s,payOrderType=%s,eventName=%s,befPayCoin=%s,aftPayCoin=%s" 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
index c85fd31..a5bd730 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -3283,7 +3283,12 @@
     DataRecordPack.DR_UseMoney(curPlayer, eventName, type_Price, price, infoDict) # 流向
     EventReport.WriteEvent_virtual_resource(curPlayer, type_Price, reason_name, quantity,
                                             unitPrice, ShareDefine.Def_UserAction_Money_Use, infoDict)
-            
+    if type_Price == ShareDefine.TYPE_Price_PayCoin:
+        playerID = curPlayer.GetPlayerID()
+        nowMoney = GetMoneyReal(curPlayer, type_Price)
+        orderInfo = infoDict.get("orderInfo", "")
+        GameWorld.Log("记录消耗代币: eventName=%s,price=%s,nowMoney=%s,orderInfo=%s" % (eventName, price, nowMoney, orderInfo), playerID)
+        GameWorld.AddPlayerRec(playerID, ShareDefine.Def_PlayerRecType_PayCoin, [2, price, nowMoney], orderInfo, 1)
     #===========================================================================
     # if type_Price == IPY_GameWorld.TYPE_Price_Gold_Money:
     #    EventReport.WriteEvent_virtual_cost(curPlayer, quantity, unitPrice, reason_name)
@@ -3485,7 +3490,7 @@
     
     EventShell.EventRespons_OnMoneyChange(curPlayer, priceType)
     
-    if priceType not in [IPY_GameWorld.TYPE_Price_Gold_Money, IPY_GameWorld.TYPE_Price_Gold_Paper] \
+    if priceType not in [IPY_GameWorld.TYPE_Price_Gold_Money, IPY_GameWorld.TYPE_Price_Gold_Paper, ShareDefine.TYPE_Price_PayCoin] \
         and giveType == ChConfig.Def_GiveMoney_Unknown:
         #GameWorld.DebugLog("该货币没有指定来源类型不记录!priceType=%s,giveType=%s" % (priceType, giveType))
         return
@@ -3497,6 +3502,13 @@
     DataRecordPack.DR_GiveMoney(curPlayer, eventName, priceType, value, addDataDict)
     EventReport.WriteEvent_virtual_resource(curPlayer, priceType, giveType, 1, value,
                                             ShareDefine.Def_UserAction_Money_Get, addDataDict)
+    
+    if priceType == ShareDefine.TYPE_Price_PayCoin:
+        playerID = curPlayer.GetPlayerID()
+        nowMoney = GetMoneyReal(curPlayer, priceType)
+        orderInfo = addDataDict.get("orderInfo", "")
+        GameWorld.Log("记录获得代币: eventName=%s,value=%s,nowMoney=%s,orderInfo=%s" % (eventName, value, nowMoney, orderInfo), playerID)
+        GameWorld.AddPlayerRec(playerID, ShareDefine.Def_PlayerRecType_PayCoin, [1, value, nowMoney], orderInfo, 1)
 #===============================================================================
 #    reason_name = "Unknown" if not giveType else giveType
 #    eventName = reason_name
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_GMTDelPlayerMoney.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_GMTDelPlayerMoney.py
index b28e886..5369aae 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_GMTDelPlayerMoney.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_GMTDelPlayerMoney.py
@@ -41,7 +41,7 @@
     
     retMsg = ""
     Result = GMCommon.Def_Success
-    if moneyType not in [1, 2, 3, 4] and moneyType not in ShareDefine.TYPE_Price_CurrencyDict:
+    if moneyType not in [1, 2, 3, 4, ShareDefine.TYPE_Price_PayCoin] and moneyType not in ShareDefine.TYPE_Price_CurrencyDict:
         Result = GMCommon.Def_MoneyTypeErr
     elif not moneyValue:
         Result = GMCommon.Def_ParamErr
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
index b0348e2..5158df0 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -1310,11 +1310,8 @@
 Def_PlayerRecTypeList = (
                          Def_PlayerRecType_WorshipPlayer, # 被膜拜的玩家 1
                          Def_PlayerRecType_WorshipDaily, # 玩家每日膜拜记录 2
-                         ) = range(1, 1 + 2)
-
-#玩家记录类型每人限制条数,没有配置的类型不限制,由功能自行控制
-Def_PlayerRecCountDict = {
-                          }
+                         Def_PlayerRecType_PayCoin, # 代币记录 3
+                         ) = range(1, 1 + 3)
 
 #通用信息记录类型
 Def_UniversalGameRecTypeList = (

--
Gitblit v1.8.0