From 3d3a72a7c8482ec217d936c8fcee3cea07cfb785 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期四, 06 六月 2024 11:17:47 +0800
Subject: [PATCH] 10130 【后端】福地争夺资源功能

---
 ServerPython/CoreServerGroup/GameServer/PyNetPack.ini                                                       |   15 
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py                                      |    2 
 ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py                                          |  301 ++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py                          |    1 
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py                                        |   11 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py                          |  268 ++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py                      |  533 +++++++
 ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/MineArea.py                                      |  228 +++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_MineArea.py |   47 
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py                                               |  268 ++++
 ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py                                           |    3 
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py                                           |  533 +++++++
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py                          | 1320 +++++++++++++++++++
 ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py                                             |   25 
 ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py                                                 |    5 
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py                           |    6 
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py                                    |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MineArea.py                 |   80 +
 ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py                                               |    1 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py                  |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py            |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMineArea.py                |  316 ++++
 PySysDB/PySysDBG.h                                                                                          |   15 
 23 files changed, 3,981 insertions(+), 4 deletions(-)

diff --git a/PySysDB/PySysDBG.h b/PySysDB/PySysDBG.h
index f3a6d7e..7e8b811 100644
--- a/PySysDB/PySysDBG.h
+++ b/PySysDB/PySysDBG.h
@@ -1202,6 +1202,21 @@
 	BYTE		UnSuitRate;	//单件非套装加成概率
 };
 
+//福地物品表
+
+struct tagMineAreaItem
+{
+	BYTE		_MineID;	//矿物ID
+	WORD		LimitLV;	//解锁等级
+	DWORD		ItemID;		//物品ID
+	BYTE		ItemLV;		//物品等级
+	DWORD		ItemCount;	//物品个数
+	float		ItemWeight;	//物品总重量
+	DWORD		RefreshWeightSys;	//系统刷新权重
+	DWORD		RefreshWeight;	//常规刷新权重
+	DWORD		RefreshWeightSuper;	//超级刷新权重
+};
+
 //仙盟联赛排名奖励表
 
 struct tagFamilyWarRankAward
diff --git a/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini b/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
index 5b9405c..e5501c3 100644
--- a/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
+++ b/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
@@ -541,3 +541,18 @@
 PacketSubCMD_1=0x07
 PacketCallFunc_1=OnVoiceChat
 
+[GameWorldMineArea]
+ScriptName = GameWorldLogic\GameWorldMineArea.py
+Writer = hxp
+Releaser = hxp
+RegType = 0
+RegisterPackCount = 2
+
+PacketCMD_1=0xB0
+PacketSubCMD_1=0x33
+PacketCallFunc_1=OnMineAreaView
+
+PacketCMD_2=0xB0
+PacketSubCMD_2=0x34
+PacketCallFunc_2=OnMineAreaAwardGet
+
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
index f32553e..55fd724 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
@@ -2117,6 +2117,110 @@
 
 
 #------------------------------------------------------
+# B0 34 福地请求结算奖励 #tagCGMineAreaAwardGet
+
+class  tagCGMineAreaAwardGet(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB0
+        self.SubCmd = 0x34
+        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 = 0x34
+        return
+
+    def GetLength(self):
+        return sizeof(tagCGMineAreaAwardGet)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B0 34 福地请求结算奖励 //tagCGMineAreaAwardGet:
+                                Cmd:%s,
+                                SubCmd:%s
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd
+                                )
+        return DumpString
+
+
+m_NAtagCGMineAreaAwardGet=tagCGMineAreaAwardGet()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGMineAreaAwardGet.Cmd,m_NAtagCGMineAreaAwardGet.SubCmd))] = m_NAtagCGMineAreaAwardGet
+
+
+#------------------------------------------------------
+# B0 33 福地查看 #tagCGMineAreaView
+
+class  tagCGMineAreaView(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("QueryType", c_ubyte),    # 查询同步类型:0-后端主动同步;1-查看指定福地;2-查看道友福地列表;3-查看周围随机福地列表;4-退出他人福地;
+                  ("QueryValue", c_int),    # 查询值,类型1时-发送目标玩家ID;3时-发送是否重新随机
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB0
+        self.SubCmd = 0x33
+        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 = 0x33
+        self.QueryType = 0
+        self.QueryValue = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCGMineAreaView)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B0 33 福地查看 //tagCGMineAreaView:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                QueryType:%d,
+                                QueryValue:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.QueryType,
+                                self.QueryValue
+                                )
+        return DumpString
+
+
+m_NAtagCGMineAreaView=tagCGMineAreaView()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGMineAreaView.Cmd,m_NAtagCGMineAreaView.SubCmd))] = m_NAtagCGMineAreaView
+
+
+#------------------------------------------------------
 #B0 25 请求家族悬赏任务完成情况 #tagQueryFamilyArrestOverState
 
 class  tagQueryFamilyArrestOverState(Structure):
@@ -17341,6 +17445,170 @@
 
 
 #------------------------------------------------------
+# B0 30 福地物品拉 #tagCMMineItemPull
+
+class  tagCMMineItemPull(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("PlayerID", c_int),    # 福地所属玩家ID,0默认自己
+                  ("ItemIndex", c_ubyte),    # 物品所在位置索引0~n
+                  ("WorkerCount", c_ubyte),    # 上工人人数
+                  ("IsPreview", c_ubyte),    # 是否预览;0-直接拉,1-预览大概时间
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB0
+        self.SubCmd = 0x30
+        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 = 0x30
+        self.PlayerID = 0
+        self.ItemIndex = 0
+        self.WorkerCount = 0
+        self.IsPreview = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMMineItemPull)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B0 30 福地物品拉 //tagCMMineItemPull:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                PlayerID:%d,
+                                ItemIndex:%d,
+                                WorkerCount:%d,
+                                IsPreview:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.PlayerID,
+                                self.ItemIndex,
+                                self.WorkerCount,
+                                self.IsPreview
+                                )
+        return DumpString
+
+
+m_NAtagCMMineItemPull=tagCMMineItemPull()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMMineItemPull.Cmd,m_NAtagCMMineItemPull.SubCmd))] = m_NAtagCMMineItemPull
+
+
+#------------------------------------------------------
+# B0 31 福地物品刷新 #tagCMMineItemRefresh
+
+class  tagCMMineItemRefresh(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("IsSuper", c_ubyte),    # 是否超级刷新
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB0
+        self.SubCmd = 0x31
+        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 = 0x31
+        self.IsSuper = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMMineItemRefresh)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B0 31 福地物品刷新 //tagCMMineItemRefresh:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                IsSuper:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.IsSuper
+                                )
+        return DumpString
+
+
+m_NAtagCMMineItemRefresh=tagCMMineItemRefresh()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMMineItemRefresh.Cmd,m_NAtagCMMineItemRefresh.SubCmd))] = m_NAtagCMMineItemRefresh
+
+
+#------------------------------------------------------
+# B0 32 福地工人雇佣 #tagCMMineWorkerEmploy
+
+class  tagCMMineWorkerEmploy(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB0
+        self.SubCmd = 0x32
+        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 = 0x32
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMMineWorkerEmploy)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B0 32 福地工人雇佣 //tagCMMineWorkerEmploy:
+                                Cmd:%s,
+                                SubCmd:%s
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd
+                                )
+        return DumpString
+
+
+m_NAtagCMMineWorkerEmploy=tagCMMineWorkerEmploy()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMMineWorkerEmploy.Cmd,m_NAtagCMMineWorkerEmploy.SubCmd))] = m_NAtagCMMineWorkerEmploy
+
+
+#------------------------------------------------------
 #B0 26 请求家族悬赏奖励领取情况 #tagQueryFamilyArrestAwardReceiveState
 
 class  tagQueryFamilyArrestAwardReceiveState(Structure):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
index 012a73d..2922b4d 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -7722,6 +7722,424 @@
 
 
 #------------------------------------------------------
+# B0 34 福地结算奖励信息 #tagGCMineAreaAwardInfo
+
+class  tagGCMineAreaAwardInfo(Structure):
+    Head = tagHead()
+    AwardType = 0    #(BYTE AwardType)// 0-通知有奖励,前端下次进入福地可请求进行结算;1-结算奖励结果通知
+    AwardLen = 0    #(BYTE AwardLen)
+    AwardInfo = ""    #(String AwardInfo)//奖励信息 [物品ID,个数,是否拍品], ...]
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB0
+        self.Head.SubCmd = 0x34
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.AwardType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.AwardLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.AwardInfo,_pos = CommFunc.ReadString(_lpData, _pos,self.AwardLen)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB0
+        self.Head.SubCmd = 0x34
+        self.AwardType = 0
+        self.AwardLen = 0
+        self.AwardInfo = ""
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 1
+        length += 1
+        length += len(self.AwardInfo)
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.AwardType)
+        data = CommFunc.WriteBYTE(data, self.AwardLen)
+        data = CommFunc.WriteString(data, self.AwardLen, self.AwardInfo)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                AwardType:%d,
+                                AwardLen:%d,
+                                AwardInfo:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.AwardType,
+                                self.AwardLen,
+                                self.AwardInfo
+                                )
+        return DumpString
+
+
+m_NAtagGCMineAreaAwardInfo=tagGCMineAreaAwardInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCMineAreaAwardInfo.Head.Cmd,m_NAtagGCMineAreaAwardInfo.Head.SubCmd))] = m_NAtagGCMineAreaAwardInfo
+
+
+#------------------------------------------------------
+# B0 33 福地详细信息 #tagGCMineAreaInfo
+
+class  tagGCMineItem(Structure):
+    Index = 0    #(BYTE Index)// 矿物所在福地位置索引,0~n
+    MineID = 0    #(WORD MineID)// 矿物ID,对应福地采集表中ID,0代表该索引位置没有矿物
+    MineType = 0    #(BYTE MineType)// 矿物类型:0-常规;1-超级
+    UpdTime = 0    #(DWORD UpdTime)// 最后一次更新时间戳
+    PosLen = 0    #(BYTE PosLen)
+    Position = ""    #(String Position)// 最后一次更新时所在位置百分比,0~100,支持小数,下0上100,可认为分为100格,速度为 x格/秒
+    SpeedLen = 0    #(BYTE SpeedLen)
+    MoveSpeed = ""    #(String MoveSpeed)// 移动速度,x格/秒,支持小数
+    EndTime = 0    #(DWORD EndTime)// 拉取结束时间戳
+    WorkerCount = 0    #(BYTE WorkerCount)// 工人个数,为0时代表福地玩家没有使用工人拉回
+    RobPlayerID = 0    #(DWORD RobPlayerID)// 抢夺玩家ID,为0时代表没人抢夺
+    RobWorkerCount = 0    #(BYTE RobWorkerCount)// 抢夺工人个数
+    RobPlayerName = ""    #(char RobPlayerName[33])
+    RobFace = 0    #(DWORD RobFace)
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.Index,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.MineID,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.MineType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.UpdTime,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.PosLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.Position,_pos = CommFunc.ReadString(_lpData, _pos,self.PosLen)
+        self.SpeedLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.MoveSpeed,_pos = CommFunc.ReadString(_lpData, _pos,self.SpeedLen)
+        self.EndTime,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.WorkerCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.RobPlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.RobWorkerCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.RobPlayerName,_pos = CommFunc.ReadString(_lpData, _pos,33)
+        self.RobFace,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        return _pos
+
+    def Clear(self):
+        self.Index = 0
+        self.MineID = 0
+        self.MineType = 0
+        self.UpdTime = 0
+        self.PosLen = 0
+        self.Position = ""
+        self.SpeedLen = 0
+        self.MoveSpeed = ""
+        self.EndTime = 0
+        self.WorkerCount = 0
+        self.RobPlayerID = 0
+        self.RobWorkerCount = 0
+        self.RobPlayerName = ""
+        self.RobFace = 0
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 1
+        length += 2
+        length += 1
+        length += 4
+        length += 1
+        length += len(self.Position)
+        length += 1
+        length += len(self.MoveSpeed)
+        length += 4
+        length += 1
+        length += 4
+        length += 1
+        length += 33
+        length += 4
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteBYTE(data, self.Index)
+        data = CommFunc.WriteWORD(data, self.MineID)
+        data = CommFunc.WriteBYTE(data, self.MineType)
+        data = CommFunc.WriteDWORD(data, self.UpdTime)
+        data = CommFunc.WriteBYTE(data, self.PosLen)
+        data = CommFunc.WriteString(data, self.PosLen, self.Position)
+        data = CommFunc.WriteBYTE(data, self.SpeedLen)
+        data = CommFunc.WriteString(data, self.SpeedLen, self.MoveSpeed)
+        data = CommFunc.WriteDWORD(data, self.EndTime)
+        data = CommFunc.WriteBYTE(data, self.WorkerCount)
+        data = CommFunc.WriteDWORD(data, self.RobPlayerID)
+        data = CommFunc.WriteBYTE(data, self.RobWorkerCount)
+        data = CommFunc.WriteString(data, 33, self.RobPlayerName)
+        data = CommFunc.WriteDWORD(data, self.RobFace)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Index:%d,
+                                MineID:%d,
+                                MineType:%d,
+                                UpdTime:%d,
+                                PosLen:%d,
+                                Position:%s,
+                                SpeedLen:%d,
+                                MoveSpeed:%s,
+                                EndTime:%d,
+                                WorkerCount:%d,
+                                RobPlayerID:%d,
+                                RobWorkerCount:%d,
+                                RobPlayerName:%s,
+                                RobFace:%d
+                                '''\
+                                %(
+                                self.Index,
+                                self.MineID,
+                                self.MineType,
+                                self.UpdTime,
+                                self.PosLen,
+                                self.Position,
+                                self.SpeedLen,
+                                self.MoveSpeed,
+                                self.EndTime,
+                                self.WorkerCount,
+                                self.RobPlayerID,
+                                self.RobWorkerCount,
+                                self.RobPlayerName,
+                                self.RobFace
+                                )
+        return DumpString
+
+
+class  tagGCMineArea(Structure):
+    PlayerID = 0    #(DWORD PlayerID)// 福地所属玩家ID,可能是自己或其他玩家ID,当ID小于10000时为假人
+    PlayerName = ""    #(char PlayerName[33])// 可能为空,如自己或假人
+    Face = 0    #(DWORD Face)
+    MineCount = 0    #(BYTE MineCount)
+    MineItemList = list()    #(vector<tagGCMineItem> MineItemList)// 矿物列表
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.PlayerName,_pos = CommFunc.ReadString(_lpData, _pos,33)
+        self.Face,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.MineCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.MineCount):
+            temMineItemList = tagGCMineItem()
+            _pos = temMineItemList.ReadData(_lpData, _pos)
+            self.MineItemList.append(temMineItemList)
+        return _pos
+
+    def Clear(self):
+        self.PlayerID = 0
+        self.PlayerName = ""
+        self.Face = 0
+        self.MineCount = 0
+        self.MineItemList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 4
+        length += 33
+        length += 4
+        length += 1
+        for i in range(self.MineCount):
+            length += self.MineItemList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteDWORD(data, self.PlayerID)
+        data = CommFunc.WriteString(data, 33, self.PlayerName)
+        data = CommFunc.WriteDWORD(data, self.Face)
+        data = CommFunc.WriteBYTE(data, self.MineCount)
+        for i in range(self.MineCount):
+            data = CommFunc.WriteString(data, self.MineItemList[i].GetLength(), self.MineItemList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                PlayerID:%d,
+                                PlayerName:%s,
+                                Face:%d,
+                                MineCount:%d,
+                                MineItemList:%s
+                                '''\
+                                %(
+                                self.PlayerID,
+                                self.PlayerName,
+                                self.Face,
+                                self.MineCount,
+                                "..."
+                                )
+        return DumpString
+
+
+class  tagGCMineAreaInfo(Structure):
+    Head = tagHead()
+    QueryType = 0    #(BYTE QueryType)// 查询同步类型:0-后端主动同步;1-查看指定福地;2-查看道友福地列表;3-查看周围随机福地列表
+    QueryValue = 0    #(DWORD QueryValue)// 查询值,类型1时-发送目标玩家ID;3时-发送是否重新随机
+    AreaCount = 0    #(BYTE AreaCount)
+    AreaList = list()    #(vector<tagGCMineArea> AreaList)// 福地列表
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB0
+        self.Head.SubCmd = 0x33
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.QueryType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.QueryValue,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.AreaCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.AreaCount):
+            temAreaList = tagGCMineArea()
+            _pos = temAreaList.ReadData(_lpData, _pos)
+            self.AreaList.append(temAreaList)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB0
+        self.Head.SubCmd = 0x33
+        self.QueryType = 0
+        self.QueryValue = 0
+        self.AreaCount = 0
+        self.AreaList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 1
+        length += 4
+        length += 1
+        for i in range(self.AreaCount):
+            length += self.AreaList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.QueryType)
+        data = CommFunc.WriteDWORD(data, self.QueryValue)
+        data = CommFunc.WriteBYTE(data, self.AreaCount)
+        for i in range(self.AreaCount):
+            data = CommFunc.WriteString(data, self.AreaList[i].GetLength(), self.AreaList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                QueryType:%d,
+                                QueryValue:%d,
+                                AreaCount:%d,
+                                AreaList:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.QueryType,
+                                self.QueryValue,
+                                self.AreaCount,
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagGCMineAreaInfo=tagGCMineAreaInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCMineAreaInfo.Head.Cmd,m_NAtagGCMineAreaInfo.Head.SubCmd))] = m_NAtagGCMineAreaInfo
+
+
+#------------------------------------------------------
+# B0 32 福地物品拉预览结果 #tagGCMineItemPullPreviewRet
+
+class  tagGCMineItemPullPreviewRet(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("PlayerID", c_int),    # 福地所属玩家ID,0默认自己
+                  ("ItemIndex", c_ubyte),    # 物品所在位置索引0~n
+                  ("WorkerCount", c_ubyte),    # 上工人人数
+                  ("NeedSeconds", c_int),    # 预计需要时间,秒
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB0
+        self.SubCmd = 0x32
+        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 = 0x32
+        self.PlayerID = 0
+        self.ItemIndex = 0
+        self.WorkerCount = 0
+        self.NeedSeconds = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagGCMineItemPullPreviewRet)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B0 32 福地物品拉预览结果 //tagGCMineItemPullPreviewRet:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                PlayerID:%d,
+                                ItemIndex:%d,
+                                WorkerCount:%d,
+                                NeedSeconds:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.PlayerID,
+                                self.ItemIndex,
+                                self.WorkerCount,
+                                self.NeedSeconds
+                                )
+        return DumpString
+
+
+m_NAtagGCMineItemPullPreviewRet=tagGCMineItemPullPreviewRet()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCMineItemPullPreviewRet.Cmd,m_NAtagGCMineItemPullPreviewRet.SubCmd))] = m_NAtagGCMineItemPullPreviewRet
+
+
+#------------------------------------------------------
 # B0 04 使用协助感谢礼盒预览 #tagGCUseAssistThanksGiftPreview
 
 class  tagGCAssistPlayerInfo(Structure):
@@ -44010,6 +44428,121 @@
 
 
 #------------------------------------------------------
+# B0 30 玩家福地相关信息 #tagMCPlayerMineAreaInfo
+
+class  tagMCPlayerMineAreaInfo(Structure):
+    Head = tagHead()
+    WorkerCount = 0    #(BYTE WorkerCount)// 已雇佣工人数
+    EnergyUsed = 0    #(WORD EnergyUsed)// 今日已消耗体力
+    RefreshCount = 0    #(DWORD RefreshCount)// 今日福地刷新物品次数 - 普通刷新
+    RefreshCountSuper = 0    #(BYTE RefreshCountSuper)// 今日福地刷新物品次数 - 超级刷新
+    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
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB0
+        self.Head.SubCmd = 0x30
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.WorkerCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.EnergyUsed,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.RefreshCount,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.RefreshCountSuper,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.TreasureCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.TreasureCount):
+            value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
+            self.TreasureState.append(value)
+        for i in range(self.TreasureCount):
+            value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
+            self.TreasureAward.append(value)
+        for i in range(self.TreasureCount):
+            value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
+            self.TreasureProgress.append(value)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB0
+        self.Head.SubCmd = 0x30
+        self.WorkerCount = 0
+        self.EnergyUsed = 0
+        self.RefreshCount = 0
+        self.RefreshCountSuper = 0
+        self.TreasureCount = 0
+        self.TreasureState = list()
+        self.TreasureAward = list()
+        self.TreasureProgress = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 1
+        length += 2
+        length += 4
+        length += 1
+        length += 1
+        length += 1 * self.TreasureCount
+        length += 1 * self.TreasureCount
+        length += 1 * self.TreasureCount
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.WorkerCount)
+        data = CommFunc.WriteWORD(data, self.EnergyUsed)
+        data = CommFunc.WriteDWORD(data, self.RefreshCount)
+        data = CommFunc.WriteBYTE(data, self.RefreshCountSuper)
+        data = CommFunc.WriteBYTE(data, self.TreasureCount)
+        for i in range(self.TreasureCount):
+            data = CommFunc.WriteBYTE(data, self.TreasureState[i])
+        for i in range(self.TreasureCount):
+            data = CommFunc.WriteBYTE(data, self.TreasureAward[i])
+        for i in range(self.TreasureCount):
+            data = CommFunc.WriteBYTE(data, self.TreasureProgress[i])
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                WorkerCount:%d,
+                                EnergyUsed:%d,
+                                RefreshCount:%d,
+                                RefreshCountSuper:%d,
+                                TreasureCount:%d,
+                                TreasureState:%s,
+                                TreasureAward:%s,
+                                TreasureProgress:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.WorkerCount,
+                                self.EnergyUsed,
+                                self.RefreshCount,
+                                self.RefreshCountSuper,
+                                self.TreasureCount,
+                                "...",
+                                "...",
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagMCPlayerMineAreaInfo=tagMCPlayerMineAreaInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCPlayerMineAreaInfo.Head.Cmd,m_NAtagMCPlayerMineAreaInfo.Head.SubCmd))] = m_NAtagMCPlayerMineAreaInfo
+
+
+#------------------------------------------------------
 # B0 07 今日协助活跃令信息 #tagMCTodayAssistMoneyInfo
 
 class  tagMCTodayAssistMoneyInfo(Structure):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/MineArea.py b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/MineArea.py
new file mode 100644
index 0000000..acb9ec2
--- /dev/null
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/MineArea.py
@@ -0,0 +1,228 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package GM.Commands.MineArea
+#
+# @todo:福地
+# @author hxp
+# @date 2024-03-07
+# @version 1.0
+#
+# 详细描述: 福地
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2024-03-07 19:30"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import PyDataManager
+import GameWorldMineArea
+import IpyGameDataPY
+
+import time
+
+#逻辑实现
+## 执行逻辑
+#  @param curPlayer 当前玩家
+#  @param gmList [cmdIndex gmAccID msg]
+#  @return None
+#  @remarks 函数详细说明.
+def OnExec(curPlayer, msgList):
+    if not msgList:
+        GameWorld.DebugAnswer(curPlayer, "以下是GameServer命令")
+        GameWorld.DebugAnswer(curPlayer, "随机重新刷新: MineArea item [是否超级 坐标 索引]")
+        GameWorld.DebugAnswer(curPlayer, "刷新指定等级: MineArea lv 等级 [坐标 索引]")
+        GameWorld.DebugAnswer(curPlayer, "刷新指定物品: MineArea id 矿物ID [坐标 索引]")
+        GameWorld.DebugAnswer(curPlayer, "派工人拉物品: MineArea pull 索引 人数 状态")
+        GameWorld.DebugAnswer(curPlayer, "[工人玩家ID 福地玩家ID]")
+        GameWorld.DebugAnswer(curPlayer, "输出在拉物品: MineArea pulling [玩家ID]")
+        GameWorld.DebugAnswer(curPlayer, "输出福地物品: MineArea area [福地玩家ID]")
+        GameWorld.DebugAnswer(curPlayer, "清除福地物品: MineArea clear [福地玩家ID,isPop]")
+        GameWorld.DebugAnswer(curPlayer, "输出功能数据: MineArea info")
+        GameWorld.DebugAnswer(curPlayer, "坐标: 0~100; []内为可选参数")
+        GameWorld.DebugAnswer(curPlayer, "玩家ID可以是假人ID: 1~%s" % GameWorldMineArea.Def_FakeAreaCount)
+        return
+    
+    playerID = curPlayer.GetPlayerID()
+    value1 = msgList[0]
+    if value1 == "item":
+        isSuper = msgList[1] if len(msgList) > 1 else 0
+        position = msgList[2] if len(msgList) > 2 else None
+        refreshIndexList = [msgList[3]] if len(msgList) > 3 else None
+        refreshDict = GameWorldMineArea.__DoMineItemRefresh(playerID, curPlayer, isSuper=isSuper, refreshIndexList=refreshIndexList, setPosition=position)
+        __PrintRefreshDict(curPlayer, refreshDict, "超级" if isSuper else "普通")
+        
+    # 刷新指定等级
+    elif value1 == "lv":
+        itemLV = msgList[1] if len(msgList) > 1 else 1
+        position = msgList[2] if len(msgList) > 2 else None
+        refreshIndexList = [msgList[3]] if len(msgList) > 3 else None
+        refreshDict = GameWorldMineArea.__DoMineItemRefresh(playerID, curPlayer, refreshIndexList=refreshIndexList, setPosition=position, setItemLV=itemLV)
+        __PrintRefreshDict(curPlayer, refreshDict, "指定等级:%s" % itemLV)
+        
+    # 刷新指定物品
+    elif value1 == "id":
+        mineID = msgList[1] if len(msgList) > 1 else 1
+        position = msgList[2] if len(msgList) > 2 else None
+        refreshIndexList = [msgList[3]] if len(msgList) > 3 else None
+        refreshDict = GameWorldMineArea.__DoMineItemRefresh(playerID, curPlayer, refreshIndexList=refreshIndexList, setPosition=position, setMineID=mineID)
+        __PrintRefreshDict(curPlayer, refreshDict, "指定ID:%s" % mineID)
+        
+    # 派工人拉物品
+    elif value1 == "pull":
+        itemIndex = msgList[1] if len(msgList) > 1 else 0
+        workerCount = msgList[2] if len(msgList) > 2 else 1
+        workerState = msgList[3] if len(msgList) > 3 else 0
+        workerID = msgList[4] if len(msgList) > 4 else playerID
+        areaPlayerID = msgList[5] if len(msgList) > 5 else playerID
+        if not workerID:
+            workerID = playerID
+        workerPlayer = GameWorld.GetPlayerManager().FindPlayerByID(workerID)
+        if not areaPlayerID:
+            areaPlayerID = playerID
+        
+        workerTotal, isPreview = 999, False
+        dataMsg = [areaPlayerID, itemIndex, workerCount, workerState, workerTotal, isPreview]
+        GameWorldMineArea.__DoPullItem(workerID, workerPlayer, dataMsg)
+        
+    # 输出正在拉的物品
+    elif value1 == "pulling":
+        pullPlayerID = msgList[1] if len(msgList) > 1 else playerID
+        mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+        itemList = mineItemMgr.pullingItemListDict.get(pullPlayerID, [])
+        GameWorld.DebugAnswer(curPlayer, "正在拉的物品数: %s %s %s" % (len(itemList), pullPlayerID, GameWorld.ChangeTimeNumToStr(int(time.time()))))
+        GameWorld.DebugLog("------ 正在拉的物品 ------ %s" % len(itemList), pullPlayerID)
+        for mineItemData in itemList:
+            __PrintMineItemLog(curPlayer, mineItemData.PlayerID, mineItemData.Index)
+        GameWorld.DebugLog("---------------------", pullPlayerID)
+        
+    # 输出福地物品
+    elif value1 == "area":
+        areaPlayerID = msgList[1] if len(msgList) > 1 else playerID
+        GameWorld.DebugAnswer(curPlayer, "福地物品: %s %s" % (areaPlayerID, GameWorld.ChangeTimeNumToStr(int(time.time()))))
+        GameWorld.DebugLog("------ 福地物品 ------", areaPlayerID)
+        for index in range(IpyGameDataPY.GetFuncCfg("MineAreaBase", 1)):
+            __PrintMineItemLog(curPlayer, areaPlayerID, index)
+        GameWorld.DebugLog("---------------------", areaPlayerID)
+        
+    # 清除福地物品
+    elif value1 == "clear":
+        areaPlayerID = msgList[1] if len(msgList) > 1 else playerID
+        if not areaPlayerID:
+            areaPlayerID = playerID
+        isPop = msgList[2] if len(msgList) > 2 else 1
+        __ClearAreaData(curPlayer, areaPlayerID, isPop)
+        
+    # 输出功能数据
+    elif value1 == "info":
+        __PrintAreaFuncInfo(curPlayer)
+        
+    else:
+        GameWorld.DebugAnswer(curPlayer, "没有该命令")
+        
+    return
+
+def __PrintRefreshDict(curPlayer, refreshDict, mark):
+    if not refreshDict:
+        GameWorld.DebugAnswer(curPlayer, "没有刷新出新物品")
+        return
+    GameWorld.DebugAnswer(curPlayer, "刷新福地物品: %s" % mark)
+    for index, refreshInfo in refreshDict.items():
+        randMineID = refreshInfo["randMineID"]
+        position = refreshInfo["position"]
+        mineType = refreshInfo["mineType"]
+        itemLV = refreshInfo["itemLV"]
+        GameWorld.DebugAnswer(curPlayer, "位置索引=%s,坐标=%s,类型=%s,等级=%s,ID=%s" % (index, position, mineType, itemLV, randMineID))
+    return
+
+def __PrintMineItemLog(curPlayer, areaPlayerID, index):
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    mineItemData = mineItemMgr.GetMineItem(areaPlayerID, index)
+    MineID = mineItemData.MineID
+    MineType = mineItemData.MineType
+    UpdTime = mineItemData.UpdTime
+    Position = mineItemData.Position
+    WorkerCount = mineItemData.WorkerCount
+    WorkerState = mineItemData.WorkerState
+    RobPlayerID = mineItemData.RobPlayerID
+    RobWorkerCount = mineItemData.RobWorkerCount
+    RobWorkerState = mineItemData.RobWorkerState
+    MoveSpeed = getattr(mineItemData, GameWorldMineArea.MineItemAttr_MoveSpeed, 0)
+    EndTime = getattr(mineItemData, GameWorldMineArea.MineItemAttr_EndTime, 0)
+    GameWorld.DebugLog("i=%s,MineID=%s,Position=%s,WorkerCnt-State=(%s-%s),RobWorkerCnt-State=(%s-%s),RobPlayerID=%s,UpdTime=%s,MineType=%s" 
+                       % (index, MineID, Position, WorkerCount, WorkerState, RobWorkerCount, RobWorkerState,
+                          RobPlayerID, GameWorld.ChangeTimeNumToStr(UpdTime), MineType), areaPlayerID)
+    endTimeStr = ""
+    remainHms = ""
+    if MoveSpeed and EndTime:
+        endTimeStr = GameWorld.ChangeTimeNumToStr(EndTime)
+        remainSeconds = EndTime - int(time.time())
+        remainH = remainSeconds / 3600
+        remainM = remainSeconds % 3600 / 60
+        remainS = remainSeconds % 60
+        remainHms = "%02d:%02d:%02d" % (remainH, remainM, remainS)
+        GameWorld.DebugLog("    MoveSpeed=%s,remainSeconds=%s(%s),EndTime=%s" 
+                           % (MoveSpeed, remainSeconds, remainHms, endTimeStr), areaPlayerID)
+        
+    GameWorld.DebugAnswer(curPlayer, "%s,ID(%s-%s),拉(%s-%s-%s),抢(%s-%s-%s),%s" 
+                          % (index, MineID, MineType, WorkerCount, WorkerState, areaPlayerID, RobWorkerCount, RobWorkerState, RobPlayerID, remainHms))
+    return
+
+def __ClearAreaData(curPlayer, areaPlayerID, isPop):
+    mineIndexList = range(IpyGameDataPY.GetFuncCfg("MineAreaBase", 1))
+    notifyPlayerIDListEx = []
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    for index in mineIndexList:
+        mineItemData = mineItemMgr.GetMineItem(areaPlayerID, index)
+        if mineItemData.RobPlayerID:
+            notifyPlayerIDListEx.append(mineItemData.RobPlayerID)
+        mineItemMgr.ClearMineItem(mineItemData)
+    GameWorldMineArea.SyncMineAreaItemInfo(areaPlayerID, mineIndexList, notifyPlayerIDListEx=notifyPlayerIDListEx)
+    if isPop:
+        mineItemMgr.playerMineItemDict.pop(areaPlayerID, None)
+        if areaPlayerID in mineItemMgr.realAreaPlayerIDList:
+            mineItemMgr.realAreaPlayerIDList.remove(areaPlayerID)
+        if areaPlayerID in mineItemMgr.fackAreaPlayerIDList:
+            mineItemMgr.fackAreaPlayerIDList.remove(areaPlayerID)
+    GameWorld.DebugAnswer(curPlayer, "清除福地数据! %s, isPop:%s" % (areaPlayerID, isPop))
+    return
+
+def __PrintAreaFuncInfo(curPlayer):
+    ## 输出功能数据,开发测试用
+    GameWorld.DebugAnswer(curPlayer, "----- 福地数据汇总 ----- %s" % GameWorld.GetGameWorld().GetTick(), False)
+    GameWorld.DebugLog("---------------------")
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    GameWorld.DebugLog("假人数: %s %s" % (len(mineItemMgr.fackAreaPlayerIDList), mineItemMgr.fackAreaPlayerIDList))
+    GameWorld.DebugLog("真人数: %s %s" % (len(mineItemMgr.realAreaPlayerIDList), mineItemMgr.realAreaPlayerIDList))
+    GameWorld.DebugAnswer(curPlayer, "假人数: %s" % (len(mineItemMgr.fackAreaPlayerIDList)), False)
+    GameWorld.DebugAnswer(curPlayer, "真人数: %s" % (len(mineItemMgr.realAreaPlayerIDList)), False)
+    pullingTotal = 0
+    for playerID, pullingItemList in mineItemMgr.pullingItemListDict.items():
+        GameWorld.DebugLog("拉取中物品: playerID=%s,数量=%s" % (playerID, len(pullingItemList)))
+        if pullingItemList:
+            GameWorld.DebugAnswer(curPlayer, "拉取中物品:%s,数量=%s" % (playerID, len(pullingItemList)), False)
+        pullingTotal += len(pullingItemList)
+    GameWorld.DebugLog("等待结束总数: %s, 拉取中总数=%s" % (len(mineItemMgr.allMineItemByEndTimeList), pullingTotal))
+    GameWorld.DebugAnswer(curPlayer, "等待结束总数:%s,拉取中总数:%s" % (len(mineItemMgr.allMineItemByEndTimeList), pullingTotal), False)
+    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)
+        
+    for areaPlayerID, viewPlayerIDList in mineItemMgr.viewAreaPlayerIDDict.items():
+        GameWorld.DebugLog("查看福地列表: areaPlayerID=%s,viewPlayerIDList=%s" % (areaPlayerID, viewPlayerIDList))
+        GameWorld.DebugAnswer(curPlayer, "查看福地列表:%s,%s" % (areaPlayerID, viewPlayerIDList), False)
+        
+    awardMgr = PyDataManager.GetDBPyMineAreaAwardManager()
+    awardPlayerIDList = awardMgr.playerAreaAwardDict.keys()
+    GameWorld.DebugLog("未领取结算奖励玩家: %s" % awardPlayerIDList)
+    GameWorld.DebugAnswer(curPlayer, "未领取结算奖励玩家: %s" % awardPlayerIDList, False)
+    GameWorld.DebugLog("---------------------")
+    GameWorld.DebugAnswer(curPlayer, "详见日志输出", False)
+    return
+
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py
index c6504ef..237cb4a 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py
@@ -1122,13 +1122,14 @@
     
     return 0
 
-def DebugAnswer(curPlayer, text):
+def DebugAnswer(curPlayer, text, isLog=True):
     '''转码后再发DebugAnswer'''
     #===========================================================================
     # if not GetGameWorld().GetDebugLevel():
     #    return
     #===========================================================================
-    DebugLog(text)
+    if isLog:
+        DebugLog(text)
     text = text.decode(ShareDefine.Def_Game_Character_Encoding).encode(GetCharacterEncoding())
     curPlayer.DebugAnswer(text)
     return
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py
new file mode 100644
index 0000000..7f3d41e
--- /dev/null
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py
@@ -0,0 +1,1320 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package GameWorldMineArea
+#
+# @todo:矿物福地
+# @author hxp
+# @date 2024-03-07
+# @version 1.0
+#
+# 详细描述: 矿物福地
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2024-03-07 19:30"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import NetPackCommon
+import PyDataManager
+import ChPyNetSendPack
+import PyGameDataStruct
+import PlayerViewCache
+import PlayerDBGSEvent
+import PlayerControl
+import IpyGameDataPY
+import ShareDefine
+import CommFunc
+    
+import operator
+import random
+import time
+import uuid
+
+Def_FakeAreaCount = 50 # 假人福地个数,一般就前期有用,上线后只能调大,不调小
+
+Def_RecordMax = 50 # 每个玩家保留最近50条记录
+
+Def_PositionMax = 100 # 最大距离,格
+Def_PositionMid = Def_PositionMax / 2 # 中间距离
+
+# 物品实例额外属性名
+MineItemAttr_MoveSpeed = "MoveSpeed"
+MineItemAttr_EndTime = "EndTime"
+
+# 物品类型
+MineType_Normal = 0 # 常规物品
+MineType_Super = 1 # 超级物品
+
+# 福地记录类型
+MineAreaRecordType_Pull = 1 # 拉物品
+MineAreaRecordType_BeRobbed = 2 # 被人抢
+
+MineAreaAwardGetTick = "MineAreaAwardGetTick"
+NeighborAreaRefreshTick = "NeighborAreaRefreshTick"
+
+class DBPyMineAreaAwardManager(object):
+    ## 福地奖励结算管理
+    
+    def __init__(self):
+        self.playerAreaAwardDict = {} # {playerID:{GUID:tagDBPyMineAreaAward, ...}, ...}
+        return
+    
+    def AddPlayerAreaAward(self, awardData):
+        playerID = awardData.PlayerID
+        if playerID not in self.playerAreaAwardDict:
+            self.playerAreaAwardDict[playerID] = {}
+        awardDict = self.playerAreaAwardDict[playerID]
+        awardDict[awardData.GUID] = awardData
+        return
+    
+    # 保存数据 存数据库和realtimebackup
+    def GetSaveData(self):
+        savaData = ""
+        cntData = ""
+        cnt = 0
+        
+        for awardDict in self.playerAreaAwardDict.values():
+            for awardData in awardDict.values():
+                cnt += 1
+                savaData += awardData.getBuffer()
+                
+        GameWorld.Log("Save DBPyMineAreaAward count :%s len=%s" % (cnt, len(savaData)))
+        return CommFunc.WriteDWORD(cntData, cnt) + savaData
+    
+    # 从数据库载入数据
+    def LoadPyGameData(self, datas, pos, dataslen):
+        cnt, pos = CommFunc.ReadDWORD(datas, pos)
+        GameWorld.Log("Load DBPyMineAreaAward count :%s" % cnt)
+        
+        self.playerAreaAwardDict = {}
+        
+        for _ in xrange(cnt):
+            awardData = PyGameDataStruct.tagDBPyMineAreaAward()
+            awardData.clear()
+            pos += awardData.readData(datas, pos, dataslen)
+            
+            self.AddPlayerAreaAward(awardData)
+            
+        return pos
+    
+class DBPyMineAreaRecordManager(object):
+    ## 福地矿物记录管理
+    
+    def __init__(self):
+        self.playerMineRecordListDict = {} # {playerID:[tagDBPyMineAreaRecord, ...], ...}
+        return
+    
+    def AddPlayerRecord(self, recordData):
+        playerID = recordData.PlayerID
+        if playerID not in self.playerMineRecordListDict:
+            self.playerMineRecordListDict[playerID] = []
+        recordList = self.playerMineRecordListDict[playerID]
+        recordList.append(recordData)
+        return recordList
+    
+    # 保存数据 存数据库和realtimebackup
+    def GetSaveData(self):
+        savaData = ""
+        cntData = ""
+        cnt = 0
+        
+        for recordList in self.playerMineRecordListDict.values():
+            for recordData in recordList:
+                cnt += 1
+                savaData += recordData.getBuffer()
+                        
+        GameWorld.Log("Save DBPyMineAreaRecord count :%s len=%s" % (cnt, len(savaData)))
+        return CommFunc.WriteDWORD(cntData, cnt) + savaData
+    
+    # 从数据库载入数据
+    def LoadPyGameData(self, datas, pos, dataslen):
+        cnt, pos = CommFunc.ReadDWORD(datas, pos)
+        GameWorld.Log("Load DBPyMineAreaRecord count :%s" % cnt)
+        
+        self.playerMineRecordListDict = {}
+        
+        for _ in xrange(cnt):
+            recordData = PyGameDataStruct.tagDBPyMineAreaRecord()
+            recordData.clear()
+            pos += recordData.readData(datas, pos, dataslen)
+            
+            self.AddPlayerRecord(recordData)
+            
+        return pos
+    
+class DBPyMineAreaItemManager(object):
+    ## 福地矿物管理
+    
+    def __init__(self):
+        self.Clear()
+        return
+    
+    def Clear(self):
+        self.playerMineItemDict = {} # 玩家福地物品信息 {playerID:{index:tagDBPyMineAreaItem, ...}, ...}
+        self.allMineItemByEndTimeList = [] # 根据结束时间排序的所有矿物 [tagDBPyMineAreaItem, ...]
+        self.pullingItemListDict = {} # 玩家拉取中的物品信息 {playerID:[tagDBPyMineAreaItem, ...], ...}
+        self.freeSuperItemList = [] # 没人拉的超级物品实例列表 [tagDBPyMineAreaItem, ...]
+        self.endSelfItemList = [] # 拉自己物品完结实例列表 [tagDBPyMineAreaItem, ...]
+        self.endRobItemList = [] # 被抢劫物品完结实例列表 [tagDBPyMineAreaItem, ...]
+        self.realAreaPlayerIDList = [] # 真实福地玩家ID列表
+        self.fackAreaPlayerIDList = [] # 假人福地玩家ID列表
+        self.viewAreaPlayerIDDict = {} # 正在查看某个福地中的玩家ID {areaPlayerID:[viewPlayerID, ...], ...}
+        
+        self.neighborIDListDict = {} # 玩家周围福地玩家ID列表 {playerID:[playerID, ...], ...}
+        self.socialIDListDict = {} # 玩家有关系道友福地玩家ID列表 {playerID:[playerID, ...], ...} playerID列表倒序
+        return
+    
+    def AddViewAreaPlayerID(self, viewPlayerID, areaPlayerID):
+        if areaPlayerID not in self.viewAreaPlayerIDDict:
+            self.viewAreaPlayerIDDict[areaPlayerID] = []
+        viewPlayerIDList = self.viewAreaPlayerIDDict[areaPlayerID]
+        if viewPlayerID not in viewPlayerIDList:
+            viewPlayerIDList.append(viewPlayerID)
+        return
+    def DelViewAreaPlayerID(self, viewPlayerID):
+        for viewPlayerIDList in self.viewAreaPlayerIDDict.values():
+            if viewPlayerID in viewPlayerIDList:
+                viewPlayerIDList.remove(viewPlayerID)
+        return
+    
+    def AddPlayerPullingItem(self, playerID, mineItemData):
+        if playerID not in self.pullingItemListDict:
+            self.pullingItemListDict[playerID] = []
+        pullingItemList = self.pullingItemListDict[playerID]
+        if mineItemData not in pullingItemList:
+            pullingItemList.append(mineItemData)
+        if mineItemData in self.freeSuperItemList:
+            self.freeSuperItemList.remove(mineItemData)
+        return
+    
+    def RemovePlayerPullingItem(self, playerID, mineItemData):
+        if playerID not in self.pullingItemListDict:
+            self.pullingItemListDict[playerID] = []
+        pullingItemList = self.pullingItemListDict[playerID]
+        if mineItemData in pullingItemList:
+            pullingItemList.remove(mineItemData)
+        return
+    
+    def ClearMineItem(self, mineItemData):
+        '''清除矿物,仅清除数据,对象保留,清除后 MineID 为0
+        @param mineItemData: PyGameDataStruct.tagDBPyMineAreaItem()
+        '''
+        if mineItemData in self.allMineItemByEndTimeList:
+            self.allMineItemByEndTimeList.remove(mineItemData)
+        if mineItemData.PlayerID:
+            self.RemovePlayerPullingItem(mineItemData.PlayerID, mineItemData)
+        if mineItemData.RobPlayerID:
+            self.RemovePlayerPullingItem(mineItemData.RobPlayerID, mineItemData)
+        if mineItemData in self.freeSuperItemList:
+            self.freeSuperItemList.remove(mineItemData)
+        self.InitMineItem(mineItemData, mineItemData.PlayerID, mineItemData.Index)
+        return
+    
+    def InitMineItem(self, mineItemData, playerID, index, mineID=0, mineType=0, position=""):
+        ## 矿物初始化
+        mineItemData.clear()
+        mineItemData.PlayerID = playerID
+        mineItemData.Index = index
+        mineItemData.MineID = mineID
+        mineItemData.MineType = mineType
+        mineItemData.UpdTime = int(time.time())
+        mineItemData.Position = "%s" % position
+        mineItemData.PosLen = len(mineItemData.Position)
+        
+        # 不入库的属性
+        setattr(mineItemData, MineItemAttr_EndTime, 0)
+        setattr(mineItemData, MineItemAttr_MoveSpeed, 0)
+        return
+    
+    def GetMineItem(self, playerID, index):
+        '''获取玩家福地矿物
+        @param playerID: 福地玩家ID
+        @param index: 矿物所在福地索引
+        @return: PyGameDataStruct.tagDBPyMineAreaItem()
+        '''
+        if playerID not in self.playerMineItemDict:
+            self.playerMineItemDict[playerID] = {}
+        itemDict = self.playerMineItemDict[playerID]
+        if index in itemDict:
+            mineItemData = itemDict[index]
+        else:
+            mineItemData = PyGameDataStruct.tagDBPyMineAreaItem()
+            self.InitMineItem(mineItemData, playerID, index)
+            itemDict[index] = mineItemData
+            self.AddMineAreaPlayerID(playerID)
+            
+        return mineItemData
+    
+    def AddMineAreaPlayerID(self, playerID):
+        if playerID > Def_FakeAreaCount:
+            if playerID not in self.realAreaPlayerIDList:
+                self.realAreaPlayerIDList.append(playerID)
+        else:
+            if playerID not in self.fackAreaPlayerIDList:
+                self.fackAreaPlayerIDList.append(playerID)
+        return
+    
+    # 保存数据 存数据库和realtimebackup
+    def GetSaveData(self):
+        savaData = ""
+        cntData = ""
+        cnt = 0
+        
+        for itemDict in self.playerMineItemDict.values():
+            for mineItemData in itemDict.values():
+                cnt += 1
+                savaData += mineItemData.getBuffer()
+                
+        GameWorld.Log("Save DBPyMineAreaItem count :%s len=%s" % (cnt, len(savaData)))
+        return CommFunc.WriteDWORD(cntData, cnt) + savaData
+    
+    # 从数据库载入数据
+    def LoadPyGameData(self, datas, pos, dataslen):
+        cnt, pos = CommFunc.ReadDWORD(datas, pos)
+        GameWorld.Log("Load DBPyMineAreaItem count :%s" % cnt)
+        
+        self.Clear()
+        
+        for _ in xrange(cnt):
+            mineItemData = PyGameDataStruct.tagDBPyMineAreaItem()
+            mineItemData.clear()
+            pos += mineItemData.readData(datas, pos, dataslen)
+            
+            OnLoadMineItemData(mineItemData)
+            
+        OnLoadMineItemOK()
+        return pos
+
+def DoMineAreaFuncOpen(curPlayer):
+    ## 福地功能开启
+    playerID = curPlayer.GetPlayerID()
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    # 还没有福地物品数据,则刷新初始化
+    if playerID not in mineItemMgr.playerMineItemDict:
+        __DoMineItemRefresh(playerID, curPlayer)
+    return
+
+def OnPlayerLogin(curPlayer):
+    playerID = curPlayer.GetPlayerID()
+    
+    # 自己福地数据
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    if playerID in mineItemMgr.playerMineItemDict:
+        NetPackCommon.SendFakePack(curPlayer, __GetMineAreaInfoPack([[playerID, []]]))
+        
+    # 拉取中的物品数据
+    SyncPullingAreaMineInfo(curPlayer)
+    
+    # 有未领取的结算奖励
+    awardMgr = PyDataManager.GetDBPyMineAreaAwardManager()
+    awardDict = awardMgr.playerAreaAwardDict.get(playerID, {})
+    if awardDict:
+        SyncMineAwardAward(curPlayer)
+        
+    return
+
+def OnLoadMineItemData(mineItemData):
+    ## 加载矿物
+    playerID = mineItemData.PlayerID
+    index = mineItemData.Index
+    mineID = mineItemData.MineID
+    if not mineID:
+        return
+    mineType = mineItemData.MineType
+    workerCount = mineItemData.WorkerCount
+    robPlayerID = mineItemData.RobPlayerID
+    robWorkerCount = mineItemData.RobWorkerCount
+    
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    
+    if playerID not in mineItemMgr.playerMineItemDict:
+        mineItemMgr.playerMineItemDict[playerID] = {}
+    itemDict = mineItemMgr.playerMineItemDict[playerID]
+    itemDict[index] = mineItemData
+    mineItemMgr.AddMineAreaPlayerID(playerID)
+    
+    if mineType == MineType_Super and not workerCount and not robWorkerCount and mineItemData not in mineItemMgr.freeSuperItemList:
+        mineItemMgr.freeSuperItemList.append(mineItemData)
+        
+    if workerCount:
+        mineItemMgr.AddPlayerPullingItem(playerID, mineItemData)
+        
+    if robPlayerID and robWorkerCount:
+        mineItemMgr.AddPlayerPullingItem(robPlayerID, mineItemData)    
+        
+    __RefreshMineItemSpeed(mineItemData)
+    return
+
+def OnLoadMineItemOK():
+    __SortMineItem()
+    __MakeFackArea()
+    
+    # 启动默认补充空位置物品...
+    refreshIndexList = range(IpyGameDataPY.GetFuncCfg("MineAreaBase", 1))
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    for areaPlayerID, itemDict in mineItemMgr.playerMineItemDict.items():
+        emptyIndexList = []
+        for index in refreshIndexList:
+            if index not in itemDict:
+                emptyIndexList.append(index)
+                continue
+            mineItemData = itemDict[index]
+            if not mineItemData or not mineItemData.MineID:
+                emptyIndexList.append(index)
+                continue
+        if not emptyIndexList:
+            continue
+        GameWorld.DebugLog("启动默认补充空位置物品: areaPlayerID=%s,emptyIndexList=%s" % (areaPlayerID, emptyIndexList))
+        __DoMineItemRefresh(areaPlayerID, refreshIndexList=emptyIndexList)
+        
+    return
+
+def __MakeFackArea():
+    # 生成假人福地数据
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    if len(mineItemMgr.playerMineItemDict) >= Def_FakeAreaCount:
+        return
+    needFackCount = Def_FakeAreaCount - len(mineItemMgr.playerMineItemDict)
+    fackPlayerID = 0
+    while needFackCount > 0 and fackPlayerID < Def_FakeAreaCount:
+        fackPlayerID += 1
+        if fackPlayerID in mineItemMgr.playerMineItemDict:
+            continue
+        if __DoMineItemRefresh(fackPlayerID, isNotify=False):
+            GameWorld.DebugLog("新增福地假人: %s" % fackPlayerID)
+            needFackCount -= 1
+    return
+
+def __SortMineItem():
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    mineItemMgr.allMineItemByEndTimeList.sort(key=operator.attrgetter(MineItemAttr_EndTime))
+    return
+
+def __RefreshMineItemPosition(mineItemData, curTime):
+    ## 刷新矿物坐标
+    playerID = mineItemData.PlayerID
+    index = mineItemData.Index
+    mineID = mineItemData.MineID
+    curPos = GameWorld.ToIntDef(mineItemData.Position, Def_PositionMid)
+    if not playerID or not mineID:
+        return curPos
+    
+    curWorkerCount = mineItemData.WorkerCount
+    robWorkerCount = mineItemData.RobWorkerCount
+    if not curWorkerCount and not robWorkerCount:
+        return curPos
+    moveSpeed = getattr(mineItemData, MineItemAttr_MoveSpeed)
+    if not moveSpeed:
+        return curPos
+    passSeconds = curTime - mineItemData.UpdTime
+    if passSeconds <= 0 or not moveSpeed:
+        return curPos
+    
+    moveDir = -1 if curWorkerCount >= robWorkerCount else 1 # 移动方向,-1-下; 1-上
+    moveDist = moveSpeed * passSeconds * moveDir
+    updPos = min(max(0, curPos + moveDist), Def_PositionMax)
+    mineItemData.Position = "%s" % updPos
+    mineItemData.PosLen = len(mineItemData.Position)
+    mineItemData.UpdTime = curTime
+    GameWorld.DebugLog("更新矿物坐标: playerID=%s,index=%s,mineID=%s,curWorkerCount=%s,robWorkerCount=%s,curPos=%s,moveSpeed=%s,passSeconds=%s,moveDist=%s,updPos=%s" 
+                       % (playerID, index, mineID, curWorkerCount, robWorkerCount, curPos, moveSpeed, passSeconds, moveDist, updPos))
+    return updPos
+
+def __RefreshMineItemSpeed(mineItemData, isSort=False):
+    ## 刷新矿物速度、完成时间
+    playerID = mineItemData.PlayerID
+    index = mineItemData.Index
+    mineID = mineItemData.MineID
+    if not playerID or not mineID:
+        return
+    
+    curPos = GameWorld.ToIntDef(mineItemData.Position, Def_PositionMid)
+    allMineItemByEndTimeList = PyDataManager.GetDBPyMineAreaItemManager().allMineItemByEndTimeList
+    curWorkerCount = mineItemData.WorkerCount
+    robWorkerCount = mineItemData.RobWorkerCount
+    if not curWorkerCount and not robWorkerCount:
+        setattr(mineItemData, MineItemAttr_EndTime, 0)
+        setattr(mineItemData, MineItemAttr_MoveSpeed, 0)
+        if mineItemData in allMineItemByEndTimeList:
+            allMineItemByEndTimeList.remove(mineItemData)
+        return
+    
+    GameWorld.DebugLog("更新矿物时间速度: playerID=%s,index=%s,mineID=%s,curWorkerCount=%s,robWorkerCount=%s,curPos=%s" 
+                       % (playerID, index, mineID, curWorkerCount, robWorkerCount, curPos))
+    curWorkerState = mineItemData.WorkerState
+    robWorkerState = mineItemData.RobWorkerState
+    ret = __calcMineItemSpeed(mineID, curPos, curWorkerCount, curWorkerState, robWorkerCount, robWorkerState)
+    if not ret:
+        return
+    moveSpeed, needSeconds = ret
+    
+    updTime = mineItemData.UpdTime
+    endTime = updTime + needSeconds
+    GameWorld.DebugLog("    updTime=%s,needSeconds=%s,endTime=%s" 
+                       % (GameWorld.ChangeTimeNumToStr(updTime), needSeconds, GameWorld.ChangeTimeNumToStr(endTime)))
+    
+    setattr(mineItemData, MineItemAttr_EndTime, endTime)
+    setattr(mineItemData, MineItemAttr_MoveSpeed, moveSpeed)
+    
+    if mineItemData not in allMineItemByEndTimeList:
+        allMineItemByEndTimeList.append(mineItemData)
+    if isSort:
+        __SortMineItem()
+    return True
+
+def __calcMineItemSpeed(mineID, curPos, curWorkerCount, curWorkerState, robWorkerCount, robWorkerState):
+    ## 计算拉物品速度,这里只处理计算逻辑,实际应用由调用者决定
+    # @param return: moveSpeed, needSeconds 或  异常返回None
+    if not curWorkerCount and not robWorkerCount:
+        return 0, 0
+    
+    ipyData = IpyGameDataPY.GetIpyGameData("MineAreaItem", mineID)
+    if not ipyData:
+        return
+    itemWeight = ipyData.GetItemWeight()
+    
+    moveDir = -1 if curWorkerCount >= robWorkerCount else 1 # 移动方向,-1-下; 1-上
+    
+    # 下 - 拉回
+    if moveDir == -1:
+        dist = curPos # 还需移动距离
+        workerState = curWorkerState
+        workerCount, batWorkerCount = curWorkerCount, robWorkerCount
+    # 上 - 抢劫
+    else:
+        dist = Def_PositionMax - curPos
+        workerState = robWorkerState
+        workerCount, batWorkerCount = robWorkerCount, curWorkerCount
+        
+    workerStateTimeList = IpyGameDataPY.GetFuncEvalCfg("MineAreaWorkCalc", 1) # 疲劳状态单位耗时列表
+    workerCountRatioList = IpyGameDataPY.GetFuncEvalCfg("MineAreaWorkCalc", 2) # 人数耗时比率列表
+    workerBattleRatioList = IpyGameDataPY.GetFuncEvalCfg("MineAreaWorkCalc", 3) # 对抗人数耗时比率列表
+    
+    baseTime = workerStateTimeList[len(workerStateTimeList) - 1] if workerState >= len(workerStateTimeList) else workerStateTimeList[workerState]
+    workRatio = workerCountRatioList[len(workerCountRatioList) - 1] if workerCount > len(workerCountRatioList) else workerCountRatioList[workerCount - 1]
+    battleRatio = 1 # 没人对抗时,默认1
+    if batWorkerCount > 0:
+        battleRatio = workerBattleRatioList[len(workerBattleRatioList) - 1] if batWorkerCount > len(workerBattleRatioList) else workerBattleRatioList[batWorkerCount - 1]
+        
+    needSeconds = int(dist * itemWeight * baseTime * workRatio * battleRatio) # 还需工作时长,秒
+    moveSpeed = dist / float(needSeconds) # 移动速度  x格/秒
+    needHms = "%02d:%02d:%02d" % (needSeconds / 3600, needSeconds % 3600 / 60, needSeconds % 60)
+    
+    GameWorld.DebugLog("    mineID=%s,curPos=%s,curWorkerCount=%s,curWorkerState=%s,robWorkerCount=%s,robWorkerState=%s" 
+                       % (mineID, curPos, curWorkerCount, curWorkerState, robWorkerCount, robWorkerState))
+    GameWorld.DebugLog("    moveDir=%s,dist=%s,itemWeight=%s,baseTime=%s,workRatio=%s,battleRatio=%s,needSeconds=%s(%s),moveSpeed=%s" 
+                       % (moveDir, dist, itemWeight, baseTime, workRatio, battleRatio, needSeconds, needHms, moveSpeed))
+    return moveSpeed, needSeconds
+
+def OnProcessOnMinute():
+    ## 定时处理,每分钟一次
+    __Process_SysRefresh()
+    return
+
+def __Process_SysRefresh():
+    ## 系统定时刷新
+    sysRefreshHMList = IpyGameDataPY.GetFuncEvalCfg("MineAreaSysRefresh", 1)
+    if not sysRefreshHMList:
+        return
+    dayTime = GameWorld.GetServerTime()
+    curHourMinute = [dayTime.hour, dayTime.minute]
+    if curHourMinute not in sysRefreshHMList:
+        return
+    GameWorld.Log("福地系统定时刷新! %s" % str(curHourMinute))
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    for playerID in mineItemMgr.playerMineItemDict.keys():
+        __DoMineItemRefresh(playerID, isSuper=True)
+    return
+
+def OnMineItemTimeProcess(curTime, tick):
+    ## 定时处理,每秒触发一次
+    
+    # 待优化处理...
+    # 定时删除多余数据,如过天处理,多余记录
+    # 合服多余数据清理,合服假人ID重复问题
+    
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    __Process_EndItemRefresh(mineItemMgr.endSelfItemList, IpyGameDataPY.GetFuncCfg("MineAreaSysRefresh", 2), curTime)
+    __Process_EndItemRefresh(mineItemMgr.endRobItemList, IpyGameDataPY.GetFuncCfg("MineAreaSysRefresh", 3), curTime)
+    __Process_SuperItem(curTime)
+    __Process_MineItemByEndTimeList(curTime)
+    return
+
+def __Process_EndItemRefresh(endItemList, refreshCD, curTime):
+    ## 定时处理空位置物品刷新
+    if not endItemList:
+        return
+    doCount = len(endItemList)
+    index = 0
+    while doCount > 0 and index < len(endItemList):
+        doCount -= 1
+        mineItemData = endItemList[index]
+        if not mineItemData or mineItemData.MineID:
+            # None 或 已经有物品了,不再处理,直接移除
+            endItemList.pop(index)
+            continue
+        UpdTime = mineItemData.UpdTime
+        if curTime - UpdTime < refreshCD:
+            # 因为是按结束先后顺序添加的,所以只要还在CD,则后面的一定也是CD中
+            break
+        areaPlayerID = mineItemData.PlayerID
+        itemIndex = mineItemData.Index
+        if __DoMineItemRefresh(areaPlayerID, refreshIndexList=[itemIndex]):
+            endItemList.pop(index) # 成功刷新后直接移除
+            continue
+        index += 1
+    return
+
+def __Process_SuperItem(curTime):
+    ## 定时处理超级物品
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    freeSuperItemList = mineItemMgr.freeSuperItemList
+    if not freeSuperItemList:
+        return
+    superItemExistSeconds = IpyGameDataPY.GetFuncCfg("MineAreaSuperItem", 1)
+    
+    doCount = len(freeSuperItemList)
+    index = 0
+    while doCount > 0 and freeSuperItemList:
+        doCount -= 1
+        mineItemData = freeSuperItemList[index]
+        if not mineItemData or mineItemData.WorkerCount or mineItemData.RobWorkerCount:
+            # None 或 已经有人再拉了,不再处理,直接移除
+            freeSuperItemList.pop(index)
+            continue
+        UpdTime = mineItemData.UpdTime
+        if curTime - UpdTime < superItemExistSeconds:
+            break
+        areaPlayerID = mineItemData.PlayerID
+        itemIndex = mineItemData.Index
+        GameWorld.DebugLog("超级物品过期! areaPlayerID=%s,itemIndex=%s" % (areaPlayerID, itemIndex))
+        mineItemMgr.ClearMineItem(mineItemData)
+        __OnEndSelfItem(mineItemMgr, mineItemData, areaPlayerID, itemIndex)
+        SyncMineAreaItemInfo(areaPlayerID, [itemIndex])
+        
+    return
+
+def __Process_MineItemByEndTimeList(curTime):
+    ## 定时处理拉时间到物品
+    allMineItemByEndTimeList = PyDataManager.GetDBPyMineAreaItemManager().allMineItemByEndTimeList
+    if not allMineItemByEndTimeList:
+        return
+    index = 0
+    doCount = len(allMineItemByEndTimeList)
+    while doCount > 0 and allMineItemByEndTimeList:
+        doCount -= 1
+        mineItemData = allMineItemByEndTimeList[index]
+        endTime = getattr(mineItemData, MineItemAttr_EndTime)
+        if curTime < endTime:
+            break
+        
+        ret = __EndMineItemByTime(mineItemData.PlayerID, mineItemData.Index, curTime)
+        if ret == None:
+            if index < len(allMineItemByEndTimeList):
+                allMineItemByEndTimeList.pop(index)
+        elif ret == False:
+            index += 1
+    return
+
+def __EndMineItemByTime(areaPlayerID, itemIndex, curTime):
+    ## 根据时间结束矿物
+    ## @return: 是否结束,None-异常情况
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    mineItemData = mineItemMgr.GetMineItem(areaPlayerID, itemIndex)
+    mineID = mineItemData.MineID
+    if not mineID:
+        return
+    
+    useWorkerCount = 1
+    notifyPlayerIDListEx = []
+    curPos = __RefreshMineItemPosition(mineItemData, curTime)    
+    # 兼容1格
+    # 自己拉回
+    if curPos <= 1:
+        awardPlayerID = areaPlayerID
+        useWorkerCount = mineItemData.WorkerCount
+    # 抢劫拉走
+    elif curPos >= Def_PositionMax - 1:
+        awardPlayerID = mineItemData.RobPlayerID
+        useWorkerCount = mineItemData.RobWorkerCount
+        notifyPlayerIDListEx = [awardPlayerID]
+    else:
+        return False
+    
+    ipyData = IpyGameDataPY.GetIpyGameData("MineAreaItem", mineID)
+    if not ipyData:
+        return
+    
+    # 奖励玩家并不一定在线,统一添加进奖励,由玩家请求结算
+    awardData = PyGameDataStruct.tagDBPyMineAreaAward()
+    awardData.GUID = str(uuid.uuid1())
+    awardData.GUIDLen = len(awardData.GUID)
+    awardData.PlayerID = awardPlayerID
+    awardData.AwardTime = int(time.time())
+    awardData.MineID = mineID
+    awardData.WorkerCount = useWorkerCount
+    awardData.AreaPlayerID = areaPlayerID
+    PyDataManager.GetDBPyMineAreaAwardManager().AddPlayerAreaAward(awardData)
+    # 通知有奖励
+    awardPlayer = GameWorld.GetPlayerManager().FindPlayerByID(awardPlayerID)
+    if awardPlayer:
+        SyncMineAwardAward(awardPlayer)
+        
+    GameWorld.DebugLog("根据时间结束物品: areaPlayerID=%s,itemIndex=%s,mineID=%s,awardPlayerID=%s" 
+                       % (areaPlayerID, itemIndex, mineID, awardPlayerID))
+    
+    mineItemMgr.ClearMineItem(mineItemData)
+    
+    #增加记录
+    AddMineItemRecord(awardPlayerID, MineAreaRecordType_Pull, areaPlayerID, mineID, curTime)
+    if areaPlayerID != awardPlayerID:
+        AddMineItemRecord(areaPlayerID, MineAreaRecordType_BeRobbed, awardPlayerID, mineID, curTime)
+        
+        # 被抢的
+        if IpyGameDataPY.GetFuncCfg("MineAreaSysRefresh", 3) > 0:
+            mineItemMgr.endRobItemList.append(mineItemData)
+        else:
+            __DoMineItemRefresh(areaPlayerID, isNotify=False, refreshIndexList=[itemIndex])
+    else:
+        # 拉自己的
+        __OnEndSelfItem(mineItemMgr, mineItemData, areaPlayerID, itemIndex)
+        
+    SyncMineAreaItemInfo(areaPlayerID, [itemIndex], notifyPlayerIDListEx)
+    return True
+
+def __OnEndSelfItem(mineItemMgr, mineItemData, areaPlayerID, itemIndex):
+    # 自己的物品结束,包含自己拉的,自己消失的(如超级物品),不含被抢的
+    if IpyGameDataPY.GetFuncCfg("MineAreaSysRefresh", 2) > 0:
+        mineItemMgr.endSelfItemList.append(mineItemData)
+    else:
+        __DoMineItemRefresh(areaPlayerID, isNotify=False, refreshIndexList=[itemIndex])
+    return
+
+def AddMineItemRecord(playerID, recordType, tagPlayerID, mineID, curTime):
+    recordData = PyGameDataStruct.tagDBPyMineAreaRecord()
+    recordData.PlayerID = playerID
+    recordData.RecordType = recordType
+    recordData.TagPlayerID = tagPlayerID
+    recordData.MineID = mineID
+    recordData.RecordTime = curTime
+    
+    recordMgr = PyDataManager.GetDBPyMineAreaRecordManager()
+    recordList = recordMgr.AddPlayerRecord(recordData)
+    
+    # 被人抢,更新关系福地ID记录
+    if recordData.RecordType == MineAreaRecordType_BeRobbed and playerID > Def_FakeAreaCount:
+        __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:
+            ## 优先保留被抢记录关系玩家
+            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
+
+def MapServer_MineArea(curPlayer, msgList):
+    mapID = curPlayer.GetRealMapID()
+    playerID = curPlayer.GetPlayerID()
+    GameWorld.DebugLog("MapServer_MineArea mapID=%s,msgList=%s" % (mapID, msgList), playerID)
+    if not msgList:
+        return
+    
+    msgType, dataMsg = msgList
+    ret = None
+    
+    # 拉物品
+    if msgType == "Pull":
+        __DoPullItem(playerID, curPlayer, dataMsg)
+
+    # 刷新福地物品
+    elif msgType == "MineItemRefresh":
+        playerID, isSuper = dataMsg
+        __DoMineItemRefresh(playerID, curPlayer, isSuper=isSuper)
+
+    # 地图结算奖励OK
+    elif msgType == "MineAreaAwardGetOK":
+        __DoMineAreaAwardGetOK(curPlayer, dataMsg)
+        
+    if ret == None:
+        return
+    return msgList + [ret]
+
+def __DoPullItem(playerID, curPlayer, dataMsg):
+    areaPlayerID, itemIndex, workerCount, workerState, workerTotal, isPreview = dataMsg
+    if itemIndex < 0 or itemIndex >= IpyGameDataPY.GetFuncCfg("MineAreaBase", 1):
+        GameWorld.ErrLog("不存在该福地物品位置索引! itemIndex=%s" % itemIndex)
+        return
+    if workerCount <= 0:
+        if not isPreview:
+            __DoCancelPull(playerID, areaPlayerID, itemIndex)
+        return
+    GameWorld.DebugLog("请求福地拉物品! areaPlayerID=%s,itemIndex=%s,workerCount=%s,workerState=%s,workerTotal=%s,isPreview=%s" 
+                       % (areaPlayerID, itemIndex, workerCount, workerState, workerTotal, isPreview), playerID)
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    mineItemData = mineItemMgr.GetMineItem(areaPlayerID, itemIndex)
+    mineID = mineItemData.MineID
+    if not mineID:
+        GameWorld.ErrLog("该福地位置没有矿物,无法拉取! areaPlayerID=%s,itemIndex=%s" % (areaPlayerID, itemIndex), playerID)
+        return
+    
+    if mineItemData.MineType == MineType_Super:
+        if playerID != areaPlayerID:
+            GameWorld.DebugLog("福地超级物品,仅自己可拉! areaPlayerID=%s,itemIndex=%s" % (areaPlayerID, itemIndex), playerID)
+            return
+        
+    ipyData = IpyGameDataPY.GetIpyGameData("MineAreaItem", mineID)
+    if not ipyData:
+        return
+    itemLV = ipyData.GetItemLV()
+    itemLVWorkerMaxList = IpyGameDataPY.GetFuncEvalCfg("MineAreaBase", 3)
+    assignMax = itemLVWorkerMaxList[itemLV - 1] if itemLV <= len(itemLVWorkerMaxList) else itemLVWorkerMaxList[-1] # 最大可上工人数
+    
+    atWorkCount = 0 # 已经在其他物品工作的工人数
+    pullingItemList = mineItemMgr.pullingItemListDict.get(playerID, [])
+    for pullItemData in pullingItemList:
+        if pullItemData.PlayerID == areaPlayerID and pullItemData.Index == itemIndex:
+            # 对同一物品操作,不算工作人数,可能是修改人数
+            continue
+        if pullItemData.PlayerID == playerID:
+            atWorkCount += pullItemData.WorkerCount
+        elif pullItemData.RobPlayerID == playerID:
+            atWorkCount += pullItemData.RobWorkerCount
+            if pullItemData.PlayerID == areaPlayerID:
+                GameWorld.DebugLog("不能同时抢劫同个人多个物品! 已经在抢福地位置: areaPlayerID=%s,index=%s" % (areaPlayerID, pullItemData.Index), playerID)
+                return
+    freeWorkerCount = workerTotal - atWorkCount # 空闲工人数
+    
+    assignWorkerCount = min(freeWorkerCount, assignMax, workerCount) # 实际可派遣的工人数
+    if assignWorkerCount <= 0:
+        GameWorld.DebugLog("没有工人可派遣! atWorkCount=%s,workerTotal=%s,assignWorkerCount=%s" % (atWorkCount, workerTotal, assignWorkerCount), playerID)
+        return
+    
+    curTime = int(time.time())
+    # 先刷新下物品最新位置
+    __RefreshMineItemPosition(mineItemData, curTime)
+    
+    if isPreview:
+        ## 预览速度时间
+        curPos = GameWorld.ToIntDef(mineItemData.Position, Def_PositionMid)
+        if playerID == areaPlayerID:
+            curWorkerCount = assignWorkerCount
+            curWorkerState = workerState
+            robWorkerCount = mineItemData.RobWorkerCount
+            robWorkerState = mineItemData.RobWorkerState
+        else:
+            curWorkerCount = mineItemData.WorkerCount
+            curWorkerState = mineItemData.WorkerState
+            robWorkerCount = assignWorkerCount
+            robWorkerState = workerState
+        ret = __calcMineItemSpeed(mineID, curPos, curWorkerCount, curWorkerState, robWorkerCount, robWorkerState)
+        if not ret:
+            return
+        _, needSeconds = ret
+        if curPlayer:
+            clientPack = ChPyNetSendPack.tagGCMineItemPullPreviewRet()
+            clientPack.PlayerID = areaPlayerID
+            clientPack.ItemIndex = itemIndex
+            clientPack.WorkerCount = assignWorkerCount
+            clientPack.NeedSeconds = needSeconds
+            NetPackCommon.SendFakePack(curPlayer, clientPack)
+        return
+    
+    notifyPlayerIDListEx = []
+    # 替换新数据
+    if playerID == areaPlayerID:
+        mineItemData.WorkerCount = assignWorkerCount
+        mineItemData.WorkerState = workerState
+    else:
+        mineItemData.RobPlayerID = playerID
+        mineItemData.RobWorkerCount = assignWorkerCount
+        mineItemData.RobWorkerState = workerState
+        notifyPlayerIDListEx = [playerID]
+    mineItemData.UpdTime = curTime
+    
+    mineItemMgr.AddPlayerPullingItem(playerID, mineItemData)
+    
+    # 重新刷新下速度时间
+    __RefreshMineItemSpeed(mineItemData, True)
+    
+    SyncMineAreaItemInfo(areaPlayerID, [itemIndex], notifyPlayerIDListEx)
+    return
+
+def __DoCancelPull(playerID, areaPlayerID, itemIndex):
+    ## 取消拉取
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    mineItemData = mineItemMgr.GetMineItem(areaPlayerID, itemIndex)
+    mineID = mineItemData.MineID
+    if not mineID:
+        return
+    
+    notifyPlayerIDListEx = []
+    
+    if mineItemData.MineType == MineType_Super:
+        mineItemMgr.ClearMineItem(mineItemData)
+        __OnEndSelfItem(mineItemMgr, mineItemData, areaPlayerID, itemIndex)
+    else:
+        curTime = int(time.time())
+        # 先刷新下物品最新位置
+        __RefreshMineItemPosition(mineItemData, curTime)
+        
+        # 替换新数据
+        if playerID == areaPlayerID:
+            mineItemData.WorkerCount = 0
+            mineItemData.WorkerState = 0
+        else:
+            mineItemData.RobPlayerID = 0
+            mineItemData.RobWorkerCount = 0
+            mineItemData.RobWorkerState = 0
+            notifyPlayerIDListEx = [playerID]
+        mineItemData.UpdTime = curTime
+        
+        mineItemMgr.RemovePlayerPullingItem(playerID, mineItemData)
+        
+        # 重新刷新下速度时间
+        __RefreshMineItemSpeed(mineItemData, True)
+        
+    SyncMineAreaItemInfo(areaPlayerID, [itemIndex], notifyPlayerIDListEx)
+    return
+
+def __DoMineItemRefresh(areaPlayerID, areaPlayer=None, isSys=False, isSuper=False, isNotify=True, refreshIndexList=None, setPosition=None, setItemLV=None, setMineID=None):
+    '''刷新福地物品
+    @param areaPlayerID: 福地玩家ID,可能是假人
+    @param areaPlayer: 福地玩家实例
+    @param isSuper: 是否超级刷新,默认刷1个时效满级物品,默认自己可采,取消后消失,时间到没采也消失
+    @param refreshIndexList: 指定只刷位置索引列表,没有指定则只刷新可刷新的
+    @param setPosition: 指定坐标位置,没有指定则随机
+    @param setItemLV: 指定只刷某个等级物品,没有指定则随机
+    @param setMineID: 指定只刷某个ID,没有指定则随机
+    '''
+    
+    GameWorld.DebugLog("刷新福地物品: refreshIndexList=%s,isSys=%s,isSuper=%s" % (refreshIndexList, isSys, isSuper), areaPlayerID)
+    if setPosition or setItemLV or setMineID:
+        GameWorld.DebugLog("    setPosition=%s,setItemLV=%s,setMineID=%s" % (setPosition, setItemLV, setMineID), areaPlayerID)
+        
+    playerLV = 0
+    if areaPlayerID > Def_FakeAreaCount:
+        if areaPlayer and areaPlayer.GetPlayerID() == areaPlayerID:
+            playerLV = areaPlayer.GetLV()
+        else:
+            tagCacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(areaPlayerID))
+            playerLV = tagCacheDict.get("LV", 0)
+        GameWorld.DebugLog("    取玩家等级 playerLV=%s" % (playerLV), areaPlayerID)
+        
+    if not playerLV:
+        # 取世界等级
+        playerLV = max(1, PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv))
+        GameWorld.DebugLog("    取世界等级 playerLV=%s" % (playerLV), areaPlayerID)
+        
+    randWeightList = []
+    randWeightListSuper = []
+    ipyDataMgr = IpyGameDataPY.IPY_Data()
+    for index in range(ipyDataMgr.GetMineAreaItemCount()):
+        ipyData = ipyDataMgr.GetMineAreaItemByIndex(index)
+        mineID = ipyData.GetMineID()
+        limitLV = ipyData.GetLimitLV()
+        if limitLV and playerLV < limitLV:
+            continue
+        if setItemLV and setItemLV != ipyData.GetItemLV():
+            continue
+        if setMineID and setMineID != mineID:
+            continue
+        
+        weight = ipyData.GetRefreshWeightSuper()
+        if weight:
+            randWeightListSuper.append([weight, ipyData])
+            
+        weight = ipyData.GetRefreshWeightSys() if isSys else ipyData.GetRefreshWeight()
+        if weight:
+            randWeightList.append([weight, ipyData])
+            
+    #GameWorld.DebugLog("    randWeightList=%s" % randWeightList, areaPlayerID)
+    #GameWorld.DebugLog("    randWeightListSuper=%s" % randWeightListSuper, areaPlayerID)
+    if not randWeightList and not randWeightListSuper:
+        return
+    
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    randDist = IpyGameDataPY.GetFuncCfg("MineAreaBase", 2)
+    superCount = 0
+    superCountMax = 1 # 每次刷新最大刷出超级物品数量,已经刷新出的不计算在内
+    
+    refreshDict = {}
+    if not refreshIndexList:
+        refreshIndexList = range(IpyGameDataPY.GetFuncCfg("MineAreaBase", 1))
+    for index in refreshIndexList:
+        mineItemData = mineItemMgr.GetMineItem(areaPlayerID, index)
+        if mineItemData.MineID and (mineItemData.WorkerCount or mineItemData.RobWorkerCount):
+            # 有人了,不刷新
+            continue
+        
+        randIpyData = None
+        mineType = MineType_Normal
+        
+        if isSuper and superCount < superCountMax:
+            randIpyData = GameWorld.GetResultByWeightList(randWeightListSuper)
+            if randIpyData:
+                superCount += 1
+                mineType = MineType_Super
+        else:
+            randIpyData = GameWorld.GetResultByWeightList(randWeightList)
+            
+        if not randIpyData:
+            continue
+        randMineID = randIpyData.GetMineID()
+        itemLV = randIpyData.GetItemLV()
+        
+        if setPosition:
+            position = min(Def_PositionMax - 1, max(1, setPosition))
+        else:
+            position = random.randint(Def_PositionMid - randDist, Def_PositionMid + randDist) # 随机位置
+        mineItemMgr.InitMineItem(mineItemData, areaPlayerID, index, randMineID, mineType, position)
+        
+        if mineType == MineType_Super and mineItemData not in mineItemMgr.freeSuperItemList:
+            mineItemMgr.freeSuperItemList.append(mineItemData)
+            
+        refreshDict[index] = {"randMineID":randMineID, "position":position, "mineType":mineType, "itemLV":itemLV}
+        GameWorld.DebugLog("    index=%s,randMineID=%s,position=%s,mineType=%s,itemLV=%s" % (index, randMineID, position, mineType, itemLV), areaPlayerID)
+        
+    if isNotify and refreshDict:
+        SyncMineAreaItemInfo(areaPlayerID, refreshDict.keys())
+    return refreshDict
+
+#// B0 33 福地查看 #tagCGMineAreaView
+#
+#struct    tagCGMineAreaView
+#{
+#    tagHead        Head;
+#    BYTE        QueryType;    // 查询同步类型:0-后端主动同步;1-查看指定福地;2-查看道友福地列表;3-查看周围随机福地列表;4-退出他人福地
+#    DWORD        QueryValue;    // 查询值,类型1时-发送目标玩家ID;3时-发送是否重新随机
+#};
+def OnMineAreaView(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    
+    queryType = clientData.QueryType
+    queryValue = clientData.QueryValue
+    
+    # 查看指定福地
+    if queryType == 1:
+        areaPlayerID = queryValue if queryValue > 0 else  playerID
+        mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+        if areaPlayerID not in mineItemMgr.playerMineItemDict:
+            GameWorld.DebugLog("不存在该福地! areaPlayerID=%s" % areaPlayerID)
+            return
+        if playerID != areaPlayerID:
+            mineItemMgr.AddViewAreaPlayerID(playerID, areaPlayerID)
+            
+        clientPack = __GetMineAreaInfoPack([[areaPlayerID, []]], queryType, queryValue)
+        NetPackCommon.SendFakePack(curPlayer, clientPack)
+        
+    # 查看道友福地列表
+    elif queryType == 2:
+        SyncSocialAreaInfo(curPlayer, queryType, queryValue)
+                
+    # 查看周围随机福地列表
+    elif queryType == 3:
+        SyncNeighborAreaInfo(curPlayer, tick, queryType, queryValue)
+        
+    # 退出他人福地
+    elif queryType == 4:
+        PyDataManager.GetDBPyMineAreaItemManager().DelViewAreaPlayerID(playerID)
+        
+    return
+
+def SyncMineAreaItemInfo(areaPlayerID, mineIndexList, notifyPlayerIDListEx=None):
+    '''某个福地物品变更时同步,会同步给相关玩家
+    @param areaPlayerID: 福地玩家ID,可能是假人
+    @param mineIndexList: 需要同步的矿物索引
+    @param notifyPlayerIDListEx: 额外需要通知的玩家ID列表
+    '''
+    if not mineIndexList:
+        return
+    
+    notifyPlayerIDList = [] # 同步给相关的玩家,默认包含自己
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    
+    # 自己,假人不用
+    if areaPlayerID > Def_FakeAreaCount:
+        notifyPlayerIDList.append(areaPlayerID)
+        
+    # 列表中
+    for playerID, socialIDList in mineItemMgr.socialIDListDict.items():
+        if areaPlayerID in socialIDList:
+            notifyPlayerIDList.append(playerID)
+    for playerID, neighborIDList in mineItemMgr.neighborIDListDict.items():
+        if areaPlayerID in neighborIDList:
+            notifyPlayerIDList.append(playerID)
+            
+    # 抢劫中
+    for index in mineIndexList:
+        mineItemData = mineItemMgr.GetMineItem(areaPlayerID, index)
+        if mineItemData.RobPlayerID:
+            notifyPlayerIDList.append(mineItemData.RobPlayerID)
+            
+    # 查看中
+    if areaPlayerID in mineItemMgr.viewAreaPlayerIDDict:
+        notifyPlayerIDList += mineItemMgr.viewAreaPlayerIDDict[areaPlayerID]
+        
+    # 额外的
+    if notifyPlayerIDListEx:
+        notifyPlayerIDList += notifyPlayerIDListEx
+        
+    if not notifyPlayerIDList:
+        return
+    
+    clientPack = __GetMineAreaInfoPack([[areaPlayerID, mineIndexList]])
+    # 去重同步
+    playerManager = GameWorld.GetPlayerManager()
+    for playerID in set(notifyPlayerIDList):
+        if playerID <= Def_FakeAreaCount:
+            continue
+        curPlayer = playerManager.FindPlayerByID(playerID)
+        if curPlayer == None or not curPlayer.GetInitOK():
+            continue
+        if PlayerControl.GetIsTJG(curPlayer):
+            continue
+        NetPackCommon.SendFakePack(curPlayer, clientPack)
+    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)
+        
+    areaMineList = [[areaPlayerID, []] for areaPlayerID in socialIDList]
+    clientPack = __GetMineAreaInfoPack(areaMineList, queryType, queryValue)
+    NetPackCommon.SendFakePack(curPlayer, clientPack)
+    return
+
+def SyncNeighborAreaInfo(curPlayer, tick, queryType=0, queryValue=0):
+    ## 同步周围随机福地列表
+    playerID = curPlayer.GetPlayerID()
+    isRefresh = queryValue
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    neighborIDList = mineItemMgr.neighborIDListDict.get(playerID, [])
+    neighborIDListBef = neighborIDList
+    if isRefresh:
+        refreshCD = IpyGameDataPY.GetFuncCfg("MineAreaRob", 3) * 1000
+        if refreshCD:
+            if tick - curPlayer.GetDictByKey(NeighborAreaRefreshTick) < refreshCD:
+                GameWorld.Log("周围随机福地刷新CD中!", playerID)
+                return
+            curPlayer.SetDict(NeighborAreaRefreshTick, tick)
+        neighborIDList = [] # 置空重新随机
+    else:
+        neighborIDList = mineItemMgr.neighborIDListDict.get(playerID, [])
+        
+    if not neighborIDList:
+        random.shuffle(mineItemMgr.realAreaPlayerIDList) 
+        random.shuffle(mineItemMgr.fackAreaPlayerIDList)
+        areaPlayerIDList = mineItemMgr.realAreaPlayerIDList + mineItemMgr.fackAreaPlayerIDList
+        if playerID in areaPlayerIDList:
+            areaPlayerIDList.remove(playerID)
+        for neighborIDBef in neighborIDListBef: # 之前的先不随机
+            if neighborIDBef in areaPlayerIDList:
+                areaPlayerIDList.remove(neighborIDBef)
+        neighborCount = IpyGameDataPY.GetFuncCfg("MineAreaRob", 2)
+        neighborIDList = areaPlayerIDList[:neighborCount]
+        mineItemMgr.neighborIDListDict[playerID] = neighborIDList
+        GameWorld.DebugLog("刷新周围随机福地: %s" % neighborIDList, playerID)
+        
+    areaMineList = [[areaPlayerID, []] for areaPlayerID in neighborIDList]
+    clientPack = __GetMineAreaInfoPack(areaMineList, queryType, queryValue)
+    NetPackCommon.SendFakePack(curPlayer, clientPack)
+    return
+
+def SyncPullingAreaMineInfo(curPlayer):
+    ## 同步拉取中的物品信息,仅登录时主动同步一次
+    playerID = curPlayer.GetPlayerID()
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    if playerID not in mineItemMgr.pullingItemListDict:
+        return
+    pullingItemList = mineItemMgr.pullingItemListDict[playerID]
+    if not pullingItemList:
+        return
+    
+    pullIndexDict = {}
+    for mineItemData in pullingItemList:
+        areaPlayerID = mineItemData.PlayerID
+        if areaPlayerID not in pullIndexDict:
+            pullIndexDict[areaPlayerID] = []
+        indexList = pullIndexDict[areaPlayerID]
+        indexList.append(mineItemData.Index)
+    areaMineList = []
+    for areaPlayerID, indexList in pullIndexDict.items():
+        areaMineList.append([areaPlayerID, indexList])
+    clientPack = __GetMineAreaInfoPack(areaMineList)
+    NetPackCommon.SendFakePack(curPlayer, clientPack)
+    return
+
+def __GetMineAreaInfoPack(areaMineList, queryType=0, queryValue=0):
+    ''' 获取同步福地详细信息包
+    @param areaMineList: [[areaPlayerID, mineIndexList], ...] 按指定福地ID顺序列表获取,mineIndexList为空时同步该福地全部物品,否则只同步指定索引物品
+    '''
+    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
+    clientPack = ChPyNetSendPack.tagGCMineAreaInfo()
+    clientPack.QueryType = queryType
+    clientPack.QueryValue = queryValue
+    clientPack.AreaList = []
+    for areaPlayerID, mineIndexList in areaMineList:
+        areaInfo = ChPyNetSendPack.tagGCMineArea()
+        areaInfo.PlayerID = areaPlayerID
+        if areaPlayerID > Def_FakeAreaCount:
+            cacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(areaPlayerID))
+            areaInfo.PlayerName = cacheDict.get("Name", "")
+            areaInfo.Face = cacheDict.get("Face", 0)
+                    
+        areaInfo.MineItemList = []
+        if not mineIndexList:
+            mineIndexList = range(IpyGameDataPY.GetFuncCfg("MineAreaBase", 1))
+        for index in mineIndexList:
+            mineItemData = mineItemMgr.GetMineItem(areaPlayerID, index)
+            mineItem = ChPyNetSendPack.tagGCMineItem()
+            mineItem.Index = index
+            mineItem.MineID = mineItemData.MineID
+            mineItem.MineType = mineItemData.MineType
+            mineItem.UpdTime = mineItemData.UpdTime
+            mineItem.Position = mineItemData.Position
+            mineItem.PosLen = len(mineItem.Position)
+            mineItem.MoveSpeed = "%s" % getattr(mineItemData, MineItemAttr_MoveSpeed)
+            mineItem.SpeedLen = len(mineItem.MoveSpeed)
+            mineItem.EndTime = getattr(mineItemData, MineItemAttr_EndTime)
+            mineItem.WorkerCount = mineItemData.WorkerCount
+            mineItem.RobPlayerID = mineItemData.RobPlayerID
+            mineItem.RobWorkerCount = mineItemData.RobWorkerCount
+            if mineItemData.RobPlayerID:
+                robCacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(mineItemData.RobPlayerID))
+                mineItem.RobPlayerName = robCacheDict.get("Name", "")
+                mineItem.RobFace = robCacheDict.get("Face", 0)
+            areaInfo.MineItemList.append(mineItem)
+        areaInfo.MineCount = len(areaInfo.MineItemList)
+        
+        clientPack.AreaList.append(areaInfo)
+    clientPack.AreaCount = len(clientPack.AreaList)
+    return clientPack
+
+#// B0 34 福地请求结算奖励 #tagCGMineAreaAwardGet
+#
+#struct    tagCGMineAreaAwardGet
+#{
+#    tagHead        Head;
+#};
+def OnMineAreaAwardGet(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    
+    if tick - curPlayer.GetDictByKey(MineAreaAwardGetTick) < 10000:
+        GameWorld.DebugLog("结算福地奖励请求CD中!", playerID)
+        return
+    
+    awardMgr = PyDataManager.GetDBPyMineAreaAwardManager()
+    awardDict = awardMgr.playerAreaAwardDict.get(playerID, {})
+    if not awardDict:
+        GameWorld.DebugLog("当前福地玩家没有待领取奖励!", playerID)
+        return
+    
+    awardItemDict = {}
+    awardInfoList = []
+    for GUID, awardData in awardDict.items():
+        mineID = awardData.MineID
+        awardTime = awardData.AwardTime
+        workerCount = awardData.WorkerCount
+        areaPlayerID = awardData.AreaPlayerID
+        ipyData = IpyGameDataPY.GetIpyGameData("MineAreaItem", mineID)
+        if not ipyData:
+            continue
+        itemID = ipyData.GetItemID()
+        itemCount = ipyData.GetItemCount()
+        itemLV = ipyData.GetItemLV()
+        awardItemDict[itemID] = awardItemDict.get(itemID, 0) + itemCount
+        awardInfoList.append([GUID, awardTime, workerCount, areaPlayerID, mineID, itemLV, itemID, itemCount])
+        
+    # 通知地图玩家给物品
+    curPlayer.SetDict(MineAreaAwardGetTick, tick)
+    MapServer_QueryPlayerResult(curPlayer, "MineAreaAwardGet", [awardInfoList])
+    return
+
+def __DoMineAreaAwardGetOK(curPlayer, dataMsg):
+    
+    playerID = curPlayer.GetPlayerID()
+    GUIDList, awardItemList = dataMsg
+    curPlayer.SetDict(MineAreaAwardGetTick, 0)
+    
+    awardMgr = PyDataManager.GetDBPyMineAreaAwardManager()
+    awardDict = awardMgr.playerAreaAwardDict.get(playerID, {})
+    if not awardDict:
+        return
+    
+    for GUID in GUIDList:
+        awardDict.pop(GUID, None)
+        
+    SyncMineAwardAward(curPlayer, 1, awardItemList)
+    return
+
+def SyncMineAwardAward(curPlayer, awardType=0, awardItemList=None):
+    # @param awardType: 0-通知有奖励,前端下次进入福地可请求进行结算;1-结算奖励结果通知
+    # @param awardItemList: 奖励信息 [[物品ID,个数,是否拍品], ...]
+    clientPack = ChPyNetSendPack.tagGCMineAreaAwardInfo()
+    clientPack.AwardType = awardType
+    if awardItemList:
+        clientPack.AwardInfo = str(awardItemList)
+    clientPack.AwardLen = len(clientPack.AwardInfo)
+    NetPackCommon.SendFakePack(curPlayer, clientPack)
+    return
+
+def MapServer_QueryPlayerResult(curPlayer, queryType, queryData, ret=1):
+    resultMsg = str([queryType, queryData, ret])
+    curPlayer.MapServer_QueryPlayerResult(0, 0, "MineArea", resultMsg, len(resultMsg))
+    GameWorld.Log("福地发送MapServer: %s" % resultMsg, curPlayer.GetPlayerID())
+    return
+
+    
\ No newline at end of file
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
index d1fc6ae..9d78eee 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
@@ -112,6 +112,7 @@
 import GameWorldOpenServerCampaign
 import CrossBillboard
 import CrossChampionship
+import GameWorldMineArea
 #---------------------------------------------------------------------
 
 #---------------------------------------------------------------------
@@ -326,6 +327,9 @@
     #情缘
     PlayerLove.OnTimeProcess(curTime, tick)
     
+    #福地
+    GameWorldMineArea.OnMineItemTimeProcess(curTime, tick)
+    
     #每整分钟处理一次
     curDateTime = datetime.datetime.today()
     curMinute = curDateTime.minute
@@ -384,6 +388,8 @@
     PlayerFamilyRedPacket.OnRedPacketMinuteProcess()
     #拍卖行
     AuctionHouse.OnAuctionItemMinuteProcess(tick)
+    #福地
+    GameWorldMineArea.OnProcessOnMinute()
     #每5分钟触发一次仙盟总战力更新
     if curMinute % 5 == 0:
         PlayerFamily.UpdFamilyTotalFightPower()
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
index d6d1a38..2c17a38 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
@@ -74,6 +74,7 @@
 import CrossBattlefield
 import CrossActAllRecharge
 import CrossYaomoBoss
+import GameWorldMineArea
 #---------------------------------------------------------------------
 
 #---------------------------------------------------------------------
@@ -205,6 +206,8 @@
         PlayerAssist.OnPlayerLogin(curPlayer)
         #天星塔
         GameWorldSkyTower.OnPlayerLogin(curPlayer)
+        #福地
+        GameWorldMineArea.OnPlayerLogin(curPlayer)
         GMT_CTG.OnPlayerLogin(curPlayer)
         
     else:
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py
index 3c0ca30..dce2503 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py
@@ -31,6 +31,7 @@
 import IPY_GameServer
 import PlayerDBGSEvent
 import CrossChampionship
+import GameWorldMineArea
 import IpyGameDataPY
 import CrossRealmMsg
 import ShareDefine
@@ -437,6 +438,7 @@
     playerID = curPlayer.GetPlayerID()
     FuncOpenLogicDict = {
                          ShareDefine.GameFuncID_Championship:lambda curObj:CrossChampionship.DoChampionshipOpen(curObj),
+                         ShareDefine.GameFuncID_MineArea:lambda curObj:GameWorldMineArea.DoMineAreaFuncOpen(curObj),
                          }
     for funcID in funcIDList:
         if funcID in FuncOpenLogicDict:
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
index 23652a3..7211e0f 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
@@ -81,6 +81,7 @@
 import AuctionHouse
 import PlayerFairyDomain
 import GameWorldSkyTower
+import GameWorldMineArea
 import GameWorldArena
 import GameWorldItem
 import PlayerAssist
@@ -1025,6 +1026,16 @@
             return
         resultName = '%s' % ret
         
+    # 福地
+    if callName =="MineArea":
+        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID)
+        if not curPlayer:
+            return
+        ret = GameWorldMineArea.MapServer_MineArea(curPlayer, eval(resultName))
+        if ret == None:
+            return
+        resultName = '%s' % ret
+        
     # 天星塔
     if callName == "SkyTower":
         curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py
index 9c220f0..78a97b5 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py
@@ -147,6 +147,8 @@
 
 def GetCachePropDataDict(curCache):
     ## 获取缓存基础属性字典信息
+    if not curCache:
+        return {}
     if not hasattr(curCache, "PropDataDict"):
         curCache.PropDataDict = {}
     if not curCache.PropDataDict and curCache.PropData:
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py b/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
index d69ec33..e35a1a5 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
@@ -26,6 +26,7 @@
 import CrossRealmPK
 import AuctionHouse
 import PlayerAssist
+import GameWorldMineArea
 import PyGameDataStruct
 import IpyGameDataPY
 import PlayerCharm
@@ -309,6 +310,9 @@
 
 class PyGameDataManager(object):
     def __init__(self):
+        self.DBPyMineAreaAwardManager = GameWorldMineArea.DBPyMineAreaAwardManager()
+        self.DBPyMineAreaRecordManager = GameWorldMineArea.DBPyMineAreaRecordManager()
+        self.DBPyMineAreaItemManager = GameWorldMineArea.DBPyMineAreaItemManager()
         self.DBPyCoupleManager = PlayerLove.DBPyCoupleManager()
         self.DBPyUnNotifyLoveGiftRecManager = PlayerLove.DBPyUnNotifyLoveGiftRecManager()
         self.DBPyCharmValueRecManager = PlayerCharm.DBPyCharmValueRecManager()
@@ -338,6 +342,9 @@
 
     def GetSaveData(self):
         buff = ""
+        buff += self.DBPyMineAreaAwardManager.GetSaveData()
+        buff += self.DBPyMineAreaRecordManager.GetSaveData()
+        buff += self.DBPyMineAreaItemManager.GetSaveData()
         buff += self.DBPyCoupleManager.GetSaveData()
         buff += self.DBPyUnNotifyLoveGiftRecManager.GetSaveData()
         buff += self.DBPyCharmValueRecManager.GetSaveData()
@@ -366,6 +373,9 @@
         return buff
     
     def LoadGameData(self, gameBuffer, pos):
+        pos = self.DBPyMineAreaAwardManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
+        pos = self.DBPyMineAreaRecordManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
+        pos = self.DBPyMineAreaItemManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
         pos = self.DBPyCoupleManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
         pos = self.DBPyUnNotifyLoveGiftRecManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
         pos = self.DBPyCharmValueRecManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
@@ -481,6 +491,21 @@
     pyGameDataMgr = GetPyGameDataManager()
     return pyGameDataMgr.familyStoreItemManager
 
+def GetDBPyMineAreaAwardManager():
+    # 福地奖励结算管理
+    pyGameDataMgr = GetPyGameDataManager()
+    return pyGameDataMgr.DBPyMineAreaAwardManager
+
+def GetDBPyMineAreaRecordManager():
+    # 福地矿物记录管理
+    pyGameDataMgr = GetPyGameDataManager()
+    return pyGameDataMgr.DBPyMineAreaRecordManager
+
+def GetDBPyMineAreaItemManager():
+    # 福地矿物管理
+    pyGameDataMgr = GetPyGameDataManager()
+    return pyGameDataMgr.DBPyMineAreaItemManager
+
 def GetDBPyCoupleManager():
     # 伴侣管理
     pyGameDataMgr = GetPyGameDataManager()
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py b/ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py
index 0556db9..a04b1fa 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py
@@ -2618,4 +2618,303 @@
                 self.ADOResult,
             )
         return output
-            
+
+
+# 福地矿物表 #tagDBPyMineAreaItem
+class tagDBPyMineAreaItem(Structure):
+    _pack_ = 1
+    _fields_ = [
+        ('PlayerID', ctypes.c_ulong),
+        ('Index', ctypes.c_ubyte),
+        ('MineID', ctypes.c_ushort),
+        ('MineType', ctypes.c_ubyte),
+        ('UpdTime', ctypes.c_ulong),
+        ('PosLen', ctypes.c_ubyte),
+        ('Position', ctypes.c_char_p),
+        ('WorkerCount', ctypes.c_ubyte),
+        ('WorkerState', ctypes.c_ubyte),
+        ('RobPlayerID', ctypes.c_ulong),
+        ('RobWorkerCount', ctypes.c_ubyte),
+        ('RobWorkerState', ctypes.c_ubyte),
+        ('ADOResult', ctypes.c_ulong),
+    ]
+
+    def __init__(self):
+        Structure.__init__(self)
+        self.clear()
+
+    def clear(self):
+        self.PlayerID = 0
+        self.Index = 0
+        self.MineID = 0
+        self.MineType = 0
+        self.UpdTime = 0
+        self.PosLen = 0
+        self.Position = ''
+        self.WorkerCount = 0
+        self.WorkerState = 0
+        self.RobPlayerID = 0
+        self.RobWorkerCount = 0
+        self.RobWorkerState = 0
+
+    def readData(self, buf, pos = 0, length = 0):
+        if not pos <= length:
+            return -1
+        if len(buf) < pos + self.getLength():
+            return -1
+        self.clear()
+        self.PlayerID, pos = CommFunc.ReadDWORD(buf, pos)
+        self.Index, pos = CommFunc.ReadBYTE(buf, pos)
+        self.MineID, pos = CommFunc.ReadWORD(buf, pos)
+        self.MineType, pos = CommFunc.ReadBYTE(buf, pos)
+        self.UpdTime, pos = CommFunc.ReadDWORD(buf, pos)
+        self.PosLen, pos = CommFunc.ReadBYTE(buf, pos)
+        tmp, pos = CommFunc.ReadString(buf, pos, self.PosLen)
+        self.Position = ctypes.c_char_p(tmp)
+        self.WorkerCount, pos = CommFunc.ReadBYTE(buf, pos)
+        self.WorkerState, pos = CommFunc.ReadBYTE(buf, pos)
+        self.RobPlayerID, pos = CommFunc.ReadDWORD(buf, pos)
+        self.RobWorkerCount, pos = CommFunc.ReadBYTE(buf, pos)
+        self.RobWorkerState, pos = CommFunc.ReadBYTE(buf, pos)
+        return self.getLength()
+
+    def getBuffer(self):
+        buf = ''
+        buf = CommFunc.WriteDWORD(buf, self.PlayerID)
+        buf = CommFunc.WriteBYTE(buf, self.Index)
+        buf = CommFunc.WriteWORD(buf, self.MineID)
+        buf = CommFunc.WriteBYTE(buf, self.MineType)
+        buf = CommFunc.WriteDWORD(buf, self.UpdTime)
+        buf = CommFunc.WriteBYTE(buf, self.PosLen)
+        buf = CommFunc.WriteString(buf, self.PosLen, self.Position)
+        buf = CommFunc.WriteBYTE(buf, self.WorkerCount)
+        buf = CommFunc.WriteBYTE(buf, self.WorkerState)
+        buf = CommFunc.WriteDWORD(buf, self.RobPlayerID)
+        buf = CommFunc.WriteBYTE(buf, self.RobWorkerCount)
+        buf = CommFunc.WriteBYTE(buf, self.RobWorkerState)
+        return buf
+
+    def getLength(self):
+        length = 0
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ubyte)
+        length += sizeof(ctypes.c_ushort)
+        length += sizeof(ctypes.c_ubyte)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ubyte)
+        length += self.PosLen
+        length += sizeof(ctypes.c_ubyte)
+        length += sizeof(ctypes.c_ubyte)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ubyte)
+        length += sizeof(ctypes.c_ubyte)
+        return length
+
+    def outputString(self):
+        output = '''// 福地矿物表 #tagDBPyMineAreaItem:
+            PlayerID = %s,
+            Index = %s,
+            MineID = %s,
+            MineType = %s,
+            UpdTime = %s,
+            PosLen = %s,
+            Position = %s,
+            WorkerCount = %s,
+            WorkerState = %s,
+            RobPlayerID = %s,
+            RobWorkerCount = %s,
+            RobWorkerState = %s,
+            ADOResult = %s,
+            '''%(
+                self.PlayerID,
+                self.Index,
+                self.MineID,
+                self.MineType,
+                self.UpdTime,
+                self.PosLen,
+                self.Position,
+                self.WorkerCount,
+                self.WorkerState,
+                self.RobPlayerID,
+                self.RobWorkerCount,
+                self.RobWorkerState,
+                self.ADOResult,
+            )
+        return output
+
+
+# 福地记录表 #tagDBPyMineAreaRecord
+class tagDBPyMineAreaRecord(Structure):
+    _pack_ = 1
+    _fields_ = [
+        ('PlayerID', ctypes.c_ulong),
+        ('RecordType', ctypes.c_ulong),
+        ('TagPlayerID', ctypes.c_ulong),
+        ('RecordTime', ctypes.c_ulong),
+        ('MineID', ctypes.c_ushort),
+        ('DataLen', ctypes.c_ushort),
+        ('Data', ctypes.c_char_p),
+        ('ADOResult', ctypes.c_ulong),
+    ]
+
+    def __init__(self):
+        Structure.__init__(self)
+        self.clear()
+
+    def clear(self):
+        self.PlayerID = 0
+        self.RecordType = 0
+        self.TagPlayerID = 0
+        self.RecordTime = 0
+        self.MineID = 0
+        self.DataLen = 0
+        self.Data = ''
+
+    def readData(self, buf, pos = 0, length = 0):
+        if not pos <= length:
+            return -1
+        if len(buf) < pos + self.getLength():
+            return -1
+        self.clear()
+        self.PlayerID, pos = CommFunc.ReadDWORD(buf, pos)
+        self.RecordType, pos = CommFunc.ReadDWORD(buf, pos)
+        self.TagPlayerID, pos = CommFunc.ReadDWORD(buf, pos)
+        self.RecordTime, pos = CommFunc.ReadDWORD(buf, pos)
+        self.MineID, pos = CommFunc.ReadWORD(buf, pos)
+        self.DataLen, pos = CommFunc.ReadWORD(buf, pos)
+        tmp, pos = CommFunc.ReadString(buf, pos, self.DataLen)
+        self.Data = ctypes.c_char_p(tmp)
+        return self.getLength()
+
+    def getBuffer(self):
+        buf = ''
+        buf = CommFunc.WriteDWORD(buf, self.PlayerID)
+        buf = CommFunc.WriteDWORD(buf, self.RecordType)
+        buf = CommFunc.WriteDWORD(buf, self.TagPlayerID)
+        buf = CommFunc.WriteDWORD(buf, self.RecordTime)
+        buf = CommFunc.WriteWORD(buf, self.MineID)
+        buf = CommFunc.WriteWORD(buf, self.DataLen)
+        buf = CommFunc.WriteString(buf, self.DataLen, self.Data)
+        return buf
+
+    def getLength(self):
+        length = 0
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ushort)
+        length += sizeof(ctypes.c_ushort)
+        length += self.DataLen
+        return length
+
+    def outputString(self):
+        output = '''// 福地记录表 #tagDBPyMineAreaRecord:
+            PlayerID = %s,
+            RecordType = %s,
+            TagPlayerID = %s,
+            RecordTime = %s,
+            MineID = %s,
+            DataLen = %s,
+            Data = %s,
+            ADOResult = %s,
+            '''%(
+                self.PlayerID,
+                self.RecordType,
+                self.TagPlayerID,
+                self.RecordTime,
+                self.MineID,
+                self.DataLen,
+                self.Data,
+                self.ADOResult,
+            )
+        return output
+
+
+# 福地结算奖励表 #tagDBPyMineAreaAward
+class tagDBPyMineAreaAward(Structure):
+    _pack_ = 1
+    _fields_ = [
+        ('GUIDLen', ctypes.c_ubyte),
+        ('GUID', ctypes.c_char_p),
+        ('PlayerID', ctypes.c_ulong),
+        ('AwardTime', ctypes.c_ulong),
+        ('MineID', ctypes.c_ushort),
+        ('WorkerCount', ctypes.c_ubyte),
+        ('AreaPlayerID', ctypes.c_ulong),
+        ('ADOResult', ctypes.c_ulong),
+    ]
+
+    def __init__(self):
+        Structure.__init__(self)
+        self.clear()
+
+    def clear(self):
+        self.GUIDLen = 0
+        self.GUID = ''
+        self.PlayerID = 0
+        self.AwardTime = 0
+        self.MineID = 0
+        self.WorkerCount = 0
+        self.AreaPlayerID = 0
+
+    def readData(self, buf, pos = 0, length = 0):
+        if not pos <= length:
+            return -1
+        if len(buf) < pos + self.getLength():
+            return -1
+        self.clear()
+        self.GUIDLen, pos = CommFunc.ReadBYTE(buf, pos)
+        tmp, pos = CommFunc.ReadString(buf, pos, self.GUIDLen)
+        self.GUID = ctypes.c_char_p(tmp)
+        self.PlayerID, pos = CommFunc.ReadDWORD(buf, pos)
+        self.AwardTime, pos = CommFunc.ReadDWORD(buf, pos)
+        self.MineID, pos = CommFunc.ReadWORD(buf, pos)
+        self.WorkerCount, pos = CommFunc.ReadBYTE(buf, pos)
+        self.AreaPlayerID, pos = CommFunc.ReadDWORD(buf, pos)
+        return self.getLength()
+
+    def getBuffer(self):
+        buf = ''
+        buf = CommFunc.WriteBYTE(buf, self.GUIDLen)
+        buf = CommFunc.WriteString(buf, self.GUIDLen, self.GUID)
+        buf = CommFunc.WriteDWORD(buf, self.PlayerID)
+        buf = CommFunc.WriteDWORD(buf, self.AwardTime)
+        buf = CommFunc.WriteWORD(buf, self.MineID)
+        buf = CommFunc.WriteBYTE(buf, self.WorkerCount)
+        buf = CommFunc.WriteDWORD(buf, self.AreaPlayerID)
+        return buf
+
+    def getLength(self):
+        length = 0
+        length += sizeof(ctypes.c_ubyte)
+        length += self.GUIDLen
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ulong)
+        length += sizeof(ctypes.c_ushort)
+        length += sizeof(ctypes.c_ubyte)
+        length += sizeof(ctypes.c_ulong)
+        return length
+
+    def outputString(self):
+        output = '''// 福地结算奖励表 #tagDBPyMineAreaAward:
+            GUIDLen = %s,
+            GUID = %s,
+            PlayerID = %s,
+            AwardTime = %s,
+            MineID = %s,
+            WorkerCount = %s,
+            AreaPlayerID = %s,
+            ADOResult = %s,
+            '''%(
+                self.GUIDLen,
+                self.GUID,
+                self.PlayerID,
+                self.AwardTime,
+                self.MineID,
+                self.WorkerCount,
+                self.AreaPlayerID,
+                self.ADOResult,
+            )
+        return output
+
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
index 3d11842..ded36dd 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -1188,6 +1188,7 @@
 GameFuncID_FaQi = 199           # 法器
 GameFuncID_LianTi = 207         # 炼体
 GameFuncID_Championship = 210   # 排位
+GameFuncID_MineArea = 223   	# 福地
 # 以下为暂时无用的
 GameFuncID_Truck = 33           # 运镖
 GameFuncID_RunDaily = 34        # 日常跑环
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
index f32553e..55fd724 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -2117,6 +2117,110 @@
 
 
 #------------------------------------------------------
+# B0 34 福地请求结算奖励 #tagCGMineAreaAwardGet
+
+class  tagCGMineAreaAwardGet(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB0
+        self.SubCmd = 0x34
+        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 = 0x34
+        return
+
+    def GetLength(self):
+        return sizeof(tagCGMineAreaAwardGet)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B0 34 福地请求结算奖励 //tagCGMineAreaAwardGet:
+                                Cmd:%s,
+                                SubCmd:%s
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd
+                                )
+        return DumpString
+
+
+m_NAtagCGMineAreaAwardGet=tagCGMineAreaAwardGet()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGMineAreaAwardGet.Cmd,m_NAtagCGMineAreaAwardGet.SubCmd))] = m_NAtagCGMineAreaAwardGet
+
+
+#------------------------------------------------------
+# B0 33 福地查看 #tagCGMineAreaView
+
+class  tagCGMineAreaView(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("QueryType", c_ubyte),    # 查询同步类型:0-后端主动同步;1-查看指定福地;2-查看道友福地列表;3-查看周围随机福地列表;4-退出他人福地;
+                  ("QueryValue", c_int),    # 查询值,类型1时-发送目标玩家ID;3时-发送是否重新随机
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB0
+        self.SubCmd = 0x33
+        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 = 0x33
+        self.QueryType = 0
+        self.QueryValue = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCGMineAreaView)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B0 33 福地查看 //tagCGMineAreaView:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                QueryType:%d,
+                                QueryValue:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.QueryType,
+                                self.QueryValue
+                                )
+        return DumpString
+
+
+m_NAtagCGMineAreaView=tagCGMineAreaView()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGMineAreaView.Cmd,m_NAtagCGMineAreaView.SubCmd))] = m_NAtagCGMineAreaView
+
+
+#------------------------------------------------------
 #B0 25 请求家族悬赏任务完成情况 #tagQueryFamilyArrestOverState
 
 class  tagQueryFamilyArrestOverState(Structure):
@@ -17341,6 +17445,170 @@
 
 
 #------------------------------------------------------
+# B0 30 福地物品拉 #tagCMMineItemPull
+
+class  tagCMMineItemPull(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("PlayerID", c_int),    # 福地所属玩家ID,0默认自己
+                  ("ItemIndex", c_ubyte),    # 物品所在位置索引0~n
+                  ("WorkerCount", c_ubyte),    # 上工人人数
+                  ("IsPreview", c_ubyte),    # 是否预览;0-直接拉,1-预览大概时间
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB0
+        self.SubCmd = 0x30
+        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 = 0x30
+        self.PlayerID = 0
+        self.ItemIndex = 0
+        self.WorkerCount = 0
+        self.IsPreview = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMMineItemPull)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B0 30 福地物品拉 //tagCMMineItemPull:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                PlayerID:%d,
+                                ItemIndex:%d,
+                                WorkerCount:%d,
+                                IsPreview:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.PlayerID,
+                                self.ItemIndex,
+                                self.WorkerCount,
+                                self.IsPreview
+                                )
+        return DumpString
+
+
+m_NAtagCMMineItemPull=tagCMMineItemPull()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMMineItemPull.Cmd,m_NAtagCMMineItemPull.SubCmd))] = m_NAtagCMMineItemPull
+
+
+#------------------------------------------------------
+# B0 31 福地物品刷新 #tagCMMineItemRefresh
+
+class  tagCMMineItemRefresh(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("IsSuper", c_ubyte),    # 是否超级刷新
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB0
+        self.SubCmd = 0x31
+        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 = 0x31
+        self.IsSuper = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMMineItemRefresh)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B0 31 福地物品刷新 //tagCMMineItemRefresh:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                IsSuper:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.IsSuper
+                                )
+        return DumpString
+
+
+m_NAtagCMMineItemRefresh=tagCMMineItemRefresh()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMMineItemRefresh.Cmd,m_NAtagCMMineItemRefresh.SubCmd))] = m_NAtagCMMineItemRefresh
+
+
+#------------------------------------------------------
+# B0 32 福地工人雇佣 #tagCMMineWorkerEmploy
+
+class  tagCMMineWorkerEmploy(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB0
+        self.SubCmd = 0x32
+        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 = 0x32
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMMineWorkerEmploy)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B0 32 福地工人雇佣 //tagCMMineWorkerEmploy:
+                                Cmd:%s,
+                                SubCmd:%s
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd
+                                )
+        return DumpString
+
+
+m_NAtagCMMineWorkerEmploy=tagCMMineWorkerEmploy()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMMineWorkerEmploy.Cmd,m_NAtagCMMineWorkerEmploy.SubCmd))] = m_NAtagCMMineWorkerEmploy
+
+
+#------------------------------------------------------
 #B0 26 请求家族悬赏奖励领取情况 #tagQueryFamilyArrestAwardReceiveState
 
 class  tagQueryFamilyArrestAwardReceiveState(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index 012a73d..2922b4d 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -7722,6 +7722,424 @@
 
 
 #------------------------------------------------------
+# B0 34 福地结算奖励信息 #tagGCMineAreaAwardInfo
+
+class  tagGCMineAreaAwardInfo(Structure):
+    Head = tagHead()
+    AwardType = 0    #(BYTE AwardType)// 0-通知有奖励,前端下次进入福地可请求进行结算;1-结算奖励结果通知
+    AwardLen = 0    #(BYTE AwardLen)
+    AwardInfo = ""    #(String AwardInfo)//奖励信息 [物品ID,个数,是否拍品], ...]
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB0
+        self.Head.SubCmd = 0x34
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.AwardType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.AwardLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.AwardInfo,_pos = CommFunc.ReadString(_lpData, _pos,self.AwardLen)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB0
+        self.Head.SubCmd = 0x34
+        self.AwardType = 0
+        self.AwardLen = 0
+        self.AwardInfo = ""
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 1
+        length += 1
+        length += len(self.AwardInfo)
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.AwardType)
+        data = CommFunc.WriteBYTE(data, self.AwardLen)
+        data = CommFunc.WriteString(data, self.AwardLen, self.AwardInfo)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                AwardType:%d,
+                                AwardLen:%d,
+                                AwardInfo:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.AwardType,
+                                self.AwardLen,
+                                self.AwardInfo
+                                )
+        return DumpString
+
+
+m_NAtagGCMineAreaAwardInfo=tagGCMineAreaAwardInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCMineAreaAwardInfo.Head.Cmd,m_NAtagGCMineAreaAwardInfo.Head.SubCmd))] = m_NAtagGCMineAreaAwardInfo
+
+
+#------------------------------------------------------
+# B0 33 福地详细信息 #tagGCMineAreaInfo
+
+class  tagGCMineItem(Structure):
+    Index = 0    #(BYTE Index)// 矿物所在福地位置索引,0~n
+    MineID = 0    #(WORD MineID)// 矿物ID,对应福地采集表中ID,0代表该索引位置没有矿物
+    MineType = 0    #(BYTE MineType)// 矿物类型:0-常规;1-超级
+    UpdTime = 0    #(DWORD UpdTime)// 最后一次更新时间戳
+    PosLen = 0    #(BYTE PosLen)
+    Position = ""    #(String Position)// 最后一次更新时所在位置百分比,0~100,支持小数,下0上100,可认为分为100格,速度为 x格/秒
+    SpeedLen = 0    #(BYTE SpeedLen)
+    MoveSpeed = ""    #(String MoveSpeed)// 移动速度,x格/秒,支持小数
+    EndTime = 0    #(DWORD EndTime)// 拉取结束时间戳
+    WorkerCount = 0    #(BYTE WorkerCount)// 工人个数,为0时代表福地玩家没有使用工人拉回
+    RobPlayerID = 0    #(DWORD RobPlayerID)// 抢夺玩家ID,为0时代表没人抢夺
+    RobWorkerCount = 0    #(BYTE RobWorkerCount)// 抢夺工人个数
+    RobPlayerName = ""    #(char RobPlayerName[33])
+    RobFace = 0    #(DWORD RobFace)
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.Index,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.MineID,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.MineType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.UpdTime,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.PosLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.Position,_pos = CommFunc.ReadString(_lpData, _pos,self.PosLen)
+        self.SpeedLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.MoveSpeed,_pos = CommFunc.ReadString(_lpData, _pos,self.SpeedLen)
+        self.EndTime,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.WorkerCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.RobPlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.RobWorkerCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.RobPlayerName,_pos = CommFunc.ReadString(_lpData, _pos,33)
+        self.RobFace,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        return _pos
+
+    def Clear(self):
+        self.Index = 0
+        self.MineID = 0
+        self.MineType = 0
+        self.UpdTime = 0
+        self.PosLen = 0
+        self.Position = ""
+        self.SpeedLen = 0
+        self.MoveSpeed = ""
+        self.EndTime = 0
+        self.WorkerCount = 0
+        self.RobPlayerID = 0
+        self.RobWorkerCount = 0
+        self.RobPlayerName = ""
+        self.RobFace = 0
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 1
+        length += 2
+        length += 1
+        length += 4
+        length += 1
+        length += len(self.Position)
+        length += 1
+        length += len(self.MoveSpeed)
+        length += 4
+        length += 1
+        length += 4
+        length += 1
+        length += 33
+        length += 4
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteBYTE(data, self.Index)
+        data = CommFunc.WriteWORD(data, self.MineID)
+        data = CommFunc.WriteBYTE(data, self.MineType)
+        data = CommFunc.WriteDWORD(data, self.UpdTime)
+        data = CommFunc.WriteBYTE(data, self.PosLen)
+        data = CommFunc.WriteString(data, self.PosLen, self.Position)
+        data = CommFunc.WriteBYTE(data, self.SpeedLen)
+        data = CommFunc.WriteString(data, self.SpeedLen, self.MoveSpeed)
+        data = CommFunc.WriteDWORD(data, self.EndTime)
+        data = CommFunc.WriteBYTE(data, self.WorkerCount)
+        data = CommFunc.WriteDWORD(data, self.RobPlayerID)
+        data = CommFunc.WriteBYTE(data, self.RobWorkerCount)
+        data = CommFunc.WriteString(data, 33, self.RobPlayerName)
+        data = CommFunc.WriteDWORD(data, self.RobFace)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Index:%d,
+                                MineID:%d,
+                                MineType:%d,
+                                UpdTime:%d,
+                                PosLen:%d,
+                                Position:%s,
+                                SpeedLen:%d,
+                                MoveSpeed:%s,
+                                EndTime:%d,
+                                WorkerCount:%d,
+                                RobPlayerID:%d,
+                                RobWorkerCount:%d,
+                                RobPlayerName:%s,
+                                RobFace:%d
+                                '''\
+                                %(
+                                self.Index,
+                                self.MineID,
+                                self.MineType,
+                                self.UpdTime,
+                                self.PosLen,
+                                self.Position,
+                                self.SpeedLen,
+                                self.MoveSpeed,
+                                self.EndTime,
+                                self.WorkerCount,
+                                self.RobPlayerID,
+                                self.RobWorkerCount,
+                                self.RobPlayerName,
+                                self.RobFace
+                                )
+        return DumpString
+
+
+class  tagGCMineArea(Structure):
+    PlayerID = 0    #(DWORD PlayerID)// 福地所属玩家ID,可能是自己或其他玩家ID,当ID小于10000时为假人
+    PlayerName = ""    #(char PlayerName[33])// 可能为空,如自己或假人
+    Face = 0    #(DWORD Face)
+    MineCount = 0    #(BYTE MineCount)
+    MineItemList = list()    #(vector<tagGCMineItem> MineItemList)// 矿物列表
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.PlayerName,_pos = CommFunc.ReadString(_lpData, _pos,33)
+        self.Face,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.MineCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.MineCount):
+            temMineItemList = tagGCMineItem()
+            _pos = temMineItemList.ReadData(_lpData, _pos)
+            self.MineItemList.append(temMineItemList)
+        return _pos
+
+    def Clear(self):
+        self.PlayerID = 0
+        self.PlayerName = ""
+        self.Face = 0
+        self.MineCount = 0
+        self.MineItemList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 4
+        length += 33
+        length += 4
+        length += 1
+        for i in range(self.MineCount):
+            length += self.MineItemList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteDWORD(data, self.PlayerID)
+        data = CommFunc.WriteString(data, 33, self.PlayerName)
+        data = CommFunc.WriteDWORD(data, self.Face)
+        data = CommFunc.WriteBYTE(data, self.MineCount)
+        for i in range(self.MineCount):
+            data = CommFunc.WriteString(data, self.MineItemList[i].GetLength(), self.MineItemList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                PlayerID:%d,
+                                PlayerName:%s,
+                                Face:%d,
+                                MineCount:%d,
+                                MineItemList:%s
+                                '''\
+                                %(
+                                self.PlayerID,
+                                self.PlayerName,
+                                self.Face,
+                                self.MineCount,
+                                "..."
+                                )
+        return DumpString
+
+
+class  tagGCMineAreaInfo(Structure):
+    Head = tagHead()
+    QueryType = 0    #(BYTE QueryType)// 查询同步类型:0-后端主动同步;1-查看指定福地;2-查看道友福地列表;3-查看周围随机福地列表
+    QueryValue = 0    #(DWORD QueryValue)// 查询值,类型1时-发送目标玩家ID;3时-发送是否重新随机
+    AreaCount = 0    #(BYTE AreaCount)
+    AreaList = list()    #(vector<tagGCMineArea> AreaList)// 福地列表
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB0
+        self.Head.SubCmd = 0x33
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.QueryType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.QueryValue,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.AreaCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.AreaCount):
+            temAreaList = tagGCMineArea()
+            _pos = temAreaList.ReadData(_lpData, _pos)
+            self.AreaList.append(temAreaList)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB0
+        self.Head.SubCmd = 0x33
+        self.QueryType = 0
+        self.QueryValue = 0
+        self.AreaCount = 0
+        self.AreaList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 1
+        length += 4
+        length += 1
+        for i in range(self.AreaCount):
+            length += self.AreaList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.QueryType)
+        data = CommFunc.WriteDWORD(data, self.QueryValue)
+        data = CommFunc.WriteBYTE(data, self.AreaCount)
+        for i in range(self.AreaCount):
+            data = CommFunc.WriteString(data, self.AreaList[i].GetLength(), self.AreaList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                QueryType:%d,
+                                QueryValue:%d,
+                                AreaCount:%d,
+                                AreaList:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.QueryType,
+                                self.QueryValue,
+                                self.AreaCount,
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagGCMineAreaInfo=tagGCMineAreaInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCMineAreaInfo.Head.Cmd,m_NAtagGCMineAreaInfo.Head.SubCmd))] = m_NAtagGCMineAreaInfo
+
+
+#------------------------------------------------------
+# B0 32 福地物品拉预览结果 #tagGCMineItemPullPreviewRet
+
+class  tagGCMineItemPullPreviewRet(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("PlayerID", c_int),    # 福地所属玩家ID,0默认自己
+                  ("ItemIndex", c_ubyte),    # 物品所在位置索引0~n
+                  ("WorkerCount", c_ubyte),    # 上工人人数
+                  ("NeedSeconds", c_int),    # 预计需要时间,秒
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB0
+        self.SubCmd = 0x32
+        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 = 0x32
+        self.PlayerID = 0
+        self.ItemIndex = 0
+        self.WorkerCount = 0
+        self.NeedSeconds = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagGCMineItemPullPreviewRet)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B0 32 福地物品拉预览结果 //tagGCMineItemPullPreviewRet:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                PlayerID:%d,
+                                ItemIndex:%d,
+                                WorkerCount:%d,
+                                NeedSeconds:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.PlayerID,
+                                self.ItemIndex,
+                                self.WorkerCount,
+                                self.NeedSeconds
+                                )
+        return DumpString
+
+
+m_NAtagGCMineItemPullPreviewRet=tagGCMineItemPullPreviewRet()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCMineItemPullPreviewRet.Cmd,m_NAtagGCMineItemPullPreviewRet.SubCmd))] = m_NAtagGCMineItemPullPreviewRet
+
+
+#------------------------------------------------------
 # B0 04 使用协助感谢礼盒预览 #tagGCUseAssistThanksGiftPreview
 
 class  tagGCAssistPlayerInfo(Structure):
@@ -44010,6 +44428,121 @@
 
 
 #------------------------------------------------------
+# B0 30 玩家福地相关信息 #tagMCPlayerMineAreaInfo
+
+class  tagMCPlayerMineAreaInfo(Structure):
+    Head = tagHead()
+    WorkerCount = 0    #(BYTE WorkerCount)// 已雇佣工人数
+    EnergyUsed = 0    #(WORD EnergyUsed)// 今日已消耗体力
+    RefreshCount = 0    #(DWORD RefreshCount)// 今日福地刷新物品次数 - 普通刷新
+    RefreshCountSuper = 0    #(BYTE RefreshCountSuper)// 今日福地刷新物品次数 - 超级刷新
+    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
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB0
+        self.Head.SubCmd = 0x30
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.WorkerCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.EnergyUsed,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.RefreshCount,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.RefreshCountSuper,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.TreasureCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.TreasureCount):
+            value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
+            self.TreasureState.append(value)
+        for i in range(self.TreasureCount):
+            value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
+            self.TreasureAward.append(value)
+        for i in range(self.TreasureCount):
+            value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
+            self.TreasureProgress.append(value)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB0
+        self.Head.SubCmd = 0x30
+        self.WorkerCount = 0
+        self.EnergyUsed = 0
+        self.RefreshCount = 0
+        self.RefreshCountSuper = 0
+        self.TreasureCount = 0
+        self.TreasureState = list()
+        self.TreasureAward = list()
+        self.TreasureProgress = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 1
+        length += 2
+        length += 4
+        length += 1
+        length += 1
+        length += 1 * self.TreasureCount
+        length += 1 * self.TreasureCount
+        length += 1 * self.TreasureCount
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.WorkerCount)
+        data = CommFunc.WriteWORD(data, self.EnergyUsed)
+        data = CommFunc.WriteDWORD(data, self.RefreshCount)
+        data = CommFunc.WriteBYTE(data, self.RefreshCountSuper)
+        data = CommFunc.WriteBYTE(data, self.TreasureCount)
+        for i in range(self.TreasureCount):
+            data = CommFunc.WriteBYTE(data, self.TreasureState[i])
+        for i in range(self.TreasureCount):
+            data = CommFunc.WriteBYTE(data, self.TreasureAward[i])
+        for i in range(self.TreasureCount):
+            data = CommFunc.WriteBYTE(data, self.TreasureProgress[i])
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                WorkerCount:%d,
+                                EnergyUsed:%d,
+                                RefreshCount:%d,
+                                RefreshCountSuper:%d,
+                                TreasureCount:%d,
+                                TreasureState:%s,
+                                TreasureAward:%s,
+                                TreasureProgress:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.WorkerCount,
+                                self.EnergyUsed,
+                                self.RefreshCount,
+                                self.RefreshCountSuper,
+                                self.TreasureCount,
+                                "...",
+                                "...",
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagMCPlayerMineAreaInfo=tagMCPlayerMineAreaInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCPlayerMineAreaInfo.Head.Cmd,m_NAtagMCPlayerMineAreaInfo.Head.SubCmd))] = m_NAtagMCPlayerMineAreaInfo
+
+
+#------------------------------------------------------
 # B0 07 今日协助活跃令信息 #tagMCTodayAssistMoneyInfo
 
 class  tagMCTodayAssistMoneyInfo(Structure):
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
new file mode 100644
index 0000000..a89ab18
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MineArea.py
@@ -0,0 +1,80 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package GM.Commands.MineArea
+#
+# @todo:福地
+# @author hxp
+# @date 2024-03-07
+# @version 1.0
+#
+# 详细描述: 福地
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2024-03-07 19:30"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import PlayerControl
+import PlayerMineArea
+import ChConfig
+
+## GM命令执行入口
+#  @param curPlayer 当前玩家
+#  @param msgList 参数列表 [addSkillID]
+#  @return None
+#  @remarks 函数详细说明.
+def OnExec(curPlayer, msgList):
+    # @return: 是否发送到GameServer
+    
+    if not msgList:
+        GameWorld.DebugAnswer(curPlayer, "---------- 福地命令 ----------")
+        GameWorld.DebugAnswer(curPlayer, "重置福地玩家: MineArea 0")
+        GameWorld.DebugAnswer(curPlayer, "设置已用精力: MineArea e 精力")
+        GameWorld.DebugAnswer(curPlayer, "设置工人数量: MineArea w 数量")
+        GameWorld.DebugAnswer(curPlayer, "设置刷新次数: MineArea r 次数 [是否超级]")
+        GameWorld.DebugAnswer(curPlayer, "设置聚宝进度: MineArea t 类型 进度值")
+        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_MineRefreshCount % 0, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineRefreshCount % 1, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineTreasureState, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineTreasureAward, 0)
+        for treasureType in range(10):
+            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineTreasureProgess % treasureType, 0)
+        GameWorld.DebugAnswer(curPlayer, "重置福地玩家")
+        
+    elif value1 == "e":
+        energyUsed = msgList[1] if len(msgList) > 1 else 0
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineWorkerEnergyUsed, energyUsed)
+        GameWorld.DebugAnswer(curPlayer, "设置已用精力: %s" % energyUsed)
+        
+    elif value1 == "w":
+        workerCount = msgList[1] if len(msgList) > 1 else 0
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineWorkerCount, workerCount)
+        GameWorld.DebugAnswer(curPlayer, "设置工人数量: %s" % workerCount)
+        
+    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
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineRefreshCount % refreshType, refreshCount)
+        GameWorld.DebugAnswer(curPlayer, "设置刷新次数: %s, isSuper=%s" % (refreshCount, isSuper))
+        
+    elif value1 == "t":
+        treasureType = msgList[1] if len(msgList) > 1 else 0
+        setProgress = msgList[2] if len(msgList) > 2 else 0
+        setProgress = min(setProgress, PlayerMineArea.MineTreasureProgressMax)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineTreasureProgess % treasureType, setProgress)
+        GameWorld.DebugAnswer(curPlayer, "设置聚宝进度: Type:%s,进度=%s" % (treasureType, setProgress))
+        
+    else:
+        return True
+    
+    PlayerMineArea.SyncPlayerMineAreaInfo(curPlayer)
+    return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py
index c8f5f5a..0211847 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py
@@ -91,7 +91,7 @@
 #                     }
 
 # 功能开启需要同步到GameServer的
-FuncOpenNotifyGameServer = [ShareDefine.GameFuncID_Championship]
+FuncOpenNotifyGameServer = [ShareDefine.GameFuncID_Championship, ShareDefine.GameFuncID_MineArea]
 
 def GetFuncOpenLVIpyData(funcID): return IpyGameDataPY.GetIpyGameData("FuncOpenLV", funcID)
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
index 377e6e3..7a5e7bd 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
@@ -129,6 +129,7 @@
 import PlayerArena
 import PyGameData
 import PlayerTJG
+import PlayerMineArea
 
 import datetime
 import time
@@ -599,6 +600,8 @@
         PlayerArena.OnDayEx(curPlayer)
         #协助
         PlayerAssist.DoPlayerOnDay(curPlayer)
+        #福地
+        PlayerMineArea.PlayerOnDay(curPlayer)
         #特殊时间点过天的,一般是游戏功能,此时立即同步一次跨服玩家数据
         CrossPlayerData.SendMergePlayerDataNow(curPlayer)
         
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMineArea.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMineArea.py
new file mode 100644
index 0000000..93016c2
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMineArea.py
@@ -0,0 +1,316 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Player.PlayerMineArea
+#
+# @todo:矿物福地
+# @author hxp
+# @date 2024-03-07
+# @version 1.0
+#
+# 详细描述: 矿物福地
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2024-03-07 19:30"""
+#-------------------------------------------------------------------------------
+
+import ChConfig
+import PlayerControl
+import IpyGameDataPY
+import IPY_GameWorld
+import ChPyNetSendPack
+import NetPackCommon
+import ItemControler
+import ItemCommon
+import GameWorld
+
+# 聚宝盆默认最大进度
+MineTreasureProgressMax = 100
+
+def OnPlayerLogin(curPlayer):
+    SyncPlayerMineAreaInfo(curPlayer)
+    return
+
+def PlayerOnDay(curPlayer):
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineWorkerEnergyUsed, 0)
+    for refreshType in [0, 1]:
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineRefreshCount % refreshType, 0)
+    SyncPlayerMineAreaInfo(curPlayer)
+    return
+
+def GetWorkerTotal(curPlayer):
+    ## 获取玩家工人总数
+    initCount = 0 # 起始默认工人数
+    employCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineWorkerCount)
+    return initCount + employCount
+
+def GetWorkerState(curPlayer):
+    ## 获取工人疲劳状态
+    workerStateEnergyList = IpyGameDataPY.GetFuncEvalCfg("MineAreaWorker", 1) # 工人疲劳状态体力列表 [充沛体力, 正常, 虚弱, 枯竭],总体力=所有体力相加
+    funcEnergy = 0 # 其他功能增加的体力
+    stateEnergy = 0
+    energyUsed = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineWorkerEnergyUsed)
+    for state, energy in enumerate(workerStateEnergyList):
+        if state == 0:
+            energy += funcEnergy
+        stateEnergy += energy
+        if energyUsed <= stateEnergy:
+            return state
+    return len(workerStateEnergyList) - 1 # 默认最大疲劳
+
+#// B0 30 福地物品拉 #tagCMMineItemPull
+#
+#struct    tagCMMineItemPull
+#{
+#    tagHead        Head;
+#    DWORD        PlayerID;        // 福地所属玩家ID,0默认自己
+#    BYTE        ItemIndex;    // 物品所在位置索引0~n
+#    BYTE        WorkerCount;    // 上工人人数
+#    BYTE        IsPreview;    // 是否预览;0-直接拉,1-预览大概时间
+#};
+def OnMineItemPull(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    areaPlayerID = clientData.PlayerID
+    itemIndex = clientData.ItemIndex
+    workerCount = clientData.WorkerCount
+    isPreview = clientData.IsPreview
+    if not areaPlayerID:
+        areaPlayerID = curPlayer.GetPlayerID()
+        
+    workerTotal = GetWorkerTotal(curPlayer)
+    workerState = GetWorkerState(curPlayer)
+    
+    SendToGameServer_MineArea(curPlayer, "Pull", [areaPlayerID, itemIndex, workerCount, workerState, workerTotal, isPreview])
+    return
+
+#// B0 31 福地物品刷新 #tagCMMineItemRefresh
+#
+#struct    tagCMMineItemRefresh
+#
+#{
+#    tagHead        Head;
+#    BYTE        IsSuper;    // 是否超级刷新
+#};
+def OnMineItemRefresh(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    isSuper = clientData.IsSuper
+    
+    refreshType = str(1 if isSuper else 0)
+    
+    moneyDict = IpyGameDataPY.GetFuncEvalCfg("MineAreaRefresh", 1, {})
+    if refreshType not in moneyDict:
+        return
+    moneyType, moneyValue = moneyDict[refreshType]
+    if not PlayerControl.HaveMoney(curPlayer, moneyType, moneyValue):
+        return
+    
+    refreshMaxDict = IpyGameDataPY.GetFuncEvalCfg("MineAreaRefresh", 2, {})
+    refreshCountMax = refreshMaxDict.get(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:
+        refreshCountUpd = refreshCountNow + 1
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineRefreshCount % refreshType, refreshCountUpd)            
+        SyncPlayerMineAreaInfo(curPlayer)
+        
+    SendToGameServer_MineArea(curPlayer, "MineItemRefresh", [playerID, isSuper])
+    return
+
+#// B0 32 福地工人雇佣 #tagCMMineWorkerEmploy
+#
+#struct    tagCMMineWorkerEmploy
+#
+#{
+#    tagHead        Head;
+#};
+def OnMineWorkerEmploy(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    employCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineWorkerCount)
+    
+    costItemCountList = IpyGameDataPY.GetFuncEvalCfg("MineAreaWorker", 3)
+    if employCount >= len(costItemCountList):
+        GameWorld.DebugLog("已达到福地雇佣工人数上限! employCount=%s" % employCount)
+        return
+    costItemCount = costItemCountList[employCount]
+    costItemID = IpyGameDataPY.GetFuncCfg("MineAreaWorker", 2)
+    if not costItemID:
+        return
+    
+    # 支持配0不消耗个数
+    if costItemCount > 0:
+        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,已雇佣数=%s" 
+                               % (costItemID, costItemCount, bindCnt, unBindCnt, lackCnt, employCount))
+            return
+        delCnt = costItemCount
+        ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, delCnt, "MineWorkerEmploy")
+        
+    updEmployCount = employCount + 1
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineWorkerCount, updEmployCount)
+    SyncPlayerMineAreaInfo(curPlayer)
+    GameWorld.DebugLog("福地雇佣工人! costItemID=%s,costItemCount=%s,updEmployCount=%s" % (costItemID, costItemCount, updEmployCount), playerID)
+    return
+
+def SendToGameServer_MineArea(curPlayer, msgType, dataMsg=""):
+    playerID = curPlayer.GetPlayerID()
+    msgList = str([msgType, dataMsg])
+    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(playerID, 0, 0, "MineArea", msgList, len(msgList))
+    GameWorld.Log("福地发送GameServer: %s, %s" % (msgType, dataMsg), playerID)
+    return
+
+def GameServer_MineArea_DoResult(curPlayer, msgData):
+    
+    msgType, dataMsg, _ = msgData
+    
+    ## 结算奖励
+    if msgType == "MineAreaAwardGet":
+        awardInfoList = dataMsg[0]
+        __DoGiveMineAreaAward(curPlayer, awardInfoList)
+            
+    return
+
+def __DoGiveMineAreaAward(curPlayer, awardInfoList):
+    
+    playerID = curPlayer.GetPlayerID()
+    energyUsed = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineWorkerEnergyUsed)
+    addEnergyUsed = 0
+    awardItemDict = {}
+    robCount = 0 # 抢劫数
+    GUIDList = []
+    for awardInfo in awardInfoList:
+        GUID, awardTime, workerCount, areaPlayerID, mineID, itemLV, itemID, itemCount = awardInfo
+        isToday = GameWorld.CheckTimeIsSameServerDayEx(awardTime)
+        if isToday:
+            addEnergyUsed += workerCount
+        if playerID != areaPlayerID:
+            robCount += 1
+        awardItemDict[itemID] = awardItemDict.get(itemID, 0) + itemCount
+        GUIDList.append(GUID)
+        GameWorld.DebugLog("结算福地奖励! areaPlayerID=%s,mineID=%s,itemLV=%s,itemID=%s,itemCount=%s,awardTime=%s,isToday=%s,workerCount=%s %s" 
+                           % (areaPlayerID, mineID, itemLV, itemID, itemCount, GameWorld.ChangeTimeNumToStr(awardTime), isToday, workerCount, GUID), playerID)
+        
+    if addEnergyUsed:
+        energyUsed += addEnergyUsed
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineWorkerEnergyUsed, energyUsed)
+        GameWorld.DebugLog("    增加福地工人已用精力! addEnergyUsed=%s,updEnergyUsed=%s" % (addEnergyUsed, energyUsed), playerID)
+        
+    if robCount:
+        OnAddMineTreasureProgress(curPlayer, robCount, False)
+        
+    SyncPlayerMineAreaInfo(curPlayer)
+    
+    awardItemList = [[itemID, itemCount, 0] for itemID, itemCount in awardItemDict.items()]
+    ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, None, ["MineAreaAward", False, {}])
+    
+    SendToGameServer_MineArea(curPlayer, "MineAreaAwardGetOK", [GUIDList, awardItemList])
+    return
+
+def OnMineTreasureByCTGID(curPlayer, ctgID):
+    ## 充值激活聚宝盆
+    treasureCTGIDList = IpyGameDataPY.GetFuncEvalCfg("MineAreaTreasure", 1)
+    for treasureType, ctgIDList in enumerate(treasureCTGIDList):
+        if not ctgIDList or ctgID not in ctgIDList: # 配空列表的默认激活
+            continue
+        state = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineTreasureState)
+        if state&pow(2, treasureType):
+            break
+        updState = state|pow(2, treasureType)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineTreasureState, updState)
+        SyncPlayerMineAreaInfo(curPlayer)
+        GameWorld.Log("激活福地聚宝盆: treasureType=%s,updState=%s" % (treasureType, updState), curPlayer.GetPlayerID())
+        break
+    
+    return
+
+def OnAddMineTreasureProgress(curPlayer, robCount, isNotify=True):
+    ## 增加聚宝盆进度
+    # @param robCount: 抢夺物品数
+    if robCount <= 0:
+        return
+    
+    playerID = curPlayer.GetPlayerID()
+    treasureCTGIDList = IpyGameDataPY.GetFuncEvalCfg("MineAreaTreasure", 1)    
+    treasureAddProgressList = IpyGameDataPY.GetFuncEvalCfg("MineAreaTreasure", 2)
+    treasureState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineTreasureState)
+    for treasureType, addProgressSet in enumerate(treasureAddProgressList):
+        ctgIDList = treasureCTGIDList[treasureType]
+        isActivite = 1 if (not ctgIDList or treasureState&pow(2, treasureType)) else 0
+        if not isActivite:
+            continue
+        curProgress = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineTreasureProgess % treasureType)
+        if curProgress >= MineTreasureProgressMax:
+            continue
+        addProgress = addProgressSet * robCount
+        updProgress = min(curProgress + addProgress, MineTreasureProgressMax)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineTreasureProgess % treasureType, updProgress)
+        GameWorld.DebugLog("    增加福地聚宝盆进度: robCount=%s,treasureType=%s,curProgress=%s,addProgress=%s,updProgress=%s" 
+                           % (robCount, treasureType, curProgress, addProgress, updProgress), playerID)
+        
+    if isNotify:
+        SyncPlayerMineAreaInfo(curPlayer)
+    return
+
+def GetMineTreasureAward(curPlayer, treasureType):
+    ## 领取聚宝盆奖励
+    
+    playerID = curPlayer.GetPlayerID()
+    
+    treasureAward = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineTreasureAward)
+    if treasureAward&pow(2, treasureType):
+        GameWorld.DebugLog("福地聚宝盆奖励已领取过! treasureType=%s,treasureAward=%s" % (treasureType, treasureAward), playerID)
+        return
+    
+    curProgress = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineTreasureProgess % treasureType)
+    if curProgress < MineTreasureProgressMax:
+        GameWorld.DebugLog("福地聚宝盆进度未满,无法领奖! treasureType=%s,curProgress=%s" % (treasureType, curProgress), playerID)
+        return
+    
+    treasureAwardList = IpyGameDataPY.GetFuncEvalCfg("MineAreaTreasure", 3)
+    if treasureType >= len(treasureAwardList):
+        return
+    awardItemList = treasureAwardList[treasureType]
+    
+    if not ItemControler.CheckPackSpaceEnough(curPlayer, awardItemList):
+        return
+    
+    updAward = treasureAward|pow(2, treasureType)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineTreasureAward, updAward)
+    SyncPlayerMineAreaInfo(curPlayer)
+    
+    for itemID, itemCount, isAuctionItem in awardItemList:
+        ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isAuctionItem, [IPY_GameWorld.rptItem])
+        
+    GameWorld.DebugLog("福地聚宝盆领奖! treasureType=%s,updAward=%s,awardItemList=%s" % (treasureType, updAward, awardItemList), playerID)
+    return
+
+def SyncPlayerMineAreaInfo(curPlayer):
+    clientPack = ChPyNetSendPack.tagMCPlayerMineAreaInfo()
+    clientPack.WorkerCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineWorkerCount)
+    clientPack.EnergyUsed = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineWorkerEnergyUsed)
+    clientPack.RefreshCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineRefreshCount % 0)
+    clientPack.RefreshCountSuper = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineRefreshCount % 1)
+    
+    treasureState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineTreasureState)
+    treasureAward = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineTreasureAward)
+    treasureCTGIDList = IpyGameDataPY.GetFuncEvalCfg("MineAreaTreasure", 1)
+    clientPack.TreasureCount = len(treasureCTGIDList)
+    clientPack.TreasureState = [0] * clientPack.TreasureCount
+    clientPack.TreasureAward = [0] * clientPack.TreasureCount
+    clientPack.TreasureProgress = [0] * clientPack.TreasureCount
+    for treasureType, ctgIDList in enumerate(treasureCTGIDList):
+        isActivite = 1 if (not ctgIDList or treasureState&pow(2, treasureType)) else 0
+        clientPack.TreasureState[treasureType] = isActivite
+        clientPack.TreasureAward[treasureType] = 1 if treasureAward&pow(2, treasureType) else 0
+        clientPack.TreasureProgress[treasureType] = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineTreasureProgess % treasureType)
+        
+    NetPackCommon.SendFakePack(curPlayer, clientPack)
+    return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_MineArea.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_MineArea.py
new file mode 100644
index 0000000..d686788
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_MineArea.py
@@ -0,0 +1,47 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Player.RemoteQuery.GY_Query_MineArea
+#
+# @todo:福地
+# @author hxp
+# @date 2024-03-07
+# @version 1.0
+#
+# 详细描述: 福地
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2024-03-07 19:30"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import PlayerMineArea
+
+#---------------------------------------------------------------------
+#逻辑实现
+## 请求逻辑
+#  @param query_Type 请求类型
+#  @param query_ID 请求的玩家ID
+#  @param packCMDList 发包命令 [ ]
+#  @param tick 当前时间
+#  @return "True" or "False" or ""
+#  @remarks 函数详细说明.
+def DoLogic(query_Type, query_ID, packCMDList, tick):
+    return ""
+
+#---------------------------------------------------------------------
+#执行结果
+## 执行结果
+#  @param curPlayer 发出请求的玩家
+#  @param callFunName 功能名称
+#  @param funResult 查询的结果
+#  @param tick 当前时间
+#  @return None
+#  @remarks 函数详细说明.
+def DoResult(curPlayer, callFunName, funResult, tick):
+    GameWorld.DebugLog("GY_Query_MineArea DoResult %s" % str(funResult), curPlayer.GetPlayerID())
+    if funResult != "":
+        PlayerMineArea.GameServer_MineArea_DoResult(curPlayer, eval(funResult))
+    return
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
index 3d11842..ded36dd 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -1188,6 +1188,7 @@
 GameFuncID_FaQi = 199           # 法器
 GameFuncID_LianTi = 207         # 炼体
 GameFuncID_Championship = 210   # 排位
+GameFuncID_MineArea = 223   	# 福地
 # 以下为暂时无用的
 GameFuncID_Truck = 33           # 运镖
 GameFuncID_RunDaily = 34        # 日常跑环

--
Gitblit v1.8.0