From 7d72b082da27e949902ef083eb4ea2da201a013f Mon Sep 17 00:00:00 2001
From: hch <305670599@qq.com>
Date: 星期六, 01 九月 2018 17:04:46 +0800
Subject: [PATCH] 3191 极光推送混服修改

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/BossHurtMng.py |   16 ++
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py                 |    1 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGeTui.py         |   30 +--
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py                |   11 +
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerGeTui.py                              |  105 +++++++++---
 Tool/webbottle/lib/ConfigIniReader.py                                                             |  144 +----------------
 Tool/webbottle/webapp.py                                                                          |   76 +++++----
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py                    |    2 
 Tool/webbottle/Config.ini                                                                         |   15 +
 ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py                                     |   11 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTJG.py           |   52 ++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py |   16 ++
 12 files changed, 265 insertions(+), 214 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py
index 50b7182..02a3f75 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py
@@ -914,7 +914,7 @@
         killBossCntLimitDict = IpyGameDataPY.GetFuncEvalCfg('KillBossCntLimit', 1, {})
         canRebornBossIDList = []
         for bidlist, bkey in killBossCntLimitDict.items():
-            if bkey not in [0, 1]:
+            if bkey not in [ShareDefine.Def_Boss_Func_World, ShareDefine.Def_Boss_Func_Home]:
                 continue
             canRebornBossIDList += list(bidlist)
         
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
index 8e1857b..175d242 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
@@ -169,6 +169,7 @@
     #GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_ServerDay, openServerDay)
     #清理过期补偿
     PlayerCompensation.ClearUpTimeOutCompensation()
+    PlayerGeTui.ClearFMTGeTuiLimit()
     import PlayerBourse
     PlayerBourse.OverTimeItemsDeal()
     return
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerGeTui.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerGeTui.py
index d8a56ce..eea8d25 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerGeTui.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerGeTui.py
@@ -24,7 +24,7 @@
 import PlayerControl
 import PyDataManager
 import time
-
+import json
 # VIP权限
 Def_Onoff_VIPCount = 5
 (
@@ -40,6 +40,14 @@
 
 # 新玩家还没有脱机时间 有利于挽回流失玩家
 g_NewGuyNoTJGTime = {} # {playerID:[playername,getuiid, tick]}
+
+g_FMTGeTuiLimit = {}    # 封魔坛推送限制 过于频繁控制下短时间通知
+
+def ClearFMTGeTuiLimit():
+    global g_FMTGeTuiLimit
+    g_FMTGeTuiLimit = {}
+
+
 
 def GetTimeLimit(timeStr):
     # 检查格式后转数字
@@ -149,22 +157,19 @@
 # 服务端群推暂不由游戏服务器推送,可从第三方个推网站推送
 # 游戏服务器只推送具有变化性的内容
 # 支持单推和多人推送
-# getuiIDList 玩家个推ID
-# playerNameList 如果存在则必须与getuiIDList一一对应,若不存在则是多推,若存在则会一一单推
+# appIDDict 混服使用对应不同key {平台ID:[[玩家个推ID, 玩家名],[玩家个推ID2, 玩家名2]。。。]}
+# 如果玩家名存在则必须与个推ID一一对应,若不存在则是多推,若存在则会一一单推
 #                带名字会被组合成 格式如【玩家名】您关注的BOSSxx已复活
 # EventReport_EventReport 向游戏服务器的个推小程序发送 webbottle
-def GeTuiNotify(getuiIDList, playerNameList, notifyMsg):
-    if type(getuiIDList) != list:
+def GeTuiNotify(appIDDict, notifyMsg):
+    if not appIDDict:
         return
-    osName = ReadChConfig.GetPyMongoConfig("GeTui", "OSName")
+    #osName = ReadChConfig.GetPyMongoConfig("GeTui", "OSName") 混服无法配置系统
     geTuiUrl = ReadChConfig.GetPyMongoConfig("GeTui", "GeTuiUrl")
     
-    playerNames = "|".join(playerNameList)  #组合成字符串发送
-    getuiIDs = "|".join(getuiIDList)
-    
+    playerInfo = json.dumps(appIDDict, ensure_ascii=False)
     #含中文部分要urlencode
-    postInfo = urllib.urlencode({"PlayerName": playerNames, "NotifyMsg":notifyMsg, 
-                                "RegID":getuiIDs, "OSName":osName})
+    postInfo = urllib.urlencode({"PlayerInfo": playerInfo, "NotifyMsg":notifyMsg})
     
     GameWorld.GetGameWorld().EventReport_EventReport(postInfo, "", "", "", 1, geTuiUrl)
     return
@@ -209,6 +214,41 @@
     return
     
     
+
+
+# 判断BOSS剩余次数, 避免通知频繁
+# 注意玩家次数用完第二天未上线则不会同步BOSS次数,则不推送
+def CheckBossGeTuiCnt(playerID, bossID, geTuiType, cacheDict):
+    global g_FMTGeTuiLimit
+    
+    if geTuiType == Def_GeTui_FMT:
+        if not cacheDict.get("CntMark_%s"%ChConfig.Def_FBMapID_SealDemon, 0):
+            return False
+        
+        # 封魔坛比较频繁默认1小时通知一次
+        if playerID not in g_FMTGeTuiLimit:
+            g_FMTGeTuiLimit[playerID] = {}
+        
+        lastTime = g_FMTGeTuiLimit[playerID].get(bossID, 0)
+        if lastTime != 0 and time.time() - lastTime < 3600:
+            # 离上次通知还没超过1小时
+            return False
+        
+        g_FMTGeTuiLimit[playerID][bossID] = int(time.time())
+            
+            
+    elif geTuiType == Def_Onoff_Boss:
+        #重生boss
+        killBossCntLimitDict = IpyGameDataPY.GetFuncEvalCfg('KillBossCntLimit', 1, {})
+        for bidlist, bkey in killBossCntLimitDict.items():
+            if bossID not in bidlist:
+                continue
+            if not cacheDict.get("CntMark_%s"%bkey, 0):
+                return False
+            else:
+                return True
+    return True
+    
 def BossAttentionGeTui(bossData, bossID):
     if bossData.GetMapID() == ChConfig.Def_FBMapID_SealDemon:
         # 非VIP玩家 封魔坛个推
@@ -219,9 +259,7 @@
     #找到关注这只BOSS的玩家
     pdict = PyDataManager.GetBossAttentionManager().GetBossAttentionDict()
     
-    geTuiIDList = []
-    playerNameList = []
-    
+    appIDDict = {}    # 混服需要推到不同的个推应用
     for playerID, bossAttentionData in pdict.items():
         curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
         if curPlayer and not PlayerControl.GetIsTJG(curPlayer):
@@ -229,6 +267,7 @@
 
         recordDict = eval(bossAttentionData.RecordData)
         if recordDict.get(bossID, 0) in [0, 9]:
+            #0-默认未关注, 1-主动关注, 2-自动关注, 9-主动取消关注
             continue
         curCache = PlayerViewCache.ViewCacheMgr.FindCache(playerID)
         if not curCache:
@@ -238,11 +277,18 @@
             # 过滤个推
             continue
         
-        geTuiIDList.append(cacheDict.get("GeTuiClientID", ""))
-        playerNameList.append(cacheDict.get("Name", ""))
-    
+        if not CheckBossGeTuiCnt(playerID, bossID, geTuiType, cacheDict):
+            # 判断BOSS剩余次数, 避免通知频繁
+            continue
+        
+        appID = GameWorld.GetPlayerPlatform(cacheDict.get("AccID", ""))
+        if appID not in appIDDict:
+            appIDDict[appID] = []
+            
+        appIDDict[appID].append([cacheDict.get("GeTuiClientID", ""), cacheDict.get("Name", "")])
+             
 
-    if not geTuiIDList:
+    if not appIDDict:
         return
     
     npcName = GameWorld.GetNPCData(bossID).GetNPCName()
@@ -253,7 +299,7 @@
     elif geTuiType == Def_Onoff_Boss:
         showStr = GameWorld.GbkToCode(IpyGameDataPY.GetFuncCfg("GeTuiOffLine", 2)%(bossData.GetSourceName(), npcName, npcLV))    # 文字信息
         
-    GeTuiNotify(geTuiIDList, playerNameList, showStr)
+    GeTuiNotify(appIDDict, showStr)
     
 
 # 私聊
@@ -268,7 +314,7 @@
         return
     
     showStr = GameWorld.GbkToCode(IpyGameDataPY.GetFuncCfg("GeTuiOffLine", 3))%(tagPlayerName)    # 文字信息
-    GeTuiNotify([cacheDict.get("GeTuiClientID", "")], [playerName], showStr)
+    GeTuiNotify({GameWorld.GetPlayerPlatform(cacheDict.get("AccID", "")):[[cacheDict.get("GeTuiClientID", ""), playerName]]}, showStr)
     return
 
 # 下线时,低级玩家没有离线时间的玩家提示, 上线清空
@@ -279,7 +325,8 @@
     if curPlayer.GetLV() > 100:
         return
     playerID = curPlayer.GetID()
-    g_NewGuyNoTJGTime[playerID] = [curPlayer.GetName(), curPlayer.GetGeTuiClientID(), tick]  # curPlayer.GetGeTuiClientID()
+    g_NewGuyNoTJGTime[playerID] = [curPlayer.GetName(), curPlayer.GetGeTuiClientID(), tick, 
+                                   GameWorld.GetPlayerPlatform(curPlayer.GetAccID())]  # curPlayer.GetGeTuiClientID()
     return
 
 # 上线清除
@@ -299,20 +346,24 @@
     global g_NewGuyNoTJGTime
     
     playerIDList = []
-    geTuiIDs = []
-    playerNames = []
+    appIDDict = {}
+    
     for playerID, getuiInfo in g_NewGuyNoTJGTime.items():
         if tick - getuiInfo[2] < 300000:
             continue
         playerIDList.append(playerID)
         
-        geTuiIDs.append(getuiInfo[1])
-        playerNames.append(getuiInfo[0])
+        appID = getuiInfo[3]
+        if appID not in appIDDict:
+            appIDDict[appID] = []
+            
+        appIDDict[appID].append([getuiInfo[1],getuiInfo[0]])
         
-    if not geTuiIDs:
+        
+    if not appIDDict:
         return
     showStr = GameWorld.GbkToCode(IpyGameDataPY.GetFuncCfg("GeTuiOffLine", 4))    # 文字信息
-    GeTuiNotify(geTuiIDs, playerNames, showStr)
+    GeTuiNotify(appIDDict, showStr)
         
     for playerID in playerIDList:
         CleanNewGuyCallBackGeTui(playerID)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
index 7c75f72..6a98a8e 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -1712,4 +1712,13 @@
 FamilyActive_War, #仙盟联赛
 FamilyActive_HelpDujie, #同盟护法
 FamilyActive_SWRH, #守卫人皇
-) = range(1,6+1)
\ No newline at end of file
+) = range(1,6+1)
+
+
+# BOSS 功能标识区分 对应KillBossCntLimit,主要根据击杀类型不同区分
+(
+Def_Boss_Func_World, # 世界BOSS
+Def_Boss_Func_Home, # BOSS之家
+Def_Boss_Func_Dogz, # 神兽功能BOSS
+) = range(3)
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/BossHurtMng.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/BossHurtMng.py
index 3b4c329..d4fa441 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/BossHurtMng.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/BossHurtMng.py
@@ -47,6 +47,7 @@
 import ItemControler
 import ChConfig
 import FBLogic
+import PlayerVip
 
 import operator
 import json
@@ -548,3 +549,18 @@
     NetPackCommon.SendFakePack(curPlayer, packdata)
     return
 
+
+# BOSS剩余可击杀次数
+def GetCanKillBossCnt(curPlayer, bossFuncIndex):
+    hasKillCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Boss_KillCnt%bossFuncIndex, 0)
+    itemAddKillCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Boss_KillCntItemAddCnt%bossFuncIndex, 0)
+    killLimitPrivilege = IpyGameDataPY.GetFuncEvalCfg('KillBossCntLimit', 4, {}).get(bossFuncIndex, 0)
+    if killLimitPrivilege:
+        limitCnt = PlayerVip.GetPrivilegeValue(curPlayer, killLimitPrivilege)
+    else:
+        limitCnt = IpyGameDataPY.GetFuncEvalCfg('KillBossCntLimit', 2, {}).get(bossFuncIndex, 0)
+    
+    
+    return max(limitCnt + itemAddKillCnt - hasKillCnt, 0)
+
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGeTui.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGeTui.py
index 63ed1cc..04256d6 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGeTui.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGeTui.py
@@ -26,6 +26,7 @@
 import PlayerViewCacheTube
 import urllib
 import PlayerVip
+import json
 #===============================================================================
 # //B2 05 推送提醒设置 tagCMPushNotificationsSetting
 # 
@@ -196,27 +197,23 @@
 # 服务端群推暂不由游戏服务器推送,可从第三方个推网站推送
 # 游戏服务器只推送具有变化性的内容
 # 支持单推和多人推送
-# getuiIDList 玩家个推ID
-# playerNameList 如果存在则必须与getuiIDList一一对应,若不存在则是多推,若存在则会一一单推
+# appIDDict 混服使用对应不同key {平台ID:[[玩家个推ID, 玩家名],[玩家个推ID2, 玩家名2]。。。]}
+# 如果玩家名存在则必须与个推ID一一对应,若不存在则是多推,若存在则会一一单推
 #                带名字会被组合成 格式如【玩家名】您关注的BOSSxx已复活
 # EventReport_EventReport 向游戏服务器的个推小程序发送 webbottle
-def GeTuiNotify(getuiIDList, playerNameList, notifyMsg):
-    if type(getuiIDList) != list:
+def GeTuiNotify(appIDDict, notifyMsg):
+    if not appIDDict:
         return
-
-    osName = ReadChConfig.GetPyMongoConfig("GeTui", "OSName")
+    #osName = ReadChConfig.GetPyMongoConfig("GeTui", "OSName") 混服无法配置系统
     geTuiUrl = ReadChConfig.GetPyMongoConfig("GeTui", "GeTuiUrl")
     
-    playerNames = "|".join(playerNameList)  #组合成字符串发送
-    getuiIDs = "|".join(getuiIDList)
-    
+    playerInfo = json.dumps(appIDDict, ensure_ascii=False)
     #含中文部分要urlencode
-    postInfo = urllib.urlencode({"PlayerName": playerNames, "NotifyMsg":notifyMsg, 
-                                "RegID":getuiIDs, "OSName":osName})
+    postInfo = urllib.urlencode({"PlayerInfo": playerInfo, "NotifyMsg":notifyMsg})
     
-
     GameWorld.GetGameWorld().EventReport_EventReport(postInfo, "", "", "", 1, geTuiUrl)
     return
+
 
 # 时间不足
 def TJGTimeLess(curPlayer):
@@ -234,8 +231,7 @@
         return
     
     showStr = GameWorld.GbkToCode(IpyGameDataPY.GetFuncCfg("GeTuiTJG", 4))    # 文字信息
-    
-    GeTuiNotify([GetGeTuiClientID(curPlayer)], [curPlayer.GetName()], showStr)
+    GeTuiNotify({GameWorld.GetPlayerPlatform(curPlayer.GetAccID()) :[[GetGeTuiClientID(curPlayer), curPlayer.GetName()]]}, showStr)
     return
 
 
@@ -273,7 +269,7 @@
     
     tjgTime = PlayerTJG.GetTJGTime(curPlayer)
     
-    GeTuiNotify([GetGeTuiClientID(curPlayer)], [curPlayer.GetName()], 
+    GeTuiNotify({GameWorld.GetPlayerPlatform(curPlayer.GetAccID()) : [[GetGeTuiClientID(curPlayer), curPlayer.GetName()]]}, 
                 GameWorld.GbkToCode(showStr%(expStr, tjgTime/60/60, tjgTime/60%60)))
     return
 
@@ -290,7 +286,7 @@
     showStr = GameWorld.GbkToCode(IpyGameDataPY.GetFuncCfg("GeTuiTJG", 2))    # 文字信息
     tjgTime = PlayerTJG.GetTJGTime(curPlayer)
     
-    GeTuiNotify([GetGeTuiClientID(curPlayer)], [curPlayer.GetName()], 
+    GeTuiNotify({GameWorld.GetPlayerPlatform(curPlayer.GetAccID()) : [[GetGeTuiClientID(curPlayer), curPlayer.GetName()]]}, 
                 showStr%(tagName, tjgTime/60/60, tjgTime/60%60))
     return
 
@@ -307,7 +303,7 @@
         return
     
     showStr = GameWorld.GbkToCode(IpyGameDataPY.GetFuncCfg("GeTuiTJG", 3))    # 文字信息
-    GeTuiNotify([GetGeTuiClientID(curPlayer)], [curPlayer.GetName()], showStr)
+    GeTuiNotify({GameWorld.GetPlayerPlatform(curPlayer.GetAccID()) : [[GetGeTuiClientID(curPlayer), curPlayer.GetName()]]}, showStr)
     
     
     
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTJG.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTJG.py
index f13b50d..fb4486a 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTJG.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTJG.py
@@ -826,6 +826,58 @@
     return
 
 
+def TJGGM(curPlayer, times):
+    # 真实上线
+    npcID = FindTJGNPC(curPlayer)
+    if not npcID:
+        return
+    
+    # 此时由服务端重新找一次挂机NPC
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PlayerKey_TJGNPC, npcID)
+
+    GameWorld.DebugAnswer(curPlayer, "GM模拟脱机产出,npcid:%s, 时间秒:%s, 经验倍率:%s"%(
+                    curPlayer.NomalDictGetProperty(ChConfig.Def_PlayerKey_TJGNPC), times,
+                    curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_TotalExpRate)))
+    
+    
+    # 设置脱机登录时的等级, 上线通知清空, 没清空说明多次脱机挂登录 使用旧等级
+    notifyLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDictType_TJGNotify_LV, 0, ChConfig.Def_PDictType_TJGNotify)
+    if not notifyLV:
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDictType_TJGNotify_LV, curPlayer.GetLV(), ChConfig.Def_PDictType_TJGNotify)
+    
+    
+    # 记录秒单位
+    NoteTJGTime(curPlayer, times)
+    OnTJGKillNPCByTimes(curPlayer, times)
+
+    sendPack = ChPyNetSendPack.tagMCTJGInfo()
+    sendPack.Clear()
+    sendPack.Exp1 = curPlayer.NomalDictGetProperty(ChConfig.Def_PDictType_TJGNotify_Exp1, 0, ChConfig.Def_PDictType_TJGNotify)
+    sendPack.Exp2 = curPlayer.NomalDictGetProperty(ChConfig.Def_PDictType_TJGNotify_Exp2, 0, ChConfig.Def_PDictType_TJGNotify)
+    sendPack.Times = times
+    sendPack.PurpleEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDictType_TJGNotify_Purple, 0, ChConfig.Def_PDictType_TJGNotify)
+    sendPack.OrangeEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDictType_TJGNotify_Orange, 0, ChConfig.Def_PDictType_TJGNotify)
+    sendPack.EatPurpleEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDictType_TJGNotify_EatPurple, 0, ChConfig.Def_PDictType_TJGNotify)
+    sendPack.GiveCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDictType_TJGNotify_GiveCnt, 0, ChConfig.Def_PDictType_TJGNotify)
+    sendPack.BeforeLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDictType_TJGNotify_LV, 0, ChConfig.Def_PDictType_TJGNotify)
+    sendPack.Items = []
+    itemIDList = IpyGameDataPY.GetFuncEvalCfg('OfflinePostItem', 1)
+    for itemID in itemIDList:
+        count = curPlayer.NomalDictGetProperty(ChConfig.Def_PDictType_TJGNotify_ItemID%itemID, 0, ChConfig.Def_PDictType_TJGNotify)
+        if count == 0:
+            continue
+        itemInfo = ChPyNetSendPack.tagMCTJGItems()
+        itemInfo.ItemID = itemID
+        itemInfo.Count = count
+        sendPack.Items.append(itemInfo)
+    sendPack.Cnt = len(sendPack.Items)
+    
+    NetPackCommon.SendFakePack(curPlayer, sendPack)
+    
+    curPlayer.ClearNomalDict(ChConfig.Def_PDictType_TJGNotify)
+
+
+
 # 上线检查脱机时间是否正常运行, 弥补对应缺失时间,如维护2小时缺失的脱机挂收益
 # 1. 非脱机死亡,2.存在脱机时间,3.离线时间超过5分钟;则一次补齐 离线时间-5分钟的收益并减少脱机时间
 # 按当前经验倍率计算,且不会减buff时间
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py
index aa723b7..16167c8 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py
@@ -28,6 +28,9 @@
 import ItemControler
 import IpyGameDataPY
 import ChEquip
+import FBCommon
+import BossHurtMng
+
 import time
 import json
 
@@ -81,6 +84,7 @@
     #-----------
     #玩家属性缓存
     curPlayerPropDict = {}
+    curPlayerPropDict["AccID"] = curPlayer.GetAccID()
     curPlayerPropDict["LV"] = curPlayer.GetLV()
     curPlayerPropDict["RealmLV"] = curPlayer.GetOfficialRank()
     curPlayerPropDict["Job"] = curPlayer.GetJob()
@@ -101,6 +105,18 @@
     curPlayerPropDict['GeTuiClientID'] = curPlayer.GetAccountData().GetGeTuiClientID()
     curPlayerPropDict['Time'] = int(time.time())    # 最后一次发送即当做离线时间
     
+    # 各类功能 BOSS次数, BOSS相关对应B.Boss信息.xlsx的CntMark
+    # 封魔坛剩余次数
+    enterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntDay % ChConfig.Def_FBMapID_SealDemon)
+    maxCnt = FBCommon.GetEnterFBMaxCnt(curPlayer, ChConfig.Def_FBMapID_SealDemon)
+    curPlayerPropDict['CntMark_%s'%ChConfig.Def_FBMapID_SealDemon] = max(maxCnt - enterCnt, 0)
+    # 世界BOSS剩余次数
+    curPlayerPropDict['CntMark_%s'%ShareDefine.Def_Boss_Func_World] = BossHurtMng.GetCanKillBossCnt(curPlayer, ShareDefine.Def_Boss_Func_World)
+    # BOSS之家剩余次数
+    curPlayerPropDict['CntMark_%s'%ShareDefine.Def_Boss_Func_Home] = BossHurtMng.GetCanKillBossCnt(curPlayer, ShareDefine.Def_Boss_Func_Home)
+    # 神兽BOSS剩余次数
+    curPlayerPropDict['CntMark_%s'%ShareDefine.Def_Boss_Func_Dogz] = BossHurtMng.GetCanKillBossCnt(curPlayer, ShareDefine.Def_Boss_Func_Dogz)
+
     #-----------
     #装备数据打包缓存
     curEquipItemList = __GetPackEquipCacheList(curPlayer, IPY_GameWorld.rptEquip)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
index 7c75f72..6a98a8e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -1712,4 +1712,13 @@
 FamilyActive_War, #仙盟联赛
 FamilyActive_HelpDujie, #同盟护法
 FamilyActive_SWRH, #守卫人皇
-) = range(1,6+1)
\ No newline at end of file
+) = range(1,6+1)
+
+
+# BOSS 功能标识区分 对应KillBossCntLimit,主要根据击杀类型不同区分
+(
+Def_Boss_Func_World, # 世界BOSS
+Def_Boss_Func_Home, # BOSS之家
+Def_Boss_Func_Dogz, # 神兽功能BOSS
+) = range(3)
+
diff --git a/Tool/webbottle/Config.ini b/Tool/webbottle/Config.ini
new file mode 100644
index 0000000..cf5c66b
--- /dev/null
+++ b/Tool/webbottle/Config.ini
@@ -0,0 +1,15 @@
+[GeTuiConfig]
+# 一个自由APPID对应一对app_key和master_secret为极光推送应用生成
+app_key_822055139 = 1c060648058afe0b5faf72ca
+master_secret_822055139 = 568ae9f1a2a7650220af3921
+
+app_key_828115704 = 1c060648058afe0b5faf72ca
+master_secret_828115704 = 568ae9f1a2a7650220af3921
+
+
+
+# 通知格式  【玩家名】信息
+NotifyFormat = 【%s】%s
+
+# Def_NoName为名字缺失时默认的显示
+Def_NoName = 亲
\ No newline at end of file
diff --git a/Tool/webbottle/lib/ConfigIniReader.py b/Tool/webbottle/lib/ConfigIniReader.py
index afa4c07..f1da951 100644
--- a/Tool/webbottle/lib/ConfigIniReader.py
+++ b/Tool/webbottle/lib/ConfigIniReader.py
@@ -15,153 +15,29 @@
 import logging
 
 class AppConfig():
-    def __init__(self, filePath):
+    def __init__(self, filePath, sectionName):
         self.config = ConfigParser.ConfigParser()
         self.config.read(filePath)
+        self.sectionName = sectionName
         
-    def SetSection(self, sectionName ):
+    def SetSection(self, sectionName):
         self.sectionName = sectionName
         
     def GetValue(self, key):
-        return self.config.get(self.sectionName,key) 
+        return self.config.get(self.sectionName, key) 
     
     def GetIntValue(self, key):
-        return self.config.getint(self.sectionName,key) 
+        return self.config.getint(self.sectionName, key) 
 
-class GameConfig():
-    def __init__(self, filePath):
-        config = AppConfig( filePath )
-        logging.debug( "Config file:%s", filePath )
-        config.SetSection( "ServerConfig" )
-        self.ip = config.GetValue( "IP" )
-        self.port = config.GetIntValue( "Port" )
-        
-        config.SetSection( "VersionConfig" )
-        self.ClientVersion = config.GetValue( "ClientVersion" )
-        self.VersionNO = config.GetIntValue( "VERSION_NO" )
-        self.StartCnt = config.GetIntValue( "PACK_START_COUNT" )
-        self.KeyName = config.GetValue( "Key" )
-        keylen = len(self.KeyName)-1
-        self.KeyName = self.KeyName[1:keylen]
-        self.SendKeyDictPath = config.GetValue( "SendKeyDictFile" )
-        
-        config.SetSection( "MapDataConfig" )
-        self.MapFilePath = config.GetValue( "MapFilePath" )
-        self.MapPostFix = config.GetValue( "MapPostFix" )
-        
-        
-        config.SetSection( "ThreadNumberControl" )
-        self.IOThreadNum = config.GetIntValue( "IOWorkerThreadNum" )
-        self.AIThreadNum = config.GetIntValue( "AIWorkerThreadNum" )
-        
-        config.SetSection( "RunningParams" )
-        self.UsePsyco = config.GetIntValue( "UsePsyco" )
-        self.AISleepPeriod = config.GetIntValue( "AISleepPeriod" )
-        self.PlayerOffTime = config.GetIntValue( "PlayerOffTime")
-        self.ProcessFindTJGTime = config.GetIntValue( "ProcessFindTJGTime")
-        self.ServerDBConfigPath = config.GetValue( "ServerDBConfigPath")
-        self.StartRunTime = config.GetIntValue( "StartRunTime")
-        
-    def GetIOThreadNum(self):
-        return self.IOThreadNum
-    
-    def GetAIThreadNum(self):
-        return self.AIThreadNum
-        
-    def GetServerIP(self):
-        return self.ip
-    
-    def GetServerPort(self):
-        return self.port
-    
-    def GetClientVersion(self):
-        return self.ClientVersion
-    
-    def GetVersionNo(self):
-        return self.VersionNO
-    
-    def GetPackStartCount(self):
-        return self.StartCnt
-    
-    def GetKeyString(self):
-        return self.KeyName
-    
-    def GetSendKeyDictFilePath(self):
-        return self.SendKeyDictPath
-    
-    def GetMapFilePath(self):
-        return self.MapFilePath
-    
-    def GetMapFilePostFix(self):
-        return self.MapPostFix
-    
-    def GetUsePsyco(self):
-        return self.UsePsyco
-    
-    def GetAISleepPeriod(self):
-        return self.AISleepPeriod
-    
-    # 玩家下线时长
-    def GetPlayerOffTime(self):
-        return self.PlayerOffTime
-    
-    # 从数据库查询脱机挂玩家的间隔
-    def GetProcessFindTJGTime(self):
-        return self.ProcessFindTJGTime
-
-    def GetServerDBConfigPath(self):
-        return self.ServerDBConfigPath
-
-    def GetStartRunTime(self):
-        return self.StartRunTime
-    
-    def __str__(self):
-        return "ClientVersion:[%s]\n" \
-            "KeyString:[%s]\n" \
-            "MapFilePath:[%s]\n" \
-            "MapFilePostFix:[%s]\n" \
-            "PackStartCount:[%u]\n" \
-            "SendKeyDictFile:[%s]\n" \
-            "ServerIP:[%s]\n" \
-            "ServerPort:[%u]\n" \
-            "VersionNO:[%u]\n" \
-            "IOThreadNum:[%u]\n" \
-            "AIThreadNum:[%u]\n" \
-            "UsePsyco:[%u]\n" \
-            "AISleepPeriod:[%u]\n" \
-         % \
-        ( \
-            self.GetClientVersion(),\
-            self.GetKeyString(), \
-            self.GetMapFilePath(), \
-            self.GetMapFilePostFix(), \
-            self.GetPackStartCount(), \
-            self.GetSendKeyDictFilePath(), \
-            self.GetServerIP(), \
-            self.GetServerPort(), \
-            self.GetVersionNo(), \
-            self.GetIOThreadNum(), \
-            self.GetAIThreadNum(), \
-            self.GetUsePsyco(), \
-            self.GetAISleepPeriod(), \
-        )
-        
 __gGameConfig = None
 
-def ReadConfig( filename ):
-    global __gGameConfig
-    if not __gGameConfig:
-        __gGameConfig =  GameConfig( filename )
-        
+
         
 def GetConfig():
     global __gGameConfig
+    if not __gGameConfig:
+        FilePath = ".\Config.ini"
+        SectionName = "GeTuiConfig"
+        __gGameConfig = AppConfig (FilePath, SectionName)
     return __gGameConfig
 
-if __name__ == '__main__':
-    FilePath = "..\Configuration\Config.ini" 
-    SectionName = "GameConfig"
-
-    ReadConfig( FilePath )
-    config = GetConfig()
-    print config
diff --git a/Tool/webbottle/webapp.py b/Tool/webbottle/webapp.py
index 00b0268..a816810 100644
--- a/Tool/webbottle/webapp.py
+++ b/Tool/webbottle/webapp.py
@@ -18,11 +18,13 @@
 import jpush
 import requests
 import urllib
+from lib import ConfigIniReader
+import json
 
-app_key = u'22186239fee975f883198cf4'
-master_secret = u'cb2b72ba143a3f3fb13a6f45'
+#app_key = u'22186239fee975f883198cf4'
+#master_secret = u'cb2b72ba143a3f3fb13a6f45'
 
-_jpush = jpush.JPush(app_key, master_secret)
+#_jpush = jpush.JPush(app_key, master_secret)
 #_jpush.set_logging("DEBUG")
 
 requests.packages.urllib3.disable_warnings()
@@ -37,55 +39,63 @@
 myapp = Bottle()
 
 Def_Split_Mark = "|"
-Def_NoName = "浜�"
-NotifyFormat = "銆�%s銆�%s" # 閫氱煡鏍煎紡  銆愮帺瀹跺悕銆戜俊鎭�
+
+# 鏂囨湰鏍煎紡GBK鍙栧嚭鍑烘潵杞瑄nicode锛屾湇鍔″櫒鍙戣繃鏉ヤ篃鏄痷nicode 鎺ㄩ�佺粺涓�unicode
+Def_NoName = ConfigIniReader.GetConfig().GetValue('Def_NoName').decode("gbk")
+NotifyFormat = ConfigIniReader.GetConfig().GetValue('NotifyFormat').decode("gbk")
 
 
 # 鎺ㄩ�佹秷鎭�
-# ?RegID=111141|1414|2141&PlayerName=鐔熺粌搴︾┖闂磡鍦h癁蹇箰|sjlkd&OSName=ios&NotifyMsg=BOSS澶嶆椿
-
+# 娣锋湇浣跨敤瀵瑰簲涓嶅悓key {骞冲彴ID锛歔[鐜╁涓帹ID锛� 鐜╁鍚峕,[鐜╁涓帹ID2锛� 鐜╁鍚�2]銆傘�傘�俔}
+# {u'822055139': [[u'160a3797c8504368d60', u'\u76f8\u601d\u59ff\u6653']]}-1234567
 
 @myapp.route('/getui/index.php', method='POST')
 def JGGeTui():
     getDict = request.POST
-    notifyMsg = urllib.unquote(getDict.get("NotifyMsg",""))
-    logging.info("%s-%s-%s"%(getDict.get("RegID",""), getDict.get("PlayerName",""), notifyMsg))
-    if not getDict.get("RegID",""):
+    notifyMsg = urllib.unquote(getDict.get("NotifyMsg","")).decode("utf8")
+    playerDict = json.loads(urllib.unquote_plus(getDict.get("PlayerInfo", "")))
+    
+    logging.info("%s-%s"%(playerDict, notifyMsg))
+    if not playerDict:
         # 鍙兘鍗昞澶氭帹锛屼笉鑳藉叏閮ㄦ帹
         return
     
-    regIDs = getDict.get("RegID","").split(Def_Split_Mark)
-    playrNames = getDict.get("PlayerName","")
-    osName = getDict.get("OSName","")
-    if not osName or osName == jpush.all_:
-        osName = jpush.all_
-    else:
-        osName = getDict.get("OSName","").split(Def_Split_Mark)
+    osName = jpush.all_
         
-    
     #logging.info("%s-%s-%s"%(getDict.get("RegID",""), playrNames, notifyMsg))
     #return "璐﹀彿锛�" + getDict.get("AccountID",""), "鍏呭��", getDict.get("money","") 
     
-    if not playrNames:
-        PushOne(regIDs, notifyMsg, osName)
-    else:
-        # 涓嶆敮鎸乶otifymsg鍐呭涓嶄竴鏍风殑澶氭帹锛屽彧鑳戒竴涓�瀵瑰簲鎺ㄩ��
-        playrNames = playrNames.split(Def_Split_Mark)
-        index = 0
-        for regID in regIDs:
-            playerName = playrNames[index] if index < len(playrNames) else Def_NoName
-            playerName = urllib.unquote(playerName)
-            geTuiMsg = NotifyFormat%(playerName, notifyMsg)
-            #logging.info("PushOne%s-%s-%s"%([regID], geTuiMsg, osName))
-            PushOne([regID], geTuiMsg, osName)
-            index += 1
+    # 绾﹀畾 {appID:[鎺ㄩ�両D1锛� 鎺ㄩ�両D2...]} 涓虹兢鎺�
+    # 绾﹀畾 {appID:[[鎺ㄩ�両D1, 鐜╁鍚嶇О1]锛� [鎺ㄩ�両D2, 鐜╁鍚嶇О2]...]} 涓轰竴涓�涓帹
+    for appID in playerDict:
+        # 鎵惧埌瀵瑰簲KEY
+        try:
+            app_key = ConfigIniReader.GetConfig().GetValue('app_key_%s'%appID)
+            master_secret = ConfigIniReader.GetConfig().GetValue('master_secret_%s'%appID)
+        except:
+            logging.warn("no key = %s"%appID)
+            continue
+        jpushObj = jpush.JPush(app_key, master_secret)
         
-def PushOne(regIDList, notifyMsg, osName=jpush.all_):
+        if type(playerDict[appID][0]) != list:  # 鍒楄〃涓殑鍏冪礌涓嶆槸鍒楄〃璇存槑鏄兢鎺�
+            PushOne(jpushObj, playerDict[appID], notifyMsg, osName)
+        else:
+            # 涓嶆敮鎸乶otifymsg鍐呭涓嶄竴鏍风殑澶氭帹锛屽彧鑳戒竴涓�瀵瑰簲鎺ㄩ��
+            for regID, playerName in playerDict[appID]:
+                playerName = playerName if playerName else Def_NoName
+                #playerName = urllib.unquote(playerName)
+                #playerName = playerName.encode('utf-8')
+                geTuiMsg = NotifyFormat%(playerName, notifyMsg)
+                #logging.info("PushOne%s-%s-%s"%([regID], geTuiMsg, osName))
+                PushOne(jpushObj, [regID], geTuiMsg, osName)
+
+        
+def PushOne(jpushObj, regIDList, notifyMsg, osName=jpush.all_):
     # 1.鎺ㄩ�佸璞� 鍗曟帹锛堝鎺級锛�  缇ゆ帹鍙兘鎻愪氦涓績鎺�
     # 2.骞冲彴 ios  瀹夊崜  榛樿鍏ㄥ钩鍙�
     # 3.閫氱煡娑堟伅
     
-    push = _jpush.create_push()
+    push = jpushObj.create_push()
     push.audience =  {"registration_id" : regIDList}
     push.notification = jpush.notification(alert=notifyMsg)
     push.platform = osName

--
Gitblit v1.8.0