From 9d5ec7599f3abe0cebb76ce1df3c3b8c4e0aa51e Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 10 二月 2026 11:40:15 +0800
Subject: [PATCH] 66 【公会】基础主体-服务端(跨服聊天;)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py | 3262 ++++++++++++++++++++++++++++++++++------------------------
1 files changed, 1,906 insertions(+), 1,356 deletions(-)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py
index 93c6f86..9e5032a 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py
@@ -28,11 +28,15 @@
import IPY_PlayerDefine
import IpyGameDataPY
import IPY_GameWorld
-import ItemControler
-import GameFuncComm
-import DBDataMgr
+import PlayerMail
+import PlayerTask
+import CrossPlayer
+import PlayerTalk
import DirtyList
-import ObjPool
+import DBDataMgr
+import DBFamily
+import CrossMsg
+import CrossMgr
import random
import time
@@ -41,24 +45,7 @@
Def_CreatFamily_MaxStr = 33
-#仙盟变更类型
-FamilyChangeTypes = (
-FamilyChangeType_None,
-FamilyChangeType_MemJoin, # 成员加入 1
-FamilyChangeType_MemLeave, # 成员退出 2
-FamilyChangeType_JoinSet, # 收人设置修改 3
-FamilyChangeType_Broadcast, # 公告修改 4
-FamilyChangeType_EChange, # 徽章修改 5
-FamilyChangeType_LeaderChange, # 盟主变更 6
-FamilyChangeType_MemFmlvChange, # 成员职位变更 7
-FamilyChangeType_MemLogin, # 成员上线 8
-FamilyChangeType_MemLogout, # 成员离线9
-FamilyChangeType_FamilyLVExp, # 仙盟等级经验变更 10
-FamilyChangeType_MemContrib, # 成员贡献变更 11
-FamilyChangeType_OnDay, # 过天 12
-) = range(13)
-
-#仙盟权限
+#公会权限
(
FamilyPowerID_Call, #招人 1
FamilyPowerID_ChangeFmlv, #变更职位 2
@@ -66,56 +53,135 @@
FamilyPowerID_Kick, #踢人 4
) = range(1, 1 + 4)
-#仙盟职位对应人数设置属性名
+#公会职位对应人数设置属性名
Def_FmlSetAttrName = {
IPY_PlayerDefine.fmlMember:"MemberMax",
IPY_PlayerDefine.fmlCounsellor:"EliteMax",
IPY_PlayerDefine.fmlViceLeader:"DeputyLeaderMax",
}
-def FamilyOnDay():
+def GetRenameTime(family): return family.GetExtra1()
+def SetRenameTime(family, renameTime): return family.SetExtra1(renameTime)
+
+def OnMinute():
+ #战力刷新在DBFamily.OnMinute
if GameWorld.IsCrossServer():
+ pass
+ elif not GameWorld.IsMainServer() or DBFamily.IsFamilyCross():
+ return
+ PlayerFamilyEmblem.CheckExpireEmblem()
+ return
+
+def FamilyCrossCenterOnHour():
+ if GameWorld.IsCrossServer():
+ __doFamilyOnHour()
+ return
+
+def FamilyOnHour():
+ if not GameWorld.IsMainServer() or DBFamily.IsFamilyCross():
+ GameWorld.DebugLog("非游戏服或本服已跨服互通了不处理 FamilyOnHour")
+ return
+ __doFamilyOnHour()
+ return
+
+def __doFamilyOnHour():
+ familyManager = DBDataMgr.GetFamilyMgr()
+ for zoneID in familyManager.GetZoneIDListThisServer():
+ zoneMgr = familyManager.GetZoneFamilyMgr(zoneID)
+ for i in range(0, zoneMgr.GetCount()):
+ family = zoneMgr.GetAt(i)
+ #自动传位
+ __AutoChangeLeader(family)
+ return
+
+def FamilyCrossCenterOnDay():
+ if GameWorld.IsCrossServer():
+ __doFamilyOnDay()
+ return
+
+def FamilyOnDay():
+ ## 本服时间自己触发的onday逻辑
+
+ if not GameWorld.IsMainServer() or DBFamily.IsFamilyCross():
+ GameWorld.DebugLog("非游戏服或本服已跨服互通了不处理 FamilyOnDay")
return
+ __doFamilyOnDay()
+ DBFamily.CheckCrossFamilyTransData()
+ return
+
+def __doFamilyOnDay():
familyManager = DBDataMgr.GetFamilyMgr()
- for i in range(0, familyManager.GetCount()):
- family = familyManager.GetAt(i)
- familyID = family.GetID()
-
- PlayerFamilyZhenbaoge.OnDay(family)
- PlayerFamilyTaofa.OnDay(family)
-
- for index in xrange(family.GetCount()):
- member = family.GetAt(index)
- # 重置成员日信息
- member.SetContribDay(0)
- member.SetDonateCntDay(0)
+ for zoneID in familyManager.GetZoneIDListThisServer():
+ zoneMgr = familyManager.GetZoneFamilyMgr(zoneID)
+ for i in range(0, zoneMgr.GetCount()):
+ family = zoneMgr.GetAt(i)
+ familyID = family.GetID()
- Broadcast_FamilyChange(familyID, FamilyChangeType_OnDay)
-
+ PlayerFamilyZhenbaoge.OnDay(family)
+ PlayerFamilyTaofa.OnDay(family)
+
+ for index in xrange(family.GetCount()):
+ member = family.GetAt(index)
+ # 重置成员日信息
+ member.SetContribDay(0)
+ member.SetDonateCntDay(0)
+
+ Broadcast_FamilyInfo(familyID) # onday
+ return
+
+def PlayerCrossCenterOnDay(curPlayer):
+ ## 处理跨服中心同步的onday玩家事件
+ if not DBFamily.IsFamilyCross():
+ GameWorld.DebugLog("公会还属于本服,不处理成员跨服过天", curPlayer.GetPlayerID())
+ return
+ __doPlayerOnDay(curPlayer)
return
def PlayerOnDay(curPlayer):
- if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Family):
+ ## 本服时间的onday玩家事件
+ if DBFamily.IsFamilyCross():
+ GameWorld.DebugLog("公会已经跨服了,不处理成员本服过天", curPlayer.GetPlayerID())
return
- ResetDailyDonateCnt(curPlayer)
+ __doPlayerOnDay(curPlayer)
+ return
+
+def __doPlayerOnDay(curPlayer):
PlayerFamilyZhenbaoge.PlayerOnDay(curPlayer)
PlayerFamilyTaofa.PlayerOnDay(curPlayer)
+ ResetDailyDonateCnt(curPlayer)
return
def OnPlayerLogin(curPlayer, tick):
- if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Family):
+ if DBFamily.IsFamilyCross():
+ GameWorld.DebugLog("公会已跨服不处理,由所属跨服服务器处理成员登录逻辑 OnPlayerLogin", curPlayer.GetPlayerID())
return
- PlayerLoginRefreshFamily(curPlayer, tick)
- Sync_RequestAddFamilyInfo(curPlayer, False)
- SyncDonateCntInfo(curPlayer)
- PlayerFamilyZhenbaoge.OnPlayerLogin(curPlayer)
- PlayerFamilyTaofa.OnPlayerLogin(curPlayer)
+ crossPlayer = CrossPlayer.GetCrossPlayerMgr().FindCrossPlayer(curPlayer.GetPlayerID())
+ OnCrossPlayerLogin(crossPlayer)
+ return
+
+def OnCrossPlayerLogin(crossPlayer):
+ ## 玩家上线,游戏服跨服通用,流程上当做以前GameServer处理公会一样,处理后再通知地图(现在的游戏服)
+ PlayerLoginRefreshFamily(crossPlayer) # 必须先刷新
+ Sync_RequestAddFamilyInfo(crossPlayer, False)
+ PlayerTalk.NotifyTalkCache(crossPlayer, [IPY_GameWorld.tcFamily]) # 公会聊天缓存
+ if GameWorld.IsCrossServer():
+ PlayerTalk.NotifyTalkCache(crossPlayer, [IPY_GameWorld.tcCountry]) # 跨服公会聊天缓存
+ PlayerFamilyTaofa.OnCrossPlayerLogin(crossPlayer)
return
def OnPlayerLogout(curPlayer):
- playerID = curPlayer.GetPlayerID()
- familyID = curPlayer.GetFamilyID()
+ if DBFamily.IsFamilyCross():
+ GameWorld.DebugLog("公会已跨服不处理,由所属跨服服务器处理成员离线逻辑 OnPlayerLogout", curPlayer.GetPlayerID())
+ return
+ crossPlayer = CrossPlayer.GetCrossPlayerMgr().FindCrossPlayer(curPlayer.GetPlayerID())
+ OnCrossPlayerLogout(crossPlayer)
+ return
+
+def OnCrossPlayerLogout(crossPlayer):
+ ## 玩家下线,游戏服跨服通用,流程上当做以前GameServer处理公会一样,处理后再通知地图(现在的游戏服)
+ playerID = crossPlayer.GetPlayerID()
+ familyID = crossPlayer.GetFamilyID()
if not familyID:
return
familyMgr = DBDataMgr.GetFamilyMgr()
@@ -126,24 +192,68 @@
if not curMember:
return
curMember.SetOffTime(int(time.time()))
- #XW_JZ_LeaguerLeaveline <n color="0,190,255">{%S1%}</n><n color="255,255,0">下线了!</n> 25 - -
- #NotifyAllFamilyMemberMsg(familyID, "XW_JZ_LeaguerLeaveline", [curPlayer.GetPlayerName()])
- Broadcast_FamilyChange(familyID, FamilyChangeType_MemLogout, excludeIDList=[playerID])
+
+ # 通知成员下线
+ Broadcast_FamilyInfo(familyID, changeMemIDList=[playerID]) # 成员下线
return
-def OnWeekEx(curPlayer):
- #重置
+def SendToFamilyMapPlayer(crossPlayer, doType, doData):
+ playerID = crossPlayer.GetPlayerID()
+ dataMsg = {"doType":doType, "doData":doData}
+ if GameWorld.IsCrossServer():
+ CrossMsg.SendToClientServer(ShareDefine.C2S_FamilyMapPlayer, dataMsg, [crossPlayer.GetMainServerID()], playerID)
+ else:
+ C2S_FamilyMapPlayer(dataMsg, playerID)
return
-def PlayerLoginRefreshFamily(curPlayer, tick):
+def MapServer_FamilyRefresh(crossPlayer, familyID, isVoluntarily=0, isLogin=False):
+ ''' 相当于GameServer调用 curPlayer.MapServer_FamilyRefresh()
+ '''
+ playerID = crossPlayer.GetPlayerID()
+ FmLV = 0 # 职位
+ FamilyLV = 0 # 公会等级
+ JoinTime = 0
+ FamilyName = ""
+ EmblemID, EmblemWord = 0, ""
+ if familyID:
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ curFamily = familyMgr.FindFamily(familyID)
+ if curFamily:
+ FamilyLV = curFamily.GetLV()
+ FamilyName = curFamily.GetName()
+ EmblemID = curFamily.GetEmblemID()
+ EmblemWord = curFamily.GetEmblemWord()
+ member = curFamily.FindMember(playerID)
+ if member:
+ FmLV = member.GetFmLV()
+ JoinTime = member.GetJoinTime()
+ else:
+ familyID = 0
+
+ crossPlayer.SetFamilyID(familyID)
+ # 同步更新查看缓存
+ PlayerViewCache.UpdPlayerViewFamilyInfo(playerID, familyID, FamilyName, EmblemID, EmblemWord)
+
+ doData = {"FamilyID":familyID}
+ if familyID:
+ doData.update({"FmLV":FmLV, "JoinTime":JoinTime, "FamilyLV":FamilyLV, "FamilyName":FamilyName, "EmblemID":EmblemID, "EmblemWord":EmblemWord})
+ if isVoluntarily:
+ doData["isVoluntarily"] = 1
+ if isLogin:
+ doData["isLogin"] = 1
+ SendToFamilyMapPlayer(crossPlayer, "FamilyRefresh", doData)
+ return
+
+def PlayerLoginRefreshFamily(crossPlayer):
## 玩家登录时刷新家族
- playerID = curPlayer.GetPlayerID()
+ playerID = crossPlayer.GetPlayerID()
familyMgr = DBDataMgr.GetFamilyMgr()
refreshFamilyID = familyMgr.GetPlayerFamilyID(playerID)
- MapServer_FamilyRefresh(curPlayer, refreshFamilyID)
-
- familyID = curPlayer.GetFamilyID()
+ GameWorld.DebugLog("PlayerLoginRefreshFamily playerID=%s,refreshFamilyID=%s" % (playerID, refreshFamilyID))
+ crossPlayer.SetFamilyID(refreshFamilyID)
+ MapServer_FamilyRefresh(crossPlayer, refreshFamilyID, isLogin=True) # 登录
+ familyID = refreshFamilyID
if not familyID:
return
@@ -154,55 +264,170 @@
if not curMember:
return
curMember.SetOffTime(0) # 在线0,脱机1,>1离线时间
- curMember.RefreshMember(curPlayer)
- Sync_FamilyInfo(curPlayer)
- SendFamilyActionInfo(curPlayer, familyID, ShareDefine.Def_ActionType_FamilyData)
+ curMember.RefreshMemberByID(playerID)
+
+ Sync_FamilyInfo(crossPlayer) # 给自己同步完整的
+ # 广播成员在线
+ Broadcast_FamilyInfo(familyID, changeMemIDList=[playerID], excludeIDList=[playerID]) # 成员登录
#通知招人
if GetFamilyMemberHasPow(curMember, FamilyPowerID_Call):
- NetPackCommon.SendFakePack(curPlayer, GetPack_FamilyReqJoinInfo(familyID))
-
- #XW_JZ_LeaguerOnline <n color="0,190,255">{%S1%}</n><n color="255,255,0">上线了!</n> 25 - -
- #NotifyAllFamilyMemberMsg(familyID, "XW_JZ_LeaguerOnline", [curPlayer.GetName()], [playerID])
- Broadcast_FamilyChange(familyID, FamilyChangeType_MemLogin, excludeIDList=[playerID])
-
+ CrossPlayer.SendFakePack(crossPlayer, GetPack_FamilyReqJoinInfo(familyID))
+
# 盟主上线处理
- if curMember.GetFmLV() == IPY_PlayerDefine.fmlLeader:
- OnFamilyLeaderLogin(curPlayer)
+ #if curMember.GetFmLV() == IPY_PlayerDefine.fmlLeader:
+ # OnFamilyLeaderLogin(curPlayer)
return
-def OnFamilyLeaderLogin(curPlayer):
- ## 盟主登录额外处理
-
- return
-
-def OnMinute():
- #战力刷新在DBFamily.OnMinute
- PlayerFamilyEmblem.CheckExpireEmblem()
- return
-
-def RefreshFamilyMember(curPlayer):
+def RefreshFamilyMember(crossPlayer):
## 玩家成员相关属性变更时同步更新家族成员信息
- familyID = curPlayer.GetFamilyID()
+ if GameWorld.IsCrossServer():
+ pass
+ elif not GameWorld.IsMainServer() or DBFamily.IsFamilyCross():
+ return
+ familyID = crossPlayer.GetFamilyID()
if not familyID:
return
familyMgr = DBDataMgr.GetFamilyMgr()
family = familyMgr.FindFamily(familyID)
if not family:
return
- playerID = curPlayer.GetPlayerID()
+ playerID = crossPlayer.GetPlayerID()
member = family.FindMember(playerID)
if not member:
return
- member.RefreshMember(curPlayer)
+ member.RefreshMemberByID(playerID)
+ Broadcast_FamilyInfo(familyID, changeMemIDList=[playerID], excludeIDList=[playerID]) # 成员信息变更
return
-def GetRenameTime(dataAction): return dataAction.GetValue1()
-def SetRenameTime(dataAction, setTime): dataAction.SetValue1(setTime)
-def GetFamilyDataAction(familyID):
- ## 家族额外数据存储的行为数据,可以视为Family公共数据的一个扩展
- action = DBDataMgr.GetFamilyActionMgr().GetFamilyAction(familyID, ShareDefine.Def_ActionType_FamilyData)
- return action.GetOneAction(True)
+def FamilyPyPackForwarding(curPlayer, clientData, tick, funcName, needResult=False, reqCD=0.5, reqDataEx=None):
+ ## 玩家请求公会功能包转发处理
+ # @needResult: 转发跨服处理完毕是否需要回复状态,一般有消耗货币、物品相关的都要回复,且设置一个较长请求cd,防止重复处理
+ # @param reqCD: 转发跨服请求cd,秒,支持小数
+
+ playerID = curPlayer.GetPlayerID()
+
+ crossServerID = DBDataMgr.GetFamilyMgr().GetCurCrossServerID()
+ if crossServerID == -2:
+ PlayerControl.NotifyCode(curPlayer, "FamilyInTransData")
+ return
+
+ if crossServerID < 0:
+ GameWorld.ErrLog("公会功能异常! crossServerID=%s" % crossServerID)
+ return
+
+ # 本服处理
+ if crossServerID == 0 or crossServerID == GameWorld.GetGameWorld().GetServerID():
+ isOK = CallPyPackFunc(playerID, clientData, funcName, reqDataEx=reqDataEx)
+ if needResult:
+ __doFamilyPyPackRet(curPlayer, clientData, funcName, isOK)
+ return
+
+ ssServer = CrossMgr.GetSSServerMgr().GetSSServer(crossServerID)
+ if not ssServer or not ssServer.IsServerOpen():
+ PlayerControl.NotifyCode(curPlayer, "ServerNoOpen")
+ return
+
+ # 转发请求CD验证
+ if reqCD:
+ reqTick = curPlayer.GetDictByKey(funcName) # 根据函数名单独处理CD,防止相互影响
+ if reqTick and (tick - reqTick) < reqCD * 1000:
+ PlayerControl.NotifyCode(curPlayer, "RequestLater")
+ return
+ curPlayer.SetDict(funcName, tick)
+
+ # 剩下的就是大于0
+ dataMsg = {"funcName":funcName}
+ if clientData:
+ dataMsg["packBuff"] = clientData.GetBuffer()
+ if reqDataEx:
+ dataMsg["reqDataEx"] = reqDataEx
+ if needResult:
+ dataMsg["needResult"] = 1
+ CrossMsg.SendToCrossServer(ShareDefine.S2C_FamilyPyPack, dataMsg, [crossServerID], playerID)
+ return
+
+def S2C_FamilyPyPack(dataMsg, fromServerID, playerID):
+ funcName = dataMsg["funcName"]
+ packBuff = dataMsg.get("packBuff")
+ reqDataEx = dataMsg.get("reqDataEx")
+ clientData = None
+ if packBuff:
+ clientData = NetPackCommon.ReadRecPyPackData(packBuff)
+ if not clientData:
+ return
+ isOK = CallPyPackFunc(playerID, clientData, funcName, fromServerID, reqDataEx)
+ # 处理结束回复,无论成功与否
+ if "needResult" in dataMsg:
+ dataMsg.pop("needResult")
+ dataMsg["isOK"] = isOK
+ CrossMsg.SendToClientServer(ShareDefine.C2S_FamilyPyPackRet, dataMsg, [fromServerID], playerID)
+ return
+
+def C2S_FamilyPyPackRet(dataMsg, playerID):
+ curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
+ if not curPlayer:
+ return
+ funcName = dataMsg["funcName"]
+ packBuff = dataMsg.get("packBuff")
+
+ curPlayer.SetDict(funcName, 0) # 重置CD
+
+ clientData = None
+ if packBuff:
+ clientData = NetPackCommon.ReadRecPyPackData(packBuff)
+ if not clientData:
+ return
+ isOK = dataMsg.get("isOK")
+ __doFamilyPyPackRet(curPlayer, clientData, funcName, isOK)
+ return
+
+def CallPyPackFunc(playerID, clientData, funcName, fromServerID=0, reqDataEx=None):
+ crossPlayer = CrossPlayer.GetCrossPlayerMgr().FindCrossPlayer(playerID)
+ if not crossPlayer:
+ GameWorld.ErrLog("找不到该CrossPlayer! playerID=%s" % playerID, playerID)
+ return
+
+ callFunc = GetCallFunc(funcName)
+ if not callFunc:
+ GameWorld.ErrLog("公会封包功能函数名不存在! %s" % funcName)
+ return
+
+ # 执行函数
+ tick = GameWorld.GetGameWorld().GetTick()
+ isOK = callFunc(crossPlayer, clientData, tick, fromServerID, reqDataEx)
+ return isOK
+
+def __doFamilyPyPackRet(curPlayer, clientData, funcName, isOK):
+ ## 处理后额外处理,如成就、任务等
+ funcName = "%s_Ret" % funcName
+ callFunc = GetCallFunc(funcName)
+ if not callFunc:
+ # 结果额外处理函数允许不一定需要,根据功能自行决定
+ return
+ callFunc(curPlayer, clientData, isOK)
+ return
+
+def GetCallFunc(funcName):
+ callFunc = None
+ if "." in funcName:
+ # 分割字符串,最后一个部分是函数名
+ parts = funcName.split('.')
+ if len(parts) == 2:
+ moduleName, func_name = parts
+ # 导入模块
+ module = __import__(moduleName)
+ # 获取函数
+ if hasattr(module, func_name):
+ func = getattr(module, func_name)
+ if callable(func):
+ callFunc = func
+ else:
+ gDict = globals()
+ if funcName in gDict and callable(gDict[funcName]):
+ # 获取函数对象
+ callFunc = gDict[funcName]
+ return callFunc
#// A6 04 创建家族 #tagCMCreateFamily
#
@@ -210,72 +435,103 @@
#{
# tagHead Head;
# char Name[33];
-# WORD EmblemID; //选择徽章ID,解锁仙盟等级为1级的均为可选ID
+# WORD EmblemID; //选择徽章ID,解锁公会等级为1级的均为可选ID
# char EmblemWord[3]; //徽章文字
#};
-def OnCreateFamily(index, clientPack, tick):
+def OnCreateFamily(index, clientData, tick):
curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
- inputName = clientPack.Name
- emblemID = clientPack.EmblemID
- emblemWord = clientPack.EmblemWord
+ inputName = clientData.Name
- if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Family):
+ GameWorld.DebugLog("OnCreateFamily: %s" % GameWorld.CodeToGbk(inputName))
+
+ # 通用的前置验证,直接游戏服处理即可
+ if not CheckInputFamilyName(curPlayer, inputName):
return
+
+ needMoney = IpyGameDataPY.GetFuncCfg("CreateFamily", 1)
+ moneyType = IpyGameDataPY.GetFuncCfg("CreateFamily", 2)
+ if moneyType and needMoney:
+ if not PlayerControl.HaveMoney(curPlayer, moneyType, needMoney):
+ return
- playerID = curPlayer.GetPlayerID()
- playerFamilyID = curPlayer.GetFamilyID()
+ FamilyPyPackForwarding(curPlayer, clientData, tick, "__OnCreateFamily", True, 20)
+ return
+
+def __OnCreateFamily(crossPlayer, clientData, tick, fromServerID=0, reqDataEx=None):
+ inputName = clientData.Name
+ emblemID = clientData.EmblemID
+ emblemWord = clientData.EmblemWord
+
+ GameWorld.DebugLog("__OnCreateFamily: %s" % GameWorld.CodeToGbk(inputName))
+
+ fullFamilyName = inputName
+
+ playerID = crossPlayer.GetPlayerID()
+ playerFamilyID = crossPlayer.GetFamilyID()
familyMgr = DBDataMgr.GetFamilyMgr()
if playerFamilyID:
curFamily = familyMgr.FindFamily(playerFamilyID)
if curFamily:
if curFamily.FindMember(playerID):
#玩家已经有家族, 创建失败
- PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_85890")
+ CrossPlayer.NotifyCode(crossPlayer, "GeRen_chenxin_85890")
return
- fullFamilyName = CheckInputFamilyName(curPlayer, inputName)
- if not fullFamilyName:
+ # 验证重名
+ if CheckFamilyNameExists(crossPlayer, fullFamilyName, fromServerID):
return
- needMoney = IpyGameDataPY.GetFuncCfg("CreateFamily", 1)
- moneyType = IpyGameDataPY.GetFuncCfg("CreateFamily", 2)
- if moneyType and needMoney:
- if not PlayerControl.PayMoney(curPlayer, moneyType, needMoney, "CreateFamily"):
- return
-
- serverID = GameWorld.GetPlayerServerID(curPlayer)
+ serverID = crossPlayer.GetServerID()
curFamily = familyMgr.AddFamily(fullFamilyName, serverID)
if curFamily == None:
GameWorld.ErrLog("创建家族失败", playerID)
return
newFamilyID = curFamily.GetID()
+ zoneMgr = familyMgr.GetZoneFamilyMgrByFamilyID(newFamilyID)
+ zoneID = zoneMgr.GetZoneID() if zoneMgr else -1
curFamily.SetLV(1)
emblemIDList = PlayerFamilyEmblem.GetDefaultFamilyEmblemIDList()
if not emblemID or emblemID not in emblemIDList:
emblemID = random.choice(emblemIDList) # 从默认徽章中随机选择一个
- GameWorld.Log("创建仙盟: familyID=%s,playerID=%s,emblemID=%s" % (newFamilyID, playerID, emblemID))
+ GameWorld.Log("创建公会: familyID=%s,playerID=%s,emblemID=%s,serverID=%s,zoneID=%s" % (newFamilyID, playerID, emblemID, serverID, zoneID))
curFamily.SetEmblemID(emblemID)
curFamily.SetEmblemWord(emblemWord)
+ # 扣除消耗
+ needMoney = IpyGameDataPY.GetFuncCfg("CreateFamily", 1)
+ moneyType = IpyGameDataPY.GetFuncCfg("CreateFamily", 2)
+ if moneyType and needMoney:
+ CrossPlayer.CostPlayerResources(crossPlayer, "CreateFamily", costMoneyDict={moneyType:needMoney})
+
#-设置家族成员属性
- DoPlayerJionFamily(curFamily, playerID, curPlayer, IPY_PlayerDefine.fmlLeader)
- familyMgr.Sort()
-
+ DoPlayerJionFamily(curFamily, playerID, crossPlayer, IPY_PlayerDefine.fmlLeader)
+ if zoneMgr:
+ zoneMgr.Sort()
+
#XW_JZ_EstablishSud <n color="255,255,0">恭喜您,家族建立成功!</n> 25 - -
- PlayerControl.NotifyCode(curPlayer, "XW_JZ_EstablishSud")
- PlayerControl.WorldNotify(0, "jiazu_liubo_671654", [curPlayer.GetName(), fullFamilyName, newFamilyID])
+ #CrossPlayer.NotifyCode(crossPlayer, "XW_JZ_EstablishSud")
+ #PlayerControl.WorldNotify(0, "jiazu_liubo_671654", [curPlayer.GetName(), fullFamilyName, newFamilyID])
PlayerFamilyZhenbaoge.OnZhenbaogeReset(curFamily)
- return
+ return True
def CheckInputFamilyName(curPlayer, inputName):
- '''检查玩家输入的仙盟名是否合法,建盟、改名通用
- @return: None-不合法;非空-合法的仙盟全名
+ '''检查玩家输入的公会名是否合法,建盟、改名通用
+ 【注】该函数仅在游戏服验证名字的通用合法性,如长度、敏感词等,公会名重名请在公会所在数据服验证
+ @return: None-不合法;非空-合法的公会全名
'''
#C++过滤空格
familyName = GameWorld.GetGameWorld().GetCharTrim(inputName)
- fullFamilyName = GetFamilyFullName(curPlayer, familyName)
- if not fullFamilyName:
- GameWorld.ErrLog("家族全名异常!", curPlayer.GetPlayerID())
+
+ serverID = GameWorld.GetPlayerServerID(curPlayer)
+ maxServerID = IpyGameDataPY.GetFuncCfg("FamilyNameFormat", 3)
+ if serverID > maxServerID or serverID <= 0:
+ GameWorld.ErrLog("公会全名 serverID=%s error! maxServerID=%s, check FamilyNameFormat.txt" % (serverID, maxServerID))
+ return
+
+ maxLen = IpyGameDataPY.GetFuncCfg("FamilyNameFormat", 2)
+ if len(familyName) > maxLen:
+ GameWorld.ErrLog("公会全名 familyName=%s, len=%s > %s, check FamilyNameFormat.txt" % (familyName, len(familyName), maxLen))
+ PlayerControl.NotifyCode(curPlayer, "NameLenLimit", [maxLen / 3, maxLen])
return
if DirtyList.IsWordForbidden(familyName):
@@ -287,49 +543,30 @@
PlayerControl.NotifyCode(curPlayer, "NameLenLimit", [Def_CreatFamily_MaxStr / 3, Def_CreatFamily_MaxStr])
return
+ return True
+
+def CheckFamilyNameExists(crossPlayer, familyName, fromServerID=0):
+ ## 重名在数据所在服务器验证
familyMgr = DBDataMgr.GetFamilyMgr()
- if familyMgr.FindFamilyByName(fullFamilyName):
+ zoneID = familyMgr.GetZoneIDInThisServer(fromServerID)
+ if zoneID < 0:
+ GameWorld.ErrLog("验证公会重名时分区异常也视为重名")
+ return True
+ zoneMgr = familyMgr.GetZoneFamilyMgr(zoneID)
+ # 不同分区暂时允许重名
+ if zoneMgr.FindFamilyByName(familyName):
#XW_JZ_EstablishErr_Name <n color="255,255,0">对不起,您输入的家族名已存在,建立家族失败!</n> 25 - -
- PlayerControl.NotifyCode(curPlayer, "NameExists")
- return
-
- return fullFamilyName
+ CrossPlayer.NotifyCode(crossPlayer, "NameExists")
+ return True
+ return False
-
-## 获取家族全名
-def GetFamilyFullName(curPlayer, familyName):
- serverID = GameWorld.GetPlayerServerID(curPlayer)
-
- maxServerID = IpyGameDataPY.GetFuncCfg("FamilyNameFormat", 3)
- if serverID > maxServerID or serverID <= 0:
- GameWorld.ErrLog("仙盟全名 serverID=%s error! maxServerID=%s, check FamilyNameFormat.txt" % (serverID, maxServerID))
- return ""
-
- specServerDict = IpyGameDataPY.GetFuncEvalCfg("FamilyNameFormat", 4, {})
- nameFormatInfo = GameWorld.GetDictValueByRangeKey(specServerDict, serverID)
- if not nameFormatInfo:
- nameFormatInfo = IpyGameDataPY.GetFuncEvalCfg("FamilyNameFormat", 1)
- if not nameFormatInfo:
- return ""
- nameFormat = nameFormatInfo[0]
- paramList = [eval(pName) for pName in nameFormatInfo[1:]]
- fullName = nameFormat % tuple(paramList)
-
- maxLen = IpyGameDataPY.GetFuncCfg("FamilyNameFormat", 2)
- if len(fullName) > maxLen:
- GameWorld.ErrLog("仙盟全名 familyName=%s,全名=%s len=%s > %s, check FamilyNameFormat.txt" % (familyName, fullName, len(fullName), maxLen))
- PlayerControl.NotifyCode(curPlayer, "NameLenLimit", [maxLen / 3, maxLen])
- return ""
-
- return fullName
-
-def DoPlayerJionFamily(family, playerID, jionPlayer, jionFamilySetLv=IPY_PlayerDefine.fmlMember, broadcastFamilyChange=True):
+def DoPlayerJionFamily(family, playerID, crossPlayer, jionFamilySetLv=IPY_PlayerDefine.fmlMember, broadcastFamilyChange=True):
'''加入家族,支持离线玩家加入
- @param jionPlayer: 如果是离线玩家则为None
+ @param crossPlayer: 如果是离线玩家则为None
'''
+ familyMgr = DBDataMgr.GetFamilyMgr()
if isinstance(family, int):
familyID = family
- familyMgr = DBDataMgr.GetFamilyMgr()
curFamily = familyMgr.FindFamily(familyID)
else:
curFamily = family
@@ -340,37 +577,33 @@
familyID = curFamily.GetID()
member = curFamily.AddMember(playerID)
member.SetFmLV(jionFamilySetLv)
- if jionPlayer:
- member.RefreshMember(jionPlayer)
- else:
- member.RefreshMemberByID(playerID)
- curFamily.SetFightPowerTotal(curFamily.GetFightPowerTotal() + member.GetFightPowerTotal())
+ member.RefreshMemberByID(playerID)
if jionFamilySetLv == IPY_PlayerDefine.fmlLeader:
curFamily.SetLeaderID(playerID)
+ if broadcastFamilyChange:
+ # 广播其他在线成员
+ Broadcast_FamilyInfo(familyID, changeMemIDList=[playerID], excludeIDList=[playerID]) # 成员加入
+
+ familyMgr.DelPlayerReqJoinFamilyIDAll(playerID)
#设置玩家身上保存的家族信息
- if jionPlayer:
- MapServer_FamilyRefresh(jionPlayer, familyID)
- Sync_FamilyInfo(jionPlayer)
+ if crossPlayer:
+ MapServer_FamilyRefresh(crossPlayer, familyID) # 加入
+ Sync_FamilyInfo(crossPlayer) # 给自己同步完整的
+ Sync_RequestAddFamilyInfo(crossPlayer)
+ PlayerFamilyTaofa.OnCrossPlayerEnterFamily(crossPlayer)
if jionFamilySetLv != IPY_PlayerDefine.fmlLeader:
- if broadcastFamilyChange:
- Broadcast_FamilyChange(familyID, FamilyChangeType_MemJoin, excludeIDList=[playerID])
#通知所有家族成员, 这个人加入了家族
- #NotifyAllFamilyMemberMsg(familyID, "XW_JZ_EnterFamily", [member.GetPlayerName()], excludeIDList=[playerID])
- if jionPlayer:
- PlayerControl.NotifyCode(jionPlayer, 'XW_JZ_EnterFamilyInfo', [family.GetName()])
+ CrossPlayer.FamilyNotify(familyID, "XW_JZ_EnterFamily", [member.GetPlayerName()], excludeIDList=[playerID])
+ #if jionPlayer:
+ # PlayerControl.NotifyCode(jionPlayer, 'XW_JZ_EnterFamilyInfo', [family.GetName()])
#记录加入事件
tick = GameWorld.GetGameWorld().GetTick()
AddFamilyActionNote(member.GetPlayerName(), familyID, ShareDefine.Def_ActionType_FamilyEvent,
[ShareDefine.Def_FamilyActionEvent_MemberChange, ShareDefine.Def_FamilyMemberChange_Join, jionFamilySetLv, 0], tick)
-
- #玩家缓存
- #PlayerViewCache.OnPlayerFamilyChange(jionPlayer.GetPlayerID(), curFamily.GetID(), curFamily.GetName())
- #SetMemberFightPower(familyMember, PlayerControl.GetFightPower(jionPlayer))
- #GetFamilyMgr().AddFamilyIDToFightPowerChangeList(curFamily.GetID(), jionPlayer.GetPlayerID())
return
def AddFamilyActionNote(curName, familyID, actionType, actionDataList, tick, isClearNone=True, useData=""):
@@ -395,31 +628,1495 @@
setFunc(value)
return True
-def MapServer_FamilyRefresh(curPlayer, refreshFamilyID, isVoluntarily=0):
- ''' 相当于GameServer调用 curPlayer.MapServer_FamilyRefresh()
- @param familyID: 玩家更新的familyID
- @param isVoluntarily: 是否自愿离开的,仅离开刷新时有效
- '''
+def GetFamilyMemberHasPow(member, powerID):
+ ## 公会成员是否有该权限
+ powerDict = IpyGameDataPY.GetFuncEvalCfg("FamilyPower", 1, {})
+ if str(powerID) not in powerDict:
+ return False
+ needMemberLV = powerDict[str(powerID)]
+ return member.GetFmLV() >= needMemberLV
+
+def Sync_FamilyInfo(crossPlayer, syncMemIDList=None, isSyncMem=True):
+ ## 通知指定玩家 // A5 20 玩家家族信息 #tagMCRoleFamilyInfo
+ familyID = crossPlayer.GetFamilyID()
+ if not familyID:
+ return
+ clientPack = GetPack_FamilyInfo(familyID, syncMemIDList, isSyncMem)
+ CrossPlayer.SendFakePack(crossPlayer, clientPack)
+ return
+
+def Broadcast_FamilyInfo(familyID, changeMemIDList=None, isSyncMem=True, excludeIDList=None):
+ ## 广播给公会成员 // A5 20 玩家家族信息 #tagMCRoleFamilyInfo
+ # @param changeMemIDList: 指定仅通知哪些变化成员信息,差异更新通知
+ # @param isSyncMem: 是否需要通知成员信息
+ clientPack = GetPack_FamilyInfo(familyID, changeMemIDList, isSyncMem)
+ CrossPlayer.SendFakePackByFamily(familyID, clientPack, excludeIDList)
+ return
+
+def GetPack_FamilyInfo(familyID, changeMemIDList=None, isSyncMem=True):
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ curFamily = familyMgr.FindFamily(familyID)
+ if not curFamily:
+ return
+ clientPack = ChPyNetSendPack.tagMCRoleFamilyInfo()
+ clientPack.FamilyID = familyID
+ clientPack.FamilyName = curFamily.GetName()
+ clientPack.FamilyLV = curFamily.GetLV()
+ clientPack.FamilyLVExp = curFamily.GetExp()
+ clientPack.JoinReview = curFamily.GetJoinReview()
+ clientPack.JoinLVMin = curFamily.GetJoinLVMin()
+ clientPack.ServerID = curFamily.GetServerID()
+ clientPack.EmblemID = curFamily.GetEmblemID()
+ clientPack.EmblemWord = curFamily.GetEmblemWord()
+ clientPack.FightPower = curFamily.GetFightPower()
+ clientPack.FightPowerEx = curFamily.GetFightPowerEx()
+ clientPack.Broadcast = curFamily.GetBroadcast()
+ clientPack.BroadcastLen = len(clientPack.Broadcast)
+ clientPack.LeaderID = curFamily.GetLeaderID()
+ clientPack.MemberList = []
+ # ---------------
+ # 测试用,同步全部,等前端同步修改后删除
+ #isSyncMem = True
+ #changeMemIDList = []
+ # ---------------
+ if isSyncMem:
+ for index in xrange(curFamily.GetCount()):
+ member = curFamily.GetAt(index)
+ memID = member.GetPlayerID()
+ if changeMemIDList and memID not in changeMemIDList:
+ continue
+ memInfo = ChPyNetSendPack.tagMCRoleFamilyMember()
+ memInfo.PlayerID = member.GetPlayerID()
+ memInfo.JoinTime = member.GetJoinTime()
+ memInfo.Name = member.GetPlayerName()
+ memInfo.NameLen = len(memInfo.Name)
+ memInfo.LV = member.GetLV()
+ memInfo.Job = member.GetJob()
+ memInfo.RealmLV = member.GetRealmLV()
+ memInfo.Face = member.GetFace()
+ memInfo.FacePic = member.GetFacePic()
+ memInfo.TitleID = member.GetTitleID()
+ memInfo.FightPower = member.GetFightPower()
+ memInfo.FightPowerEx = member.GetFightPowerEx()
+ memInfo.FmLV = member.GetFmLV()
+ memInfo.ServerID = member.GetServerID()
+ memInfo.ContribTotal = member.GetContribTotal()
+ memInfo.ContribDay = member.GetContribDay()
+ memInfo.DonateCntTotal = member.GetDonateCntTotal()
+ memInfo.DonateCntDay = member.GetDonateCntDay()
+ memInfo.OffTime = member.GetOffTime()
+ clientPack.MemberList.append(memInfo)
+ clientPack.MemberCount = len(clientPack.MemberList)
+ clientPack.Extra1 = curFamily.GetExtra1()
+ return clientPack
+
+def GetPack_FamilyDel(delPlayerID, playerName, delType=0):
+ # @param delType: 0-踢出;1-主动退出
+ clientPack = ChPyNetSendPack.tagSCFamilyMemDel()
+ clientPack.Type = delType
+ clientPack.PlayerID = delPlayerID
+ clientPack.Name = playerName
+ clientPack.NameLen = len(clientPack.Name)
+ return clientPack
+
+#// A6 01 向玩家申请加入家族 #tagCMRequestJoinFamilyByPlayer
+#
+#struct tagCMRequestJoinFamilyByPlayer
+#{
+# tagHead Head;
+# DWORD TagPlayerID; //目标家族玩家ID
+#};
+def OnRequestJoinFamilyByPlayer(index, clientData, tick):
+ #屏蔽,默认只使用 A6 02
+ #curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ #tagPlayerID = clientData.TagPlayerID
+ #tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(tagPlayerID)
+ #if not tagPlayer:
+ # GameWorld.DebugLog("对方不在线! tagPlayerID=%s" % tagPlayerID)
+ # return
+ #tagFamilyID = tagPlayer.GetFamilyID()
+ #if tagFamilyID <= 0:
+ # GameWorld.DebugLog("对方没有家族! tagPlayerID=%s" % tagPlayerID)
+ # return
+ #RequestJoinTagFamily(curPlayer, tagFamilyID)
+ return
+
+#// A6 02 申请加入家族#tagCMRequesJoinFamily
+#
+#struct tagCMRequesJoinFamily
+#{
+# tagHead Head;
+# BYTE Type; //申请类型,0-申请;1-撤销
+# DWORD TagFamilyID; //目标家族ID,申请时为0代表一键申请家族任意家族
+#};
+def OnRequesJoinFamily(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ requestType = clientData.Type
+ if requestType == 0:
+ if CheckInJoinCD(curPlayer):
+ return
+ FamilyPyPackForwarding(curPlayer, clientData, tick, "__OnRequesJoinFamily", True)
+ return
+
+def __OnRequesJoinFamily(crossPlayer, clientData, tick, fromServerID=0, reqDataEx=None):
+ tagFamilyID = clientData.TagFamilyID # 申请进入的家族ID
+ requestType = clientData.Type # 申请类型(申请/撤销)
+ GameWorld.DebugLog("__OnRequesJoinFamily: tagFamilyID=%s,requestType=%s" % (tagFamilyID, requestType))
+
+ # 申请加入
+ if requestType == 0:
+ if not tagFamilyID:
+ AutoJoinFamily(crossPlayer)
+ else:
+ RequestJoinTagFamily(crossPlayer, tagFamilyID)
+
+ # 撤销申请
+ elif requestType == 1:
+ CancelJoinTagFamily(crossPlayer, tagFamilyID)
+
+ return True
+
+def __OnRequesJoinFamily_Ret(curPlayer, clientData, isOK):
+ requestType = clientData.Type # 申请类型(申请/撤销)
+ # 申请加入
+ if requestType == 0:
+ PlayerTask.AddTaskValue(curPlayer, ChConfig.TaskType_ReqOrJoinFamily, 1)
+
+ return
+
+def CheckInJoinCD(curPlayer):
+ ## 检查是否加入公会CD中
+ leaveFamilyTime = PlayerControl.GetLeaveFamilyTimeEx(curPlayer)
+ if not leaveFamilyTime:
+ return False
+
+ leaveCnt, kickedCnt, lastVoluntarily = PlayerControl.GetLeaveFamilyInfo(curPlayer)
+ joinCDMinute = 0
+ if lastVoluntarily:
+ if leaveCnt <= 0:
+ return False
+ joinCDMinuteList = IpyGameDataPY.GetFuncEvalCfg("FamilyLeave", 1)
+ if joinCDMinuteList:
+ joinCDMinute = joinCDMinuteList[leaveCnt - 1] if len(joinCDMinuteList) >= leaveCnt else joinCDMinuteList[-1]
+ else:
+ if kickedCnt <= 0:
+ return False
+ joinCDMinuteList = IpyGameDataPY.GetFuncEvalCfg("FamilyLeave", 2)
+ if joinCDMinuteList:
+ joinCDMinute = joinCDMinuteList[kickedCnt - 1] if len(joinCDMinuteList) >= kickedCnt else joinCDMinuteList[-1]
+ if joinCDMinute:
+ cdTimes = joinCDMinute * 60
+ passTimes = int(time.time()) - leaveFamilyTime
+ if passTimes < cdTimes:
+ GameWorld.DebugLog("加入公会CD中: leaveCnt=%s,kickedCnt=%s,lastVoluntarily=%s,leaveFamilyTime=%s(%s),passTimes=%s < %s"
+ % (leaveCnt, kickedCnt, lastVoluntarily, leaveFamilyTime, GameWorld.ChangeTimeNumToStr(leaveFamilyTime), passTimes, cdTimes))
+ return True
+ return False
+
+def AutoJoinFamily(crossPlayer):
+ if crossPlayer.GetFamilyID():
+ return
+ playerID = crossPlayer.GetPlayerID()
+ realmLV = crossPlayer.GetRealmLV()
+ GameWorld.DebugLog("玩家一键自动加入家族! realmLV=%s" % realmLV, playerID)
+ #if CheckInJoinCD(curPlayer):
+ # return
+
+ mainServerID = crossPlayer.GetMainServerID()
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ zoneID = familyMgr.GetZoneIDInThisServer(mainServerID)
+ if zoneID < 0:
+ return
+ zoneMgr = familyMgr.GetZoneFamilyMgr(zoneID)
+ indexList = range(zoneMgr.GetCount())
+ random.shuffle(indexList) #打乱顺序
+ for index in indexList:
+ family = zoneMgr.GetAt(index)
+ if not family:
+ continue
+ #familyID = family.GetID()
+ lvMin = family.GetJoinLVMin()
+ if lvMin and realmLV < lvMin:
+ #GameWorld.DebugLog(" 官职不足的不处理! familyID=%s,lvMin=%s" % (familyID, lvMin), playerID)
+ continue
+ if family.GetJoinReview():
+ #GameWorld.DebugLog(" 需要审核的不处理! familyID=%s" % familyID, playerID)
+ continue
+ MemberMax = GetFamilySetting(family.GetLV(), "MemberMax")
+ if family.GetCount() >= MemberMax:
+ #GameWorld.DebugLog(" 成员已满的不处理! familyID=%s" % familyID, playerID)
+ continue
+
+ #直接加入
+ DoPlayerJionFamily(family, playerID, crossPlayer)
+ return
+
+ # 可再扩展自动请求,暂时不处理
+ GameWorld.DebugLog("没有可自动进入的公会!")
+ CrossPlayer.NotifyCode(crossPlayer, "QuickEnterFamilyFail")
+ return
+
+def GetFamilySetting(familyLV, fieldName):
+ ## 获取公会等级表对应字段值
+ if not fieldName:
+ return 0
+ ipyData = IpyGameDataPY.GetIpyGameData("Family", familyLV)
+ if not ipyData:
+ return 0
+ attrName = "Get%s" % fieldName
+ if not hasattr(ipyData, attrName):
+ return 0
+ return getattr(ipyData, attrName)()
+
+def RequestJoinTagFamily(crossPlayer, familyID):
+ ## 申请加入
+ #if CheckInJoinCD(curPlayer):
+ # return
+ playerID = crossPlayer.GetPlayerID()
+ if crossPlayer.GetFamilyID():
+ GameWorld.DebugLog('已经有公会不能再申请加入! familyID=%s' % crossPlayer.GetFamilyID(), playerID)
+ return
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ reqFamilyIDList = familyMgr.GetPlayerReqJoinFamilyIDList(playerID)
+ if playerID in reqFamilyIDList:
+ GameWorld.DebugLog('已经在申请加入公会列表中! familyID=%s' % familyID, playerID)
+ return
+
+ maxReqFamilyCnt = IpyGameDataPY.GetFuncCfg("FamilyReqJoin", 2)
+ if len(reqFamilyIDList) >= maxReqFamilyCnt:
+ GameWorld.DebugLog('已经达到最大申请加入公会数! %s, %s' % (len(reqFamilyIDList), reqFamilyIDList), playerID)
+ return
+
+ tagFamily = familyMgr.FindFamily(familyID)
+ if not tagFamily:
+ return
+
+ lvMin = tagFamily.GetJoinLVMin()
+ if crossPlayer.GetRealmLV() < lvMin:
+ GameWorld.DebugLog('官职未达到该公会加入最低限制! realmLV=%s < %s' % (crossPlayer.GetRealmLV(), lvMin), playerID)
+ return
+
+ # 需要审核,满员后端不限制申请,由前端自行决定是否可申请
+ if tagFamily.GetJoinReview():
+ reqPlayerIDDict = tagFamily.GetReqJoinPlayerInfo()
+ if playerID not in reqPlayerIDDict:
+ maxReqPlayerCnt = IpyGameDataPY.GetFuncCfg("FamilyReqJoin", 1)
+ if len(reqPlayerIDDict) >= maxReqPlayerCnt:
+ GameWorld.DebugLog('目标公会申请加入数已满! %s, %s' % (len(reqFamilyIDList), reqFamilyIDList), playerID)
+ CrossPlayer.NotifyCode(crossPlayer, "jiazu_pan_141056")
+ return
+
+ tagFamily.AddReqJoinPlayerID(playerID)
+ # 广播给有招人权限的
+ SendFamilyReqJoinInfo(familyID)
+
+ #jiazu_pan_500807:申请入帮成功!请等待帮会管理人员审批!
+ CrossPlayer.NotifyCode(crossPlayer, "jiazu_pan_500807")
+ Sync_RequestAddFamilyInfo(crossPlayer)
+ return
+
+ # 不需要审核,自动加入
+ memberMax = GetFamilySetting(tagFamily.GetLV(), "MemberMax")
+ if tagFamily.GetCount() >= memberMax:
+ GameWorld.DebugLog('目标公会成员已满! familyLV=%s,memberMax=%s' % (tagFamily.GetLV(), memberMax), playerID)
+ return
+
+ DoPlayerJionFamily(tagFamily, playerID, crossPlayer)
+ return
+
+def CancelJoinTagFamily(crossPlayer, familyID):
+ # 撤销申请
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ playerID = crossPlayer.GetPlayerID()
+ tagFamily = familyMgr.FindFamily(familyID)
+ if tagFamily:
+ tagFamily.DelReqJoinPlayerID(playerID)
+ familyMgr.DelPlayerReqJoinFamilyID(playerID, familyID)
+ SendFamilyReqJoinInfo(familyID)
+ Sync_RequestAddFamilyInfo(crossPlayer)
+ return
+
+def Sync_RequestAddFamilyInfo(crossPlayer, isForce=True):
+ ## 通知当前申请加入的哪些家族
+ playerID = crossPlayer.GetPlayerID()
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ reqFamilyIDList = familyMgr.GetPlayerReqJoinFamilyIDList(playerID)
+ # 非强制通知时没有申请记录的可不通知,如登录
+ if not isForce and not reqFamilyIDList:
+ return
+ clientPack = ChPyNetSendPack.tagMCNotifyRequestJoinFamilyInfo()
+ clientPack.Clear()
+ clientPack.RequestJoinFamilyIDList = reqFamilyIDList
+ clientPack.RequestCount = len(clientPack.RequestJoinFamilyIDList)
+ CrossPlayer.SendFakePack(crossPlayer, clientPack)
+ return
+
+def IsFamilyNeedViewPlayer(playerID):
+ ## 公会功能中查看玩家是否需要用到的
+
+ # 公会成员已存储成员信息,所以成员不用判断,仅判断其他即可
+ # 是否有请求加入某个公会
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ if familyMgr.GetPlayerReqJoinFamilyIDList(playerID):
+ return True
+
+ return False
+
+def SendFamilyReqJoinInfo(familyID):
+ ## 广播给公会有招人权限的
+ CrossPlayer.SendFakePackByFamily(familyID, GetPack_FamilyReqJoinInfo(familyID), None, GetFamilyMemberHasPow, FamilyPowerID_Call)
+ return
+
+def GetPack_FamilyReqJoinInfo(familyID):
+ ## 获取 // A5 22 家族申请加入的玩家信息 #tagMCFamilyReqJoinInfo
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ curFamily = familyMgr.FindFamily(familyID)
+ if not curFamily:
+ return
+ reqPlayerIDDict = curFamily.GetReqJoinPlayerInfo()
+ #没人申请也要通知
+ #if not reqPlayerIDDict:
+ # return
+ crossPlayerMgr = CrossPlayer.GetCrossPlayerMgr()
+ clientPack = ChPyNetSendPack.tagMCFamilyReqJoinInfo()
+ clientPack.ReqJoinList = []
+ for playerID, reqTime in reqPlayerIDDict.items():
+ crossPlayer = crossPlayerMgr.FindCrossPlayer(playerID)
+ reqInfo = ChPyNetSendPack.tagMCFamilyReqJoinPlayer()
+ reqInfo.PlayerID = playerID
+ reqInfo.ReqTime = reqTime
+ reqInfo.IsOnLine = 1 if crossPlayer else 0
+ viewCache = PlayerViewCache.FindViewCache(playerID)
+ if viewCache:
+ reqInfo.Name = viewCache.GetPlayerName()
+ reqInfo.NameLen = len(reqInfo.Name)
+ reqInfo.LV = viewCache.GetLV()
+ reqInfo.Job = viewCache.GetJob()
+ reqInfo.RealmLV = viewCache.GetRealmLV()
+ reqInfo.Face = viewCache.GetFace()
+ reqInfo.FacePic = viewCache.GetFacePic()
+ reqInfo.TitleID = viewCache.GetTitleID()
+ reqInfo.FightPower = viewCache.GetFightPower()
+ reqInfo.FightPowerEx = viewCache.GetFightPowerEx()
+ reqInfo.ServerID = viewCache.GetServerID()
+ clientPack.ReqJoinList.append(reqInfo)
+ if len(clientPack.ReqJoinList) >= 100:
+ break
+ clientPack.ReqCnt = len(clientPack.ReqJoinList)
+ return clientPack
+
+#// A6 21 审核请求加入家族 #tagCMJoinFamilyReply
+#
+#struct tagCMJoinFamilyReply
+#{
+# tagHead Head;
+# DWORD TagPlayerID; //被审核玩家ID 0则代表全部
+# BYTE IsOK; //是否同意其加入
+#};
+def OnJoinFamilyReply(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ FamilyPyPackForwarding(curPlayer, clientData, tick, "__OnJoinFamilyReply")
+ return
+
+def __OnJoinFamilyReply(crossPlayer, clientData, tick, fromServerID=0, reqDataEx=None):
+ tagPlayerID = clientData.TagPlayerID
+ isOK = clientData.IsOK
+ GameWorld.DebugLog("__OnJoinFamilyReply: tagPlayerID=%s,isOK=%s" % (tagPlayerID, isOK))
+
+ playerID = crossPlayer.GetPlayerID()
+ familyID = crossPlayer.GetFamilyID()
+ if familyID <= 0:
+ return
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ family = familyMgr.FindFamily(familyID)
+ if not family:
+ return
+ curMember = family.FindMember(playerID)
+ if not curMember:
+ return
+ if not GetFamilyMemberHasPow(curMember, FamilyPowerID_Call):
+ GameWorld.DebugLog("没有招人权限,无法审核人员入盟!", playerID)
+ #PlayerControl.NotifyCode(curPlayer, "XW_JZ_InviteErr_Popedom")
+ return
+
+ GameWorld.DebugLog("审核入盟申请: tagPlayerID=%s,familyID=%s,isOK=%s" % (tagPlayerID, familyID, isOK), playerID)
+ reqPlayerIDDict = family.GetReqJoinPlayerInfo()
+ tagPlayerIDList = reqPlayerIDDict.keys()
+ if tagPlayerID:
+ if tagPlayerID not in reqPlayerIDDict:
+ GameWorld.DebugLog("不存在该申请人员! tagPlayerID=%s" % tagPlayerID)
+ return
+ tagPlayerIDList = [tagPlayerID]
+
+ if not tagPlayerIDList:
+ GameWorld.DebugLog("没有申请人员!")
+ return
+
+ crossPlayerMgr = CrossPlayer.GetCrossPlayerMgr()
+ # 拒绝
+ if not isOK:
+ for tagPlayerID in tagPlayerIDList:
+ family.DelReqJoinPlayerID(tagPlayerID)
+ tagCrossPlayer = crossPlayerMgr.FindCrossPlayer(tagPlayerID)
+ if not tagCrossPlayer:
+ continue
+ Sync_RequestAddFamilyInfo(tagCrossPlayer)
+ #jiazu_pan_592934:{%S}拒绝了您的入帮申请
+ CrossPlayer.NotifyCode(tagCrossPlayer, "jiazu_pan_592934", [family.GetName()])
+
+ SendFamilyReqJoinInfo(familyID)
+ return
+
+ # 处理同意
+ offlinePlayerCanJoin = IpyGameDataPY.GetFuncCfg("FamilyReqJoin", 3)
+ MemberMax = GetFamilySetting(family.GetLV(), "MemberMax")
+ joinOKPlayerIDList = []
+ for tagPlayerID in tagPlayerIDList:
+ if family.GetCount() >= MemberMax:
+ CrossPlayer.NotifyCode(crossPlayer, "jiazu_lhs_202580")
+ break
+ tagCrossPlayer = crossPlayerMgr.FindCrossPlayer(tagPlayerID)
+ #申请目标不在线
+ if not tagCrossPlayer:
+ if not offlinePlayerCanJoin:
+ GameWorld.DebugLog("离线玩家无法加入公会! tagPlayerID=%s" % tagPlayerID, playerID)
+ CrossPlayer.NotifyCode(crossPlayer, "jiazu_hwj35_367906")
+ continue
+
+ family.DelReqJoinPlayerID(tagPlayerID) # 以下只要操作的都删除
+
+ if family.FindMember(tagPlayerID):
+ GameWorld.DebugLog("已经是本盟成员! tagPlayerID=%s" % tagPlayerID, playerID)
+ CrossPlayer.NotifyCode(crossPlayer, "XW_JZ_InviteErr_Repeat")
+ continue
+
+ tagFamilyID = familyMgr.GetPlayerFamilyID(tagPlayerID)
+ if tagFamilyID:
+ GameWorld.DebugLog("已经加入其他公会! tagPlayerID=%s,tagFamilyID=%s" % (tagPlayerID, tagFamilyID), playerID)
+ CrossPlayer.NotifyCode(crossPlayer, "XW_JZ_InviteErr_Repeat")
+ continue
+
+ DoPlayerJionFamily(family, tagPlayerID, tagCrossPlayer, broadcastFamilyChange=False)
+ joinOKPlayerIDList.append(tagPlayerID)
+
+ #if not joinOKPlayerIDList:
+ # return
+ SendFamilyReqJoinInfo(familyID)
+ if joinOKPlayerIDList:
+ Broadcast_FamilyInfo(familyID, changeMemIDList=joinOKPlayerIDList, excludeIDList=joinOKPlayerIDList) # 审核
+ return
+
+#// A6 22 修改收人方式 #tagCMChangeFamilyJoin
+#
+#struct tagCMChangeFamilyJoin
+#{
+# tagHead Head;
+# BYTE JoinReview; //成员加入是否需要审核,默认0自动加入
+# WORD JoinLVMin; //限制最低可加入的玩家等级
+#};
+def OnChangeFamilyJoin(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ FamilyPyPackForwarding(curPlayer, clientData, tick, "__OnChangeFamilyJoin")
+ return
+
+def __OnChangeFamilyJoin(crossPlayer, clientData, tick, fromServerID=0, reqDataEx=None):
+ joinReview = clientData.JoinReview
+ joinLVMin = clientData.JoinLVMin # 官职
+ GameWorld.DebugLog("__OnChangeFamilyJoin: joinReview=%s,joinLVMin=%s" % (joinReview, joinLVMin))
+
+ playerID = crossPlayer.GetPlayerID()
+ familyID = crossPlayer.GetFamilyID()
+ if familyID <= 0:
+ return
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ family = familyMgr.FindFamily(familyID)
+ if not family:
+ return
+ curMember = family.FindMember(playerID)
+ if not curMember:
+ return
+ if not GetFamilyMemberHasPow(curMember, FamilyPowerID_Call):
+ GameWorld.DebugLog("没有招人权限", playerID)
+ return
+ GameWorld.DebugLog("修改招人设置: familyID=%s,joinReview=%s,joinLVMin=%s" % (familyID, joinReview, joinLVMin), playerID)
+ family.SetJoinReview(joinReview)
+ family.SetJoinLVMin(joinLVMin)
+ Broadcast_FamilyInfo(familyID, isSyncMem=False) # 修改招人
+ return
+
+#// A6 23 修改家族公告 #tagCMChangeFamilyBroadcast
+#
+#struct tagCMChangeFamilyBroadcast
+#{
+# tagHead Head;
+# char Msg[200];
+#};
+def OnChangeFamilyBroadcast(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ FamilyPyPackForwarding(curPlayer, clientData, tick, "__OnChangeFamilyBroadcast")
+ return
+
+def __OnChangeFamilyBroadcast(crossPlayer, clientData, tick, fromServerID=0, reqDataEx=None):
+ broadcast = clientData.Msg
+
+ playerID = crossPlayer.GetPlayerID()
+ familyID = crossPlayer.GetFamilyID()
+ if familyID <= 0:
+ return
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ family = familyMgr.FindFamily(familyID)
+ if not family:
+ return
+ curMember = family.FindMember(playerID)
+ if not curMember:
+ return
+ if not GetFamilyMemberHasPow(curMember, FamilyPowerID_Broadcast):
+ GameWorld.DebugLog("没有修改公告权限", playerID)
+ return
+ family.SetBroadcast(broadcast)
+ GameWorld.DebugLog('更改公会公告: Family=%s,公告=%s' % (GameWorld.CodeToGbk(family.GetName()), GameWorld.CodeToGbk(broadcast)), playerID)
+ Broadcast_FamilyInfo(familyID, isSyncMem=False) # 修改公告
+ return
+
+#// A6 24 修改家族徽章 #tagCMChangeFamilyEmblem
+#
+#struct tagCMChangeFamilyEmblem
+#{
+# tagHead Head;
+# BYTE EmblemID; // 更换的徽章ID
+# char EmblemWord[3]; // 徽章文字
+#};
+def OnChangeFamilyEmblem(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ FamilyPyPackForwarding(curPlayer, clientData, tick, "__OnChangeFamilyEmblem")
+ return
+
+def __OnChangeFamilyEmblem(crossPlayer, clientData, tick, fromServerID=0, reqDataEx=None):
+ changeEmblemID = clientData.EmblemID
+ emblemWord = clientData.EmblemWord
+ PlayerFamilyEmblem.OnChangeFamilyEmblem(crossPlayer, changeEmblemID, emblemWord)
+ return
+
+#// A6 25 修改家族成员职位 #tagCMChangeFamilyMemLV
+#
+#struct tagCMChangeFamilyMemLV
+#{
+# tagHead Head;
+# DWORD PlayerID; // 目标成员ID
+# BYTE FmLV; // 变更为xx职位
+#};
+def OnChangeFamilyMemLV(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ FamilyPyPackForwarding(curPlayer, clientData, tick, "__OnChangeFamilyMemLV")
+ return
+
+def __OnChangeFamilyMemLV(crossPlayer, clientData, tick, fromServerID=0, reqDataEx=None):
+ OnChangeFamilyMemberLV(crossPlayer, clientData.PlayerID, clientData.FmLV)
+ return
+
+def OnChangeFamilyMemberLV(crossPlayer, tagID, changeFmlv, isGMOP=False):
+ '''变更成员职位
+ @param curPlayer: 操作的玩家
+ @param tagID: 目标成员ID
+ @param changeFmlv: 修改为xx职位
+ @param isGMOP: 是否是GM后台发起的,如果是GM发起的,一般curPlayer传入的为目标成员ID实例
+ '''
+ if not crossPlayer:
+ return
+ playerID = crossPlayer.GetPlayerID()
+ familyID = crossPlayer.GetFamilyID()
+ if familyID <= 0:
+ return
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ family = familyMgr.FindFamily(familyID)
+ if not family:
+ return
+ curMember = family.FindMember(playerID)
+ if not curMember:
+ return
+ if changeFmlv < 0 or changeFmlv > IPY_PlayerDefine.fmlLeader:
+ GameWorld.DebugLog("不存在该职位等级! changeFmlv=%s" % changeFmlv)
+ return
+ # 非GM操作的需检查权限
+ if not isGMOP:
+ if not GetFamilyMemberHasPow(curMember, FamilyPowerID_ChangeFmlv):
+ return
+ if playerID == tagID:
+ GameWorld.DebugLog("不能任免自己的家族职位", playerID)
+ return
+
+ tagMember = family.FindMember(tagID)
+ if tagMember == None:
+ GameWorld.DebugLog("更改家族成员职位时目标成员不存在! tagID=%s" % tagID, playerID)
+ return
+
+ if not isGMOP:
+ if curMember.GetFmLV() != IPY_PlayerDefine.fmlLeader:
+ if changeFmlv >= curMember.GetFmLV():
+ GameWorld.DebugLog("修改的职位不能比自己高或平级! changeFmlv=%s" % changeFmlv, playerID)
+ return
+ if tagMember.GetFmLV() >= curMember.GetFmLV():
+ GameWorld.DebugLog("修改的目标成员职位不能比自己高或平级! tagFmlv=%s" % tagMember.GetFmLV(), playerID)
+ return
+
+ changeMemIDList = [tagID]
+ if changeFmlv == IPY_PlayerDefine.fmlLeader:
+ ChangeFamilyLeader(family, tagMember)
+ changeMemIDList.append(playerID)
+
+ else:
+ fmLVMemCnt = 0
+ for index in range(family.GetCount()):
+ familyMember = family.GetAt(index)
+ if familyMember.GetFmLV() != changeFmlv:
+ continue
+ fmLVMemCnt += 1
+
+ maxCnt = GetFamilySetting(family.GetLV(), Def_FmlSetAttrName.get(changeFmlv, ""))
+ if fmLVMemCnt >= maxCnt:
+ # jiazu_hwj35_272921 改为 jiazu_chenxin_31379
+ CrossPlayer.NotifyCode(crossPlayer, "jiazu_chenxin_31379")
+ GameWorld.DebugLog("目前该职位的人数已经达到上限! changeFmlv=%s,fmLVMemCnt=%s >= %s" % (changeFmlv, fmLVMemCnt, maxCnt))
+ return
+ ChangeFamilyMemberLv(tagMember, changeFmlv)
+
+ if isGMOP:
+ family.SetBroadcast("")
+ Broadcast_FamilyInfo(familyID, changeMemIDList=changeMemIDList) # 修改职位
+ return True
+
+def ChangeFamilyLeader(family, newLeaderMem):
+ ## 变更家族族长
+
+ familyID = family.GetID()
+ befLeaderID = family.GetLeaderID()
+ newLeaderID = newLeaderMem.GetPlayerID()
+ if befLeaderID == newLeaderID:
+ return
+
+ befLeaderMem = family.FindMember(befLeaderID)
+ if befLeaderMem:
+ #把原族长降为普通成员
+ ChangeFamilyMemberLv(befLeaderMem, IPY_PlayerDefine.fmlMember)
+
+ family.SetLeaderID(newLeaderID)
+ ChangeFamilyMemberLv(newLeaderMem, IPY_PlayerDefine.fmlLeader)
+ GameWorld.Log("家族设置新族长! familyID=%s,newLeaderID=%s,befLeaderID=%s" % (familyID, newLeaderID, befLeaderID))
+ return
+
+def ChangeFamilyMemberLv(tagMember, changeFamilyLV):
+ ## 修改成员职位,只做修改逻辑,不做验证,验证由各调用入口自行验证
+ familyID = tagMember.GetFamilyID()
+ tagID = tagMember.GetPlayerID()
+ memName = tagMember.GetPlayerName()
+ befFamilyLV = tagMember.GetFmLV()
+
+ tagMember.SetFmLV(changeFamilyLV)
+
+ tagCrossPlayer = CrossPlayer.GetCrossPlayerMgr().FindCrossPlayer(tagID)
+ if tagCrossPlayer:
+ MapServer_FamilyRefresh(tagCrossPlayer, familyID) # 修改职位
+ if GetFamilyMemberHasPow(tagMember, FamilyPowerID_Call):
+ CrossPlayer.SendFakePack(tagCrossPlayer, GetPack_FamilyReqJoinInfo(familyID))
+
+ # 记录家族事件记录信息
+ tick = GameWorld.GetGameWorld().GetTick()
+ AddFamilyActionNote(memName, familyID, ShareDefine.Def_ActionType_FamilyEvent,
+ [ShareDefine.Def_FamilyActionEvent_MemberChange, ShareDefine.Def_FamilyMemberChange_FMLV, changeFamilyLV, befFamilyLV], tick)
+
+ #xx被任命为xx
+ CrossPlayer.FamilyNotify(familyID, "XW_JZ_AppointFamily", [memName, changeFamilyLV])
+ return
+
+def __AutoChangeLeader(curFamily):
+ ## 自动传位
+ leaderID = curFamily.GetLeaderID()
+ leaderMem = curFamily.FindMember(leaderID)
+ if not leaderMem:
+ return
+ offTime = leaderMem.GetOffTime()
+ if not offTime:
+ return
+ familyID = curFamily.GetID()
+ curTime = int(time.time())
+ passTime = curTime - offTime
+ passHours = passTime / 3600.0
+ needHours = IpyGameDataPY.GetFuncCfg("FamilyLeaderAutoChange", 1)
+ if passHours < needHours:
+ GameWorld.DebugLogEx("盟主离线未超过限制小时,不处理自动传位!familyID=%s,leaderID=%s,offTime=%s,passHours=%s < %s",
+ familyID, leaderID, GameWorld.ChangeTimeNumToStr(offTime), passHours, needHours)
+ return
+
+ priorityHours = IpyGameDataPY.GetFuncCfg("FamilyLeaderAutoChange", 1) # 优先传给离线不超过x小时的成员,一样按优先级
+
+ priorityList = []
+ commList = []
+ for i in range(0, curFamily.GetCount()):
+ member = curFamily.GetAt(i)
+ if member.GetFmLV() == IPY_PlayerDefine.fmlLeader:
+ continue
+
+ memOffTime = member.GetOffTime()
+ if memOffTime:
+ sortTime = memOffTime
+ memPassTime = curTime - memOffTime
+ memPassHours = memPassTime / 3600.0
+ else:
+ sortTime = curTime # 排序用的时间,越大越优先
+ memPassTime = 0
+ memPassHours = 0
+
+ fmLV = member.GetFmLV() # 职位
+ contribTotal = member.GetContribTotal() # 总贡献
+
+ commList.append([fmLV, sortTime, contribTotal, member])
+ if priorityHours and memPassHours <= priorityHours:
+ priorityList.append([fmLV, sortTime, contribTotal, member])
+
+ if not priorityList and not commList:
+ # 没有可传位的目标成员
+ return
+
+ toMember = None
+ if priorityList:
+ priorityList.sort(reverse=True)
+ toMember = priorityList[0][-1]
+ else:
+ commList.sort(reverse=True)
+ toMember = commList[0][-1]
+
+ if not toMember:
+ return
+
+ newLeaderID = toMember.GetPlayerID()
+ GameWorld.Log("公会自动传位: familyID=%s,leaderID=%s,offTime=%s,passHours=%s,newLeaderID=%s"
+ % (familyID, leaderID, GameWorld.ChangeTimeNumToStr(offTime), passHours, newLeaderID))
+ ChangeFamilyLeader(curFamily, toMember)
+ Broadcast_FamilyInfo(familyID, changeMemIDList=[leaderID, newLeaderID]) # 自动传位
+
+ # 邮件通知
+ toServerID = toMember.GetServerID()
+ PlayerMail.SendMailByKey("FamilyLeaderAutoChange", newLeaderID, [], [curFamily.GetName()], toServerID=toServerID)
+ return
+
+#// A6 26 请求家族成员列表 #tagCMGetFamilyInfo
+#
+#struct tagCMGetFamilyInfo
+#{
+# tagHead Head;
+#};
+def OnGetFamilyInfo(index, clientData, tick):
+ #改为后端主动同步差异,不用再请求了
+ #curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ #Sync_FamilyInfo(crossPlayer)
+ return
+
+#// A6 03 离开家族 #tagCMLeaveFamily
+#
+#struct tagCMLeaveFamily
+#{
+# tagHead Head;
+#};
+def OnLeaveFamily(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ FamilyPyPackForwarding(curPlayer, clientData, tick, "__OnMemLeaveFamily")
+ return
+
+def __OnMemLeaveFamily(crossPlayer, clientData, tick, fromServerID=0, reqDataEx=None):
+ playerID = crossPlayer.GetPlayerID()
+ familyID = crossPlayer.GetFamilyID()
+ if familyID <= 0:
+ return
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ family = familyMgr.FindFamily(familyID)
+ if not family:
+ return
+ curMember = family.FindMember(playerID)
+ if not curMember:
+ return
+
+ familyLV = curMember.GetFmLV() # 职位
+ if family.GetCount() > 1 and familyLV == IPY_PlayerDefine.fmlLeader:
+ GameWorld.DebugLog("族长在成员人数大于1时不能直接退出家族", playerID)
+ return
+
+ # 功能限制退出公会
+ # ...
+
+ # 进出时间限制暂不做,等正式功能再补
+ #PlayerControl.SetLeaveFamilyTime(curPlayer, updTime)
+
+ # 执行退出
+ GameWorld.DebugLog("离开家族! familyID=%s" % familyID, playerID)
+
+ family.DeleteMember(playerID)
+ AddFamilyActionNote(crossPlayer.GetPlayerName(), familyID, ShareDefine.Def_ActionType_FamilyEvent,
+ [ShareDefine.Def_FamilyActionEvent_MemberChange, ShareDefine.Def_FamilyMemberChange_Leave], tick)
+
+ __DoPlayerLeaveFamilyByID(family, playerID, crossPlayer)
+ MapServer_FamilyRefresh(crossPlayer, 0, 1) # 主动退出
+ CrossPlayer.SendFakePackByFamily(familyID, GetPack_FamilyDel(playerID, crossPlayer.GetPlayerName(), 1))
+ CrossPlayer.FamilyNotify(familyID, "XW_JZ_LeaveFamily", [crossPlayer.GetPlayerName()])
+ Broadcast_FamilyInfo(familyID, isSyncMem=False) # 退出
+
+ if family.GetCount() == 0:
+ #玩家离开后, 家族没有人了 , 删除这个家族
+ familyMgr.DelFamily(familyID)
+ return
+
+ return
+
+#// A6 05 删除家族成员 #tagCMDeleteFamilyMember
+#
+#struct tagCMDeleteFamilyMember
+#{
+# tagHead Head;
+# DWORD MemberID;
+#};
+def OnDeleteFamilyMember(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ FamilyPyPackForwarding(curPlayer, clientData, tick, "__OnDeleteFamilyMember")
+ return
+
+def __OnDeleteFamilyMember(crossPlayer, clientData, tick, fromServerID=0, reqDataEx=None):
+ tagMemberID = clientData.MemberID
+ GameWorld.DebugLog("__OnDeleteFamilyMember tagMemberID=%s" % tagMemberID)
+
+ playerID = crossPlayer.GetPlayerID()
+ if playerID == tagMemberID:
+ return
+
+ familyID = crossPlayer.GetFamilyID()
+ if familyID <= 0:
+ return
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ family = familyMgr.FindFamily(familyID)
+ if not family:
+ return
+ curMember = family.FindMember(playerID)
+ if not curMember:
+ return
+
+ if not GetFamilyMemberHasPow(curMember, FamilyPowerID_Kick):
+ GameWorld.DebugLog("没有踢人权限!")
+ return
+
+ tagMember = family.FindMember(tagMemberID)
+ if not tagMember:
+ return
+
+ curFmlv = curMember.GetFmLV()
+ tagFmlv = tagMember.GetFmLV()
+ if tagFmlv >= curFmlv:
+ GameWorld.DebugLog("只能踢比自己职位低的成员! tagMemberID=%s,tagFmlv(%s) >= curFmlv(%s)" % (tagMemberID, tagFmlv, curFmlv), playerID)
+ return
+
+ # 功能限制踢人
+ # ...
+
+ tagPlayerName = tagMember.GetPlayerName() # 被踢玩家名
+ tagPlayerID = tagMember.GetPlayerID() # 被踢玩家ID
+
+ family.DeleteMember(tagPlayerID)
+
+ AddFamilyActionNote(tagPlayerName, familyID, ShareDefine.Def_ActionType_FamilyEvent,
+ [ShareDefine.Def_FamilyActionEvent_MemberChange, ShareDefine.Def_FamilyMemberChange_KickOut], tick)
+
+ #XW_JZ_LeaveFamily <n color="0,190,255">{%S1%}</n><n color="255,255,0">退出了家族!</n> 25 - -
+ CrossPlayer.FamilyNotify(familyID, "XW_JZ_LeaveFamily", [tagPlayerName])
+
+ #删除玩家
+ tagCrossPlayer = CrossPlayer.GetCrossPlayerMgr().FindCrossPlayer(tagMemberID)
+ __DoPlayerLeaveFamilyByID(family, tagPlayerID, tagCrossPlayer)
+ if tagCrossPlayer:
+ MapServer_FamilyRefresh(tagCrossPlayer, 0) # 被踢
+ CrossPlayer.NotifyCode(tagCrossPlayer, "XW_JZ_LeaveFamilyKick", [curMember.GetPlayerName()])
+
+ CrossPlayer.SendFakePackByFamily(familyID, GetPack_FamilyDel(tagMemberID, tagPlayerName, 0))
+ Broadcast_FamilyInfo(familyID, isSyncMem=False) # 踢人
+ return
+
+def __DoPlayerLeaveFamilyByID(curFamily, leavePlayerID, crossPlayer=None):
+ ## 有玩家离开家族处理,主要针对家族层级的,玩家个人的在 __OnLeaveFamily 处理
+ PlayerFamilyTaofa.OnFamilyMemberLeave(curFamily, leavePlayerID)
+ return
+
+#// A6 11 家族改名 #tagCMRenameFamily
+#
+#struct tagCMRenameFamily
+#{
+# tagHead Head;
+# BYTE NewNameLen;
+# char NewName[NewNameLen];
+# BYTE ItemIndex; //改名物品在背包中的位置
+#};
+def UpdateFamilyName(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ newName = clientData.NewName
+ if not CheckInputFamilyName(curPlayer, newName):
+ GameWorld.DebugLog("名字验证不通过")
+ return
+ moneyType, moneyValue = IpyGameDataPY.GetFuncEvalCfg("FamilyRename", 1)
+ if moneyType and moneyValue and not PlayerControl.HaveMoney(curPlayer, moneyType, moneyValue):
+ return
+ FamilyPyPackForwarding(curPlayer, clientData, tick, "__UpdateFamilyName", True, 20)
+ return
+
+def __UpdateFamilyName(crossPlayer, clientData, tick, fromServerID=0, reqDataEx=None):
+ newName = clientData.NewName
+ #itemIndex = clientData.ItemIndex
+
+ playerID = crossPlayer.GetPlayerID()
+ familyID = crossPlayer.GetFamilyID()
+ if familyID <= 0:
+ return
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ family = familyMgr.FindFamily(familyID)
+ if not family:
+ return
+ curMember = family.FindMember(playerID)
+ if not curMember:
+ return
+
+ if curMember.GetFmLV() != IPY_PlayerDefine.fmlLeader:
+ GameWorld.DebugLog("非盟主不可改名!", playerID)
+ return
+
+ curTime = int(time.time())
+ cdHours = IpyGameDataPY.GetFuncCfg("FamilyRename", 2)
+ if cdHours:
+ cdSeconds = cdHours * 3600
+ lastRenameTime = GetRenameTime(family)
+ if lastRenameTime and (curTime - lastRenameTime) < cdSeconds:
+ GameWorld.DebugLog("公会改名CD中! lastRenameTime=%s,cdHours=%s" % (GameWorld.ChangeTimeNumToStr(lastRenameTime), cdHours))
+ return
+
+ # 验证重名
+ if CheckFamilyNameExists(crossPlayer, newName, fromServerID):
+ return
+
+ moneyType, moneyValue = IpyGameDataPY.GetFuncEvalCfg("FamilyRename", 1)
+ if moneyType and moneyValue:
+ CrossPlayer.CostPlayerResources(crossPlayer, "FamilyRename", costMoneyDict={moneyType:moneyValue})
+
+ family.SetName(newName)
+ if cdHours:
+ SetRenameTime(family, curTime)
+
+ crossPlayerMgr = CrossPlayer.GetCrossPlayerMgr()
+ for index in xrange(family.GetCount()):
+ member = family.GetAt(index)
+ memID = member.GetPlayerID()
+ memCrossPlayer = crossPlayerMgr.FindCrossPlayer(memID)
+ if not memCrossPlayer:
+ continue
+ MapServer_FamilyRefresh(memCrossPlayer, familyID) # 改名
+ #player.Notify_FamilyNameRefresh() #//04 36 周围玩家家族名刷新#tagPlayerFamilyNameRefresh
+
+ Broadcast_FamilyInfo(familyID, isSyncMem=False) # 改名
+ return True
+
+#// A6 19 查看目标公会 #tagCSViewTagFamily
+#
+#struct tagCSViewTagFamily
+#{
+# tagHead Head;
+# DWORD FamilyID;
+# DWORD DataServerID; //数据所在服务器ID
+#};
+def OnViewTagFamily(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ playerID = curPlayer.GetPlayerID()
+ tagFamilyID = clientData.FamilyID
+ dataServerID = clientData.DataServerID
+
+ # 本服或主服是本服
+ if not dataServerID or dataServerID == GameWorld.GetGameWorld().GetServerID():
+ NetPackCommon.SendFakePack(curPlayer, GetTagFamilyInfoPack(tagFamilyID))
+ return
+
+ CrossMsg.SendToServer(ShareDefine.S2S_ViewTagFamily, {"tagFamilyID":tagFamilyID}, [dataServerID], ShareDefine.dirType_All, playerID)
+ return
+
+def S2S_ViewTagFamily(dataMsg, fromServerID, playerID):
+ tagFamilyID = dataMsg["tagFamilyID"]
+ CrossPlayer.SendFakePackByID(playerID, GetTagFamilyInfoPack(tagFamilyID), fromServerID)
+ return
+
+def GetTagFamilyInfoPack(tagFamilyID):
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ family = familyMgr.FindFamily(tagFamilyID)
+ if not family:
+ GameWorld.ErrLog("本服数据找不到目标公会! tagFamilyID=%s" % tagFamilyID)
+ return
+ clientPack = ChPyNetSendPack.tagSCTagFamilyInfo()
+ clientPack.FamilyID = family.GetID()
+ clientPack.FamilyName = family.GetName()
+ clientPack.FamilyNameLen = len(clientPack.FamilyName)
+ clientPack.LeaderID = family.GetLeaderID()
+ leaderMember = family.FindMember(clientPack.LeaderID)
+ if leaderMember:
+ clientPack.LeaderName = leaderMember.GetPlayerName()
+ clientPack.LeaderNameLen = len(clientPack.LeaderName)
+ clientPack.LeaderServerID = leaderMember.GetServerID()
+ clientPack.FamilyLV = family.GetLV()
+ clientPack.ServerID = family.GetServerID()
+ clientPack.EmblemID = family.GetEmblemID()
+ clientPack.EmblemWord = family.GetEmblemWord()
+ clientPack.FightPower = family.GetFightPower()
+ clientPack.FightPowerEx = family.GetFightPowerEx()
+ clientPack.Broadcast = family.GetBroadcast()
+ clientPack.BroadcastLen = len(clientPack.Broadcast)
+ clientPack.MemberCount = family.GetCount()
+ clientPack.DataServerID = GameWorld.GetGameWorld().GetServerID()
+ return clientPack
+
+#// A6 20 搜索家族列表 #tagCMViewFamilyPage
+#
+#struct tagCMViewFamilyPage
+#{
+# tagHead Head;
+# BYTE MsgLen; //模糊搜索家族,如果输入为空,则为不限制该条件
+# char Msg[MsgLen]; //size = MsgLen
+# BYTE PageIndex; //查询第X页索引,0~n
+# BYTE ShowCount; //每页数量,前端可自行指定,最大50
+#};
+def OnViewFamilyPage(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ FamilyPyPackForwarding(curPlayer, clientData, tick, "__OnViewFamilyPage")
+ return
+
+def __OnViewFamilyPage(crossPlayer, clientData, tick, fromServerID=0, reqDataEx=None):
+ msg = clientData.Msg
+ pageIndex = clientData.PageIndex
+ showCount = min(clientData.ShowCount, 50)
+
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ zoneID = familyMgr.GetZoneIDInThisServer(fromServerID)
+ if zoneID < 0:
+ GameWorld.ErrLog("找不到服务器ID在本服中的公会分区! fromServerID=%s" % fromServerID)
+ return
+
+ playerFamilyID = crossPlayer.GetFamilyID()
+ zoneMgr = familyMgr.GetZoneFamilyMgr(zoneID)
+ zoneMgr.Sort(True)
+ familyCount = zoneMgr.GetCount()
+
+ totalPage = 0
+
+ if not msg:
+ startIndex = pageIndex * showCount
+ endIndex = startIndex + showCount - 1
+ if familyCount > 0:
+ totalPage = GameWorld.GetIntUpper(familyCount, showCount)
+
+ # 有指定搜索内容的后端固定返回单页
+ else:
+ pageIndex = 0
+ showCount = 20
+ totalPage = 1
+ startIndex = 0
+ endIndex = familyCount - 1
+
+ clientPack = ChPyNetSendPack.tagMCFamilyViewList()
+ clientPack.Msg = msg
+ clientPack.MsgLen = len(clientPack.Msg)
+ clientPack.PageIndex = pageIndex
+ clientPack.ShowCount = showCount
+ clientPack.TotalPage = totalPage
+ clientPack.Rank = zoneMgr.GetFamilyRank(playerFamilyID)
+ clientPack.FamilyList = []
+ for index in range(startIndex, endIndex + 1):
+ if index >= familyCount:
+ break
+ family = zoneMgr.GetAt(index)
+ if not family:
+ continue
+ if msg:
+ if msg in family.GetName() or msg == str(family.GetID()):
+ pass
+ else:
+ continue
+ familyView = ChPyNetSendPack.tagMCFamilyView()
+ familyView.Rank = index + 1
+ familyView.FamilyID = family.GetID()
+ familyView.FamilyName = family.GetName()
+ familyView.FamilyNameLen = len(familyView.FamilyName)
+ familyView.LeaderID = family.GetLeaderID()
+ leaderMember = family.FindMember(familyView.LeaderID)
+ familyView.LeaderName = leaderMember.GetPlayerName() if leaderMember else ""
+ familyView.LeaderNameLen = len(familyView.LeaderName)
+ familyView.LeaderServerID = leaderMember.GetServerID() if leaderMember else family.GetServerID()
+ familyView.FamilyLV = family.GetLV()
+ familyView.JoinReview = family.GetJoinReview()
+ familyView.JoinLVMin = family.GetJoinLVMin()
+ familyView.ServerID = family.GetServerID()
+ familyView.EmblemID = family.GetEmblemID()
+ familyView.EmblemWord = family.GetEmblemWord()
+ familyView.FightPower = family.GetFightPower()
+ familyView.FightPowerEx = family.GetFightPowerEx()
+ familyView.MemberCount = family.GetCount()
+ clientPack.FamilyList.append(familyView)
+ clientPack.FamilyCount = len(clientPack.FamilyList)
+ if clientPack.FamilyCount >= showCount:
+ break
+ CrossPlayer.SendFakePack(crossPlayer, clientPack)
+ return
+
+
+#// A6 12 家族捐献货币 #tagCMFamilyMoneyDonate
+#
+#struct tagCMFamilyMoneyDonate
+#{
+# tagHead Head;
+# BYTE DonateType; // 捐献类型
+#};
+def OnFamilyMoneyDonate(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ playerID = curPlayer.GetPlayerID()
+ donateType = clientData.DonateType
+
+ ipyData = IpyGameDataPY.GetIpyGameData("FamilyDonate", donateType)
+ if not ipyData:
+ return
+ dailyCntMax = ipyData.GetDailyCnt()
+ donateCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FamilyDonateCnt % donateType)
+ if donateCnt >= dailyCntMax:
+ GameWorld.DebugLog("今日捐献次数已达上限! donateType=%s,donateCnt=%s >= %s" % (donateType, donateCnt, dailyCntMax), playerID)
+ return
+
+ moneyType = ipyData.GetMoneyType()
+ moneyValue = ipyData.GetMoneyValue()
+ if not moneyType or not moneyValue:
+ return
+ if not PlayerControl.HaveMoney(curPlayer, moneyType, moneyValue):
+ return
+
+ reqDataEx = {"donateCnt":donateCnt}
+ FamilyPyPackForwarding(curPlayer, clientData, tick, "__OnFamilyMoneyDonate", True, 20, reqDataEx=reqDataEx)
+ return
+
+def __OnFamilyMoneyDonate(crossPlayer, clientData, tick, fromServerID=0, reqDataEx=None):
+ donateType = clientData.DonateType
+ playerID = crossPlayer.GetPlayerID()
+ familyID = crossPlayer.GetFamilyID()
+ if familyID <= 0:
+ return
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ curFamily = familyMgr.FindFamily(familyID)
+ if not curFamily:
+ return
+ curMember = curFamily.FindMember(playerID)
+ if not curMember:
+ return
+
+ if not reqDataEx:
+ return
+
+ if "donateCnt" not in reqDataEx:
+ return
+ donateCnt = reqDataEx["donateCnt"]
+
+ ipyData = IpyGameDataPY.GetIpyGameData("FamilyDonate", donateType)
+ if not ipyData:
+ return
+
+ moneyType = ipyData.GetMoneyType()
+ moneyValue = ipyData.GetMoneyValue()
+ if not moneyType or not moneyValue:
+ return
+
+ CrossPlayer.CostPlayerResources(crossPlayer, "FamilyMoneyDonate", costMoneyDict={moneyType:moneyValue})
+
+ awardItemList = ipyData.GetAwardItemList()
+ donateCnt += 1
+ CrossPlayer.SetPlayerNomalDict(crossPlayer, {ChConfig.Def_Player_Dict_FamilyDonateCnt % donateType:donateCnt}, isDayReset=True)
+ #SyncDonateCntInfo(curPlayer)
+ # 增加成员捐献次数记录
+ memDonateCntDay = curMember.GetDonateCntDay() + 1
+ memDonateCntTotal = min(curMember.GetDonateCntTotal() + 1, ChConfig.Def_UpperLimit_DWord)
+ curMember.SetDonateCntDay(memDonateCntDay)
+ curMember.SetDonateCntTotal(memDonateCntTotal)
+ GameWorld.DebugLog("家族捐献: donateType=%s,donateCnt=%s,%s,memDonateCntDay=%s,memDonateCntDay=%s"
+ % (donateType, donateCnt, awardItemList, memDonateCntDay, memDonateCntTotal), playerID)
+ CrossPlayer.GivePlayerResources(crossPlayer, awardItemList, eventName="FamilyMoneyDonate")
+ return True
+
+def __OnFamilyMoneyDonate_Ret(curPlayer, clientData, isOK):
+ if not isOK:
+ return
+ SyncDonateCntInfo(curPlayer)
+ return
+
+def AddFamilyExp(curPlayer, addExp):
+ ## 增加玩家家族经验
+ clientData, tick = None, 0
+ reqDataEx = {"addExp":addExp}
+ FamilyPyPackForwarding(curPlayer, clientData, tick, "__AddFamilyExp", reqCD=0, reqDataEx=reqDataEx)
+ return
+def __AddFamilyExp(crossPlayer, clientData, tick, fromServerID=0, reqDataEx=None):
+ playerID = crossPlayer.GetPlayerID()
+ familyID = crossPlayer.GetFamilyID()
+ if familyID <= 0:
+ return
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ curFamily = familyMgr.FindFamily(familyID)
+ if not curFamily:
+ return
+ curLV = curFamily.GetLV()
+ curExp = curFamily.GetExp()
+
+ if not reqDataEx:
+ return
+ addExp = reqDataEx["addExp"]
+
+ updLV = curLV
+ updExp = curExp + addExp
+ GameWorld.DebugLog("增加公会经验: curLV=%s,curExp=%s,addExp=%s,updExp=%s" % (curLV, curExp, addExp, updExp), playerID)
+
+ ipyData = IpyGameDataPY.GetIpyGameData("Family", curLV)
+ lvUPExp = ipyData.GetNeedExp()
+ while lvUPExp and updExp >= lvUPExp:
+ ipyData = IpyGameDataPY.GetIpyGameDataNotLog("Family", updLV + 1)
+ if not ipyData:
+ break
+ updLV += 1
+ updExp -= lvUPExp
+ lvUPExp = ipyData.GetNeedExp()
+ GameWorld.DebugLog(" 公会升级: updLV=%s,updExp=%s,lvUPExp=%s" % (updLV, updExp, lvUPExp), playerID)
+
+ curFamily.SetLV(updLV)
+ curFamily.SetExp(updExp)
+
+ Broadcast_FamilyInfo(familyID, isSyncMem=False) # 公会经验
+ return True
+
+def AddFamilyContrib(curPlayer, addContribValue):
+ ## 增加玩家累计家族贡献
+ clientData, tick = None, 0
+ reqDataEx = {"addContribValue":addContribValue}
+ FamilyPyPackForwarding(curPlayer, clientData, tick, "__AddFamilyContrib", reqCD=0, reqDataEx=reqDataEx)
+ return
+def __AddFamilyContrib(crossPlayer, clientData, tick, fromServerID=0, reqDataEx=None):
+ playerID = crossPlayer.GetPlayerID()
+ familyID = crossPlayer.GetFamilyID()
+ if familyID <= 0:
+ return
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ curFamily = familyMgr.FindFamily(familyID)
+ if not curFamily:
+ return
+ curMember = curFamily.FindMember(playerID)
+ if not curMember:
+ return
+
+ if not reqDataEx:
+ return
+ addContribValue = reqDataEx["addContribValue"]
+
+ contribDay = curMember.GetContribDay() + addContribValue
+ contribTotal = min(curMember.GetContribTotal() + addContribValue, ChConfig.Def_UpperLimit_DWord)
+ curMember.SetContribDay(contribDay)
+ curMember.SetContribTotal(contribTotal)
+ GameWorld.DebugLog("增加成员贡献: familyID=%s,addContribValue=%s,contribDay=%s,contribTotal=%s" % (familyID, addContribValue, contribDay, contribTotal), playerID)
+
+ Broadcast_FamilyInfo(familyID, isSyncMem=False) # 成员贡献
+ return
+
+## ------------------------------------------------------------------------------------------------
+
+#// A6 17 查询家族行为信息 #tagCMQueryFamilyAction
+#
+#struct tagCMQueryFamilyAction
+#{
+# tagHead Head;
+# BYTE ActionType; // 行为类型
+# DWORD FamilyID; // 家族ID,发0默认自己家族
+#};
+def OnQueryFamilyAction(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ FamilyPyPackForwarding(curPlayer, clientData, tick, "__OnQueryFamilyAction")
+ return
+
+def __OnQueryFamilyAction(crossPlayer, clientData, tick, fromServerID=0, reqDataEx=None):
+ actionType = clientData.ActionType
+ familyID = clientData.FamilyID
+ if not familyID:
+ familyID = crossPlayer.GetFamilyID()
+ SendFamilyActionInfo(crossPlayer, familyID, actionType)
+ return
+
+def SendFamilyActionInfo(crossPlayer, familyID, actionType):
+ ## 发送家族行为
+ # @param crossPlayer: 为None时通知该公会所有成员
+ if not familyID:
+ return
+ familyAction = DBDataMgr.GetFamilyActionMgr().GetFamilyAction(familyID, actionType)
+
+ clientPack = ChPyNetSendPack.tagMCFamilyActionInfo()
+ clientPack.FamilyID = familyID
+ clientPack.ActionType = actionType
+ clientPack.FamilyActionList = []
+
+ for index in xrange(familyAction.Count()):
+ familyActionData = familyAction.At(index)
+
+ actionData = ChPyNetSendPack.tagMCFamilyAction()
+ actionData.Time = familyActionData.GetTime()
+ actionData.Name = familyActionData.GetName()
+ actionData.NameLen = len(actionData.Name)
+ actionData.Value1 = familyActionData.GetValue1()
+ actionData.Value2 = familyActionData.GetValue2()
+ actionData.Value3 = familyActionData.GetValue3()
+ actionData.Value4 = familyActionData.GetValue4()
+ actionData.Value5 = familyActionData.GetValue5()
+ actionData.Value6 = familyActionData.GetValue6()
+ actionData.UseData = familyActionData.GetUserData()
+ actionData.UseDataLen = len(actionData.UseData)
+ clientPack.FamilyActionList.append(actionData)
+
+ clientPack.Count = len(clientPack.FamilyActionList)
+
+ if crossPlayer:
+ CrossPlayer.SendFakePack(crossPlayer, clientPack)
+ return
+ CrossPlayer.SendFakePackByFamily(familyID, clientPack)
+ return
+
+def SendFamilyAction(actionDataList, crossPlayer=None):
+ ## 同步指定公会action
+ # @param actionDataList: 支持列表或指定actionData
+ # @param crossPlayer: 为None时通知该公会所有成员
+ if not isinstance(actionDataList, list):
+ actionDataList = [actionDataList]
+ if not actionDataList:
+ return
+ familyActionData = actionDataList[0]
+ familyID = familyActionData.GetFamilyID()
+ actionType = familyActionData.GetActionType()
+
+ clientPack = ChPyNetSendPack.tagMCFamilyActionInfo()
+ clientPack.FamilyID = familyID
+ clientPack.ActionType = actionType
+ clientPack.FamilyActionList = []
+ for familyActionData in actionDataList:
+ actionData = ChPyNetSendPack.tagMCFamilyAction()
+ actionData.Time = familyActionData.GetTime()
+ actionData.Name = familyActionData.GetName()
+ actionData.NameLen = len(actionData.Name)
+ actionData.Value1 = familyActionData.GetValue1()
+ actionData.Value2 = familyActionData.GetValue2()
+ actionData.Value3 = familyActionData.GetValue3()
+ actionData.Value4 = familyActionData.GetValue4()
+ actionData.Value5 = familyActionData.GetValue5()
+ actionData.Value6 = familyActionData.GetValue6()
+ actionData.UseData = familyActionData.GetUserData()
+ actionData.UseDataLen = len(actionData.UseData)
+ clientPack.FamilyActionList.append(actionData)
+ clientPack.Count = len(clientPack.FamilyActionList)
+
+ if crossPlayer:
+ CrossPlayer.SendFakePack(crossPlayer, clientPack)
+ return
+ CrossPlayer.SendFakePackByFamily(familyID, clientPack)
+ return
+
+def OnFamilyTalk(curPlayer, familyID, talkPack, tick):
+ clientData, tick = None, 0
+ reqDataEx = {"talkBuffer":talkPack.GetBuffer()}
+ FamilyPyPackForwarding(curPlayer, clientData, tick, "__OnFamilyTalk", reqDataEx=reqDataEx)
+ return
+def __OnFamilyTalk(crossPlayer, clientData, tick, fromServerID=0, reqDataEx=None):
+ talkBuffer = reqDataEx["talkBuffer"]
+ playerID = crossPlayer.GetPlayerID()
+ familyID = crossPlayer.GetFamilyID()
+ if not familyID or not talkBuffer:
+ return
+ clientPack = ChPyNetSendPack.tagMCTalk()
+ clientPack.ReadData(talkBuffer)
+
+ CrossPlayer.SendFakePackByFamily(familyID, clientPack)
+
+ # 聊天缓存
+ channelType = clientPack.ChannelType
+ content = clientPack.Content
+ bubbleBox = clientPack.BubbleBox
+ PlayerTalk.DoTalkCache(channelType, playerID, content, bubbleBox, familyID)
+ return
+
+def OnCrossFamilyTalk(curPlayer, talkPack, tick):
+ ## 跨服公会聊天,与跨服公会互通范围一致
+ crossServerID = DBDataMgr.GetFamilyMgr().GetCurCrossServerID()
+ if crossServerID <= 0:
+ GameWorld.DebugLog("本服公会未互通,不允许跨服聊天")
+ return
+ clientData, tick = None, 0
+ reqDataEx = {"talkBuffer":talkPack.GetBuffer()}
+ FamilyPyPackForwarding(curPlayer, clientData, tick, "__OnCrossTalk", reqDataEx=reqDataEx)
+ return
+def __OnCrossTalk(crossPlayer, clientData, tick, fromServerID=0, reqDataEx=None):
+ talkBuffer = reqDataEx["talkBuffer"]
+ playerID = crossPlayer.GetPlayerID()
+
+ if not talkBuffer:
+ return
+
+ familyMgr = DBDataMgr.GetFamilyMgr()
+ zoneID = familyMgr.GetZoneIDInThisServer(fromServerID)
+ if zoneID < 0:
+ GameWorld.ErrLog("找不到服务器ID在跨服中的公会分区! fromServerID=%s" % fromServerID)
+ return
+ zoneMgr = familyMgr.GetZoneFamilyMgr(zoneID)
+ serverIDList = zoneMgr.GetZoneServerIDList()
+ if not serverIDList:
+ return
+
+ clientPack = ChPyNetSendPack.tagMCTalk()
+ clientPack.ReadData(talkBuffer)
+ CrossPlayer.SendFackPackToServerList(clientPack, serverIDList)
+
+ # 聊天缓存
+ channelType = clientPack.ChannelType
+ content = clientPack.Content
+ bubbleBox = clientPack.BubbleBox
+ PlayerTalk.DoTalkCache(channelType, playerID, content, bubbleBox)
+ return
+
+## -------------------------------------- 游戏服本服处理 --------------------------------------------
+'''
+为方便本服、跨服互通公会逻辑统一,公会相关数据处理统一使用 CrossPlayer,视为以前的GameServer处理,这样本服跨服的公会管理通用
+本服的curPlayer仅处理以前类似MapServer的curPlayer相关逻辑
+【注】 MapServer的逻辑不能再直接获取 family 实例进行逻辑处理,只能处理 curPlayer 可用的逻辑
+'''
+
+def C2S_FamilyMapPlayer(dataMsg, playerID):
+ curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
+ if not curPlayer:
+ return
+ doType = dataMsg["doType"]
+ doData = dataMsg["doData"]
+ if doType == "FamilyRefresh":
+ Do_MapServer_FamilyRefresh(curPlayer, doData)
+ return
+
+def Do_MapServer_FamilyRefresh(curPlayer, doData):
tick = GameWorld.GetGameWorld().GetTick()
playerID = curPlayer.GetPlayerID()
- refreshFmLV = 0
- refreshFamilyLV = 0
- refreshFamilyName = ""
- if refreshFamilyID:
- familyMgr = DBDataMgr.GetFamilyMgr()
- curFamily = familyMgr.FindFamily(refreshFamilyID)
- if curFamily:
- refreshFamilyLV = curFamily.GetLV()
- refreshFamilyName = curFamily.GetName()
- member = curFamily.FindMember(playerID)
- if member:
- refreshFmLV = member.GetFmLV()
- else:
- refreshFamilyID = 0
-
+ refreshFamilyID = doData["FamilyID"]
+ refreshFmLV = doData.get("FmLV", 0)
+ refreshJoinTime = doData.get("JoinTime", 0)
+ refreshFamilyLV = doData.get("FamilyLV", 0)
+ refreshFamilyName = doData.get("FamilyName", "")
+ refreshEmblemID = doData.get("EmblemID", 0)
+ refreshEmblemWord = doData.get("EmblemWord", "")
+ isLogin = doData.get("isLogin", 0) # 是否登录刷新的
+
+ PlayerViewCache.UpdPlayerViewFamilyInfo(playerID, refreshFamilyID, refreshFamilyName, refreshEmblemID, refreshEmblemWord)
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FamilyJoinTime, refreshJoinTime)
+
lastFamilyID = curPlayer.GetFamilyID()
- lastFamilyLV = curPlayer.GetFamilyLV() # 仙盟等级,非职位等级
+ lastFamilyLV = curPlayer.GetFamilyLV() # 公会等级,非职位等级
lastFmLV = PlayerControl.GetFamilyMemberLV(curPlayer)
if lastFamilyID != refreshFamilyID:
@@ -427,7 +2124,7 @@
if curPlayer.GetFamilyName() != refreshFamilyName:
curPlayer.SetFamilyName(refreshFamilyName)
- curPlayer.Notify_FamilyNameRefresh() #//04 36 周围玩家家族名刷新#tagPlayerFamilyNameRefresh
+ #curPlayer.Notify_FamilyNameRefresh() #//04 36 周围玩家家族名刷新#tagPlayerFamilyNameRefresh
if lastFmLV != refreshFmLV:
PlayerControl.SetFamilyMemberLV(curPlayer, refreshFmLV)
@@ -445,6 +2142,7 @@
if lastFamilyID != 0 and curPlayer.GetFamilyID() == 0:
#玩家离开家族
+ isVoluntarily = doData.get("isVoluntarily", 0)
__OnLeaveFamily(curPlayer, isVoluntarily, tick)
elif lastFamilyID == 0 and curPlayer.GetFamilyID() != 0:
@@ -457,14 +2155,22 @@
#---通知客户端刷新属性---
curPlayer.View_FamilyInfoRefresh() #//04 30 玩家家族名字职位等信息刷新#tagPlayerInFamilyInfoRefresh
+
+ if isLogin:
+ Do_MapServer_PlayerLogin(curPlayer)
+ return
+
+def Do_MapServer_PlayerLogin(curPlayer):
+ ## 地图公会玩家的登录逻辑由最新所属公会刷新后处理
+ DBFamily.Sync_FamilyCrossInfo(curPlayer)
+ SyncDonateCntInfo(curPlayer)
+ PlayerFamilyZhenbaoge.OnPlayerLogin(curPlayer)
+ PlayerFamilyTaofa.OnPlayerLogin(curPlayer)
return
def __OnEnterFamily(curPlayer, tick):
## 进入家族触发事件
- familyMgr = DBDataMgr.GetFamilyMgr()
- familyMgr.DelPlayerReqJoinFamilyIDAll(curPlayer.GetPlayerID())
- Sync_RequestAddFamilyInfo(curPlayer)
- PlayerFamilyTaofa.OnPlayerEnterFamily(curPlayer)
+ PlayerTask.UpdTaskValue(curPlayer, ChConfig.TaskType_ReqOrJoinFamily)
return
def __OnLeaveFamily(curPlayer, isVoluntarily, tick):
@@ -504,1002 +2210,6 @@
FBLogic.OnLeaveFamily(curPlayer, tick)
return
-def GetFamilyMemberHasPow(member, powerID):
- ## 仙盟成员是否有该权限
- powerDict = IpyGameDataPY.GetFuncEvalCfg("FamilyPower", 1, {})
- if str(powerID) not in powerDict:
- return False
- needMemberLV = powerDict[str(powerID)]
- return member.GetFmLV() >= needMemberLV
-
-def Sync_FamilyInfo(curPlayer, infoPack=None):
- ## // A5 20 玩家家族信息 #tagMCRoleFamilyInfo
- familyID = curPlayer.GetFamilyID()
- if not familyID:
- return
- if not infoPack:
- infoPack = GetPack_FamilyInfo(familyID)
- NetPackCommon.SendFakePack(curPlayer, infoPack)
- return
-
-def GetPack_FamilyInfo(familyID):
- familyMgr = DBDataMgr.GetFamilyMgr()
- curFamily = familyMgr.FindFamily(familyID)
- if not curFamily:
- return
-
- clientPack = ChPyNetSendPack.tagMCRoleFamilyInfo()
- clientPack.FamilyID = familyID
- clientPack.FamilyName = curFamily.GetName()
- clientPack.FamilyLV = curFamily.GetLV()
- clientPack.FamilyLVExp = curFamily.GetExp()
- clientPack.JoinReview = curFamily.GetJoinReview()
- clientPack.JoinLVMin = curFamily.GetJoinLVMin()
- clientPack.ServerID = curFamily.GetServerID()
- clientPack.EmblemID = curFamily.GetEmblemID()
- clientPack.EmblemWord = curFamily.GetEmblemWord()
- clientPack.FightPower = curFamily.GetFightPower()
- clientPack.FightPowerEx = curFamily.GetFightPowerEx()
- clientPack.Broadcast = curFamily.GetBroadcast()
- clientPack.BroadcastLen = len(clientPack.Broadcast)
- clientPack.LeaderID = curFamily.GetLeaderID()
- clientPack.MemberList = []
- for index in xrange(curFamily.GetCount()):
- member = curFamily.GetAt(index)
- memInfo = ChPyNetSendPack.tagMCRoleFamilyMember()
- memInfo.PlayerID = member.GetPlayerID()
- memInfo.JoinTime = member.GetJoinTime()
- memInfo.Name = member.GetPlayerName()
- memInfo.NameLen = len(memInfo.Name)
- memInfo.LV = member.GetLV()
- memInfo.Job = member.GetJob()
- memInfo.RealmLV = member.GetRealmLV()
- memInfo.Face = member.GetFace()
- memInfo.FacePic = member.GetFacePic()
- memInfo.TitleID = member.GetTitleID()
- memInfo.FightPower = member.GetFightPower()
- memInfo.FightPowerEx = member.GetFightPowerEx()
- memInfo.FmLV = member.GetFmLV()
- memInfo.ServerID = member.GetServerID()
- memInfo.ContribTotal = member.GetContribTotal()
- memInfo.ContribDay = member.GetContribDay()
- memInfo.DonateCntTotal = member.GetDonateCntTotal()
- memInfo.DonateCntDay = member.GetDonateCntDay()
- memInfo.OffTime = member.GetOffTime()
- clientPack.MemberList.append(memInfo)
- clientPack.MemberCount = len(clientPack.MemberList)
- return clientPack
-
-def Broadcast_FamilyChange(familyID, changeType=FamilyChangeType_None, powerID=None, excludeIDList=None):
- ## // A5 21 家族变更 #tagMCFamilyChange
- # @param excludeIDList: 不广播的成员ID列表
- clientPack = ChPyNetSendPack.tagMCFamilyChange()
- clientPack.Type = changeType
- Broadcast_FamilyPack(familyID, clientPack, powerID, excludeIDList)
- return
-
-def Broadcast_FamilyPack(familyID, clientPack, powerID=None, excludeIDList=None):
- ## 广播家族成员封包
- # @param powerID: 可指定只发给有该权限的成员
- # @param excludeIDList: 不广播的成员ID列表
- if not clientPack:
- return
- familyMgr = DBDataMgr.GetFamilyMgr()
- curFamily = familyMgr.FindFamily(familyID)
- if not curFamily:
- return
- playerManager = GameWorld.GetPlayerManager()
- for index in xrange(curFamily.GetCount()):
- member = curFamily.GetAt(index)
- playerID = member.GetPlayerID()
- if excludeIDList and playerID in excludeIDList:
- continue
-
- curPlayer = playerManager.FindPlayerByID(playerID)
- if not curPlayer:
- continue
-
- if powerID != None and not GetFamilyMemberHasPow(member, powerID):
- continue
-
- NetPackCommon.SendFakePack(curPlayer, clientPack)
- return
-
-def NotifyAllFamilyMemberMsg(familyID, code, paramList=[], excludeIDList=None):
- ## 通知所有家族成员信息
- # @param excludeIDList: 不通知的成员ID列表
- familyMgr = DBDataMgr.GetFamilyMgr()
- curFamily = familyMgr.FindFamily(familyID)
- if not curFamily:
- return
- playerManager = GameWorld.GetPlayerManager()
- for i in xrange(curFamily.GetCount()):
- member = curFamily.GetAt(i)
- playerID = member.GetPlayerID()
- if excludeIDList and playerID in excludeIDList:
- continue
- curPlayer = playerManager.FindPlayerByID(playerID)
- if not curPlayer:
- continue
- PlayerControl.NotifyCode(curPlayer, code, paramList)
- return
-
-#// A6 01 向玩家申请加入家族 #tagCMRequestJoinFamilyByPlayer
-#
-#struct tagCMRequestJoinFamilyByPlayer
-#{
-# tagHead Head;
-# DWORD TagPlayerID; //目标家族玩家ID
-#};
-def OnRequestJoinFamilyByPlayer(index, clientData, tick):
- curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
- tagPlayerID = clientData.TagPlayerID
- tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(tagPlayerID)
- if not tagPlayer:
- GameWorld.DebugLog("对方不在线! tagPlayerID=%s" % tagPlayerID)
- return
- tagFamilyID = tagPlayer.GetFamilyID()
- if tagFamilyID <= 0:
- GameWorld.DebugLog("对方没有家族! tagPlayerID=%s" % tagPlayerID)
- return
- RequestJoinTagFamily(curPlayer, tagFamilyID)
- return
-
-#// A6 02 申请加入家族#tagCMRequesJoinFamily
-#
-#struct tagCMRequesJoinFamily
-#{
-# tagHead Head;
-# BYTE Type; //申请类型,0-申请;1-撤销
-# DWORD TagFamilyID; //目标家族ID,申请时为0代表一键申请家族任意家族
-#};
-def OnRequesJoinFamily(index, clientData, tick):
- curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
-
- tagFamilyID = clientData.TagFamilyID # 申请进入的家族ID
- requestType = clientData.Type # 申请类型(申请/撤销)
-
- # 申请加入
- if requestType == 0:
- if not tagFamilyID:
- AutoJoinFamily(curPlayer)
- else:
- RequestJoinTagFamily(curPlayer, tagFamilyID)
-
- # 撤销申请
- elif requestType == 1:
- CancelJoinTagFamily(curPlayer, tagFamilyID)
-
- return
-
-def CheckInJoinCD(curPlayer):
- ## 检查是否加入仙盟CD中
- leaveFamilyTime = PlayerControl.GetLeaveFamilyTimeEx(curPlayer)
- if not leaveFamilyTime:
- return False
-
- leaveCnt, kickedCnt, lastVoluntarily = PlayerControl.GetLeaveFamilyInfo(curPlayer)
- joinCDMinute = 0
- if lastVoluntarily:
- if leaveCnt <= 0:
- return False
- joinCDMinuteList = IpyGameDataPY.GetFuncEvalCfg("FamilyLeave", 1)
- if joinCDMinuteList:
- joinCDMinute = joinCDMinuteList[leaveCnt - 1] if len(joinCDMinuteList) >= leaveCnt else joinCDMinuteList[-1]
- else:
- if kickedCnt <= 0:
- return False
- joinCDMinuteList = IpyGameDataPY.GetFuncEvalCfg("FamilyLeave", 2)
- if joinCDMinuteList:
- joinCDMinute = joinCDMinuteList[kickedCnt - 1] if len(joinCDMinuteList) >= kickedCnt else joinCDMinuteList[-1]
- if joinCDMinute:
- cdTimes = joinCDMinute * 60
- passTimes = int(time.time()) - leaveFamilyTime
- if passTimes < cdTimes:
- GameWorld.DebugLog("加入仙盟CD中: leaveCnt=%s,kickedCnt=%s,lastVoluntarily=%s,leaveFamilyTime=%s(%s),passTimes=%s < %s"
- % (leaveCnt, kickedCnt, lastVoluntarily, leaveFamilyTime, GameWorld.ChangeTimeNumToStr(leaveFamilyTime), passTimes, cdTimes))
- return True
- return False
-
-def AutoJoinFamily(curPlayer):
- if curPlayer.GetFamilyID():
- return
- playerID = curPlayer.GetPlayerID()
- realmLV = curPlayer.GetOfficialRank()
- GameWorld.DebugLog("玩家一键自动加入家族! realmLV=%s" % realmLV, playerID)
- if CheckInJoinCD(curPlayer):
- return
-
- familyMgr = DBDataMgr.GetFamilyMgr()
- indexList = range(familyMgr.GetCount())
- random.shuffle(indexList) #打乱顺序
- for index in indexList:
- family = familyMgr.GetAt(index)
- if not family:
- continue
- #familyID = family.GetID()
- lvMin = family.GetJoinLVMin()
- if lvMin and realmLV < lvMin:
- #GameWorld.DebugLog(" 官职不足的不处理! familyID=%s,lvMin=%s" % (familyID, lvMin), playerID)
- continue
- if family.GetJoinReview():
- #GameWorld.DebugLog(" 需要审核的不处理! familyID=%s" % familyID, playerID)
- continue
- MemberMax = GetFamilySetting(family.GetLV(), "MemberMax")
- if family.GetCount() >= MemberMax:
- #GameWorld.DebugLog(" 成员已满的不处理! familyID=%s" % familyID, playerID)
- continue
-
- #直接加入
- DoPlayerJionFamily(family, playerID, curPlayer)
- return
-
- # 可再扩展自动请求,暂时不处理
- GameWorld.DebugLog("没有可自动进入的仙盟!")
- PlayerControl.NotifyCode(curPlayer, "QuickEnterFamilyFail")
- return
-
-def GetFamilySetting(familyLV, fieldName):
- ## 获取仙盟等级表对应字段值
- if not fieldName:
- return 0
- ipyData = IpyGameDataPY.GetIpyGameData("Family", familyLV)
- if not ipyData:
- return 0
- attrName = "Get%s" % fieldName
- if not hasattr(ipyData, attrName):
- return 0
- return getattr(ipyData, attrName)()
-
-def RequestJoinTagFamily(curPlayer, familyID):
- ## 申请加入
- if CheckInJoinCD(curPlayer):
- return
- playerID = curPlayer.GetPlayerID()
- if curPlayer.GetFamilyID():
- GameWorld.DebugLog('已经有仙盟不能再申请加入! familyID=%s' % curPlayer.GetFamilyID(), playerID)
- return
- familyMgr = DBDataMgr.GetFamilyMgr()
- reqFamilyIDList = familyMgr.GetPlayerReqJoinFamilyIDList(playerID)
- if playerID in reqFamilyIDList:
- GameWorld.DebugLog('已经在申请加入仙盟列表中! familyID=%s' % familyID, playerID)
- return
-
- maxReqFamilyCnt = IpyGameDataPY.GetFuncCfg("FamilyReqJoin", 2)
- if len(reqFamilyIDList) >= maxReqFamilyCnt:
- GameWorld.DebugLog('已经达到最大申请加入仙盟数! %s, %s' % (len(reqFamilyIDList), reqFamilyIDList), playerID)
- return
-
- tagFamily = familyMgr.FindFamily(familyID)
- if not tagFamily:
- return
-
- lvMin = tagFamily.GetJoinLVMin()
- if curPlayer.GetOfficialRank() < lvMin:
- GameWorld.DebugLog('官职未达到该仙盟加入最低限制! realmLV=%s < %s' % (curPlayer.GetOfficialRank(), lvMin), playerID)
- return
-
- # 需要审核,满员后端不限制申请,由前端自行决定是否可申请
- if tagFamily.GetJoinReview():
- reqPlayerIDDict = tagFamily.GetReqJoinPlayerInfo()
- if playerID not in reqPlayerIDDict:
- maxReqPlayerCnt = IpyGameDataPY.GetFuncCfg("FamilyReqJoin", 1)
- if len(reqPlayerIDDict) >= maxReqPlayerCnt:
- GameWorld.DebugLog('目标仙盟申请加入数已满! %s, %s' % (len(reqFamilyIDList), reqFamilyIDList), playerID)
- PlayerControl.NotifyCode(curPlayer, "jiazu_pan_141056")
- return
-
- tagFamily.AddReqJoinPlayerID(playerID)
- # 广播给有招人权限的
- Broadcast_FamilyPack(familyID, GetPack_FamilyReqJoinInfo(familyID), FamilyPowerID_Call)
-
- #jiazu_pan_500807:申请入帮成功!请等待帮会管理人员审批!
- PlayerControl.NotifyCode(curPlayer, "jiazu_pan_500807")
- Sync_RequestAddFamilyInfo(curPlayer)
- return
-
- # 不需要审核,自动加入
- memberMax = GetFamilySetting(tagFamily.GetLV(), "MemberMax")
- if tagFamily.GetCount() >= memberMax:
- GameWorld.DebugLog('目标仙盟成员已满! familyLV=%s,memberMax=%s' % (tagFamily.GetLV(), memberMax), playerID)
- return
-
- DoPlayerJionFamily(tagFamily, playerID, curPlayer)
- return
-
-def CancelJoinTagFamily(curPlayer, familyID):
- # 撤销申请
- familyMgr = DBDataMgr.GetFamilyMgr()
- playerID = curPlayer.GetPlayerID()
- tagFamily = familyMgr.FindFamily(familyID)
- if tagFamily:
- tagFamily.DelReqJoinPlayerID(playerID)
- familyMgr.DelPlayerReqJoinFamilyID(playerID, familyID)
- Broadcast_FamilyPack(familyID, GetPack_FamilyReqJoinInfo(familyID), FamilyPowerID_Call)
- Sync_RequestAddFamilyInfo(curPlayer)
- return
-
-def Sync_RequestAddFamilyInfo(curPlayer, isForce=True):
- ## 通知当前申请加入的哪些家族
- playerID = curPlayer.GetPlayerID()
- familyMgr = DBDataMgr.GetFamilyMgr()
- reqFamilyIDList = familyMgr.GetPlayerReqJoinFamilyIDList(playerID)
- # 非强制通知时没有申请记录的可不通知,如登录
- if not isForce and not reqFamilyIDList:
- return
- clientPack = ChPyNetSendPack.tagMCNotifyRequestJoinFamilyInfo()
- clientPack.Clear()
- clientPack.RequestJoinFamilyIDList = reqFamilyIDList
- clientPack.RequestCount = len(clientPack.RequestJoinFamilyIDList)
- NetPackCommon.SendFakePack(curPlayer, clientPack)
- return
-
-def GetPack_FamilyReqJoinInfo(familyID):
- ## 获取 // A5 22 家族申请加入的玩家信息 #tagMCFamilyReqJoinInfo
- familyMgr = DBDataMgr.GetFamilyMgr()
- curFamily = familyMgr.FindFamily(familyID)
- if not curFamily:
- return
- reqPlayerIDDict = curFamily.GetReqJoinPlayerInfo()
-
- playerManager = GameWorld.GetPlayerManager()
- clientPack = ChPyNetSendPack.tagMCFamilyReqJoinInfo()
- clientPack.ReqJoinList = []
- for playerID, reqTime in reqPlayerIDDict.items():
- curPlayer = playerManager.FindPlayerByID(playerID)
- reqInfo = ChPyNetSendPack.tagMCFamilyReqJoinPlayer()
- reqInfo.PlayerID = playerID
- reqInfo.ReqTime = reqTime
- if curPlayer:
- reqInfo.IsOnLine = True
- viewCache = PlayerViewCache.FindViewCache(playerID)
- if viewCache:
- reqInfo.Name = viewCache.GetPlayerName()
- reqInfo.NameLen = len(reqInfo.Name)
- reqInfo.LV = viewCache.GetLV()
- reqInfo.Job = viewCache.GetJob()
- reqInfo.RealmLV = viewCache.GetRealmLV()
- reqInfo.Face = viewCache.GetFace()
- reqInfo.FacePic = viewCache.GetFacePic()
- reqInfo.TitleID = viewCache.GetTitleID()
- reqInfo.FightPower = viewCache.GetFightPower()
- reqInfo.FightPowerEx = viewCache.GetFightPowerEx()
- reqInfo.ServerID = viewCache.GetServerID()
- clientPack.ReqJoinList.append(reqInfo)
- if len(clientPack.ReqJoinList) >= 100:
- break
- clientPack.ReqCnt = len(clientPack.ReqJoinList)
- return clientPack
-
-#// A6 21 审核请求加入家族 #tagCMJoinFamilyReply
-#
-#struct tagCMJoinFamilyReply
-#{
-# tagHead Head;
-# DWORD TagPlayerID; //被审核玩家ID 0则代表全部
-# BYTE IsOK; //是否同意其加入
-#};
-def OnJoinFamilyReply(index, clientData, tick):
- curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
- tagPlayerID = clientData.TagPlayerID
- isOK = clientData.IsOK
- playerID = curPlayer.GetPlayerID()
- familyID = curPlayer.GetFamilyID()
- if familyID <= 0:
- return
- familyMgr = DBDataMgr.GetFamilyMgr()
- family = familyMgr.FindFamily(familyID)
- if not family:
- return
- curMember = family.FindMember(playerID)
- if not curMember:
- return
- if not GetFamilyMemberHasPow(curMember, FamilyPowerID_Call):
- #GameWorld.DebugLog("没有招人权限,无法审核人员入盟!", playerID)
- PlayerControl.NotifyCode(curPlayer, "XW_JZ_InviteErr_Popedom")
- return
-
- GameWorld.DebugLog("审核入盟申请: tagPlayerID=%s,familyID=%s,isOK=%s" % (tagPlayerID, familyID, isOK), playerID)
- reqPlayerIDDict = family.GetReqJoinPlayerInfo()
- tagPlayerIDList = reqPlayerIDDict.keys()
- if tagPlayerID:
- if tagPlayerID not in reqPlayerIDDict:
- GameWorld.DebugLog("不存在该申请人员! tagPlayerID=%s" % tagPlayerID)
- return
- tagPlayerIDList = [tagPlayerID]
-
- if not tagPlayerIDList:
- GameWorld.DebugLog("没有申请人员!")
- return
-
- playerManager = GameWorld.GetPlayerManager()
- # 拒绝
- if not isOK:
- for tagPlayerID in tagPlayerIDList:
- family.DelReqJoinPlayerID(tagPlayerID)
- tagPlayer = playerManager.FindPlayerByID(tagPlayerID)
- if not tagPlayer:
- continue
- Sync_RequestAddFamilyInfo(tagPlayer)
- #jiazu_pan_592934:{%S}拒绝了您的入帮申请
- PlayerControl.NotifyCode(tagPlayer, "jiazu_pan_592934", [family.GetName()])
- Broadcast_FamilyPack(familyID, GetPack_FamilyReqJoinInfo(familyID), FamilyPowerID_Call)
- return
-
- # 处理同意
- offlinePlayerCanJoin = IpyGameDataPY.GetFuncCfg("FamilyReqJoin", 3)
- MemberMax = GetFamilySetting(family.GetLV(), "MemberMax")
- joinOKPlayerIDList = []
- for tagPlayerID in tagPlayerIDList:
- if family.GetCount() >= MemberMax:
- PlayerControl.NotifyCode(curPlayer, "jiazu_lhs_202580")
- break
- tagPlayer = playerManager.FindPlayerByID(tagPlayerID)
- #申请目标不在线
- if not tagPlayer:
- if not offlinePlayerCanJoin:
- GameWorld.DebugLog("离线玩家无法加入仙盟! tagPlayerID=%s" % tagPlayerID, playerID)
- PlayerControl.NotifyCode(curPlayer, "jiazu_hwj35_367906")
- continue
-
- if family.FindMember(tagPlayerID):
- GameWorld.DebugLog("已经是本盟成员! tagPlayerID=%s" % tagPlayerID, playerID)
- PlayerControl.NotifyCode(curPlayer, "XW_JZ_InviteErr_Repeat")
- continue
-
- tagFamilyID = familyMgr.GetPlayerFamilyID(tagPlayerID)
- if tagFamilyID:
- GameWorld.DebugLog("已经加入其他仙盟! tagPlayerID=%s,tagFamilyID=%s" % (tagPlayerID, tagFamilyID), playerID)
- PlayerControl.NotifyCode(curPlayer, "XW_JZ_InviteErr_Repeat")
- continue
-
- DoPlayerJionFamily(family, tagPlayerID, tagPlayer, broadcastFamilyChange=False)
- joinOKPlayerIDList.append(tagPlayerID)
-
- if not joinOKPlayerIDList:
- return
- Broadcast_FamilyChange(familyID, FamilyChangeType_MemJoin, excludeIDList=joinOKPlayerIDList)
- Broadcast_FamilyPack(familyID, GetPack_FamilyReqJoinInfo(familyID), FamilyPowerID_Call)
- return
-
-#// A6 22 修改收人方式 #tagCMChangeFamilyJoin
-#
-#struct tagCMChangeFamilyJoin
-#{
-# tagHead Head;
-# BYTE JoinReview; //成员加入是否需要审核,默认0自动加入
-# WORD JoinLVMin; //限制最低可加入的玩家等级
-#};
-def OnChangeFamilyJoin(index, clientData, tick):
- curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
- joinReview = clientData.JoinReview
- joinLVMin = clientData.JoinLVMin # 官职
-
- playerID = curPlayer.GetPlayerID()
- familyID = curPlayer.GetFamilyID()
- if familyID <= 0:
- return
- familyMgr = DBDataMgr.GetFamilyMgr()
- family = familyMgr.FindFamily(familyID)
- if not family:
- return
- curMember = family.FindMember(playerID)
- if not curMember:
- return
- if not GetFamilyMemberHasPow(curMember, FamilyPowerID_Call):
- GameWorld.DebugLog("没有招人权限", playerID)
- return
- GameWorld.DebugLog("修改招人设置: familyID=%s,joinReview=%s,joinLVMin=%s" % (familyID, joinReview, joinLVMin), playerID)
- family.SetJoinReview(joinReview)
- family.SetJoinLVMin(joinLVMin)
- Sync_FamilyInfo(curPlayer)
- Broadcast_FamilyChange(familyID, FamilyChangeType_JoinSet, FamilyPowerID_Call, excludeIDList=[playerID])
- return
-
-#// A6 23 修改家族公告 #tagCMChangeFamilyBroadcast
-#
-#struct tagCMChangeFamilyBroadcast
-#{
-# tagHead Head;
-# char Msg[200];
-#};
-def OnChangeFamilyBroadcast(index, clientData, tick):
- curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
- broadcast = clientData.Msg
-
- playerID = curPlayer.GetPlayerID()
- familyID = curPlayer.GetFamilyID()
- if familyID <= 0:
- return
- familyMgr = DBDataMgr.GetFamilyMgr()
- family = familyMgr.FindFamily(familyID)
- if not family:
- return
- curMember = family.FindMember(playerID)
- if not curMember:
- return
- if not GetFamilyMemberHasPow(curMember, FamilyPowerID_Broadcast):
- GameWorld.DebugLog("没有修改公告权限", playerID)
- return
- family.SetBroadcast(broadcast)
- GameWorld.DebugLog('更改仙盟公告: Family=%s,公告=%s' % (GameWorld.CodeToGbk(family.GetName()), GameWorld.CodeToGbk(broadcast)), playerID)
- Sync_FamilyInfo(curPlayer)
- Broadcast_FamilyChange(familyID, FamilyChangeType_Broadcast, excludeIDList=[playerID])
- return
-
-#// A6 24 修改家族徽章 #tagCMChangeFamilyEmblem
-#
-#struct tagCMChangeFamilyEmblem
-#{
-# tagHead Head;
-# BYTE EmblemID; // 更换的徽章ID
-# char EmblemWord[3]; // 徽章文字
-#};
-def OnChangeFamilyEmblem(index, clientData, tick):
- curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
- changeEmblemID = clientData.EmblemID
- emblemWord = clientData.EmblemWord
- PlayerFamilyEmblem.OnChangeFamilyEmblem(curPlayer, changeEmblemID, emblemWord)
- return
-
-#// A6 25 修改家族成员职位 #tagCMChangeFamilyMemLV
-#
-#struct tagCMChangeFamilyMemLV
-#{
-# tagHead Head;
-# DWORD PlayerID; // 目标成员ID
-# BYTE FmLV; // 变更为xx职位
-#};
-def OnChangeFamilyMemLV(index, clientData, tick):
- curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
- OnChangeFamilyMemberLV(curPlayer, clientData.PlayerID, clientData.FmLV)
- return
-
-def OnChangeFamilyMemberLV(curPlayer, tagID, changeFmlv, isGMOP=False):
- '''变更成员职位
- @param curPlayer: 操作的玩家
- @param tagID: 目标成员ID
- @param changeFmlv: 修改为xx职位
- @param isGMOP: 是否是GM后台发起的,如果是GM发起的,一般curPlayer传入的为目标成员ID实例
- '''
- if not curPlayer:
- return
- playerID = curPlayer.GetPlayerID()
- familyID = curPlayer.GetFamilyID()
- if familyID <= 0:
- return
- familyMgr = DBDataMgr.GetFamilyMgr()
- family = familyMgr.FindFamily(familyID)
- if not family:
- return
- curMember = family.FindMember(playerID)
- if not curMember:
- return
- if changeFmlv < 0 or changeFmlv > IPY_PlayerDefine.fmlLeader:
- GameWorld.DebugLog("不存在该职位等级! changeFmlv=%s" % changeFmlv)
- return
- # 非GM操作的需检查权限
- if not isGMOP:
- if not GetFamilyMemberHasPow(curMember, FamilyPowerID_ChangeFmlv):
- return
- if playerID == tagID:
- GameWorld.DebugLog("不能任免自己的家族职位", playerID)
- return
-
- tagMember = family.FindMember(tagID)
- if tagMember == None:
- GameWorld.DebugLog("更改家族成员职位时目标成员不存在! tagID=%s" % tagID, playerID)
- return
-
- if not isGMOP:
- if curMember.GetFmLV() != IPY_PlayerDefine.fmlLeader:
- if changeFmlv >= curMember.GetFmLV():
- GameWorld.DebugLog("修改的职位不能比自己高或平级! changeFmlv=%s" % changeFmlv, playerID)
- return
- if tagMember.GetFmLV() >= curMember.GetFmLV():
- GameWorld.DebugLog("修改的目标成员职位不能比自己高或平级! tagFmlv=%s" % tagMember.GetFmLV(), playerID)
- return
-
- if changeFmlv == IPY_PlayerDefine.fmlLeader:
- changeType = FamilyChangeType_LeaderChange
- ChangeFamilyLeader(family, tagMember)
-
- else:
- fmLVMemCnt = 0
- for index in range(family.GetCount()):
- familyMember = family.GetAt(index)
- if familyMember.GetFmLV() != changeFmlv:
- continue
- fmLVMemCnt += 1
-
- maxCnt = GetFamilySetting(family.GetLV(), Def_FmlSetAttrName.get(changeFmlv, ""))
- if fmLVMemCnt >= maxCnt:
- # jiazu_hwj35_272921 改为 jiazu_chenxin_31379
- PlayerControl.NotifyCode(curPlayer, "jiazu_chenxin_31379")
- GameWorld.DebugLog("目前该职位的人数已经达到上限! changeFmlv=%s,fmLVMemCnt=%s >= %s" % (changeFmlv, fmLVMemCnt, maxCnt))
- return
- changeType = FamilyChangeType_MemFmlvChange
- ChangeFamilyMemberLv(tagMember, changeFmlv)
-
- if isGMOP:
- family.SetBroadcast("")
- Sync_FamilyInfo(curPlayer)
- Broadcast_FamilyChange(familyID, changeType, excludeIDList=[playerID, tagID])
- return True
-
-def ChangeFamilyLeader(family, newLeaderMem):
- ## 变更家族族长
-
- familyID = family.GetID()
- befLeaderID = family.GetLeaderID()
- newLeaderID = newLeaderMem.GetPlayerID()
- if befLeaderID == newLeaderID:
- return
-
- befLeaderMem = family.FindMember(befLeaderID)
- if befLeaderMem:
- #把原族长降为普通成员
- ChangeFamilyMemberLv(befLeaderMem, IPY_PlayerDefine.fmlMember)
-
- family.SetLeaderID(newLeaderID)
- ChangeFamilyMemberLv(newLeaderMem, IPY_PlayerDefine.fmlLeader)
- GameWorld.Log("家族设置新族长! familyID=%s,newLeaderID=%s,befLeaderID=%s" % (familyID, newLeaderID, befLeaderID))
- return
-
-def ChangeFamilyMemberLv(tagMember, changeFamilyLV):
- ## 修改成员职位,只做修改逻辑,不做验证,验证由各调用入口自行验证
- familyID = tagMember.GetFamilyID()
- tagID = tagMember.GetPlayerID()
- memName = tagMember.GetPlayerName()
- befFamilyLV = tagMember.GetFmLV()
-
- tagMember.SetFmLV(changeFamilyLV)
-
- tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(tagID)
- if tagPlayer:
- MapServer_FamilyRefresh(tagPlayer, familyID)
- Sync_FamilyInfo(tagPlayer)
- if GetFamilyMemberHasPow(tagMember, FamilyPowerID_Call):
- NetPackCommon.SendFakePack(tagPlayer, GetPack_FamilyReqJoinInfo(familyID))
-
- # 记录家族事件记录信息
- tick = GameWorld.GetGameWorld().GetTick()
- AddFamilyActionNote(memName, familyID, ShareDefine.Def_ActionType_FamilyEvent,
- [ShareDefine.Def_FamilyActionEvent_MemberChange, ShareDefine.Def_FamilyMemberChange_FMLV, changeFamilyLV, befFamilyLV], tick)
-
- #xx被任命为xx
- NotifyAllFamilyMemberMsg(familyID, "XW_JZ_AppointFamily", [memName, changeFamilyLV])
- #GetFamilyMgr().SetSyncCrossFamilyUpd(familyMember.GetFamilyID(), familyMember.GetPlayerID(), syncNow=True) # 成员职位变更
- return
-
-#// A6 26 请求家族成员列表 #tagCMGetFamilyInfo
-#
-#struct tagCMGetFamilyInfo
-#{
-# tagHead Head;
-#};
-def OnGetFamilyInfo(index, clientData, tick):
- curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
- Sync_FamilyInfo(curPlayer)
- return
-
-#// A6 03 离开家族 #tagCMLeaveFamily
-#
-#struct tagCMLeaveFamily
-#{
-# tagHead Head;
-#};
-def OnLeaveFamily(index, clientData, tick):
- curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
-
- playerID = curPlayer.GetPlayerID()
- familyID = curPlayer.GetFamilyID()
- if familyID <= 0:
- return
- familyMgr = DBDataMgr.GetFamilyMgr()
- family = familyMgr.FindFamily(familyID)
- if not family:
- return
- curMember = family.FindMember(playerID)
- if not curMember:
- return
-
- familyLV = curMember.GetFmLV() # 职位
- if family.GetCount() > 1 and familyLV == IPY_PlayerDefine.fmlLeader:
- GameWorld.DebugLog("族长在成员人数大于1时不能直接退出家族", playerID)
- return
-
- # 功能限制退出仙盟
- # ...
-
- # 进出时间限制暂不做,等正式功能再补
- #PlayerControl.SetLeaveFamilyTime(curPlayer, updTime)
-
- # 执行退出
- GameWorld.DebugLog("离开家族! familyID=%s" % familyID, playerID)
-
- family.DeleteMember(playerID)
- AddFamilyActionNote(curPlayer.GetName(), familyID, ShareDefine.Def_ActionType_FamilyEvent,
- [ShareDefine.Def_FamilyActionEvent_MemberChange, ShareDefine.Def_FamilyMemberChange_Leave], tick)
-
- #XW_JZ_LeaveFamily <n color="0,190,255">{%S1%}</n><n color="255,255,0">退出了家族!</n> 25 - -
- NotifyAllFamilyMemberMsg(familyID, "XW_JZ_LeaveFamily", [curPlayer.GetName()])
-
- __DoPlayerLeaveFamilyByID(family, playerID, curPlayer)
- MapServer_FamilyRefresh(curPlayer, 0, 1)
-
- if family.GetCount() == 0:
- #玩家离开后, 家族没有人了 , 删除这个家族
- familyMgr.DelFamily(familyID)
- return
- Broadcast_FamilyChange(familyID, FamilyChangeType_MemLeave)
- return
-
-#// A6 05 删除家族成员 #tagCMDeleteFamilyMember
-#
-#struct tagCMDeleteFamilyMember
-#{
-# tagHead Head;
-# DWORD MemberID;
-#};
-def OnDeleteFamilyMember(index, clientData, tick):
- curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
- tagMemberID = clientData.MemberID
-
- playerID = curPlayer.GetPlayerID()
- if playerID == tagMemberID:
- return
-
- familyID = curPlayer.GetFamilyID()
- if familyID <= 0:
- return
- familyMgr = DBDataMgr.GetFamilyMgr()
- family = familyMgr.FindFamily(familyID)
- if not family:
- return
- curMember = family.FindMember(playerID)
- if not curMember:
- return
-
- if not GetFamilyMemberHasPow(curMember, FamilyPowerID_Kick):
- GameWorld.DebugLog("没有踢人权限!")
- return
-
- tagMember = family.FindMember(tagMemberID)
- if not tagMember:
- return
-
- curFmlv = curMember.GetFmLV()
- tagFmlv = tagMember.GetFmLV()
- if tagFmlv >= curFmlv:
- GameWorld.DebugLog("只能踢比自己职位低的成员! tagMemberID=%s,tagFmlv(%s) >= curFmlv(%s)" % (tagMemberID, tagFmlv, curFmlv), playerID)
- return
-
- # 功能限制踢人
- # ...
-
- tagPlayerName = tagMember.GetPlayerName() # 被踢玩家名
- tagPlayerID = tagMember.GetPlayerID() # 被踢玩家ID
-
- family.DeleteMember(tagPlayerID)
-
- AddFamilyActionNote(tagPlayerName, familyID, ShareDefine.Def_ActionType_FamilyEvent,
- [ShareDefine.Def_FamilyActionEvent_MemberChange, ShareDefine.Def_FamilyMemberChange_KickOut], tick)
-
- #XW_JZ_LeaveFamily <n color="0,190,255">{%S1%}</n><n color="255,255,0">退出了家族!</n> 25 - -
- NotifyAllFamilyMemberMsg(familyID, "XW_JZ_LeaveFamily", [tagPlayerName])
-
- #删除玩家
- tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(tagMemberID)
- __DoPlayerLeaveFamilyByID(family, tagPlayerID, tagPlayer)
- if tagPlayer:
- MapServer_FamilyRefresh(tagPlayer, 0)
-
- Broadcast_FamilyChange(familyID, FamilyChangeType_MemLeave)
- return
-
-def __DoPlayerLeaveFamilyByID(curFamily, leavePlayerID, tagPlayer=None):
- ## 有玩家离开家族处理,主要针对家族层级的,玩家个人的在 __OnLeaveFamily 处理
- PlayerFamilyTaofa.OnFamilyMemberLeave(curFamily, leavePlayerID, tagPlayer)
- return
-
-#// A6 11 家族改名 #tagCMRenameFamily
-#
-#struct tagCMRenameFamily
-#{
-# tagHead Head;
-# BYTE NewNameLen;
-# char NewName[NewNameLen];
-# BYTE ItemIndex; //改名物品在背包中的位置
-#};
-def UpdateFamilyName(index, clientData, tick):
- curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
- newName = clientData.NewName
- #itemIndex = clientData.ItemIndex
-
- playerID = curPlayer.GetPlayerID()
- familyID = curPlayer.GetFamilyID()
- if familyID <= 0:
- return
- familyMgr = DBDataMgr.GetFamilyMgr()
- family = familyMgr.FindFamily(familyID)
- if not family:
- return
- curMember = family.FindMember(playerID)
- if not curMember:
- return
-
- if curMember.GetFmLV() != IPY_PlayerDefine.fmlLeader:
- GameWorld.DebugLog("非盟主不可改名!", playerID)
- return
-
- cdHours = IpyGameDataPY.GetFuncCfg("FamilyRename", 2)
- if cdHours:
- cdSeconds = cdHours * 3600
- curTime = int(time.time())
- dataAction = GetFamilyDataAction(familyID)
- lastRenameTime = GetRenameTime(dataAction)
- if lastRenameTime and (curTime - lastRenameTime) < cdSeconds:
- GameWorld.DebugLog("仙盟改名CD中! lastRenameTime=%s,cdHours=%s" % (GameWorld.ChangeTimeNumToStr(lastRenameTime), cdHours))
- return
-
- familyName = CheckInputFamilyName(curPlayer, newName)
- if not familyName:
- return
-
- moneyType, moneyValue = IpyGameDataPY.GetFuncEvalCfg("FamilyRename", 1)
- if moneyType and moneyValue and not PlayerControl.PayMoney(curPlayer, moneyType, moneyValue, "FamilyRename"):
- return
-
- family.SetName(familyName)
-
- infoPack = GetPack_FamilyInfo(familyID)
- playerManager = GameWorld.GetPlayerManager()
- for index in xrange(family.GetCount()):
- member = family.GetAt(index)
- memID = member.GetPlayerID()
- player = playerManager.FindPlayerByID(memID)
- if not player:
- continue
- Sync_FamilyInfo(player, infoPack)
- player.SetFamilyName(familyName)
- #player.Notify_FamilyNameRefresh() #//04 36 周围玩家家族名刷新#tagPlayerFamilyNameRefresh
-
- if cdHours:
- SetRenameTime(dataAction, curTime)
- SendFamilyActionInfo(None, familyID, ShareDefine.Def_ActionType_FamilyData)
- return
-
-#// A6 20 搜索家族列表 #tagCMViewFamilyPage
-#
-#struct tagCMViewFamilyPage
-#{
-# tagHead Head;
-# BYTE MsgLen; //模糊搜索家族,如果输入为空,则为不限制该条件
-# char Msg[MsgLen]; //size = MsgLen
-# BYTE PageIndex; //查询第X页索引,0~n
-# BYTE ShowCount; //每页数量,前端可自行指定,最大50
-#};
-def OnViewFamilyPage(index, clientData, tick):
- curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
- msg = clientData.Msg
- pageIndex = clientData.PageIndex
- showCount = min(clientData.ShowCount, 50)
-
- familyMgr = DBDataMgr.GetFamilyMgr()
- familyCount = familyMgr.GetCount()
- totalPage = 0
-
- if not msg:
- startIndex = pageIndex * showCount
- endIndex = startIndex + showCount - 1
- if familyCount > 0:
- totalPage = GameWorld.GetIntUpper(familyCount, showCount)
-
- # 有指定搜索内容的后端固定返回单页
- else:
- pageIndex = 0
- showCount = 20
- totalPage = 1
- startIndex = 0
- endIndex = familyCount - 1
-
- clientPack = ChPyNetSendPack.tagMCFamilyViewList()
- clientPack.Msg = msg
- clientPack.MsgLen = len(clientPack.Msg)
- clientPack.PageIndex = pageIndex
- clientPack.ShowCount = showCount
- clientPack.TotalPage = totalPage
- clientPack.FamilyList = []
- for index in range(startIndex, endIndex + 1):
- if index >= familyCount:
- break
- family = familyMgr.GetAt(index)
- if not family:
- continue
- if msg:
- if msg in family.GetName() or msg == str(family.GetID()):
- pass
- else:
- continue
- familyView = ChPyNetSendPack.tagMCFamilyView()
- familyView.Rank = index + 1
- familyView.FamilyID = family.GetID()
- familyView.FamilyName = family.GetName()
- familyView.FamilyNameLen = len(familyView.FamilyName)
- familyView.LeaderID = family.GetLeaderID()
- leaderMember = family.FindMember(familyView.LeaderID)
- familyView.LeaderName = leaderMember.GetPlayerName() if leaderMember else ""
- familyView.LeaderNameLen = len(familyView.LeaderName)
- familyView.FamilyLV = family.GetLV()
- familyView.JoinReview = family.GetJoinReview()
- familyView.JoinLVMin = family.GetJoinLVMin()
- familyView.ServerID = family.GetServerID()
- familyView.EmblemID = family.GetEmblemID()
- familyView.EmblemWord = family.GetEmblemWord()
- familyView.FightPower = family.GetFightPower()
- familyView.FightPowerEx = family.GetFightPowerEx()
- familyView.MemberCount = family.GetCount()
- clientPack.FamilyList.append(familyView)
- clientPack.FamilyCount = len(clientPack.FamilyList)
- if clientPack.FamilyCount >= showCount:
- break
- NetPackCommon.SendFakePack(curPlayer, clientPack)
- return
-
-
-#// A6 12 家族捐献货币 #tagCMFamilyMoneyDonate
-#
-#struct tagCMFamilyMoneyDonate
-#{
-# tagHead Head;
-# BYTE DonateType; // 捐献类型
-#};
-def OnFamilyMoneyDonate(index, clientData, tick):
- curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
- donateType = clientData.DonateType
- playerID = curPlayer.GetPlayerID()
- familyID = curPlayer.GetFamilyID()
- if familyID <= 0:
- return
- familyMgr = DBDataMgr.GetFamilyMgr()
- curFamily = familyMgr.FindFamily(familyID)
- if not curFamily:
- return
- curMember = curFamily.FindMember(playerID)
- if not curMember:
- return
-
- ipyData = IpyGameDataPY.GetIpyGameData("FamilyDonate", donateType)
- if not ipyData:
- return
- dailyCntMax = ipyData.GetDailyCnt()
- donateCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FamilyDonateCnt % donateType)
- if donateCnt >= dailyCntMax:
- GameWorld.DebugLog("今日捐献次数已达上限! donateType=%s,donateCnt=%s >= %s" % (donateType, donateCnt, dailyCntMax), playerID)
- return
-
- moneyType = ipyData.GetMoneyType()
- moneyValue = ipyData.GetMoneyValue()
- if not moneyType or not moneyValue:
- return
- if not PlayerControl.PayMoney(curPlayer, moneyType, moneyValue, "FamilyMoneyDonate"):
- return
-
- awardItemList = ipyData.GetAwardItemList()
- donateCnt += 1
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FamilyDonateCnt % donateType, donateCnt)
- SyncDonateCntInfo(curPlayer)
- # 增加成员捐献次数记录
- memDonateCntDay = curMember.GetDonateCntDay() + 1
- memDonateCntTotal = min(curMember.GetDonateCntTotal() + 1, ChConfig.Def_UpperLimit_DWord)
- curMember.SetDonateCntDay(memDonateCntDay)
- curMember.SetDonateCntTotal(memDonateCntTotal)
- GameWorld.DebugLog("家族捐献: donateType=%s,donateCnt=%s,%s,memDonateCntDay=%s,memDonateCntDay=%s"
- % (donateType, donateCnt, awardItemList, memDonateCntDay, memDonateCntTotal), playerID)
- ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["FamilyMoneyDonate", False, {}])
- return
-
def ResetDailyDonateCnt(curPlayer):
isReset = False
ipyDataMgr = IpyGameDataPY.IPY_Data()
@@ -1524,168 +2234,8 @@
donateCntList.append(donateCnt)
if not donateCntList:
return
- clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCDonateCntInfo)
+ clientPack = ChPyNetSendPack.tagSCDonateCntInfo()
clientPack.DonateCntList = donateCntList
clientPack.Count = len(clientPack.DonateCntList)
NetPackCommon.SendFakePack(curPlayer, clientPack)
return
-
-def AddFamilyExp(curPlayer, addExp):
- ## 增加玩家家族经验
- playerID = curPlayer.GetPlayerID()
- familyID = curPlayer.GetFamilyID()
- if familyID <= 0:
- return
- familyMgr = DBDataMgr.GetFamilyMgr()
- curFamily = familyMgr.FindFamily(familyID)
- if not curFamily:
- return
- curLV = curFamily.GetLV()
- curExp = curFamily.GetExp()
-
- updLV = curLV
- updExp = curExp + addExp
- GameWorld.DebugLog("增加仙盟经验: curLV=%s,curExp=%s,addExp=%s,updExp=%s" % (curLV, curExp, addExp, updExp), playerID)
-
- ipyData = IpyGameDataPY.GetIpyGameData("Family", curLV)
- lvUPExp = ipyData.GetNeedExp()
- while lvUPExp and updExp >= lvUPExp:
- ipyData = IpyGameDataPY.GetIpyGameDataNotLog("Family", updLV + 1)
- if not ipyData:
- break
- updLV += 1
- updExp -= lvUPExp
- lvUPExp = ipyData.GetNeedExp()
- GameWorld.DebugLog(" 仙盟升级: updLV=%s,updExp=%s,lvUPExp=%s" % (updLV, updExp, lvUPExp), playerID)
-
- curFamily.SetLV(updLV)
- curFamily.SetExp(updExp)
-
- Sync_FamilyInfo(curPlayer)
- Broadcast_FamilyChange(familyID, FamilyChangeType_FamilyLVExp, excludeIDList=[playerID])
- return True
-
-def AddFamilyContrib(curPlayer, addContribValue):
- ## 增加玩家累计家族贡献
-
- playerID = curPlayer.GetPlayerID()
- familyID = curPlayer.GetFamilyID()
- if familyID <= 0:
- return
- familyMgr = DBDataMgr.GetFamilyMgr()
- curFamily = familyMgr.FindFamily(familyID)
- if not curFamily:
- return
- curMember = curFamily.FindMember(playerID)
- if not curMember:
- return
-
- contribDay = curMember.GetContribDay() + addContribValue
- contribTotal = min(curMember.GetContribTotal() + addContribValue, ChConfig.Def_UpperLimit_DWord)
- curMember.SetContribDay(contribDay)
- curMember.SetContribTotal(contribTotal)
- GameWorld.DebugLog("增加成员贡献: familyID=%s,addContribValue=%s,contribDay=%s,contribTotal=%s" % (familyID, addContribValue, contribDay, contribTotal), playerID)
-
- Sync_FamilyInfo(curPlayer)
- Broadcast_FamilyChange(familyID, FamilyChangeType_MemContrib, excludeIDList=[playerID])
- return
-
-## ------------------------------------------------------------------------------------------------
-
-#// A6 17 查询家族行为信息 #tagCMQueryFamilyAction
-#
-#struct tagCMQueryFamilyAction
-#{
-# tagHead Head;
-# BYTE ActionType; // 行为类型
-# DWORD FamilyID; // 家族ID,发0默认自己家族
-#};
-def OnQueryFamilyAction(index, cliendData, tick):
- curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
-
- if not curPlayer:
- return
-
- actionType = cliendData.ActionType
- familyID = cliendData.FamilyID
- if not familyID:
- familyID = curPlayer.GetFamilyID()
-
- SendFamilyActionInfo(curPlayer, familyID, actionType)
- return
-
-def SendFamilyActionInfo(curPlayer, familyID, actionType):
- ## 发送家族行为
- # @param curPlayer: 为None时通知该仙盟所有成员
- if not familyID:
- return
- familyAction = DBDataMgr.GetFamilyActionMgr().GetFamilyAction(familyID, actionType)
-
- clientPack = ChPyNetSendPack.tagMCFamilyActionInfo()
- clientPack.FamilyID = familyID
- clientPack.ActionType = actionType
- clientPack.FamilyActionList = []
-
- for index in xrange(familyAction.Count()):
- familyActionData = familyAction.At(index)
-
- actionData = ChPyNetSendPack.tagMCFamilyAction()
- actionData.Time = familyActionData.GetTime()
- actionData.Name = familyActionData.GetName()
- actionData.NameLen = len(actionData.Name)
- actionData.Value1 = familyActionData.GetValue1()
- actionData.Value2 = familyActionData.GetValue2()
- actionData.Value3 = familyActionData.GetValue3()
- actionData.Value4 = familyActionData.GetValue4()
- actionData.Value5 = familyActionData.GetValue5()
- actionData.Value6 = familyActionData.GetValue6()
- actionData.UseData = familyActionData.GetUserData()
- actionData.UseDataLen = len(actionData.UseData)
- clientPack.FamilyActionList.append(actionData)
-
- clientPack.Count = len(clientPack.FamilyActionList)
-
- if curPlayer:
- NetPackCommon.SendFakePack(curPlayer, clientPack)
- return
- Broadcast_FamilyPack(familyID, clientPack)
- return
-
-def SendFamilyAction(actionDataList, curPlayer=None):
- ## 同步指定仙盟action
- # @param actionDataList: 支持列表或指定actionData
- # @param curPlayer: 为None时通知该仙盟所有成员
- if not isinstance(actionDataList, list):
- actionDataList = [actionDataList]
- if not actionDataList:
- return
- familyActionData = actionDataList[0]
- familyID = familyActionData.GetFamilyID()
- actionType = familyActionData.GetActionType()
-
- clientPack = ChPyNetSendPack.tagMCFamilyActionInfo()
- clientPack.FamilyID = familyID
- clientPack.ActionType = actionType
- clientPack.FamilyActionList = []
- for familyActionData in actionDataList:
- actionData = ChPyNetSendPack.tagMCFamilyAction()
- actionData.Time = familyActionData.GetTime()
- actionData.Name = familyActionData.GetName()
- actionData.NameLen = len(actionData.Name)
- actionData.Value1 = familyActionData.GetValue1()
- actionData.Value2 = familyActionData.GetValue2()
- actionData.Value3 = familyActionData.GetValue3()
- actionData.Value4 = familyActionData.GetValue4()
- actionData.Value5 = familyActionData.GetValue5()
- actionData.Value6 = familyActionData.GetValue6()
- actionData.UseData = familyActionData.GetUserData()
- actionData.UseDataLen = len(actionData.UseData)
- clientPack.FamilyActionList.append(actionData)
- clientPack.Count = len(clientPack.FamilyActionList)
-
- if curPlayer:
- NetPackCommon.SendFakePack(curPlayer, clientPack)
- return
- Broadcast_FamilyPack(familyID, clientPack)
- return
-
--
Gitblit v1.8.0