NodeTestServer.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. using CommonAI;
  2. using CommonAI.Zone;
  3. using CommonAI.Zone.Instance;
  4. using CommonAI.Zone.ZoneEditor;
  5. using CommonAIClient.Client;
  6. using CommonLang;
  7. using CommonLang.Concurrent;
  8. using CommonLang.Log;
  9. using CommonLang.Protocol;
  10. using CommonServer.Server;
  11. using RoomService.Net.BsServer;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.IO;
  15. using System.Linq;
  16. using System.Text;
  17. using XmdsCommon.Plugin;
  18. using XmdsServerNode.Node;
  19. using XmdsServerNode.Node.Interface;
  20. namespace XmdsServerTest.Server
  21. {
  22. public class NodeTestServer
  23. {
  24. private static Logger log = LoggerFactory.GetLogger("TestNodeServer");
  25. public static NodeTestServer Instance { get; private set; }
  26. public string ClientConnectString { get { return busAcceptor.ClientConnectString; } }
  27. public IServer B2CAcceptor { get { return busAcceptor; } }
  28. public readonly Random random = new Random();
  29. private List<UnitInfo> test_player_templates = new List<UnitInfo>();
  30. private IServerFactory factory;
  31. private IServer busAcceptor = null;
  32. private B2CServerListener serverListener;
  33. private AtomicInteger channel_id_gen = new AtomicInteger(0);
  34. private ZoneNodeManager node_manager = new ZoneNodeManager();
  35. private HashMap<string, ServerZoneNode> nodes = new HashMap<string, ServerZoneNode>();
  36. public DirectoryInfo StartupPath { get; private set; }
  37. public string Status { get; private set; }
  38. public bool Running { get; private set; }
  39. public NodeTestServer(DirectoryInfo startup_path)
  40. {
  41. Instance = this;
  42. this.StartupPath = startup_path;
  43. this.Running = false;
  44. this.Status = "New";
  45. this.factory = new CommonServer.SSocket.SuperSocket.ServerFactory();
  46. }
  47. public void Start(string host, int port)
  48. {
  49. try
  50. {
  51. this.serverListener = new B2CServerListener();
  52. this.Status = "Launching";
  53. // 初始化节点管理器 //
  54. {
  55. node_manager.Init(StartupPath.FullName, serverListener);
  56. }
  57. // 创建战斗场景 //
  58. {
  59. foreach (int scene_id in ZoneNodeManager.Templates.ListScenes())
  60. {
  61. ZoneNodeManager.Templates.LoadScene(scene_id);
  62. }
  63. }
  64. // 扫描玩家模板 //
  65. {
  66. foreach (UnitInfo unit in ZoneNodeManager.Templates.Templates.getAllUnits())
  67. {
  68. XmdsUnitProperties zu = unit.Properties as XmdsUnitProperties;
  69. if (zu.BotTestTemplate || unit.UType == UnitInfo.UnitType.TYPE_PLAYER)
  70. {
  71. test_player_templates.Add(unit);
  72. }
  73. }
  74. }
  75. // 创建网络 //
  76. {
  77. this.busAcceptor = factory.CreateServer(new BattleCodec(ZoneNodeManager.Templates.Templates));
  78. CommonLang.Properties game_server_cfg = new CommonLang.Properties();
  79. game_server_cfg["SuperSocket.HOST"] = host;
  80. game_server_cfg["SuperSocket.PORT"] = port.ToString();
  81. game_server_cfg["SuperSocket.CLIENT_CONNECT_STRING"] = host + ":" + port;
  82. this.busAcceptor.Open(game_server_cfg, serverListener);
  83. }
  84. this.Status = "Running";
  85. this.Running = true;
  86. }
  87. catch (Exception err)
  88. {
  89. this.Status = err.Message;
  90. Console.WriteLine(err.Message);
  91. Console.WriteLine(err.StackTrace);
  92. }
  93. }
  94. public void Shutdown()
  95. {
  96. try
  97. {
  98. this.busAcceptor.Dispose();
  99. this.node_manager.Shutdown();
  100. this.Status = "Closed";
  101. this.Running = false;
  102. }
  103. catch (Exception err)
  104. {
  105. Console.WriteLine(err.Message);
  106. Console.WriteLine(err.StackTrace);
  107. }
  108. }
  109. public int ZoneNodesCount { get { return nodes.Count; } }
  110. public List<UnitInfo> ListTestPlayerTemplates()
  111. {
  112. return new List<UnitInfo>(test_player_templates);
  113. }
  114. public List<ServerZoneNode> ListZoneNodes()
  115. {
  116. return new List<ServerZoneNode>(nodes.Values);
  117. }
  118. public ServerZoneNode GetZoneNodeByRoomID(string roomID)
  119. {
  120. return nodes.Get(roomID);
  121. }
  122. public ServerZoneNode AddTestScene(int sceneID)
  123. {
  124. if (ZoneNodeManager.Templates.ExistSceneInCache(sceneID))
  125. {
  126. ServerZoneNode node = new ServerZoneNode("");
  127. node.PauseOnNoPlayer = false;
  128. var uuid = channel_id_gen.IncrementAndGet().ToString();
  129. node.Start(uuid, sceneID, "", 1, true, 0,0,0, 0, 0, 0,
  130. true, CommonAI.Data.SceneType.Normal, null, CommonAI.XmdsConstConfig.AreaType.None);
  131. nodes.Add(uuid, node);
  132. return node;
  133. }
  134. else
  135. {
  136. throw new Exception(string.Format("场景{0}不存在", sceneID));
  137. }
  138. }
  139. }
  140. //-------------------------------------------------------------------------------------------------
  141. public class B2CServerListener : IServerListener, IServerProxy
  142. {
  143. public B2CServerListener()
  144. {
  145. }
  146. //-------------------------------------------------------------------------------------------------
  147. #region IServerListener
  148. public void OnInit(IServer server)
  149. {
  150. }
  151. public void OnDestory()
  152. {
  153. }
  154. public ISessionListener OnSessionConnected(ISession session)
  155. {
  156. return new AppSessionPlayer(session);
  157. }
  158. #endregion
  159. //-------------------------------------------------------------------------------------------------
  160. #region IServerProxy
  161. public void SendToGameServer(string playerUUID, string eventType, object msg)
  162. {
  163. }
  164. public void SendToBattleServer(InstanceZone zone, XmdsServerNode.Node.R2bNotify.R2BNotifyMessage msg)
  165. {
  166. msg.OnHandle(zone);
  167. }
  168. public void SendMsgToPlayer(string playerUUID, IMessage msg)
  169. {
  170. throw new NotImplementedException();
  171. }
  172. #endregion
  173. }
  174. //-------------------------------------------------------------------------------------------------
  175. public class AppSessionPlayer : ISessionListener, IPlayer
  176. {
  177. private static Logger log = LoggerFactory.GetLogger("AppSessionPlayer");
  178. private static AtomicInteger s_alloc_object_count = new AtomicInteger(0);
  179. /// <summary>
  180. /// 分配实例数量
  181. /// </summary>
  182. public static int AllocCount { get { return s_alloc_object_count.Value; } }
  183. //----------------------------------------------------------------------------
  184. private readonly ISession session;
  185. private ServerZoneNode node;
  186. private string player_uuid;
  187. private string display_name;
  188. private int unit_template_id;
  189. private EnterRoomRequestC2B login_data;
  190. private HashMap<string, object> mAttributes = new HashMap<string, object>();
  191. private ZoneNodeCodec codec = new ZoneNodeCodec(ZoneNodeManager.MessageFactory);
  192. public AppSessionPlayer(ISession session)
  193. {
  194. s_alloc_object_count++;
  195. this.session = session;
  196. }
  197. ~AppSessionPlayer()
  198. {
  199. s_alloc_object_count--;
  200. }
  201. public void Dispose()
  202. {
  203. }
  204. //----------------------------------------------------------------------------
  205. #region IPlayer
  206. public string PlayerUUID { get { return player_uuid; } }
  207. public string DisplayName { get { return display_name; } }
  208. public ServerZoneNode.ZoneNodePlayer BindingObject { get; set; }
  209. public bool IsAttribute(string key)
  210. {
  211. return mAttributes.ContainsKey(key);
  212. }
  213. public void SetAttribute(string key, object value)
  214. {
  215. mAttributes.Put(key, value);
  216. }
  217. public object GetAttribute(string key)
  218. {
  219. return mAttributes.Get(key);
  220. }
  221. public void SendToClient(ArraySegment<byte> data)
  222. {
  223. IMessage e;
  224. if (codec.doDecode(data.Array, out e))
  225. {
  226. session.Send(e);
  227. }
  228. }
  229. public void SendToGameServer(object msg)
  230. {
  231. }
  232. public void onPickUnit(InstanceUnit obj, InstanceUnit pickable)
  233. {
  234. }
  235. #endregion
  236. //----------------------------------------------------------------------------
  237. public void ForceExit()
  238. {
  239. if (node != null)
  240. {
  241. this.login_data = null;
  242. node.OnPlayerLeave(this.BindingObject.BindingActor, (c) => { }, (e) => { }, false);
  243. session.Disconnect(true);
  244. node = null;
  245. }
  246. }
  247. //----------------------------------------------------------------------------
  248. #region ISessionListener
  249. public void OnConnected(ISession session)
  250. {
  251. }
  252. public void OnDisconnected(ISession session, bool force, string reason)
  253. {
  254. if (node != null)
  255. {
  256. this.login_data = null;
  257. node.OnPlayerLeave(this.BindingObject.BindingActor, (c) => { }, (e) => { }, true);
  258. node = null;
  259. }
  260. }
  261. public void OnError(ISession session, Exception err)
  262. {
  263. }
  264. public void OnSentMessage(ISession session, object message)
  265. {
  266. }
  267. public void OnReceivedMessage(ISession session, object message)
  268. {
  269. try
  270. {
  271. if (message is EnterRoomRequestC2B)
  272. {
  273. do_EnterRoomResponseB2C(message as EnterRoomRequestC2B);
  274. }
  275. else if (message is LeaveRoomRequestC2B)
  276. {
  277. do_LeaveRoomRequestC2B(message as LeaveRoomRequestC2B);
  278. }
  279. else
  280. {
  281. do_RecivedMessage(message);
  282. }
  283. }
  284. catch (Exception err)
  285. {
  286. log.Error(err.Message, err);
  287. }
  288. }
  289. private void do_EnterRoomResponseB2C(EnterRoomRequestC2B req)
  290. {
  291. if (node == null)
  292. {
  293. this.node = NodeTestServer.Instance.GetZoneNodeByRoomID(req.RoomID);
  294. if (node == null)
  295. {
  296. node = CUtils.GetRandomInArray(NodeTestServer.Instance.ListZoneNodes(), NodeTestServer.Instance.random);
  297. if (node != null)
  298. {
  299. req.RoomID = node.UUID;
  300. }
  301. }
  302. if (node != null)
  303. {
  304. this.login_data = req;
  305. this.player_uuid = req.PlayerUUID;
  306. this.display_name = req.TestToken.PlayerDisplayName;
  307. this.unit_template_id = req.TestToken.Data.UnitTemplateID;
  308. var regions = node.Zone.Data.GetStartRegions();
  309. var rg = regions.Get(req.TestToken.Data.Force);
  310. if (rg == null)
  311. {
  312. rg = CUtils.GetRandomInArray(node.Zone.Data.GetStartRegionsList(), NodeTestServer.Instance.random);
  313. if (rg != null)
  314. {
  315. var force = (byte)rg.GetAbilityOf<PlayerStartAbilityData>().START_Force;
  316. req.TestToken.Data.Force = force;
  317. }
  318. }
  319. PlayerEnterRoomS2R enter = new PlayerEnterRoomS2R();
  320. enter.UnitData = req.TestToken.Data;
  321. node.OnPlayerEnter(this, enter, (c) => { }, (e) => { });
  322. }
  323. }
  324. }
  325. private void do_LeaveRoomRequestC2B(LeaveRoomRequestC2B req)
  326. {
  327. if (node != null)
  328. {
  329. this.login_data = null;
  330. node.OnPlayerLeave(this.BindingObject.BindingActor, (c) => { }, (e) => { }, false);
  331. session.Disconnect(true);
  332. node = null;
  333. }
  334. }
  335. private void do_RecivedMessage(object message)
  336. {
  337. if (node != null)
  338. {
  339. ArraySegment<byte> data;
  340. if (codec.doEncode(message as IMessage, out data))
  341. {
  342. node.OnPlayerReceivedMessage(this, data.Array);
  343. }
  344. }
  345. }
  346. #endregion
  347. }
  348. //-------------------------------------------------------------------------------------------------
  349. }