From a90833bf05d8f4a338b0224a956a3794c106bb48 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期四, 06 二月 2025 17:04:41 +0800
Subject: [PATCH] 10385 【越南】【英语】【BT】【砍树】福地新增鼠管及优化-服务端

---
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorship.py                 |    6 
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerRecData.py                       |   26 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py           |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py           |   56 +++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py       |   25 ++
 ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/MineArea.py                       |   30 ++
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py                                |   56 +++++
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py                            |   25 ++
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py           |  177 +++++++++++------
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini                   |    6 
 ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py                                   |    1 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MineArea.py  |   25 +
 ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py                                |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMineArea.py |  139 +++++++++++--
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py              |    1 
 15 files changed, 461 insertions(+), 118 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py b/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
index 365de47..bf17296 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
@@ -537,6 +537,7 @@
 #DBPlayerRecData、DBGameRecData表中UserData数据通用自定义key
 Def_RecDataKey_ServerIDList = "ServerIDList"
 Def_RecDataKey_PlayerInfo = "PlayerInfo"
+Def_RecDataKey_RobValueList = "RobValueList"
 
 #玩家记录上线需要直接同步给前端的类型
 Def_PlayerRecLoginNotifyList = [ShareDefine.Def_PlayerRecType_PayCoin]
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
index c8eb3c2..6a0e5ab 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
@@ -18496,6 +18496,54 @@
 
 
 #------------------------------------------------------
+# B0 35 福地管家免费试用 #tagCMMineHouseKeeperFreeUse
+
+class  tagCMMineHouseKeeperFreeUse(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB0
+        self.SubCmd = 0x35
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB0
+        self.SubCmd = 0x35
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMMineHouseKeeperFreeUse)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B0 35 福地管家免费试用 //tagCMMineHouseKeeperFreeUse:
+                                Cmd:%s,
+                                SubCmd:%s
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd
+                                )
+        return DumpString
+
+
+m_NAtagCMMineHouseKeeperFreeUse=tagCMMineHouseKeeperFreeUse()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMMineHouseKeeperFreeUse.Cmd,m_NAtagCMMineHouseKeeperFreeUse.SubCmd))] = m_NAtagCMMineHouseKeeperFreeUse
+
+
+#------------------------------------------------------
 # B0 30 福地物品拉 #tagCMMineItemPull
 
 class  tagCMMineItemPull(Structure):
@@ -18567,7 +18615,7 @@
     _fields_ = [
                   ("Cmd", c_ubyte),
                   ("SubCmd", c_ubyte),
-                  ("IsSuper", c_ubyte),    # 是否超级刷新
+                  ("RefreshType", c_ubyte),    # 刷新类型:0-自己物品普通刷新;1-自己物品超级刷新;2-周围福地玩家列表刷新
                   ]
 
     def __init__(self):
@@ -18584,7 +18632,7 @@
     def Clear(self):
         self.Cmd = 0xB0
         self.SubCmd = 0x31
-        self.IsSuper = 0
+        self.RefreshType = 0
         return
 
     def GetLength(self):
@@ -18597,12 +18645,12 @@
         DumpString = '''// B0 31 福地物品刷新 //tagCMMineItemRefresh:
                                 Cmd:%s,
                                 SubCmd:%s,
-                                IsSuper:%d
+                                RefreshType:%d
                                 '''\
                                 %(
                                 self.Cmd,
                                 self.SubCmd,
-                                self.IsSuper
+                                self.RefreshType
                                 )
         return DumpString
 
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
index 2866d99..1fdc316 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -8695,6 +8695,7 @@
     Job = 0    #(BYTE Job)
     Face = 0    #(DWORD Face)
     FacePic = 0    #(DWORD FacePic)
+    RobValue = 0    #(DWORD RobValue)// 抢劫敌对值
     MineCount = 0    #(BYTE MineCount)
     MineItemList = list()    #(vector<tagGCMineItem> MineItemList)// 矿物列表
     data = None
@@ -8710,6 +8711,7 @@
         self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
         self.Face,_pos = CommFunc.ReadDWORD(_lpData, _pos)
         self.FacePic,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.RobValue,_pos = CommFunc.ReadDWORD(_lpData, _pos)
         self.MineCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
         for i in range(self.MineCount):
             temMineItemList = tagGCMineItem()
@@ -8723,6 +8725,7 @@
         self.Job = 0
         self.Face = 0
         self.FacePic = 0
+        self.RobValue = 0
         self.MineCount = 0
         self.MineItemList = list()
         return
@@ -8732,6 +8735,7 @@
         length += 4
         length += 33
         length += 1
+        length += 4
         length += 4
         length += 4
         length += 1
@@ -8747,6 +8751,7 @@
         data = CommFunc.WriteBYTE(data, self.Job)
         data = CommFunc.WriteDWORD(data, self.Face)
         data = CommFunc.WriteDWORD(data, self.FacePic)
+        data = CommFunc.WriteDWORD(data, self.RobValue)
         data = CommFunc.WriteBYTE(data, self.MineCount)
         for i in range(self.MineCount):
             data = CommFunc.WriteString(data, self.MineItemList[i].GetLength(), self.MineItemList[i].GetBuffer())
@@ -8759,6 +8764,7 @@
                                 Job:%d,
                                 Face:%d,
                                 FacePic:%d,
+                                RobValue:%d,
                                 MineCount:%d,
                                 MineItemList:%s
                                 '''\
@@ -8768,6 +8774,7 @@
                                 self.Job,
                                 self.Face,
                                 self.FacePic,
+                                self.RobValue,
                                 self.MineCount,
                                 "..."
                                 )
@@ -51533,11 +51540,13 @@
     EnergyUsed = 0    #(WORD EnergyUsed)// 今日已消耗体力
     RefreshCount = 0    #(DWORD RefreshCount)// 今日福地刷新物品次数 - 普通刷新
     RefreshCountSuper = 0    #(BYTE RefreshCountSuper)// 今日福地刷新物品次数 - 超级刷新
+    RefreshCountRob = 0    #(WORD RefreshCountRob)// 今日福地刷新周围玩家次数
     TreasureCount = 0    #(BYTE TreasureCount)// 聚宝盆类型个数,对应类型 0~n
     TreasureState = list()    #(vector<BYTE> TreasureState)// 聚宝盆是否已激活列表,[类型0是否已激活, ...]
     TreasureAward = list()    #(vector<BYTE> TreasureAward)// 聚宝盆奖励是否已领取列表,[类型0是否已领取, ...]
     TreasureProgress = list()    #(vector<BYTE> TreasureProgress)// 聚宝盆进度值列表,[类型0进度值, ...],满进度100
     HelpAwardCount = 0    #(BYTE HelpAwardCount)// 今日已帮助别人奖励次数
+    HousekeeperEndTime = 0    #(DWORD HousekeeperEndTime)// 自动管家到期时间戳,有值同时也代表免费试用已使用
     data = None
 
     def __init__(self):
@@ -51553,6 +51562,7 @@
         self.EnergyUsed,_pos = CommFunc.ReadWORD(_lpData, _pos)
         self.RefreshCount,_pos = CommFunc.ReadDWORD(_lpData, _pos)
         self.RefreshCountSuper,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.RefreshCountRob,_pos = CommFunc.ReadWORD(_lpData, _pos)
         self.TreasureCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
         for i in range(self.TreasureCount):
             value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
@@ -51564,6 +51574,7 @@
             value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
             self.TreasureProgress.append(value)
         self.HelpAwardCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.HousekeeperEndTime,_pos = CommFunc.ReadDWORD(_lpData, _pos)
         return _pos
 
     def Clear(self):
@@ -51575,11 +51586,13 @@
         self.EnergyUsed = 0
         self.RefreshCount = 0
         self.RefreshCountSuper = 0
+        self.RefreshCountRob = 0
         self.TreasureCount = 0
         self.TreasureState = list()
         self.TreasureAward = list()
         self.TreasureProgress = list()
         self.HelpAwardCount = 0
+        self.HousekeeperEndTime = 0
         return
 
     def GetLength(self):
@@ -51589,11 +51602,13 @@
         length += 2
         length += 4
         length += 1
+        length += 2
         length += 1
         length += 1 * self.TreasureCount
         length += 1 * self.TreasureCount
         length += 1 * self.TreasureCount
         length += 1
+        length += 4
 
         return length
 
@@ -51604,6 +51619,7 @@
         data = CommFunc.WriteWORD(data, self.EnergyUsed)
         data = CommFunc.WriteDWORD(data, self.RefreshCount)
         data = CommFunc.WriteBYTE(data, self.RefreshCountSuper)
+        data = CommFunc.WriteWORD(data, self.RefreshCountRob)
         data = CommFunc.WriteBYTE(data, self.TreasureCount)
         for i in range(self.TreasureCount):
             data = CommFunc.WriteBYTE(data, self.TreasureState[i])
@@ -51612,6 +51628,7 @@
         for i in range(self.TreasureCount):
             data = CommFunc.WriteBYTE(data, self.TreasureProgress[i])
         data = CommFunc.WriteBYTE(data, self.HelpAwardCount)
+        data = CommFunc.WriteDWORD(data, self.HousekeeperEndTime)
         return data
 
     def OutputString(self):
@@ -51621,11 +51638,13 @@
                                 EnergyUsed:%d,
                                 RefreshCount:%d,
                                 RefreshCountSuper:%d,
+                                RefreshCountRob:%d,
                                 TreasureCount:%d,
                                 TreasureState:%s,
                                 TreasureAward:%s,
                                 TreasureProgress:%s,
-                                HelpAwardCount:%d
+                                HelpAwardCount:%d,
+                                HousekeeperEndTime:%d
                                 '''\
                                 %(
                                 self.Head.OutputString(),
@@ -51633,11 +51652,13 @@
                                 self.EnergyUsed,
                                 self.RefreshCount,
                                 self.RefreshCountSuper,
+                                self.RefreshCountRob,
                                 self.TreasureCount,
                                 "...",
                                 "...",
                                 "...",
-                                self.HelpAwardCount
+                                self.HelpAwardCount,
+                                self.HousekeeperEndTime
                                 )
         return DumpString
 
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/MineArea.py b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/MineArea.py
index 6d0c928..8f60b30 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/MineArea.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/MineArea.py
@@ -19,6 +19,8 @@
 import PyDataManager
 import GameWorldMineArea
 import IpyGameDataPY
+import ShareDefine
+import ChConfig
 
 import time
 
@@ -34,6 +36,7 @@
         GameWorld.DebugAnswer(curPlayer, "随机重新刷新: MineArea item [是否超级 坐标 索引 福地玩家ID]")
         GameWorld.DebugAnswer(curPlayer, "刷新指定等级: MineArea lv 等级 [坐标 索引 福地玩家ID]")
         GameWorld.DebugAnswer(curPlayer, "刷新指定物品: MineArea id 矿物ID [坐标 索引 福地玩家ID]")
+        GameWorld.DebugAnswer(curPlayer, "设置敌对玩家: MineArea rv 敌对玩家ID 正负敌对值")
         GameWorld.DebugAnswer(curPlayer, "派工人拉物品: MineArea pull 索引 人数 状态")
         GameWorld.DebugAnswer(curPlayer, "[工人玩家ID 福地玩家ID]")
         GameWorld.DebugAnswer(curPlayer, "输出在拉物品: MineArea pulling [玩家ID]")
@@ -85,6 +88,19 @@
         areaPlayer = curPlayer if areaPlayerID == playerID else GameWorld.GetPlayerManager().FindPlayerByID(areaPlayerID)
         refreshDict = GameWorldMineArea.__DoMineItemRefresh(areaPlayerID, areaPlayer, refreshIndexList=refreshIndexList, setPosition=position, setMineID=mineID)
         __PrintRefreshDict(curPlayer, refreshDict, "指定ID:%s" % mineID)
+        
+    # 设置敌对玩家
+    elif value1 == "rv":
+        tagPlayerID = msgList[1] if len(msgList) > 1 else 0
+        addValue = msgList[2] if len(msgList) > 2 else 1
+        if not tagPlayerID or playerID == tagPlayerID:
+            GameWorld.DebugAnswer(curPlayer, "敌对ID为0或自己:%s" % tagPlayerID)
+            return
+        if addValue > 0:
+            robValue = GameWorldMineArea.AddRobValue(playerID, tagPlayerID, addValue)
+        else:
+            robValue = GameWorldMineArea.DecRobValue(playerID, tagPlayerID, -addValue)
+        GameWorld.DebugAnswer(curPlayer, "更新与对方敌对值:%s, ID:%s" % (robValue, tagPlayerID))
         
     # 派工人拉物品
     elif value1 == "pull":
@@ -226,12 +242,14 @@
     for playerID, neighborIDList in mineItemMgr.neighborIDListDict.items():
         GameWorld.DebugLog("周围福地列表: playerID=%s,neighborIDList=%s" % (playerID, neighborIDList))
         GameWorld.DebugAnswer(curPlayer, "周围福地列表:%s,%s" % (playerID, neighborIDList), False)
-    for playerID, socialIDList in mineItemMgr.socialIDListDict.items():
-        GameWorld.DebugLog("道友福地列表: playerID=%s,socialIDList=%s" % (playerID, socialIDList))
-        GameWorld.DebugAnswer(curPlayer, "道友福地列表:%s" % (playerID), False)
-        GameWorld.DebugAnswer(curPlayer, " %s" % socialIDList[:len(socialIDList)/2], False)
-        GameWorld.DebugAnswer(curPlayer, " %s" % socialIDList[len(socialIDList)/2:], False)
-        
+    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
+    recDataDict = playerRecMgr.GetPlayerRecDataDict(ShareDefine.Def_PlayerRecType_MineAreaRecord)
+    for playerID, recDataList in recDataDict.items():
+        for recData in recDataList:
+            robValueList = recData.GetUserDataByKey(ChConfig.Def_RecDataKey_RobValueList, {})
+            GameWorld.DebugLog("敌对福地列表: playerID=%s,robValueList=%s" % (playerID, robValueList))
+            GameWorld.DebugAnswer(curPlayer, "敌对福地列表:%s,%s" % (playerID, robValueList), False)
+            
     for areaPlayerID, viewPlayerIDList in mineItemMgr.viewAreaPlayerIDDict.items():
         GameWorld.DebugLog("查看福地列表: areaPlayerID=%s,viewPlayerIDList=%s" % (areaPlayerID, viewPlayerIDList))
         GameWorld.DebugAnswer(curPlayer, "查看福地列表:%s,%s" % (areaPlayerID, viewPlayerIDList), False)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py
index ff7dc79..c576759 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py
@@ -15,6 +15,7 @@
 #"""Version = 2024-03-07 19:30"""
 #-------------------------------------------------------------------------------
 
+import ChConfig
 import GameWorld
 import NetPackCommon
 import PyDataManager
@@ -165,7 +166,6 @@
         self.viewAreaPlayerIDDict = {} # 正在查看某个福地中的玩家ID {areaPlayerID:[viewPlayerID, ...], ...}
         
         self.neighborIDListDict = {} # 玩家周围福地玩家ID列表 {playerID:[playerID, ...], ...}
-        self.socialIDListDict = {} # 玩家有关系道友福地玩家ID列表 {playerID:[playerID, ...], ...} playerID列表倒序
         return
     
     def AddViewAreaPlayerID(self, viewPlayerID, areaPlayerID):
@@ -701,6 +701,8 @@
     AddMineItemRecord(awardPlayerID, MineAreaRecordType_Pull, areaPlayerID, mineID, curTime)
     if areaPlayerID != awardPlayerID:
         AddMineItemRecord(areaPlayerID, MineAreaRecordType_BeRobbed, awardPlayerID, mineID, curTime)
+        DecRobValue(awardPlayerID, areaPlayerID, 1)
+        AddRobValue(areaPlayerID, awardPlayerID, 1)
         
         # 被抢的
         if IpyGameDataPY.GetFuncCfg("MineAreaSysRefresh", 3) > 0:
@@ -736,60 +738,98 @@
     recordMgr = PyDataManager.GetDBPyMineAreaRecordManager()
     recordList = recordMgr.AddPlayerRecord(recordData)
     
-    # 被人抢,更新关系福地ID记录
-    if recordData.RecordType == MineAreaRecordType_BeRobbed:
-        __DoUpdSocialPlayerIDList(playerID)
-    
     if len(recordList) > Def_RecordMax:
         recordList.pop(0) # 删除最早一条
     return
 
-def __DoUpdSocialPlayerIDList(playerID):
-    ## 更新有关系的道友ID列表
-    recordMgr = PyDataManager.GetDBPyMineAreaRecordManager()
-    recordList = recordMgr.playerMineRecordListDict.get(playerID, [])
-    
-    socialAreaMax = IpyGameDataPY.GetFuncCfg("MineAreaRob", 1) # 道友福地个数
-    socialIDList = [] # 反序
-    for recData in recordList[::-1]:
-        if recData.RecordType != MineAreaRecordType_BeRobbed:
-            ## 优先保留被抢记录关系玩家
+def DecRobValue(playerID, tagPlayerID, decValue):
+    ## 减少敌对值
+    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
+    robRecData = playerRecMgr.GetPlayerRecDataFirst(ShareDefine.Def_PlayerRecType_MineAreaRecord, playerID, False)
+    if not robRecData:
+        GameWorld.DebugLog("没有敌对福地记录!", playerID)
+        return 0
+    # 抢劫的人减少与对方敌对值
+    setRobValue = 0
+    robValueList = robRecData.GetUserDataByKey(ChConfig.Def_RecDataKey_RobValueList, [])
+    GameWorld.DebugLog("减少与对方敌对值: tagPlayerID=%s,decValue=%s" % (tagPlayerID, decValue), playerID)
+    GameWorld.DebugLog("    bef robValueList=%s" % robValueList, playerID)
+    for index, robValueInfo in enumerate(robValueList):
+        robValue, pID = robValueInfo
+        if pID != tagPlayerID:
             continue
-        if recData.TagPlayerID not in socialIDList:
-            socialIDList.append(recData.TagPlayerID)
-            if len(socialIDList) >= socialAreaMax:
-                break
-            
-    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
-    socialIDListBef = mineItemMgr.socialIDListDict.get(playerID, [])
-    # 优先使用历史记录
-    if len(socialIDList) < socialAreaMax:
-        for socialIDBef in socialIDListBef:
-            if socialIDBef not in socialIDList:
-                socialIDList.append(socialIDBef)
-                if len(socialIDList) >= socialAreaMax:
-                    break
-                
-    # 优先随机真人
-    if len(socialIDList) < socialAreaMax and mineItemMgr.realAreaPlayerIDList:
-        random.shuffle(mineItemMgr.realAreaPlayerIDList)
-        for areaPlayerID in mineItemMgr.realAreaPlayerIDList:
-            if areaPlayerID not in socialIDList and areaPlayerID != playerID:
-                socialIDList.append(areaPlayerID)
-                if len(socialIDList) >= socialAreaMax:
-                    break
-                
-    # 不够补充假人
-    if len(socialIDList) < socialAreaMax and mineItemMgr.fackAreaPlayerIDList:
-        random.shuffle(mineItemMgr.fackAreaPlayerIDList)
-        for areaPlayerID in mineItemMgr.fackAreaPlayerIDList:
-            if areaPlayerID not in socialIDList:
-                socialIDList.append(areaPlayerID)
-                if len(socialIDList) >= socialAreaMax:
-                    break
-                
-    mineItemMgr.socialIDListDict[playerID] = socialIDList
-    return socialIDList
+        robValue -= decValue
+        GameWorld.DebugLog("    tagPlayerID=%s,更新敌对值=%s" % (tagPlayerID, robValue), playerID)
+        if robValue <= 0:
+            robValueList.pop(index)
+        else:
+            robValueList[index] = [robValue, pID]
+        setRobValue = robValue
+        robRecData.SetUserDataByKey(ChConfig.Def_RecDataKey_RobValueList, robValueList, True)
+        break
+    
+    robValueList = robRecData.GetUserDataByKey(ChConfig.Def_RecDataKey_RobValueList, [])
+    GameWorld.DebugLog("    aft robValueList=%s" % robValueList, playerID)
+    return setRobValue
+
+def AddRobValue(playerID, tagPlayerID, addValue):
+    ## 被抢的人增加与对方敌对值,并置顶
+    
+    if playerID <= Def_FakeAreaCount:
+        return 0
+    
+    GameWorld.DebugLog("增加与对方敌对值: tagPlayerID=%s,addValue=%s" % (tagPlayerID, addValue), playerID)
+    setRobValue = 0
+    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
+    robRecData = playerRecMgr.GetPlayerRecDataFirst(ShareDefine.Def_PlayerRecType_MineAreaRecord, playerID, True)
+    robValueList = robRecData.GetUserDataByKey(ChConfig.Def_RecDataKey_RobValueList, [])
+    GameWorld.DebugLog("    bef robValueList=%s" % robValueList, playerID)
+    for index, robValueInfo in enumerate(robValueList):
+        robValue, pID = robValueInfo
+        if pID != tagPlayerID:
+            continue
+        robValueList.pop(index)
+        setRobValue = robValue
+        break
+    setRobValue += addValue
+    GameWorld.DebugLog("    tagPlayerID=%s,更新敌对值=%s" % (tagPlayerID, setRobValue), playerID)
+    
+    robValueList.insert(0, [setRobValue, tagPlayerID])
+    robRecData.SetUserDataByKey(ChConfig.Def_RecDataKey_RobValueList, robValueList)
+    
+    robValueList = robRecData.GetUserDataByKey(ChConfig.Def_RecDataKey_RobValueList, [])
+    GameWorld.DebugLog("    aft robValueList=%s" % robValueList, playerID)    
+    return setRobValue
+
+def GetRobPlayerIDList(playerID):
+    ## 获取敌对玩家ID列表
+    if playerID <= Def_FakeAreaCount:
+        return []
+    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
+    robRecData = playerRecMgr.GetPlayerRecDataFirst(ShareDefine.Def_PlayerRecType_MineAreaRecord, playerID, False)
+    if not robRecData:
+        return []
+    robIDList = []
+    rPlayerRobValueList = robRecData.GetUserDataByKey(ChConfig.Def_RecDataKey_RobValueList, [])
+    for robValueInfo in rPlayerRobValueList:
+        _, pID = robValueInfo
+        robIDList.append(pID)
+    return robIDList
+
+def GetRobValueDict(playerID):
+    ## 获取敌对玩家敌对值字典
+    if playerID <= Def_FakeAreaCount:
+        return {}
+    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
+    robRecData = playerRecMgr.GetPlayerRecDataFirst(ShareDefine.Def_PlayerRecType_MineAreaRecord, playerID, False)
+    if not robRecData:
+        return {}
+    robValueDict = {}
+    rPlayerRobValueList = robRecData.GetUserDataByKey(ChConfig.Def_RecDataKey_RobValueList, [])
+    for robValueInfo in rPlayerRobValueList:
+        robValue, pID = robValueInfo
+        robValueDict[pID] = robValue
+    return robValueDict
 
 def OnTurnFightRequest(curPlayer, mapID, funcLineID, tagPlayerID, valueList):
     
@@ -914,6 +954,12 @@
     # 地图结算奖励OK
     elif msgType == "MineAreaAwardGetOK":
         __DoMineAreaAwardGetOK(curPlayer, dataMsg)
+        
+    # 刷新周围玩家
+    elif msgType == "MineRobRefresh":
+        tick = GameWorld.GetGameWorld().GetTick()
+        queryType, queryValue = 3, 1
+        SyncNeighborAreaInfo(curPlayer, tick, queryType, queryValue)
         
     if ret == None:
         return
@@ -1195,6 +1241,7 @@
                 
     # 查看周围随机福地列表
     elif queryType == 3:
+        queryValue = 0 # GameServer默认只给查询,刷新列表改为从MapServer发起 B0 31 福地物品刷新 #tagCMMineItemRefresh 请求
         SyncNeighborAreaInfo(curPlayer, tick, queryType, queryValue)
         
     # 退出他人福地
@@ -1224,9 +1271,9 @@
         notifyPlayerIDList.append(areaPlayerID)
         
     # 列表中
-    for playerID, socialIDList in mineItemMgr.socialIDListDict.items():
-        if areaPlayerID in socialIDList:
-            notifyPlayerIDList.append(playerID)
+    robPlayerIDList = GetRobPlayerIDList(areaPlayerID)
+    if robPlayerIDList:
+        notifyPlayerIDList += robPlayerIDList
     for playerID, neighborIDList in mineItemMgr.neighborIDListDict.items():
         if areaPlayerID in neighborIDList:
             notifyPlayerIDList.append(playerID)
@@ -1263,16 +1310,12 @@
     return
 
 def SyncSocialAreaInfo(curPlayer, queryType=0, queryValue=0):
-    ## 同步有关系的道友福地列表
+    ## 同步有关系的道友福地列表 - 敌对列表
     playerID = curPlayer.GetPlayerID()
-    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
-    if playerID in mineItemMgr.socialIDListDict:
-        socialIDList = mineItemMgr.socialIDListDict[playerID]
-    else:
-        socialIDList = __DoUpdSocialPlayerIDList(playerID)
-        
+    socialIDList = GetRobPlayerIDList(playerID)
+    robValueDict = GetRobValueDict(playerID)
     areaMineList = [[areaPlayerID, []] for areaPlayerID in socialIDList]
-    clientPack = __GetMineAreaInfoPack(areaMineList, queryType, queryValue)
+    clientPack = __GetMineAreaInfoPack(areaMineList, queryType, queryValue, robValueDict)
     NetPackCommon.SendFakePack(curPlayer, clientPack)
     return
 
@@ -1305,9 +1348,14 @@
             if neighborIDBef in areaPlayerIDList:
                 areaPlayerIDList.remove(neighborIDBef)
         neighborCount = IpyGameDataPY.GetFuncCfg("MineAreaRob", 2)
+        realmLV = curPlayer.GetOfficialRank()
+        officialNeighborCountList = IpyGameDataPY.GetFuncEvalCfg("MineAreaRob2", 1)
+        for needRLV, nCount in officialNeighborCountList:
+            if realmLV >= needRLV:
+                neighborCount = nCount
         neighborIDList = areaPlayerIDList[:neighborCount]
         mineItemMgr.neighborIDListDict[playerID] = neighborIDList
-        GameWorld.DebugLog("刷新周围随机福地: %s" % neighborIDList, playerID)
+        GameWorld.DebugLog("刷新周围随机福地: realmLV=%s,neighborCount=%s,%s" % (realmLV, neighborCount, neighborIDList), playerID)
         
     areaMineList = [[areaPlayerID, []] for areaPlayerID in neighborIDList]
     clientPack = __GetMineAreaInfoPack(areaMineList, queryType, queryValue)
@@ -1338,7 +1386,7 @@
     NetPackCommon.SendFakePack(curPlayer, clientPack)
     return
 
-def __GetMineAreaInfoPack(areaMineList, queryType=0, queryValue=0):
+def __GetMineAreaInfoPack(areaMineList, queryType=0, queryValue=0, robValueDict=None):
     ''' 获取同步福地详细信息包
     @param areaMineList: [[areaPlayerID, mineIndexList], ...] 按指定福地ID顺序列表获取,mineIndexList为空时同步该福地全部物品,否则只同步指定索引物品
     '''
@@ -1356,7 +1404,8 @@
             areaInfo.Job = cacheDict.get("Job", 0)
             areaInfo.Face = cacheDict.get("Face", 0)
             areaInfo.FacePic = cacheDict.get("FacePic", 0)
-                    
+            areaInfo.RobValue = robValueDict.get(areaPlayerID, 0) if robValueDict else 0 # 敌对值,前端仅queryType为2时才更新敌对值
+            
         areaInfo.MineItemList = []
         if not mineIndexList:
             mineIndexList = range(IpyGameDataPY.GetFuncCfg("MineAreaBase", 1))
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorship.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorship.py
index 1924699..8ab7b09 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorship.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorship.py
@@ -43,6 +43,8 @@
 # 今日已膜拜记录 {tagPlayerID:[[膜拜类型, 膜拜值], ...], ...}
 # 今日是否已膜拜过该玩家某个膜拜
 def HasWorshipRecordToday(recData, tagPlayerID, worshipType, worshipValue):
+    if not recData:
+        return False
     worshipRecordList = recData.GetUserDataByKey(tagPlayerID, [])
     if not worshipRecordList:
         return False
@@ -269,7 +271,7 @@
     GameWorld.DebugLog("膜拜: tagPlayerID=%s,worshipType=%s,worshipValue=%s,moneyType=%s,moneyValue=%s" 
                        % (tagPlayerID, worshipType, worshipValue, moneyType, moneyValue), playerID)
     playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
-    worshipRecData = playerRecMgr.GetPlayerRecDataFirst(ShareDefine.Def_PlayerRecType_WorshipDaily, playerID)
+    worshipRecData = playerRecMgr.GetPlayerRecDataFirst(ShareDefine.Def_PlayerRecType_WorshipDaily, playerID, True)
     SetWorshipRecordToday(worshipRecData, tagPlayerID, worshipType, worshipValue)
     
     __SyncWorshipResult(curPlayer, tagPlayerID, worshipType, worshipValue, 0, moneyType, moneyValue)
@@ -306,7 +308,7 @@
             return
         
     playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
-    worshipRecData = playerRecMgr.GetPlayerRecDataFirst(ShareDefine.Def_PlayerRecType_WorshipDaily, playerID)
+    worshipRecData = playerRecMgr.GetPlayerRecDataFirst(ShareDefine.Def_PlayerRecType_WorshipDaily, playerID, False)
     if HasWorshipRecordToday(worshipRecData, recPlayerID, worshipType, worshipValue):
         GameWorld.DebugLog("今日已膜拜过! recPlayerID=%s,worshipType=%s, worshipValue=%s" % (recPlayerID, worshipType, worshipValue), playerID)
         return
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerRecData.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerRecData.py
index fbe659c..05dcaea 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerRecData.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerRecData.py
@@ -74,9 +74,17 @@
         if key in userDataDict:
             return userDataDict[key]
         return defaultValue
-    def SetUserDataByKey(self, key, value):
+    def SetUserDataByKey(self, key, value, noneDelKey=False):
+        if not value and noneDelKey:
+            self.DelUserDataByKey(key)
+            return
         userDataDict = self.__GetUserDataDict()
         userDataDict[key] = value
+        self.__userDataChange = True
+        return
+    def DelUserDataByKey(self, key):
+        userDataDict = self.__GetUserDataDict()
+        userDataDict.pop(key, None)
         self.__userDataChange = True
         return
     def GetUserData(self):
@@ -110,6 +118,12 @@
             curValue = getattr(self, "GetValue%s" % i)()
             if curValue != value:
                 return False
+        return True
+    
+    def IsEmpty(self):
+        if self.GetValue1() or self.GetValue2() or self.GetValue3() or self.GetUserData() not in ["", "{}"] or self.GetValue4() \
+            or self.GetValue5() or self.GetValue6() or self.GetValue7() or self.GetValue8():
+            return False
         return True
     
     def GetString(self):
@@ -225,12 +239,14 @@
         playerRecDataList.append(recData)
         return
     
-    def GetPlayerRecDataFirst(self, recType, playerID):
+    def GetPlayerRecDataFirst(self, recType, playerID, isAddNew):
         ## 获取玩家记录类型对应的第一条记录,适用于仅需一条的记录类型
+        # @param isAddNew: 没有记录时是否添加一条新记录,一般获取后需要更新数据的可以设置为True,仅判断用的建议设置为False,减少产生多余空数据
+        recData = None
         recDataList = self.GetPlayerRecDataList(recType, playerID)
         if recDataList:
             recData = recDataList[0]
-        else:
+        elif isAddNew:
             recData = self.AddPlayerRecData(recType, playerID)
         return recData
 
@@ -274,8 +290,10 @@
         for playerRecDataDict in self.recTypeDict.values():
             for recDataList in playerRecDataDict.values():
                 for recData in recDataList:
-                    cnt += 1
                     recData.SaveUserData()
+                    if recData.IsEmpty():
+                        continue
+                    cnt += 1
                     savaData += recData.dbRecData.getBuffer()
                     
         GameWorld.Log("Save DBPlayerRecData count :%s len=%s" % (cnt, len(savaData)))
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
index 940eaee..0c81cde 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -1416,7 +1416,8 @@
                          Def_PlayerRecType_WorshipDaily, # 玩家每日膜拜记录 2
                          Def_PlayerRecType_PayCoin, # 代币记录 3
                          Def_PlayerRecType_OfflineUnprocessed, # 离线未处理的逻辑 4
-                         ) = range(1, 1 + 4)
+                         Def_PlayerRecType_MineAreaRecord, # 福地其他记录信息 5
+                         ) = range(1, 1 + 5)
 
 #通用信息记录类型 - 新 从 300 开始,原通用记录类型最大到255
 Def_GameRecTypeList = (
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
index b190e76..40f70c7 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -1991,7 +1991,7 @@
 Writer = hxp
 Releaser = hxp
 RegType = 0
-RegisterPackCount = 3
+RegisterPackCount = 4
 
 PacketCMD_1=0xB0
 PacketSubCMD_1=0x30
@@ -2004,3 +2004,7 @@
 PacketCMD_3=0xB0
 PacketSubCMD_3=0x32
 PacketCallFunc_3=OnMineWorkerEmploy
+
+PacketCMD_4=0xB0
+PacketSubCMD_4=0x35
+PacketCallFunc_4=OnMineHouseKeeperFreeUse
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 3d3a4f8..68ff612 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -4553,6 +4553,7 @@
 #福地
 Def_PDict_MineWorkerCount = "MineWorkerCount" # 已雇佣工人数
 Def_PDict_MineWorkerEnergyUsed = "MineWorkerEnergyUsed" # 今日已消耗体力
+Def_PDict_MineHousekeeperEndTime = "MineHousekeeperEndTime" # 自动管家到期时间戳
 Def_PDict_MineHelpAwardCount = "MineHelpAwardCount" # 今日已帮助别人奖励次数
 Def_PDict_MineRefreshCount = "MineRefreshCount_%s" # 今日已刷新次数,参数(刷新类型)
 Def_PDict_MineTreasureState = "MineTreasureState" # 聚宝盆激活状态,按类型位运算记录是否已激活
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
index c8eb3c2..6a0e5ab 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -18496,6 +18496,54 @@
 
 
 #------------------------------------------------------
+# B0 35 福地管家免费试用 #tagCMMineHouseKeeperFreeUse
+
+class  tagCMMineHouseKeeperFreeUse(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB0
+        self.SubCmd = 0x35
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB0
+        self.SubCmd = 0x35
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMMineHouseKeeperFreeUse)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B0 35 福地管家免费试用 //tagCMMineHouseKeeperFreeUse:
+                                Cmd:%s,
+                                SubCmd:%s
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd
+                                )
+        return DumpString
+
+
+m_NAtagCMMineHouseKeeperFreeUse=tagCMMineHouseKeeperFreeUse()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMMineHouseKeeperFreeUse.Cmd,m_NAtagCMMineHouseKeeperFreeUse.SubCmd))] = m_NAtagCMMineHouseKeeperFreeUse
+
+
+#------------------------------------------------------
 # B0 30 福地物品拉 #tagCMMineItemPull
 
 class  tagCMMineItemPull(Structure):
@@ -18567,7 +18615,7 @@
     _fields_ = [
                   ("Cmd", c_ubyte),
                   ("SubCmd", c_ubyte),
-                  ("IsSuper", c_ubyte),    # 是否超级刷新
+                  ("RefreshType", c_ubyte),    # 刷新类型:0-自己物品普通刷新;1-自己物品超级刷新;2-周围福地玩家列表刷新
                   ]
 
     def __init__(self):
@@ -18584,7 +18632,7 @@
     def Clear(self):
         self.Cmd = 0xB0
         self.SubCmd = 0x31
-        self.IsSuper = 0
+        self.RefreshType = 0
         return
 
     def GetLength(self):
@@ -18597,12 +18645,12 @@
         DumpString = '''// B0 31 福地物品刷新 //tagCMMineItemRefresh:
                                 Cmd:%s,
                                 SubCmd:%s,
-                                IsSuper:%d
+                                RefreshType:%d
                                 '''\
                                 %(
                                 self.Cmd,
                                 self.SubCmd,
-                                self.IsSuper
+                                self.RefreshType
                                 )
         return DumpString
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index 2866d99..1fdc316 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -8695,6 +8695,7 @@
     Job = 0    #(BYTE Job)
     Face = 0    #(DWORD Face)
     FacePic = 0    #(DWORD FacePic)
+    RobValue = 0    #(DWORD RobValue)// 抢劫敌对值
     MineCount = 0    #(BYTE MineCount)
     MineItemList = list()    #(vector<tagGCMineItem> MineItemList)// 矿物列表
     data = None
@@ -8710,6 +8711,7 @@
         self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
         self.Face,_pos = CommFunc.ReadDWORD(_lpData, _pos)
         self.FacePic,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.RobValue,_pos = CommFunc.ReadDWORD(_lpData, _pos)
         self.MineCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
         for i in range(self.MineCount):
             temMineItemList = tagGCMineItem()
@@ -8723,6 +8725,7 @@
         self.Job = 0
         self.Face = 0
         self.FacePic = 0
+        self.RobValue = 0
         self.MineCount = 0
         self.MineItemList = list()
         return
@@ -8732,6 +8735,7 @@
         length += 4
         length += 33
         length += 1
+        length += 4
         length += 4
         length += 4
         length += 1
@@ -8747,6 +8751,7 @@
         data = CommFunc.WriteBYTE(data, self.Job)
         data = CommFunc.WriteDWORD(data, self.Face)
         data = CommFunc.WriteDWORD(data, self.FacePic)
+        data = CommFunc.WriteDWORD(data, self.RobValue)
         data = CommFunc.WriteBYTE(data, self.MineCount)
         for i in range(self.MineCount):
             data = CommFunc.WriteString(data, self.MineItemList[i].GetLength(), self.MineItemList[i].GetBuffer())
@@ -8759,6 +8764,7 @@
                                 Job:%d,
                                 Face:%d,
                                 FacePic:%d,
+                                RobValue:%d,
                                 MineCount:%d,
                                 MineItemList:%s
                                 '''\
@@ -8768,6 +8774,7 @@
                                 self.Job,
                                 self.Face,
                                 self.FacePic,
+                                self.RobValue,
                                 self.MineCount,
                                 "..."
                                 )
@@ -51533,11 +51540,13 @@
     EnergyUsed = 0    #(WORD EnergyUsed)// 今日已消耗体力
     RefreshCount = 0    #(DWORD RefreshCount)// 今日福地刷新物品次数 - 普通刷新
     RefreshCountSuper = 0    #(BYTE RefreshCountSuper)// 今日福地刷新物品次数 - 超级刷新
+    RefreshCountRob = 0    #(WORD RefreshCountRob)// 今日福地刷新周围玩家次数
     TreasureCount = 0    #(BYTE TreasureCount)// 聚宝盆类型个数,对应类型 0~n
     TreasureState = list()    #(vector<BYTE> TreasureState)// 聚宝盆是否已激活列表,[类型0是否已激活, ...]
     TreasureAward = list()    #(vector<BYTE> TreasureAward)// 聚宝盆奖励是否已领取列表,[类型0是否已领取, ...]
     TreasureProgress = list()    #(vector<BYTE> TreasureProgress)// 聚宝盆进度值列表,[类型0进度值, ...],满进度100
     HelpAwardCount = 0    #(BYTE HelpAwardCount)// 今日已帮助别人奖励次数
+    HousekeeperEndTime = 0    #(DWORD HousekeeperEndTime)// 自动管家到期时间戳,有值同时也代表免费试用已使用
     data = None
 
     def __init__(self):
@@ -51553,6 +51562,7 @@
         self.EnergyUsed,_pos = CommFunc.ReadWORD(_lpData, _pos)
         self.RefreshCount,_pos = CommFunc.ReadDWORD(_lpData, _pos)
         self.RefreshCountSuper,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.RefreshCountRob,_pos = CommFunc.ReadWORD(_lpData, _pos)
         self.TreasureCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
         for i in range(self.TreasureCount):
             value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
@@ -51564,6 +51574,7 @@
             value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
             self.TreasureProgress.append(value)
         self.HelpAwardCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.HousekeeperEndTime,_pos = CommFunc.ReadDWORD(_lpData, _pos)
         return _pos
 
     def Clear(self):
@@ -51575,11 +51586,13 @@
         self.EnergyUsed = 0
         self.RefreshCount = 0
         self.RefreshCountSuper = 0
+        self.RefreshCountRob = 0
         self.TreasureCount = 0
         self.TreasureState = list()
         self.TreasureAward = list()
         self.TreasureProgress = list()
         self.HelpAwardCount = 0
+        self.HousekeeperEndTime = 0
         return
 
     def GetLength(self):
@@ -51589,11 +51602,13 @@
         length += 2
         length += 4
         length += 1
+        length += 2
         length += 1
         length += 1 * self.TreasureCount
         length += 1 * self.TreasureCount
         length += 1 * self.TreasureCount
         length += 1
+        length += 4
 
         return length
 
@@ -51604,6 +51619,7 @@
         data = CommFunc.WriteWORD(data, self.EnergyUsed)
         data = CommFunc.WriteDWORD(data, self.RefreshCount)
         data = CommFunc.WriteBYTE(data, self.RefreshCountSuper)
+        data = CommFunc.WriteWORD(data, self.RefreshCountRob)
         data = CommFunc.WriteBYTE(data, self.TreasureCount)
         for i in range(self.TreasureCount):
             data = CommFunc.WriteBYTE(data, self.TreasureState[i])
@@ -51612,6 +51628,7 @@
         for i in range(self.TreasureCount):
             data = CommFunc.WriteBYTE(data, self.TreasureProgress[i])
         data = CommFunc.WriteBYTE(data, self.HelpAwardCount)
+        data = CommFunc.WriteDWORD(data, self.HousekeeperEndTime)
         return data
 
     def OutputString(self):
@@ -51621,11 +51638,13 @@
                                 EnergyUsed:%d,
                                 RefreshCount:%d,
                                 RefreshCountSuper:%d,
+                                RefreshCountRob:%d,
                                 TreasureCount:%d,
                                 TreasureState:%s,
                                 TreasureAward:%s,
                                 TreasureProgress:%s,
-                                HelpAwardCount:%d
+                                HelpAwardCount:%d,
+                                HousekeeperEndTime:%d
                                 '''\
                                 %(
                                 self.Head.OutputString(),
@@ -51633,11 +51652,13 @@
                                 self.EnergyUsed,
                                 self.RefreshCount,
                                 self.RefreshCountSuper,
+                                self.RefreshCountRob,
                                 self.TreasureCount,
                                 "...",
                                 "...",
                                 "...",
-                                self.HelpAwardCount
+                                self.HelpAwardCount,
+                                self.HousekeeperEndTime
                                 )
         return DumpString
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MineArea.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MineArea.py
index fa38bc0..bc5fef6 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MineArea.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MineArea.py
@@ -19,6 +19,7 @@
 import PlayerControl
 import PlayerMineArea
 import ChConfig
+import time
 
 ## GM命令执行入口
 #  @param curPlayer 当前玩家
@@ -33,18 +34,21 @@
         GameWorld.DebugAnswer(curPlayer, "重置福地玩家: MineArea 0")
         GameWorld.DebugAnswer(curPlayer, "设置已用精力: MineArea e 精力")
         GameWorld.DebugAnswer(curPlayer, "设置工人数量: MineArea w 数量")
-        GameWorld.DebugAnswer(curPlayer, "设置刷新次数: MineArea r 次数 [是否超级]")
+        GameWorld.DebugAnswer(curPlayer, "管家到期时间: MineArea k 剩余时长分钟")
+        GameWorld.DebugAnswer(curPlayer, "设置刷新次数: MineArea r 次数 刷新类型")
         GameWorld.DebugAnswer(curPlayer, "设置聚宝进度: MineArea t 类型 进度值")
         GameWorld.DebugAnswer(curPlayer, "设置帮助次数: MineArea h 次数")
+        GameWorld.DebugAnswer(curPlayer, "刷新类型:0-自己物品,1-自己超级,2-周围玩家")
         return True
     
     value1 = msgList[0]
     if value1 == 0:
         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineWorkerCount, 0)
         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineWorkerEnergyUsed, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineHousekeeperEndTime, 0)
         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineHelpAwardCount, 0)
-        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineRefreshCount % 0, 0)
-        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineRefreshCount % 1, 0)
+        for refreshType in PlayerMineArea.RefreshTypeList:
+            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineRefreshCount % refreshType, 0)
         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineTreasureState, 0)
         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineTreasureAward, 0)
         for treasureType in range(10):
@@ -61,12 +65,21 @@
         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineWorkerCount, workerCount)
         GameWorld.DebugAnswer(curPlayer, "设置工人数量: %s" % workerCount)
         
+    elif value1 == "k":
+        remainMinutes = msgList[1] if len(msgList) > 1 else 0
+        if remainMinutes > 0:
+            endTime = int(time.time()) + remainMinutes * 60
+            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineHousekeeperEndTime, endTime)
+            GameWorld.DebugAnswer(curPlayer, "设置管家到期时间: %s" % GameWorld.ChangeTimeNumToStr(endTime))
+        else:
+            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineHousekeeperEndTime, 0)
+            GameWorld.DebugAnswer(curPlayer, "重置管家到期时间: 0")
+            
     elif value1 == "r":
         refreshCount = msgList[1] if len(msgList) > 1 else 0
-        isSuper = msgList[2] if len(msgList) > 2 else 0
-        refreshType = 1 if isSuper else 0
+        refreshType = msgList[2] if len(msgList) > 2 else 0
         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineRefreshCount % refreshType, refreshCount)
-        GameWorld.DebugAnswer(curPlayer, "设置刷新次数: %s, isSuper=%s" % (refreshCount, isSuper))
+        GameWorld.DebugAnswer(curPlayer, "设置刷新次数: %s, Type:%s" % (refreshCount, refreshType))
         
     elif value1 == "t":
         treasureType = msgList[1] if len(msgList) > 1 else 0
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMineArea.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMineArea.py
index a2fc6a3..066946b 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMineArea.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMineArea.py
@@ -27,9 +27,17 @@
 import ShareDefine
 import ItemCommon
 import GameWorld
+import time
 
 # 聚宝盆默认最大进度
 MineTreasureProgressMax = 100
+
+# 刷新类型列表
+RefreshTypeList = (
+RefreshType_Comm, # 自己物品普通刷新 0
+RefreshType_Super, # 自己物品超级刷新 1
+RefreshType_Rob, # 抢劫周围玩家刷新 2
+) = range(3)
 
 def OnPlayerLogin(curPlayer):
     freeWorkerCount = 0
@@ -46,7 +54,7 @@
 def PlayerOnDay(curPlayer):
     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineHelpAwardCount, 0)
     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineWorkerEnergyUsed, 0)
-    for refreshType in [0, 1]:
+    for refreshType in RefreshTypeList:
         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineRefreshCount % refreshType, 0)
     SyncPlayerMineAreaInfo(curPlayer)
     return
@@ -102,36 +110,62 @@
 #
 #{
 #    tagHead        Head;
-#    BYTE        IsSuper;    // 是否超级刷新
+#    BYTE        RefreshType;    // 刷新类型:0-自己物品普通刷新;1-自己物品超级刷新;2-周围福地玩家列表刷新
 #};
 def OnMineItemRefresh(index, clientData, tick):
     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
     playerID = curPlayer.GetPlayerID()
-    isSuper = clientData.IsSuper
+    refreshType = clientData.RefreshType
     
-    refreshType = str(1 if isSuper else 0)
-    
+    moneyType, moneyValue = 0, 0
     moneyDict = IpyGameDataPY.GetFuncEvalCfg("MineAreaRefresh", 1, {})
-    if refreshType not in moneyDict:
-        return
-    moneyType, moneyValue = moneyDict[refreshType]
-    if not PlayerControl.HaveMoney(curPlayer, moneyType, moneyValue):
-        return
-    
+    if str(refreshType) in moneyDict:
+        moneyType, moneyValue = moneyDict[str(refreshType)]
+        if not PlayerControl.HaveMoney(curPlayer, moneyType, moneyValue):
+            return
+        
+    costItemID, costItemCount = 0, 0
     refreshMaxDict = IpyGameDataPY.GetFuncEvalCfg("MineAreaRefresh", 2, {})
-    refreshCountMax = refreshMaxDict.get(refreshType, 0)
+    refreshCountMax = refreshMaxDict.get(str(refreshType), 0)
     refreshCountNow = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineRefreshCount % refreshType)
     if refreshCountMax and refreshCountNow >= refreshCountMax:
-        GameWorld.DebugLog("福地物品刷新次数已达今日上限! isSuper=%s,refreshCountNow=%s >= %s" % (isSuper, refreshCountNow, refreshCountMax), playerID)
-        return
-    
-    PlayerControl.PayMoney(curPlayer, moneyType, moneyValue, "MineItemRefresh")
-    if refreshCountMax:
+        if refreshType == RefreshType_Super:
+            employCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineWorkerCount)
+            employMax = len(IpyGameDataPY.GetFuncEvalCfg("MineAreaWorker", 3))
+            if employCount < employMax:
+                GameWorld.DebugLog("福地雇佣工人数未达到上限,不能使用雇佣道具进行超级刷新! employCount=%s < %s" % (employCount, employMax), playerID)
+                return
+            costItemID = IpyGameDataPY.GetFuncCfg("MineAreaWorker", 2)
+            costItemCount = IpyGameDataPY.GetFuncCfg("MineAreaRefresh", 3)
+            costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, costItemID, costItemCount)
+            lackCnt = costItemCount - bindCnt - unBindCnt
+            if lackCnt > 0:
+                GameWorld.DebugLog("福地雇佣工人道具不足,无法超级刷新! costItemID=%s,costItemCount=%s,bindCnt=%s,unBindCnt=%s,lackCnt=%s" 
+                                   % (costItemID, costItemCount, bindCnt, unBindCnt, lackCnt))
+                return
+        else:
+            GameWorld.DebugLog("福地物品刷新次数已达今日上限! refreshType=%s,refreshCountNow=%s >= %s" % (refreshType, refreshCountNow, refreshCountMax), playerID)
+            return
+        
+    GameWorld.DebugLog("福地刷新: refreshType=%s,refreshCountNow=%s,moneyType=%s,moneyValue=%s,costItemID=%s,costItemCount=%s" 
+                       % (refreshType, refreshCountNow, moneyType, moneyValue, costItemID, costItemCount), playerID)
+    if moneyType and moneyValue:
+        PlayerControl.PayMoney(curPlayer, moneyType, moneyValue, "MineItemRefresh")
+        
+    if costItemID and costItemCount:
+        delCnt = costItemCount
+        ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, delCnt, "MineItemRefresh")
+        
+    if refreshCountMax and refreshCountNow < refreshCountMax:
         refreshCountUpd = refreshCountNow + 1
-        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineRefreshCount % refreshType, refreshCountUpd)            
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineRefreshCount % refreshType, refreshCountUpd)
         SyncPlayerMineAreaInfo(curPlayer)
         
-    SendToGameServer_MineArea(curPlayer, "MineItemRefresh", [playerID, isSuper])
+    if refreshType == RefreshType_Rob:
+        SendToGameServer_MineArea(curPlayer, "MineRobRefresh", [])
+    else:
+        isSuper = 1 if refreshType == RefreshType_Super else 0
+        SendToGameServer_MineArea(curPlayer, "MineItemRefresh", [playerID, isSuper])
     return
 
 #// B0 32 福地工人雇佣 #tagCMMineWorkerEmploy
@@ -248,6 +282,17 @@
         PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_MineAreaEndOther)
     return
 
+#// B0 35 福地管家免费试用 #tagCMMineHouseKeeperFreeUse
+#
+#struct    tagCMMineHouseKeeperFreeUse
+#{
+#    tagHead        Head;
+#};
+def OnMineHouseKeeperFreeUse(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    OnActMineHousekeeper(curPlayer, 0)
+    return
+
 def OnMineTreasureByCTGID(curPlayer, ctgID):
     ## 充值激活聚宝盆
     treasureCTGIDList = IpyGameDataPY.GetFuncEvalCfg("MineAreaTreasure", 1)
@@ -263,6 +308,12 @@
         GameWorld.Log("激活福地聚宝盆: treasureType=%s,updState=%s" % (treasureType, updState), curPlayer.GetPlayerID())
         break
     
+    keeperCTGIDList = IpyGameDataPY.GetFuncEvalCfg("MineAreaHousekeeper", 3)
+    for keeperIndex, ctgIDList in enumerate(keeperCTGIDList, 1):
+        if ctgID in ctgIDList:
+            OnActMineHousekeeper(curPlayer, keeperIndex)
+            break
+        
     return
 
 def OnAddMineTreasureProgress(curPlayer, robCount, isNotify=True):
@@ -326,13 +377,59 @@
     GameWorld.DebugLog("福地聚宝盆领奖! treasureType=%s,updAward=%s,awardItemList=%s" % (treasureType, updAward, awardItemList), playerID)
     return
 
+def OnActMineHousekeeper(curPlayer, keeperIndex):
+    ## 激活/增加自动管家时长
+    # @param keeperIndex: 管家档位索引,0-免费,>0-付费档
+    
+    playerID = curPlayer.GetPlayerID()
+    endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineHousekeeperEndTime)
+    if keeperIndex == 0:
+        if endTime:
+            GameWorld.DebugLog("福地免费管家已领取过!", playerID)
+            return
+        
+    openServerDayLimit = IpyGameDataPY.GetFuncCfg("MineAreaHousekeeper", 1)
+    if openServerDayLimit:
+        openServerDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay) + 1
+        if openServerDay <= openServerDayLimit:
+            GameWorld.ErrLog("开服天未到,无法使用福地管家! keeperIndex=%s,openServerDay=%s <= %s" 
+                             % (keeperIndex, openServerDay, openServerDayLimit), playerID)
+            return
+        
+    keeperDaysList = IpyGameDataPY.GetFuncEvalCfg("MineAreaHousekeeper", 2)
+    if keeperIndex < 0 or keeperIndex >= len(keeperDaysList):
+        return
+    addDays = keeperDaysList[keeperIndex]
+    addSeconds = addDays * 24 * 3600
+    curTime = int(time.time())
+    
+    endTimeStr = GameWorld.ChangeTimeNumToStr(endTime) if endTime else ""
+    GameWorld.DebugLog("激活福地管家: keeperIndex=%s,addDays=%s(%s)" % (keeperIndex, addDays, addSeconds), playerID)
+    GameWorld.DebugLog("    管家到期时间: endTime=%s, %s" % (endTime, endTimeStr), playerID)
+    if not endTime:
+        updEndTime = curTime + addSeconds
+        GameWorld.DebugLog("    激活管家", playerID)
+    elif curTime >= endTime:
+        updEndTime = curTime + addSeconds 
+        GameWorld.DebugLog("    已过期,重新激活管家", playerID)
+    else:
+        updEndTime = endTime + addSeconds
+        GameWorld.DebugLog("    续费管家时长", playerID)
+        
+    GameWorld.DebugLog("    更新管家时长: updEndTime=%s, %s" % (updEndTime, GameWorld.ChangeTimeNumToStr(updEndTime)), playerID)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineHousekeeperEndTime, updEndTime)
+    SyncPlayerMineAreaInfo(curPlayer)
+    return
+
 def SyncPlayerMineAreaInfo(curPlayer):
     clientPack = ChPyNetSendPack.tagMCPlayerMineAreaInfo()
     clientPack.WorkerCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineWorkerCount)
     clientPack.EnergyUsed = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineWorkerEnergyUsed)
+    clientPack.HousekeeperEndTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineHousekeeperEndTime)
     clientPack.HelpAwardCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineHelpAwardCount)
-    clientPack.RefreshCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineRefreshCount % 0)
-    clientPack.RefreshCountSuper = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineRefreshCount % 1)
+    clientPack.RefreshCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineRefreshCount % RefreshType_Comm)
+    clientPack.RefreshCountSuper = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineRefreshCount % RefreshType_Super)
+    clientPack.RefreshCountRob = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineRefreshCount % RefreshType_Rob)
     
     treasureState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineTreasureState)
     treasureAward = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineTreasureAward)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
index 940eaee..0c81cde 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -1416,7 +1416,8 @@
                          Def_PlayerRecType_WorshipDaily, # 玩家每日膜拜记录 2
                          Def_PlayerRecType_PayCoin, # 代币记录 3
                          Def_PlayerRecType_OfflineUnprocessed, # 离线未处理的逻辑 4
-                         ) = range(1, 1 + 4)
+                         Def_PlayerRecType_MineAreaRecord, # 福地其他记录信息 5
+                         ) = range(1, 1 + 5)
 
 #通用信息记录类型 - 新 从 300 开始,原通用记录类型最大到255
 Def_GameRecTypeList = (

--
Gitblit v1.8.0