123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705 |
- using CommonAI;
- using CommonAI.Zone.Instance;
- using CommonAI.ZoneServer.JSGModule;
- using CommonLang;
- using CommonLang.Concurrent;
- using CommonLang.Log;
- using Pomelo;
- using System;
- using System.Collections.Generic;
- using System.Configuration;
- using System.Diagnostics;
- using System.Dynamic;
- using System.Threading;
- using System.Web.Helpers;
- using XmdsCommon.Plugin;
- using XmdsCommonServer.Plugin;
- using XmdsServerNode.Node;
- using XmdsServerNode.Node.R2bNotify;
- using static CommonAI.ZoneServer.JSGModule.JSGServerProfile;
- namespace XmdsServerEdgeJS.Zone
- {
- public abstract class ZoneService : IZone
- {
- //战斗服版本号
- public static int s_bsVersion = 1;
- public static ZoneService Instance { get; private set; }
- protected ZoneService()
- {
- Instance = this;
- updatePrivateMemory(null);
- }
- //----------------------------------------------------------------------------------------------
- protected Logger log = LoggerFactory.GetLogger(typeof(ZoneService).Name);
- protected Logger monitorLog = LoggerFactory.GetLogger("monitor");
- private ZoneNodeManager zoneNodeManager;
- private BattleCodec codec;
- private AtomicLong privateMemoryMB = new AtomicLong(0);
- private Timer systemUpdateTimer;
- private Timer logUpdateTimer;
- protected XmdsServerProxy b2r_proxy = new XmdsServerProxy();
- /// <summary>
- /// 副本列表
- /// </summary>
- private HashMap<string, XmdsZoneNode> nodes = new HashMap<string, XmdsZoneNode>();
- /// <summary>
- /// 玩家列表
- /// </summary>
- private HashMap<string, XmdsPlayer> players = new HashMap<string, XmdsPlayer>();
- //----------------------------------------------------------------------------------------------
- public int PlayerCount
- {
- get
- {
- lock (players)
- {
- return players.Count;
- }
- }
- }
- public int ZoneNodeCount
- {
- get
- {
- lock (nodes)
- {
- return nodes.Count;
- }
- }
- }
- public long ProcessPrivateMemoryMB
- {
- get { return privateMemoryMB.Value; }
- }
- //----------------------------------------------------------------------------------------------
- #region Internal
- public XmdsPlayer getPlayer(string playerID)
- {
- lock (players)
- {
- return players.Get(playerID);
- }
- }
- protected XmdsZoneNode getZoneNode(string instanceID)
- {
- lock (nodes)
- {
- return nodes.Get(instanceID);//[instanceID];
- }
- }
- //internal void sendToGameServer(string name, Object param)
- //{
- // try
- // {
- // //转化为json
- // string json = Json.Encode(param);
- // IceManager.instance().eventNotify(name, json);
- // }
- // catch (Exception err)
- // {
- // log.Error(err.Message, err);
- // }
- //}
- protected void notifyBattleServer(string instanceId, R2BNotifyMessage param)
- {
- var node = getZoneNode(instanceId);
- if (node != null)
- {
- //b2r_proxy.SendToBattleServer(node.Node.Zone, param);
- param.OnHandle(node.Node.Zone);
- }
- }
- private void updatePrivateMemory(object state)
- {
- long private_memory_mb = Process.GetCurrentProcess().PrivateMemorySize64 / 1024 / 1024;
- privateMemoryMB.Value = private_memory_mb;
- }
- private void updateLog(object state)
- {
- dynamic eventStat = new ExpandoObject();
- eventStat.Type = "monitor";
- eventStat.Object = InstanceZoneObject.ActiveObjectCount + "/" + InstanceZoneObject.AllocObjectCount;
- eventStat.Zone = InstanceZone.ActiveZoneCount + "/" + InstanceZone.AllocZoneCount;
- eventStat.Node = ZoneNodeCount;
- eventStat.Player = PlayerCount;
- eventStat.Memory_MB = ProcessPrivateMemoryMB;
- eventStat.Pool = ObjectPoolStatus.TotalActive + "/" + ObjectPoolStatus.TotalCount;
- //monitorLog.Warn(eventStat);
- // 输出统计日志
- if (JSGServerProfile.CheckPrintAllData())
- {
- this.PrintAllSceneInfo();
- }
- }
- private void PrintAllSceneInfo()
- {
- lock (nodes)
- {
- foreach (var p in new List<XmdsZoneNode>(nodes.Values))
- {
- try
- {
- log.Info("场景ID:" + p.InstanceID + ", " + p.Node.GetBindGameSrvId() + ", 场景ID: " + p.Node.SceneID + ", units=" + p.Node.Zone.AllUnitsCount
- + ", spells=" + p.Node.Zone.AllSpellsCount + ", items=" + p.Node.Zone.AllItemsCount);
- }
- catch (Exception e)
- {
- log.Error("PrintAllSceneInfo: " + p.InstanceID + ", e: " + e);
- }
- }
- }
- }
- #endregion
- //----------------------------------------------------------------------------------------------
- public void Start(ZoneConfig zoneConfig)
- {
- lock (this)
- {
- try
- {
- log.Info("startPath:" + zoneConfig.startPath);
- log.Info("assetPath:" + zoneConfig.assetPath);
- JSGServerProfile.init();
- systemUpdateTimer = new Timer(updatePrivateMemory, this, 0, 10000);
- zoneNodeManager = new ZoneNodeManager();
- zoneNodeManager.Init(zoneConfig.startPath, b2r_proxy, zoneConfig.assetPath);
- codec = new BattleCodec(ZoneNodeManager.Templates.Templates);
- //日志定时器
- logUpdateTimer = new Timer(updateLog, this, 30000, 30000);
- }
- catch (Exception err)
- {
- //log.Error("初始化失败");
- //log.Error(err.Message, err);
- //Environment.Exit(0);
- throw err;
- }
- }
- }
- public void Stop()
- {
- this.ClearAllPlayers((e, c) => { });
- this.DestoryAllZones((e, c) => { });
- lock (this)
- {
- if (zoneNodeManager != null)
- {
- b2r_proxy.Dispose();
- zoneNodeManager.Shutdown();
- systemUpdateTimer.Dispose();
- logUpdateTimer.Dispose();
- zoneNodeManager = null;
- codec = null;
- }
- }
- }
- public void SetCallBack(string gameSrvId)
- {
- JSGMountainKingModule.Init(gameSrvId);
- }
- public void CreateZone(string playerId, string gameServerId, int mapTemplateId, string instanceId, bool forceCreate,
- string data, Action<int> cb, Action<Exception> err)
- {
- long lstart = TimeUtil.GetTimestampMS();
- int resCode = 0;
- if (!forceCreate && playerId != null && playerId.Length > 0)
- {
- var player = getPlayer(playerId);
- if (player != null && player.BindingActor.IsActive && player.BindingActor.Virtual.IsInPVP())
- {
- resCode = 1;
- XmdsVirtual playerVirtual = player.BindingActor.Virtual as XmdsVirtual;
- log.Warn("PVP状态下传送2:" + playerVirtual.mUnit.PlayerUUID + ", 场景ID: " + playerVirtual.mUnit.Parent.GetSceneID() + ", "
- + playerVirtual.GetHateSystem().GetHatePlayerInfo() + ", 触发PVP玩家:" + playerVirtual.mPvpTriggerPlayerId);
- }
- }
- if (resCode == 0)
- {
- long private_memory_mb = ProcessPrivateMemoryMB;
- if (private_memory_mb > ZoneNodeManager.NodeConfig.SYSTEM_MAX_HEAP_SIZE_MB)
- {
- string msg = string.Format("CreateZone failed : Private memory {0}MB out of range {1}MB", private_memory_mb, ZoneNodeManager.NodeConfig.SYSTEM_MAX_HEAP_SIZE_MB);
- log.Error(msg);
- throw new OutOfMemoryException(msg);
- }
- XmdsZoneNode node = new XmdsZoneNode(this, instanceId, gameServerId);
- node.Node.Callback = IceManager.instance().getCallback(gameServerId);
- lock (nodes)
- {
- if (nodes.ContainsKey(instanceId))
- {
- throw new Exception(string.Format("node instance id ({0}) already exist!", instanceId));
- }
- nodes.Add(node.InstanceID, node);
- }
- {
- node.Start(mapTemplateId, data, (z) =>
- {
- //监控日志
- dynamic logEvent = new ExpandoObject();
- logEvent.type = "createZone";
- logEvent.mapTemplateId = mapTemplateId;
- logEvent.instanceId = instanceId;
- monitorLog.Debug(logEvent);
- });
- }
- JSGServerProfile.RecordZoneCreate(mapTemplateId, (int)(TimeUtil.GetTimestampMS() - lstart));
- }
- else
- {
- log.Warn("玩家pvp状态创建场景:" + playerId + ", " + mapTemplateId + ", " + data);
- }
- cb(resCode);
- }
- public void DestroyZone(string instanceId, Action<Exception, object> cb)
- {
- XmdsZoneNode node;
- lock (nodes)
- {
- node = this.nodes.RemoveByKey(instanceId);
- }
- if (node != null)
- {
- //删除场景实例的所有玩家
- lock (players)
- {
- node.Node.ForEachPlayers((client) =>
- {
- var player = players.Get(client.PlayerUUID);
- if (player != null)
- {
- if (client.Node == player.Node)
- {
- players.RemoveByKey(client.PlayerUUID);
- }
- //else
- //{
- // log.Warn(client.Node + " destory zone player " + client.PlayerUUID + " in " + player.Node);
- //}
- }
- });
- }
- node.Stop((z) =>
- {
- //监控日志
- dynamic logEvent = new ExpandoObject();
- logEvent.type = "destroyZone";
- logEvent.mapTemplateId = z.Node.SceneID;
- logEvent.instanceId = instanceId;
- monitorLog.Debug(logEvent);
- });
- }
- cb(null, "done");
- }
- public void DestoryAllZones(Action<Exception, object> cb)
- {
- lock (nodes)
- {
- foreach (var p in new List<XmdsZoneNode>(nodes.Values))
- {
- try
- {
- this.DestroyZone(p.InstanceID, (e, c) => { });
- }
- catch (Exception e)
- {
- log.Error(e);
- }
- }
- }
- cb(null, "done");
- }
- public void PlayerEnter(string playerId, string instanceId, string input, Action<Exception, object> cb)
- {
- var node = getZoneNode(instanceId);
- if (node == null)
- {
- throw new InstanceNotExistException(instanceId);
- }
- long private_memory_mb = ProcessPrivateMemoryMB;
- if (private_memory_mb > ZoneNodeManager.NodeConfig.SYSTEM_MAX_HEAP_SIZE_MB)
- {
- string msg = string.Format("PlayerEnter failed : Private memory {0}MB out of range {1}MB", private_memory_mb, ZoneNodeManager.NodeConfig.SYSTEM_MAX_HEAP_SIZE_MB);
- log.Error(msg);
- throw new OutOfMemoryException(msg);
- }
- dynamic data = Json.Decode(input);
- string connectServerId = (string)data.connectServerId;
- var session = FastStream.instance().GetSessionByID(connectServerId);
- if (session == null)
- {
- throw new Exception("ConnectServerId not exist : " + connectServerId);
- }
- string uid = (string)data.uid;
- bool robot = data.robot != null ? (bool)data.robot : false;
- XmdsPlayerEnter enter = null;
- if (data["tempData"] != null)
- {
- int posX = 0;
- int posY = 0;
- float direction = 0;
- string flagName = null;
- flagName = data.tempData.flag;
- if (data.tempData["x"] != null)
- {
- posX = (int)data.tempData.x;
- }
- if (data.tempData["y"] != null)
- {
- posY = (int)data.tempData.y;
- }
- if (data.tempData["direction"] != null)
- {
- direction = (float)data.tempData.direction;
- }
- int unitTemplateID = (int)data.unitTemplateID;
- XmdsUnitProperties unitprop = new XmdsUnitProperties();
- XmdsUnitData unitData = XmdsPlayerUtil.instance().createXmdsUnitData(data, playerId);
- unitprop.ServerData = unitData;
- enter = new XmdsPlayerEnter();
- enter.Pos = new CommonLang.Vector.Vector2(posX, posY);
- enter.direction = direction;
- enter.FlagName = flagName;
- enter.UnitData = new CommonAI.ZoneServer.CreateUnitInfoR2B();
- enter.UnitData.Force = unitData.BaseInfo.force;
- enter.UnitData.alliesForce = unitData.BaseInfo.alliesForce;
- enter.UnitData.StartFlag = null;
- enter.UnitData.UnitTemplateID = unitTemplateID;
- enter.UnitData.UnitPropData = unitprop;
- foreach (dynamic obj in data.tasks)
- {
- int taskId = obj.QuestID;
- int state = obj.State;
- XmdsQuestData qData = new XmdsQuestData();
- qData.TaskID = taskId.ToString();
- qData.TaskState = state.ToString();
- foreach (dynamic attr in obj.Attributes)
- {
- qData.AddAttribute(attr.key, attr.value);
- }
- unitData.Tasks.Add(qData);
- }
- foreach (dynamic obj in data.flags)
- {
- XmdsQuestFlag flag = new XmdsQuestFlag();
- flag.FlagName = obj[0];
- flag.FlagValue = obj[1];
- unitData.QuestFlags.Add(flag);
- }
- unitData.PlayerEntered = data.playerEntered;
- }
- XmdsPlayer player = new XmdsPlayer(this, playerId, uid, session, node);
- lock (players)
- {
- if (players.ContainsKey(playerId))
- {
- this.players[playerId] = player;
- //string oldInstanceId = players.Get(playerId).InstanceId;
- //PlayerLeave(playerId, oldInstanceId, false, (err, ret) =>
- //{
- // if (err != null)
- // {
- // log.Error(err);
- // }
- //});
- }
- else
- {
- this.players.Add(playerId, player);
- }
- node.Node.OnPlayerEnter(player, enter,
- (c) =>
- {
- player.BindingActor.IsRobot = robot;
- //监控日志
- dynamic logEvent = new ExpandoObject();
- logEvent.type = "playerEnter";
- logEvent.mapTemplateId = node.Node.SceneID;
- logEvent.instanceId = instanceId;
- logEvent.playerId = playerId;
- monitorLog.Debug(logEvent);
- //cb(null, "done");
- },
- (e) =>
- {
- log.Error(e.Message, e);
- lock (this.players) { this.players.RemoveByKey(playerId); }
- //cb(e, null);
- });
- }
- cb(null, "done");
- }
- public void PlayerLeave(string playerId, string instanceId, bool keepObject, Action<Exception, object> cb)
- {
- XmdsPlayer player = null;
- try
- {
- lock (players)
- {
- player = players.Get(playerId);
- if (player != null)
- {
- if (instanceId.Equals(player.InstanceId))
- {
- this.players.RemoveByKey(playerId);
- }
- else
- {
- log.Warn(instanceId + " leave player " + player.InstanceId + player.Node);
- }
- }
- }
- var node = getZoneNode(instanceId);
- if (node == null)
- {
- //throw new InstanceNotExistException(instanceId);
- cb(null, "done");
- return;
- }
- //玩家已经离开场景
- //if (player == null)
- //{
- // throw new PlayerNotExistException(playerId);
- //}
- node.Node.OnPlayerLeave(player != null ? player.BindingActor : node.Node.GetPlayer(playerId),
- (c) =>
- {
- //监控日志
- dynamic logEvent = new ExpandoObject();
- logEvent.type = "playerLeave";
- logEvent.mapTemplateId = node.Node.SceneID;
- logEvent.playerId = playerId;
- monitorLog.Debug(logEvent);
- //cb(null, "done");
- },
- (e) =>
- {
- //cb(e, null);
- log.Error(e.Message, e);
- },
- keepObject);
- cb(null, "done");
- }
- catch (Exception e)
- {
- log.Error(e.Message, e);
- cb(e, null);
- }
- finally
- {
- if (player != null) player.Dispose();
- }
- }
- public void PlayerNetStateChanged(string playerId, string state)
- {
- var player = getPlayer(playerId);
- if (player == null)
- {
- log.Error("player not exist :" + playerId + " PlayerNetStateChanged");
- return;
- }
- var node = player.Node;
- if (node == null)
- {
- log.Error("zone node not exist :" + player.InstanceId + " PlayerNetStateChanged");
- return;
- }
- log.Debug("player:" + playerId + " PlayerNetStateChanged " + state);
- node.OnPlayerNetStateChanged(player, state);
- }
- public void PlayerReceive(string playerId, byte[] msg)
- {
- var player = getPlayer(playerId);
- if (player == null)
- {
- log.Debug("fast stream receive not exist player : " + playerId);
- return;
- }
- var node = player.Node;
- if (node == null)
- {
- log.Error("zone node not exist : " + player.InstanceId + " fast stream receive");
- return;
- }
- //log.Debug("player:" + playerId + " socket.receive");
- node.OnPlayerReceivedMessage(player, msg);
- }
- public void GetAllPlayerCount(Action<Exception, int> cb)
- {
- int count = PlayerCount;
- cb(null, count);
- }
- public void ClearAllPlayers(Action<Exception, object> cb)
- {
- try
- {
- lock (players)
- {
- foreach (var p in new List<XmdsPlayer>(players.Values))
- {
- this.PlayerLeave(p.PlayerUUID, p.InstanceId, false, (e, c) => { });
- }
- }
- cb(null, "done");
- }
- catch (Exception e)
- {
- cb(e, null);
- }
- }
- public void GetAllPlayers(Action<Exception, object> cb)
- {
- try
- {
- var ret = new List<string>();
- lock (players)
- {
- foreach (var p in new List<XmdsPlayer>(players.Values))
- {
- ret.Add(p.PlayerUUID);
- }
- }
- cb(null, ret.ToArray());
- }
- catch (Exception e)
- {
- cb(e, null);
- }
- }
- public void GetServerState(string serverID, Action<Exception, object> cb)
- {
- try
- {
- int zc = ZoneNodeCount;
- int pc = PlayerCount;
- int ActiveObjectCount = InstanceZoneObject.ActiveObjectCount;
- int AllocObjectCount = InstanceZoneObject.AllocObjectCount;
- int ActiveZoneCount = InstanceZone.ActiveZoneCount;
- int AllocZoneCount = InstanceZone.AllocZoneCount;
- float w = zc * 1000 + pc;
- int flag = IceManager.instance().getCallback(serverID) == null ? 0 : 1;
- dynamic ret = new
- {
- weight = w,
- memory = ProcessPrivateMemoryMB,
- zone_count = zc,
- player_count = pc,
- ActiveObjectCount = ActiveObjectCount,
- AllocObjectCount = AllocObjectCount,
- ActiveZoneCount = ActiveZoneCount,
- AllocZoneCount = AllocZoneCount,
- flag = flag,
- };
- cb(null, ret);
- }
- catch (Exception e)
- {
- log.Error("GetServerState failed, error: " + e.Message, e);
- cb(e, e.Message);
- }
- }
- public void RegisterGameServer(int serverId, int crossId, Action<Exception, int> cb)
- {
- try
- {
- var str = ConfigurationManager.AppSettings["game.server.id"];
- if (!string.IsNullOrEmpty(str) && int.Parse(str) != serverId && int.Parse(str) != crossId)
- {
- cb(null, -1);
- return;
- }
- }
- catch (Exception e)
- {
- cb(e, -2);
- return;
- }
- cb(null, s_bsVersion);
- }
- //获取单位血量
- public void GetUnitHP(string instanceId, int objectId, Action<Exception, int> cb)
- {
- try
- {
- var node = getZoneNode(instanceId);
- if (node == null)
- {
- cb(null, -1);
- return;
- }
- InstanceUnit unit = node.Node.Zone.getUnit((uint)objectId);
- if (unit == null)
- {
- cb(null, -2);
- return;
- }
- cb(null, unit.CurrentHP);
- }
- catch (Exception e)
- {
- cb(e, -10);
- return;
- }
- }
- //----------------------------------------------------------------------------------------------
- }
- }
|