/* Sog 游戏基础库 2016 by zouwei */ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.IO; using Sog; using ProtoCSStruct; using Sog.IO; namespace World { public class GmCmdSvc : BaseReloadableService { //不重要数据,能处理就处理,不能处理就不处理(比如停服了,reload了) //这个数据不会太多,也会很快清理,就用这个结构体先保存下 private static Dictionary needNotifyServerDealGmCmd = new Dictionary(); public override int GetServiceType() { return WorldServiceType.GmCmdSvc; } //销毁的时候清空指令注册 public override void Dispose() { GmCommandMgr.Instance.ClearAll(); } //构造的时候注册所有指令 public GmCmdSvc() { RegisterAllGmCmd(); } //有Gm指令要广播下 //做个简单排重,1秒内如果有多个同样的指令(指令名相同),则只执行一个 public static void OnNotifyWorldBroadCastGMCmd(uint remoteAppId, StructPacket packet) { ref SSNotifyWorldBroadCastGMCmd notify = ref packet.GetMessage(); // 广播发来的GM指令只接受第一个svr发来的 if (notify.UserId == 0 && ServerIDUtils.GetInstanceID(remoteAppId) != 1) { return; } notify.ServerType = ServerIDUtils.GetServerType(remoteAppId); if (needNotifyServerDealGmCmd.ContainsKey(notify.GmCmd.GetString()) == false) { needNotifyServerDealGmCmd.Add(notify.GmCmd.GetString(), notify); } } //每秒钟tick下(要不要改成5秒) public static void OnTick(long nowSec) { if (needNotifyServerDealGmCmd.Count == 0) { return; } foreach (var gmcmd in needNotifyServerDealGmCmd.Values) { SSNotifyServerDealGMCmd notify = new SSNotifyServerDealGMCmd(); notify.UserId = gmcmd.UserId; notify.GmCmd.SetString(gmcmd.GmCmd.GetString()); notify.CmdParams.SetString(gmcmd.CmdParams.GetString()); //需要广播的(到这里来又 等于0 肯定是要我广播,否则就不会进来) if (gmcmd.UserId == 0) { WorldServerUtils.GetPacketSender().Broadcast(gmcmd.ServerType, (int)SSGameMsgID.DealgmcmdNotify, ref notify, 0, 0); } else {//直接转给玩家的 PlayerInfoWorld playerInfo = WorldServerUtils.GetPlayerTableOp().GetPlayerInfo(gmcmd.UserId); if (playerInfo == null) { TraceLog.Error("GmCmdSvc.OnTick invalid userid {0} not exist or not login ", gmcmd.UserId); continue; } if (gmcmd.ServerType == (int) ServerType.Game) { WorldServerUtils.GetPacketSender().SendToServerByID(playerInfo.GameServerID, (int)SSGameMsgID.DealgmcmdNotify, ref notify, 0, 0); } else if(gmcmd.ServerType == (int) ServerType.Account) { uint accountServerID = AccountServerSelect.SelectAccountServer(playerInfo.accountInfo.AccountType, playerInfo.accountInfo.AccountID.ToString()); WorldServerUtils.GetPacketSender().SendToServerByID(accountServerID, (int)SSGameMsgID.DealgmcmdNotify, ref notify, 0, 0); }else if(gmcmd.ServerType == (int)ServerType.Chat) { WorldServerUtils.GetPacketSender().SendToChatServer((int)SSGameMsgID.DealgmcmdNotify, ref notify, 0, 0); } } } //清理下 needNotifyServerDealGmCmd.Clear(); } private void RegisterAllGmCmd() { GmCommandMgr.Instance.Register("TestGC", "TestGC", this.TestGC, GMBroadCastType.GMBroadCastType_CanNotBroad); GmCommandMgr.Instance.Register("OneServerDie", "OneServerDie [ServerID]", this.OneServerDie, GMBroadCastType.GMBroadCastType_CanNotBroad); GmCommandMgr.Instance.Register("OnlinePlayer", "log print Online player", this.OnlinePlayer); GmCommandMgr.Instance.Register("FixGrowMainlandRecordCache", "FixGrowMainlandRecordCache", this.FixGrowMainlandRecordCache); GmCommandMgr.Instance.Register("ClearPayFailInfo", "ClearPayFailInfo", this.ClearPayFailInfo); } public int ClearPayFailInfo(long arg1, string[] arg2) { var playerTable = WorldServerUtils.GetPlayerTable().m_playerTable; foreach (var playerInfo in playerTable.Values) { if (playerInfo.PayInfo.PayGoogleSuccessReqFailedCount > 0) { TraceLog.Trace("GmCmdSvc.ClearPayFailInfo uid {0} payFailNum {1}" , playerInfo.UserID, playerInfo.PayInfo.PayGoogleSuccessReqFailedCount); playerInfo.PayInfo.PayGoogleSuccessReqFailedCount = 0; } } return 0; } public int TestGC(long userid, string[] cmdParams) { var serverMode = System.Runtime.GCSettings.IsServerGC; var lMode = System.Runtime.GCSettings.LatencyMode; return 0; } //告知world某一个服务器已经挂了(由服务器管理工具发现后写gm指令通知world) public int OneServerDie(long userid, string[] cmdParams) { if (cmdParams.Length < 1) { TraceLog.Error("GmCmdSvc.OneServerDie invalid param, need serverid"); return -1; } PlayerLinkServerData.Instance.ServerIdIsDieNotRunning(ServerIDUtils.IDToNumber(cmdParams[0])); //是不是再通知下game->gate?? //断开前端所有连接这个game的连接,省得一直在那发请求(如果前端一直发请求没回应,不知道前端什么逻辑,如果前端会主动断开连接就没必要了) //之后看看效果要不要加 return 0; } public int OnlinePlayer(long userid, string[] cmdParams) { int onlineN = WorldServerUtils.GetPlayerTableOp().GetValidOnlinePlayerCount(); TraceLog.Trace("====>>>WorldServer GmCmdSvc Online Player Num {0}<<<===", onlineN); return 0; } public int FixGrowMainlandRecordCache(long userid, string[] cmdParams) { WorldBattleRecordDataCache recordData = WorldServerUtils.GetWorldMainlandRecordData(); var old = recordData.m_cacheStructBattleReplayRecording; TraceLog.Debug("GmCmdSvc.FixGrowMainlandRecordCache old {0}-{1}", old.GetTotalCount(), old.GetFreeCount()); var newCache = new StructMemoryCache(20000); for(int i=0; i< old.GetTotalCount(); i++) { ref MainlandRecordingOneCacheStruct oldOne = ref old.GetByIndex(i); if(oldOne.IsNull()) { continue; } ref MainlandRecordingOneCacheStruct newOne = ref newCache.Malloc(i); newOne.recordId = oldOne.recordId; newOne.mainlandStatistics.CopyFrom(ref oldOne.mainlandStatistics); } for (int i = 0; i < old.GetTotalCount(); i++) { newCache.m_freeQueue.Dequeue(); } TraceLog.Debug("GmCmdSvc.FixGrowMainlandRecordCache new {0}-{1}", newCache.GetTotalCount(),newCache.GetFreeCount()); recordData.m_cacheStructBattleReplayRecording = newCache; return 0; } } }