From 4e3d1ff7e0b98fc18b0b6e63e449f3d7577c0ba6 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期三, 05 十一月 2025 11:16:31 +0800
Subject: [PATCH] 16 卡牌服务端(功能开启增加开服天条件支持;)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py | 571 +++++++++++++++++++++++++++-----------------------------
1 files changed, 278 insertions(+), 293 deletions(-)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py
index 93d59c1..4584fca 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py
@@ -4,366 +4,351 @@
#
##@package Player.PlayerArena
#
-# @todo:竞技场 - 本服
+# @todo:演武场
# @author hxp
-# @date 2020-12-07
+# @date 2025-09-12
# @version 1.0
#
-# 详细描述: 竞技场 - 本服
+# 详细描述: 演武场
#
#-------------------------------------------------------------------------------
-#"""Version = 2020-12-07 19:30"""
+#"""Version = 2025-09-12 10:30"""
#-------------------------------------------------------------------------------
+import DBDataMgr
+import PlayerMail
import ShareDefine
import GameFuncComm
import PlayerControl
import IpyGameDataPY
import ChPyNetSendPack
+import PlayerViewCache
import NetPackCommon
+import PyGameData
import GameWorld
import ChConfig
-import FBCommon
-import IPY_GameWorld
-import ItemControler
-import PlayerActTask
-import PlayerWeekParty
-import PlayerFeastTravel
-import PlayerActivity
-import PlayerSuccess
-import PlayerGubao
+import ObjPool
+import random
-def DoArenaOpen(curPlayer):
- ## 竞技场功能开启
- __DoArenaSeasonReset(curPlayer)
+# 记录攻击类型
+RecAtkType_Atk = 1 # 发起攻击
+RecAtkType_Def = 2 # 被攻击的
+
+def GetRecUpdScore(recData): return recData.GetValue1() # 更新积分
+def SetRecUpdScore(recData, score): return recData.SetValue1(score)
+def GetRecAtkType(recData): return recData.GetValue2() # 攻击类型 1-发起攻击的,2-被攻击的
+def SetRecAtkType(recData, atkType): return recData.SetValue2(atkType)
+def GetRecTagPlayerID(recData): return recData.GetValue3() # 相对攻击类型的目标玩家ID
+def SetRecTagPlayerID(recData, tagPlayerID): return recData.SetValue3(tagPlayerID)
+def GetRecIsWin(recData): return recData.GetValue4() # 是否获胜 1-获胜;2-失败
+def SetRecIsWin(recData, isWin): return recData.SetValue4(1 if isWin else 0)
+def GetRecFace(recData): return recData.GetValue5() # 目标头像
+def SetRecFace(recData, face): return recData.SetValue5(face)
+def GetRecFacePic(recData): return recData.GetValue6()
+def SetRecFacePic(recData, facePic): return recData.SetValue6(facePic)
+def GetRecRealmLV(recData): return recData.GetValue7()
+def SetRecRealmLV(recData, realmLV): return recData.SetValue7(realmLV)
+def GetRecLV(recData): return recData.GetValue8()
+def SetRecLV(recData, tagLV): return recData.SetValue8(tagLV)
+#SetUserData 名字、变更积分 +-、战力
+
+def OnWeek():
+ DoArenaReset()
+ return
+
+def OnDay():
+ __DoGiveBillboardAward("Day")
+ return
+
+def DoArenaReset():
+ ''' 赛季重置
+ '''
+ GameWorld.Log("=============== 重置竞技场 ===============")
+
+ PyGameData.g_arenaPlayerMatchDict = {}
+
+ # 结算上赛季排行奖励
+ __DoGiveBillboardAward("Week")
+
+ # 重置排行榜
+ DBDataMgr.GetBillboardMgr().RemoveBillboard(ShareDefine.Def_BT_Arena)
+ # 重置记录
+ #DBDataMgr.GetGameRecMgr().DelDataByType(ShareDefine.Def_GameRecType_ArenaRecord) # 挑战记录不重置
+
+ GameWorld.Log("==========================================")
+ return True
+
+def __DoGiveBillboardAward(awardType):
+ ## 竞技场结算排行奖励, 每日、赛季通用
+
+ GameWorld.Log("=== 竞技场结算排行奖励! === %s" % awardType)
+
+ billboardMgr = DBDataMgr.GetBillboardMgr()
+ billBoard = billboardMgr.GetBillboard(ShareDefine.Def_BT_Arena)
+ if not billBoard:
+ return
+
+ if awardType == "Day":
+ billboradAwardDict = IpyGameDataPY.GetFuncEvalCfg("ArenaBillboradAward", 1, {})
+ elif awardType == "Week":
+ billboradAwardDict = IpyGameDataPY.GetFuncEvalCfg("ArenaBillboradAward", 2, {})
+ else:
+ return
+
+ billBoard.SortDelayDo()
+ orderList = [int(orderStr) for orderStr in billboradAwardDict.keys()]
+ orderList.sort()
+ GameWorld.Log(" 奖励名次列表: %s" % orderList)
+
+ awardOrder = orderList[0]
+ orderPlayerIDDict = {}
+ billboardCount, billboardMaxCount = billBoard.GetCount(), billBoard.GetMaxCount()
+ GameWorld.Log(" 榜单数据数! billboardCount=%s,billboardMaxCount=%s" % (billboardCount, billboardMaxCount))
+ for index in xrange(billboardCount):
+ billBoardData = billBoard.At(index)
+ if not billBoardData:
+ continue
+ order = index + 1
+
+ if order > awardOrder:
+ nextOrderIndex = orderList.index(awardOrder) + 1
+ if nextOrderIndex >= len(orderList):
+ break
+ awardOrder = orderList[nextOrderIndex]
+
+ playerID = billBoardData.GetID()
+ if playerID < ShareDefine.RealPlayerIDStart:
+ # 非真人不处理
+ continue
+
+ orderPlayerIDDict[playerID] = [order, awardOrder]
+
+ paramList = [order]
+ awardList = billboradAwardDict[str(awardOrder)]
+ PlayerMail.SendMailByKey("ArenaBillboardAward%s" % awardType, playerID, awardList, paramList)
+
+ GameWorld.Log(" 奖励玩家名次信息: %s" % orderPlayerIDDict)
return
def OnLogin(curPlayer):
if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Arena):
return
- OSSeasonState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaOSSeasonState)
- if not OSSeasonState:
- __DoArenaSeasonReset(curPlayer)
- else:
- Sync_ArenaInfo(curPlayer)
+ __loginUpdPlayerScore(curPlayer)
+ Sync_ArenaInfo(curPlayer)
+ return
+
+def __loginUpdPlayerScore(curPlayer):
+ playerID = curPlayer.GetPlayerID()
+ recMgr = DBDataMgr.GetGameRecMgr()
+ recIDMgr = recMgr.GetRecTypeIDMgr(ShareDefine.Def_GameRecType_ArenaRecord, playerID)
+ if not recIDMgr.GetCount():
+ return
+ finalRecData = recIDMgr.At(recIDMgr.GetCount() - 1)
+ recTime = finalRecData.GetTime()
+ if not GameWorld.CheckTimeIsSameWeek(recTime):
+ GameWorld.Log("玩家上线演武场记录积分非本周不更新! recTime=%s" % GameWorld.ChangeTimeNumToStr(recTime), playerID)
+ return
+ updScore = GetRecUpdScore(finalRecData)
+ befScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaScore, updScore)
+ GameWorld.Log("玩家上线更新演武场积分: befScore=%s,updScore=%s,recTime=%s" % (befScore, updScore, GameWorld.ChangeTimeNumToStr(recTime)), playerID)
return
def OnDayEx(curPlayer):
if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Arena):
return
-
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaItemAddCount, 0)
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaBattleCountDay, 0)
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaMatchRefreshCount, 0)
Sync_ArenaInfo(curPlayer)
-
- openServerDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay) + 1
- customMaxServerDay = IpyGameDataPY.GetFuncCfg("OperationAction", 1)
- if openServerDay <= customMaxServerDay:
- GameWorld.DebugLog("OnDayEx时竞技场开服定制赛季进行中,不处理! openServerDay=%s <= %s" % (openServerDay, customMaxServerDay))
- return
-
- OSSeasonState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaOSSeasonState)
- if OSSeasonState > 1:
- GameWorld.DebugLog("OnDayEx时竞技场开服定制赛季已结算过,不处理! OSSeasonState=%s" % (OSSeasonState))
- return
-
- __DoArenaSeasonReset(curPlayer)
return
def OnWeekEx(curPlayer):
if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Arena):
return
-
- openServerDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay) + 1
- customMaxServerDay = IpyGameDataPY.GetFuncCfg("OperationAction", 1)
- if openServerDay <= customMaxServerDay:
- GameWorld.DebugLog("OnWeekEx时在开服定制天内,不处理竞技场赛季重置! openServerDay=%s <= %s" % (openServerDay, customMaxServerDay))
- return
-
- OSSeasonState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaOSSeasonState)
- if not OSSeasonState or OSSeasonState == 1 or OSSeasonState == openServerDay:
- GameWorld.DebugLog("OnWeekEx时竞技场开服定制赛季进行中或同一天结算,不处理重置! openServerDay=%s,OSSeasonState=%s" % (openServerDay, OSSeasonState))
- return
-
+ __DoArenaSeasonReset(curPlayer)
+ return
+
+def DoArenaOpen(curPlayer):
__DoArenaSeasonReset(curPlayer)
return
def __DoArenaSeasonReset(curPlayer):
## 玩家重置竞技场
-
- OSSeasonState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaOSSeasonState)
- openServerDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay) + 1
-
- customMaxServerDay = IpyGameDataPY.GetFuncCfg("OperationAction", 1)
- if openServerDay <= customMaxServerDay and OSSeasonState != 0:
- GameWorld.DebugLog("开服定制天内不能重置!")
- return
-
- setScoreMin, setScoreMax, refScoreMax = IpyGameDataPY.GetFuncEvalCfg("ArenaSet", 2)
- setScore = setScoreMin
- if openServerDay <= customMaxServerDay and OSSeasonState == 0:
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaOSSeasonState, 1)
- GameWorld.DebugLog("竞技场开服定制赛季! setScore=%s" % setScore)
- else:
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaOSSeasonState, customMaxServerDay + 1)
-
- preSeasonscore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
- if preSeasonscore <= setScoreMin:
- setScore = setScoreMin
- elif preSeasonscore >= refScoreMax:
- setScore = setScoreMax
- else:
- # 按比例降低积分,都减去最低分的差值算比例
- calcScore = preSeasonscore - setScoreMin
- setScore = setScoreMin + int(calcScore * (setScoreMax - setScoreMin) / float(refScoreMax - setScoreMin))
-
- GameWorld.DebugLog("竞技场赛季重置! preSeasonscore=%s,setScore=%s" % (preSeasonscore, setScore))
-
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaScore, setScore)
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaItemAddCount, 0)
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaBattleCountDay, 0)
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaMatchRefreshCount, 0)
- Sync_ArenaInfo(curPlayer, True)
+ initScore = IpyGameDataPY.GetFuncCfg("ArenaSet", 1)
+ GameWorld.DebugLog("竞技场赛季重置!initScore=%s" % (initScore))
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaScore, initScore)
+ Sync_ArenaInfo(curPlayer)
return
-def CheckArenaBattleCount(curPlayer):
- ## 验证是否还有对战次数
- todayBattleCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaBattleCountDay)
- itemAddCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaItemAddCount)
- dayFreeCount = IpyGameDataPY.GetFuncCfg("ArenaSet", 3)
- return todayBattleCount < (dayFreeCount + itemAddCount)
+def GetArenaTicketStoreMax(curPlayer):
+ ## 获取挑战券存储上限
+ baseCnt = IpyGameDataPY.GetFuncCfg("ArenaSet", 3)
+
+ # 其他特权提升上限
+
+ storeMax = baseCnt
+ return storeMax
-#// B2 09 竞技场匹配玩家 #tagCMArenaMatch
+#// B2 09 演武场匹配玩家 #tagCSArenaMatch
#
-#struct tagCMArenaMatch
+#struct tagCSArenaMatch
#{
# tagHead Head;
-# BYTE IsRefresh; // 0-打开界面无匹配数据时时查询,1-强制刷新匹配列表
+# BYTE IsRefresh; // 0-打开界面无匹配数据时查询,1-强制刷新匹配列表
#};
def OnArenaMatch(index, clientData, tick):
curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
isRefresh = clientData.IsRefresh
-
- playerID = curPlayer.GetPlayerID()
- refreshCountLimit = IpyGameDataPY.GetFuncCfg("ArenaSet", 5)
- if isRefresh and refreshCountLimit:
- refreshCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaMatchRefreshCount)
- if refreshCount >= refreshCountLimit:
- GameWorld.DebugLog("竞技场刷新匹配玩家次数已满!refreshCount=%s >= %s" % (refreshCount, refreshCountLimit), playerID)
- return
-
- if not GameWorld.SetPlayerTickTime(curPlayer, ChConfig.TYPE_Player_Tick_Arena, tick):
- GameWorld.DebugLog("竞技场匹配操作CD中...", playerID)
- PlayerControl.NotifyCode(curPlayer, "RequestLater")
- return
-
- playerLV = curPlayer.GetLV()
- playerScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
- msgInfo = str(["MatchRefresh", {"isRefresh":isRefresh, "playerLV":playerLV, "playerScore":playerScore}])
- GameWorld.DebugLog("竞技场发送GameServer匹配: %s" % msgInfo, playerID)
- GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(curPlayer.GetID(), 0, 0, "Arena", msgInfo, len(msgInfo))
+ DoArenaMatchRefresh(curPlayer, isRefresh)
return
def GMArenaMatch(curPlayer, gmMatchIDList):
- playerID = curPlayer.GetPlayerID()
- playerLV = curPlayer.GetLV()
- playerScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
- msgInfo = str(["MatchRefresh", {"isRefresh":1, "playerLV":playerLV, "playerScore":playerScore, "gmMatchIDList":gmMatchIDList}])
- GameWorld.DebugLog("竞技场发送GameServer匹配: %s" % msgInfo, playerID)
- GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(curPlayer.GetID(), 0, 0, "Arena", msgInfo, len(msgInfo))
+ ## GM直接匹配
+ isRefresh = True
+ DoArenaMatchRefresh(curPlayer, isRefresh, gmMatchIDList)
return
-#// B2 10 竞技场挑战玩家 #tagCMArenaBattle
-#
-#struct tagCMArenaBattle
-#{
-# tagHead Head;
-# DWORD TagPlayerID; // 目标玩家ID或机器人ID
-# BYTE Result; // 0-进入自定义场景发送通知后端;1-胜利(后端处理,暂时不需要发送此状态);2-失败(前端被对手击杀需要发送此状态)
-#};
-def OnArenaBattle(index, clientData, tick):
- curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+def DoArenaMatchRefresh(curPlayer, isRefresh, gmMatchIDList=None, isSys=False):
+ ## 玩家刷新匹配对手
+
playerID = curPlayer.GetPlayerID()
- tagPlayerID = clientData.TagPlayerID
- result = clientData.Result
+ playerScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
+ matchScoreList = IpyGameDataPY.GetFuncEvalCfg("ArenaMatch", 1)
- GameWorld.DebugLog("竞技场挑战玩家! tagPlayerID=%s,result=%s" % (tagPlayerID, result), playerID)
- if not tagPlayerID:
+ GameWorld.DebugLog("竞技场玩家刷新匹配列表: isRefresh=%s,playerScore=%s,gmMatchIDList=%s,isSys=%s" % (isRefresh, playerScore, gmMatchIDList, isSys), playerID)
+ GameWorld.DebugLog(" matchScoreList=%s" % (matchScoreList), playerID)
+
+ # 匹配对象缓存
+ needMatchCount = len(matchScoreList)
+ if playerID not in PyGameData.g_arenaPlayerMatchDict:
+ PyGameData.g_arenaPlayerMatchDict[playerID] = []
+ matchIDList = PyGameData.g_arenaPlayerMatchDict[playerID]
+ if len(matchIDList) > needMatchCount:
+ matchIDList = matchIDList[:needMatchCount] # 删除多余的个数,一般都是相同的,除非修改匹配数重读配置
+ if not isRefresh and len(matchIDList) == needMatchCount:
+ # 非刷新的并且已经有记录的直接同步
+ GameWorld.DebugLog(" 非刷新且有数据,直接同步!", playerID)
+ __SyncMatchList(curPlayer, matchIDList)
return
-
- if not result:
- GameWorld.DebugLog("更新竞技场对战对手ID! tagPlayerID=%s" % tagPlayerID, playerID)
- # 记录对手ID
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaBattleTagID, tagPlayerID)
- return
-
- if tagPlayerID >= 10000:
- if result:
- GameWorld.DebugLog("真人由后端镜像PK决定胜负! tagPlayerID=%s" % tagPlayerID, playerID)
+ if isRefresh and not gmMatchIDList and not isSys:
+ costMoney, moneyValue = IpyGameDataPY.GetFuncEvalCfg("ArenaMatch", 4)
+ if not costMoney or not moneyValue or not PlayerControl.PayMoney(curPlayer, costMoney, moneyValue, "Arena"):
return
- isWin = 1 if result == 1 else 0
-# # 木桩被击杀,后端判断,其他前端同步
-# if isWin:
-# GameWorld.ErrLog("前端不能同步竞技场胜利状态!", playerID)
-# return
-
- recTagPlayerID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaBattleTagID)
- if tagPlayerID != recTagPlayerID:
- GameWorld.ErrLog("竞技场结算时对手ID不一致! tagPlayerID(%s) != recTagPlayerID(%s)" % (tagPlayerID, recTagPlayerID), playerID)
- __DoArenaBattleOver(curPlayer)
+ billboardMgr = DBDataMgr.GetBillboardMgr()
+ billBoard = billboardMgr.GetBillboard(ShareDefine.Def_BT_Arena)
+ if not billBoard:
return
+ maxOrder = billBoard.GetCount()
+ playerOrder = billBoard.IndexOfByID(playerID) + 1 # 玩家在排行榜中的名次,没有名次为-1
- # 失败结算入口: 前端同步
- SendGameServer_ArenaBattleOver(curPlayer, isWin)
- return
-
-def OnKillBattleNPC(curPlayer, curNPC):
-# ## 击杀对手,前端本,使用木桩NPC作为对手
-#
-# if curNPC.GetGameObjType() != IPY_GameWorld.gotNPC or curNPC.GetType() not in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:
-# GameWorld.DebugLog("击杀非木桩NPC,不结算!")
-# return
-#
-# # 胜利结算入口:后端验证击杀对手
-# tagPlayerID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaBattleTagID)
-# GameWorld.DebugLog("竞技场击杀对手! tagPlayerID=%s" % tagPlayerID, curPlayer.GetPlayerID())
-# isWin = 1
-# SendGameServer_ArenaBattleOver(curPlayer, isWin)
- return
-
-def SendGameServer_ArenaBattleOver(curPlayer, isWin):
- ## 发送GameServer通知战斗结算
+ matchRobotCntDict = IpyGameDataPY.GetFuncEvalCfg("ArenaMatch", 3)
+ if playerOrder > 0:
+ matchRobotRange = GameWorld.GetOrderValueByDict(matchRobotCntDict, playerOrder)
+ matchRobotCnt = random.randint(matchRobotRange[0], matchRobotRange[1])
+ else:
+ matchRobotCnt = needMatchCount
+ matchPlayerCnt = needMatchCount - matchRobotCnt
+ GameWorld.DebugLog(" maxOrder=%s,playerOrder=%s,matchRobotCnt=%s,matchPlayerCnt=%s" % (maxOrder, playerOrder, matchRobotCnt, matchPlayerCnt), playerID)
- playerID = curPlayer.GetPlayerID()
- tagPlayerID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaBattleTagID)
- if not tagPlayerID:
- GameWorld.ErrLog("竞技场结算时没有对手ID!", playerID)
- __DoArenaBattleOver(curPlayer)
- return
-
- if not CheckArenaBattleCount(curPlayer):
- GameWorld.ErrLog("竞技场已经没有对战次数!", playerID)
- __DoArenaBattleOver(curPlayer)
- return
-
- tick = GameWorld.GetGameWorld().GetTick()
- if not GameWorld.SetPlayerTickTime(curPlayer, ChConfig.TYPE_Player_Tick_Arena, tick):
- GameWorld.ErrLog("结算竞技场CD中!tagPlayerID=%s" % tagPlayerID, playerID)
- return
-
- playerLV = curPlayer.GetLV()
- playerScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
- msgInfo = str(["BattleResult", {"tagPlayerID":tagPlayerID, "isWin":isWin, "playerLV":playerLV, "playerScore":playerScore,
- "realmLV":curPlayer.GetOfficialRank(), "fightPower":PlayerControl.GetFightPower(curPlayer)}])
- GameWorld.DebugLog("竞技场发送GameServer结算: %s" % msgInfo, playerID)
- GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(curPlayer.GetID(), 0, 0, "Arena", msgInfo, len(msgInfo))
- return
-
-def __DoArenaBattleOver(curPlayer, retDict={}):
- ## 主动战斗结算奖励
- # @param isOK: True时才结算奖励,防止某些异常情况无法结算通知前端FBOver,导致卡副本
-
- GameWorld.DebugLog("结算竞技场对战奖励! retDict=%s" % retDict)
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaBattleTagID, 0)
-
- isOK = retDict.get("isOK", False)
- isWin = retDict.get("isWin", 0)
- if not isOK:
- # 一直异常的情况直接同步结束包,防止不结算卡副本
- FBCommon.NotifyFBOver(curPlayer, ChConfig.Def_FBMapID_ArenaBattle, 0, isWin)
- return
-
- #GameServer MapServer 同步有一定时间差,本功能存在被动挑战引发积分变动的情况,
- #curScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
- addScore = retDict["addScore"]
- updScore = retDict["updScore"]
- curOrder = retDict["curOrder"]
- updOrder = retDict["updOrder"]
- offlineRecTime = retDict.get("offlineRecTime", 0)
-
- # 扣次数
- if not offlineRecTime or GameWorld.CheckTimeIsSameServerDayEx(offlineRecTime):
- todayBattleCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaBattleCountDay) + 1
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaBattleCountDay, todayBattleCount)
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaMatchRefreshCount, 0)
+ fromLowerCnt, matchPerRank = IpyGameDataPY.GetFuncEvalCfg("ArenaMatch", 2)
+ toOrder = playerOrder + fromLowerCnt * matchPerRank # 从低名次往高名次匹配
+ GameWorld.DebugLog(" fromLowerCnt=%s,matchPerRank=%s,toOrder=%s" % (fromLowerCnt, matchPerRank, toOrder), playerID)
+ matchOrderList = [] # 匹配到的名次
+ for _ in range(matchPlayerCnt):
+ fromOrder = max(1, toOrder - matchPerRank)
+ if toOrder <= fromOrder:
+ break
+ orderList = range(fromOrder, toOrder)
+ random.shuffle(orderList)
+ if playerOrder in orderList:
+ orderList.remove(playerOrder) # 不包含自己
+ if not orderList:
+ break
- # 更新积分
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaScore, updScore)
- highestScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaHighestScore)
- if updScore > highestScore:
- highestScore = updScore
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaHighestScore, highestScore)
- GameWorld.DebugLog(" 更新竞技场历史最高分! %s" % highestScore)
+ if fromOrder == 1:
+ for order in orderList:
+ if order > maxOrder:
+ continue
+ matchOrderList.append(order)
+ if len(matchOrderList) >= matchPlayerCnt:
+ break
+ else:
+ order = orderList[0]
+ if order <= maxOrder:
+ matchOrderList.append(order)
+
+ GameWorld.DebugLog(" 匹配玩家: fromOrder=%s,toOrder=%s,matchOrderList=%s" % (fromOrder, toOrder, matchOrderList), playerID)
+ toOrder = fromOrder - 1
- # 胜利给额外奖励
- itemList = retDict.get("awardItemList", [])
- ItemControler.GivePlayerItemOrMail(curPlayer, itemList)
- jsonItemList = FBCommon.GetJsonItemList(itemList)
-
- overDict = {FBCommon.Over_itemInfo:jsonItemList, "addScore":addScore, "updScore":updScore, "curOrder":curOrder, "updOrder":updOrder}
- FBCommon.NotifyFBOver(curPlayer, ChConfig.Def_FBMapID_ArenaBattle, 0, isWin, overDict)
- Sync_ArenaInfo(curPlayer)
-
- PlayerWeekParty.AddWeekPartyActionCnt(curPlayer, ChConfig.Def_WPAct_Arena, 1)
- PlayerFeastTravel.AddFeastTravelTaskValue(curPlayer, ChConfig.Def_FeastTravel_Arena, 1)
- PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_Arena, 1)
- PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Arena, 1)
- PlayerGubao.AddGubaoItemEffValue(curPlayer, PlayerGubao.GubaoEffType_Arena, 1)
- PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_Arena)
- return
-
-def __DoUpdateArenaScore(curPlayer, cmdDict={}):
- ''' 玩家直接更新积分,有以下几种情况,都是被挑战的,只更新积分
- 1. 被动挑战在线时直接更新积分
- 2. 离线/脱机时被挑战,上线后同步最新积分
- '''
-
- playerScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
- updScore = cmdDict.get("updScore", playerScore)
- if updScore == playerScore:
- return
-
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaScore, updScore)
- Sync_ArenaInfo(curPlayer)
- return
-
-def GameServer_ArenaResult(curPlayer, msgList, tick):
- if not msgList:
- return
-
- cmd = msgList[0]
- cmdDict = msgList[1] if len(msgList) > 1 else {}
- retDict = msgList[2] if len(msgList) > 2 else {}
-
- # 刷新匹配
- if cmd == "MatchRefresh":
- isRefresh = cmdDict.get("isRefresh", False)
- refreshCountLimit = IpyGameDataPY.GetFuncCfg("ArenaSet", 5)
- if isRefresh and refreshCountLimit:
- updRefreshCount = min(250, curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaMatchRefreshCount) + 1)
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaMatchRefreshCount, updRefreshCount)
- GameWorld.DebugLog("更新竞技场刷新匹配次数! updRefreshCount=%s" % updRefreshCount)
- Sync_ArenaInfo(curPlayer)
+ # GM指定匹配测试
+ if gmMatchIDList != None and curPlayer.GetGMLevel():
+ for gmMatchID in gmMatchIDList:
+ if gmMatchID == playerID:
+ GameWorld.DebugAnswer(curPlayer, "目标ID不能是自己!无法匹配!%s" % gmMatchID)
+ continue
- # 主动对战结果
- elif cmd == "BattleResult":
- __DoArenaBattleOver(curPlayer, retDict)
+ gmMatchOrder = billBoard.IndexOfByID(gmMatchID) + 1
+ if gmMatchOrder <= 0:
+ GameWorld.DebugAnswer(curPlayer, "目标ID不在榜单上!无法匹配!%s" % gmMatchID)
+ continue
+ GameWorld.DebugAnswer(curPlayer, "指定匹配ID(%s),order(%s)" % (gmMatchID, gmMatchOrder))
+ if gmMatchID not in matchOrderList:
+ matchOrderList.insert(0, gmMatchOrder)
+ matchOrderList = matchOrderList[:needMatchCount]
- # 被动挑战更新积分
- elif cmd == "UpdScore":
- __DoUpdateArenaScore(curPlayer, cmdDict)
+ matchOrderList.sort()
+ matchIDList = [] # 最终匹配的玩家ID列表
+ for matchOrder in matchOrderList:
+ if matchOrder > maxOrder or matchOrder <= 0:
+ break
+ billData = billBoard.At(matchOrder - 1)
+ matchIDList.append(billData.GetID())
+ needRobotCnt = needMatchCount - len(matchIDList)
+ GameWorld.DebugLog(" 匹配榜单结果: matchIDList=%s,matchOrderList=%s,needRobotCnt=%s" % (matchIDList, matchOrderList, needRobotCnt), playerID)
+ ipyDataMgr = IpyGameDataPY.IPY_Data()
+ robotMax = ipyDataMgr.GetRobotCount()
+ doCnt = 100
+ while doCnt > 0 and needRobotCnt > 0 and robotMax:
+ doCnt -= 1
+ robotIndex = random.randint(0, robotMax - 1)
+ robotIpyData = ipyDataMgr.GetRobotByIndex(robotIndex)
+ robotID = robotIpyData.GetID()
+ if robotID not in matchIDList:
+ matchIDList.append(robotID)
+ needRobotCnt -= 1
+ GameWorld.DebugLog(" 最终匹配结果: matchIDList=%s" % matchIDList, playerID)
+
+ PyGameData.g_arenaPlayerMatchDict[playerID] = matchIDList
+ __SyncMatchList(curPlayer, matchIDList)
return
-def Sync_ArenaInfo(curPlayer, isReset=False):
- clientPack = ChPyNetSendPack.tagMCArenaPlayerInfo()
- clientPack.IsReset = 1 if isReset else 0
- clientPack.Score = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
- clientPack.BattleCountToday = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaBattleCountDay)
- clientPack.MatchRefreshCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaMatchRefreshCount)
- clientPack.ItemAddBattleCountToday = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaItemAddCount)
+def __SyncMatchList(curPlayer, matchIDList):
+ ## 同步匹配列表
+ objPool = ObjPool.GetPoolMgr()
+ clientPack = objPool.acquire(ChPyNetSendPack.tagSCArenaMatchList)
+ clientPack.MatchList = []
+ for matchID in matchIDList:
+ viewCache = PlayerViewCache.FindViewCache(matchID)
+ matchInfo = objPool.acquire(ChPyNetSendPack.tagSCArenaMatchInfo)
+ matchInfo.PlayerID = matchID
+ if viewCache:
+ matchInfo.PlayerName = viewCache.GetPlayerName()
+ matchInfo.RealmLV = viewCache.GetRealmLV()
+ matchInfo.LV = viewCache.GetLV()
+ matchInfo.Face = viewCache.GetFace()
+ matchInfo.FacePic = viewCache.GetFacePic()
+ matchInfo.FightPower = viewCache.GetFightPower()
+ matchInfo.FightPowerEx = viewCache.GetFightPowerEx()
+ matchInfo.TitleID = viewCache.GetTitleID()
+ else:
+ matchInfo.PlayerName = "p%s" % matchID
+ clientPack.MatchList.append(matchInfo)
+ clientPack.MatchCount = len(clientPack.MatchList)
NetPackCommon.SendFakePack(curPlayer, clientPack)
return
+def Sync_ArenaInfo(curPlayer):
+ clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCArenaPlayerInfo)
+ clientPack.Score = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
+ NetPackCommon.SendFakePack(curPlayer, clientPack)
+ return
--
Gitblit v1.8.0