using CommonAI; using CommonAI.Zone; using CommonAI.Zone.Instance; using CommonAI.Zone.ZoneEditor; using CommonAIClient.Client; using CommonLang; using CommonLang.Concurrent; using CommonLang.Log; using CommonLang.Protocol; using CommonServer.Server; using RoomService.Net.BsServer; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using XmdsCommon.Plugin; using XmdsServerNode.Node; using XmdsServerNode.Node.Interface; namespace XmdsServerTest.Server { public class NodeTestServer { private static Logger log = LoggerFactory.GetLogger("TestNodeServer"); public static NodeTestServer Instance { get; private set; } public string ClientConnectString { get { return busAcceptor.ClientConnectString; } } public IServer B2CAcceptor { get { return busAcceptor; } } public readonly Random random = new Random(); private List<UnitInfo> test_player_templates = new List<UnitInfo>(); private IServerFactory factory; private IServer busAcceptor = null; private B2CServerListener serverListener; private AtomicInteger channel_id_gen = new AtomicInteger(0); private ZoneNodeManager node_manager = new ZoneNodeManager(); private HashMap<string, ServerZoneNode> nodes = new HashMap<string, ServerZoneNode>(); public DirectoryInfo StartupPath { get; private set; } public string Status { get; private set; } public bool Running { get; private set; } public NodeTestServer(DirectoryInfo startup_path) { Instance = this; this.StartupPath = startup_path; this.Running = false; this.Status = "New"; this.factory = new CommonServer.SSocket.SuperSocket.ServerFactory(); } public void Start(string host, int port) { try { this.serverListener = new B2CServerListener(); this.Status = "Launching"; // 初始化节点管理器 // { node_manager.Init(StartupPath.FullName, serverListener); } // 创建战斗场景 // { foreach (int scene_id in ZoneNodeManager.Templates.ListScenes()) { ZoneNodeManager.Templates.LoadScene(scene_id); } } // 扫描玩家模板 // { foreach (UnitInfo unit in ZoneNodeManager.Templates.Templates.getAllUnits()) { XmdsUnitProperties zu = unit.Properties as XmdsUnitProperties; if (zu.BotTestTemplate || unit.UType == UnitInfo.UnitType.TYPE_PLAYER) { test_player_templates.Add(unit); } } } // 创建网络 // { this.busAcceptor = factory.CreateServer(new BattleCodec(ZoneNodeManager.Templates.Templates)); CommonLang.Properties game_server_cfg = new CommonLang.Properties(); game_server_cfg["SuperSocket.HOST"] = host; game_server_cfg["SuperSocket.PORT"] = port.ToString(); game_server_cfg["SuperSocket.CLIENT_CONNECT_STRING"] = host + ":" + port; this.busAcceptor.Open(game_server_cfg, serverListener); } this.Status = "Running"; this.Running = true; } catch (Exception err) { this.Status = err.Message; Console.WriteLine(err.Message); Console.WriteLine(err.StackTrace); } } public void Shutdown() { try { this.busAcceptor.Dispose(); this.node_manager.Shutdown(); this.Status = "Closed"; this.Running = false; } catch (Exception err) { Console.WriteLine(err.Message); Console.WriteLine(err.StackTrace); } } public int ZoneNodesCount { get { return nodes.Count; } } public List<UnitInfo> ListTestPlayerTemplates() { return new List<UnitInfo>(test_player_templates); } public List<ServerZoneNode> ListZoneNodes() { return new List<ServerZoneNode>(nodes.Values); } public ServerZoneNode GetZoneNodeByRoomID(string roomID) { return nodes.Get(roomID); } public ServerZoneNode AddTestScene(int sceneID) { if (ZoneNodeManager.Templates.ExistSceneInCache(sceneID)) { ServerZoneNode node = new ServerZoneNode(""); node.PauseOnNoPlayer = false; var uuid = channel_id_gen.IncrementAndGet().ToString(); node.Start(uuid, sceneID, "", 1, true, 0,0,0, 0, 0, 0, true, CommonAI.Data.SceneType.Normal, null, CommonAI.XmdsConstConfig.AreaType.None); nodes.Add(uuid, node); return node; } else { throw new Exception(string.Format("场景{0}不存在", sceneID)); } } } //------------------------------------------------------------------------------------------------- public class B2CServerListener : IServerListener, IServerProxy { public B2CServerListener() { } //------------------------------------------------------------------------------------------------- #region IServerListener public void OnInit(IServer server) { } public void OnDestory() { } public ISessionListener OnSessionConnected(ISession session) { return new AppSessionPlayer(session); } #endregion //------------------------------------------------------------------------------------------------- #region IServerProxy public void SendToGameServer(string playerUUID, string eventType, object msg) { } public void SendToBattleServer(InstanceZone zone, XmdsServerNode.Node.R2bNotify.R2BNotifyMessage msg) { msg.OnHandle(zone); } public void SendMsgToPlayer(string playerUUID, IMessage msg) { throw new NotImplementedException(); } #endregion } //------------------------------------------------------------------------------------------------- public class AppSessionPlayer : ISessionListener, IPlayer { private static Logger log = LoggerFactory.GetLogger("AppSessionPlayer"); private static AtomicInteger s_alloc_object_count = new AtomicInteger(0); /// <summary> /// 分配实例数量 /// </summary> public static int AllocCount { get { return s_alloc_object_count.Value; } } //---------------------------------------------------------------------------- private readonly ISession session; private ServerZoneNode node; private string player_uuid; private string display_name; private int unit_template_id; private EnterRoomRequestC2B login_data; private HashMap<string, object> mAttributes = new HashMap<string, object>(); private ZoneNodeCodec codec = new ZoneNodeCodec(ZoneNodeManager.MessageFactory); public AppSessionPlayer(ISession session) { s_alloc_object_count++; this.session = session; } ~AppSessionPlayer() { s_alloc_object_count--; } public void Dispose() { } //---------------------------------------------------------------------------- #region IPlayer public string PlayerUUID { get { return player_uuid; } } public string DisplayName { get { return display_name; } } public ServerZoneNode.ZoneNodePlayer BindingObject { get; set; } public bool IsAttribute(string key) { return mAttributes.ContainsKey(key); } public void SetAttribute(string key, object value) { mAttributes.Put(key, value); } public object GetAttribute(string key) { return mAttributes.Get(key); } public void SendToClient(ArraySegment<byte> data) { IMessage e; if (codec.doDecode(data.Array, out e)) { session.Send(e); } } public void SendToGameServer(object msg) { } public void onPickUnit(InstanceUnit obj, InstanceUnit pickable) { } #endregion //---------------------------------------------------------------------------- public void ForceExit() { if (node != null) { this.login_data = null; node.OnPlayerLeave(this.BindingObject.BindingActor, (c) => { }, (e) => { }, false); session.Disconnect(true); node = null; } } //---------------------------------------------------------------------------- #region ISessionListener public void OnConnected(ISession session) { } public void OnDisconnected(ISession session, bool force, string reason) { if (node != null) { this.login_data = null; node.OnPlayerLeave(this.BindingObject.BindingActor, (c) => { }, (e) => { }, true); node = null; } } public void OnError(ISession session, Exception err) { } public void OnSentMessage(ISession session, object message) { } public void OnReceivedMessage(ISession session, object message) { try { if (message is EnterRoomRequestC2B) { do_EnterRoomResponseB2C(message as EnterRoomRequestC2B); } else if (message is LeaveRoomRequestC2B) { do_LeaveRoomRequestC2B(message as LeaveRoomRequestC2B); } else { do_RecivedMessage(message); } } catch (Exception err) { log.Error(err.Message, err); } } private void do_EnterRoomResponseB2C(EnterRoomRequestC2B req) { if (node == null) { this.node = NodeTestServer.Instance.GetZoneNodeByRoomID(req.RoomID); if (node == null) { node = CUtils.GetRandomInArray(NodeTestServer.Instance.ListZoneNodes(), NodeTestServer.Instance.random); if (node != null) { req.RoomID = node.UUID; } } if (node != null) { this.login_data = req; this.player_uuid = req.PlayerUUID; this.display_name = req.TestToken.PlayerDisplayName; this.unit_template_id = req.TestToken.Data.UnitTemplateID; var regions = node.Zone.Data.GetStartRegions(); var rg = regions.Get(req.TestToken.Data.Force); if (rg == null) { rg = CUtils.GetRandomInArray(node.Zone.Data.GetStartRegionsList(), NodeTestServer.Instance.random); if (rg != null) { var force = (byte)rg.GetAbilityOf<PlayerStartAbilityData>().START_Force; req.TestToken.Data.Force = force; } } PlayerEnterRoomS2R enter = new PlayerEnterRoomS2R(); enter.UnitData = req.TestToken.Data; node.OnPlayerEnter(this, enter, (c) => { }, (e) => { }); } } } private void do_LeaveRoomRequestC2B(LeaveRoomRequestC2B req) { if (node != null) { this.login_data = null; node.OnPlayerLeave(this.BindingObject.BindingActor, (c) => { }, (e) => { }, false); session.Disconnect(true); node = null; } } private void do_RecivedMessage(object message) { if (node != null) { ArraySegment<byte> data; if (codec.doEncode(message as IMessage, out data)) { node.OnPlayerReceivedMessage(this, data.Array); } } } #endregion } //------------------------------------------------------------------------------------------------- }