ServerNode.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. using CommonAI;
  2. using CommonAI.Zone.ZoneEditor;
  3. using CommonAIServer.Node;
  4. using CommonLang.Net;
  5. using CommonServer.Server;
  6. using CommonServer.SSocket.SuperSocket;
  7. using System;
  8. using CommonFroms.G2D;
  9. using CommonAIServer.Node.Interface;
  10. using CommonLang;
  11. using CommonLang.Log;
  12. using CommonLang.Protocol;
  13. using RoomService.Net.BsServer;
  14. using System.Threading;
  15. using CommonAIServer.Connector;
  16. using CommonAI.Zone;
  17. using System.IO;
  18. using CommonLang.IO;
  19. using CommonLang.Property;
  20. namespace GameEditorPluginServer.Server
  21. {
  22. public class ServerNode : IServerListener
  23. {
  24. protected readonly Logger log = LoggerFactory.GetLogger("ServerNode");
  25. private readonly ServerFactory mServerFactory;
  26. private readonly EditorTemplates mDataRoot;
  27. private readonly ZoneNodeConfig mConfig;
  28. private readonly ZoneNode mNode;
  29. private readonly SocketAcceptor mServer;
  30. private readonly int mSceneID;
  31. private readonly ServerCodec mCodec;
  32. public ServerNode(EditorTemplates dataroot, ZoneNodeConfig cfg, int sceneID)
  33. {
  34. this.mDataRoot = dataroot;
  35. this.mConfig = cfg;
  36. this.mSceneID = sceneID;
  37. this.mCodec = new ServerCodec(dataroot.Templates);
  38. this.mServerFactory = new ServerFactory();
  39. this.mServer = mServerFactory.CreateServer(mCodec) as SocketAcceptor;
  40. this.mNode = new ZoneNode(dataroot, cfg);
  41. this.mNode.OnZoneStart += MNode_OnZoneStart;
  42. this.mNode.OnZoneStop += MNode_OnZoneStop;
  43. }
  44. public void Start()
  45. {
  46. var data = mNode.DataRoot.LoadScene(mSceneID, true, false);
  47. this.mNode.Start(data, null, null);
  48. }
  49. public void Dispose()
  50. {
  51. mServer.Dispose();
  52. mNode.Stop();
  53. }
  54. //-------------------------------------------------------------------------------------------------
  55. public ZoneNodeConfig Config
  56. {
  57. get { return mConfig; }
  58. }
  59. public ZoneNode Node
  60. {
  61. get { return mNode; }
  62. }
  63. public SocketAcceptor Server
  64. {
  65. get { return mServer; }
  66. }
  67. public EditorTemplates DataRoot
  68. {
  69. get { return mDataRoot; }
  70. }
  71. public bool Running
  72. {
  73. get { return mNode.IsRunning; }
  74. }
  75. public ServerCodec Codec
  76. {
  77. get { return mCodec; }
  78. }
  79. //-------------------------------------------------------------------------------------------------
  80. #region ServerAndRoom
  81. private void InternalOpen()
  82. {
  83. try
  84. {
  85. Random random = new Random();
  86. int port = random.Next(10000, 60000);
  87. this.mServer.Open("127.0.0.1", port, this);
  88. }
  89. catch (Exception err)
  90. {
  91. log.Error(err.Message, err);
  92. }
  93. }
  94. private void MNode_OnZoneStop(BaseZoneNode zone)
  95. {
  96. }
  97. private void MNode_OnZoneStart(BaseZoneNode zone)
  98. {
  99. new Thread(InternalOpen).Start();
  100. }
  101. void IServerListener.OnInit(IServer server)
  102. {
  103. }
  104. void IServerListener.OnDestory()
  105. {
  106. }
  107. ISessionListener IServerListener.OnSessionConnected(ISession session)
  108. {
  109. return new SessionPlayer(session as Session, mNode);
  110. }
  111. #endregion
  112. //-------------------------------------------------------------------------------------------------
  113. }
  114. //-------------------------------------------------------------------------------------------------
  115. public class ServerCodec : BattleCodec
  116. {
  117. private InputStream mInputStream;
  118. private OutputStream mOutputStream;
  119. private MemoryStream mBinBufferIn;
  120. private MemoryStream mBinBufferOut;
  121. private HashMap<Type, Record> mTypeBytes = new HashMap<Type, Record>();
  122. public ServerCodec(TemplateManager templates)
  123. : base(templates)
  124. {
  125. this.mInputStream = new InputStream(null, Factory);
  126. this.mOutputStream = new OutputStream(null, Factory);
  127. this.mBinBufferIn = new MemoryStream(1024);
  128. this.mBinBufferOut = new MemoryStream(1024);
  129. }
  130. public override bool doDecode(Stream input, out object message)
  131. {
  132. lock (mInputStream)
  133. {
  134. mInputStream.SetStream(input);
  135. int typeInt = mInputStream.GetS32();
  136. Type type = Factory.GetType(typeInt);
  137. if (type == null)
  138. {
  139. log.Error("Unknow Protocol : >>>" + typeInt + "<<<");
  140. message = null;
  141. return false;
  142. }
  143. else
  144. {
  145. IMessage nm = (IMessage)ReflectionUtil.CreateInstance(type);
  146. nm.ReadExternal(mInputStream);
  147. if (nm is BattleMessage)
  148. {
  149. ((BattleMessage)nm).EndRead(Templates);
  150. }
  151. message = nm;
  152. return true;
  153. }
  154. }
  155. }
  156. public override bool doEncode(Stream output, object message)
  157. {
  158. lock (mOutputStream)
  159. {
  160. Type type = message.GetType();
  161. int typeInt = Factory.GetTypeID(type);
  162. if (typeInt == 0)
  163. {
  164. log.Error("Unknow Protocol : >>>" + typeInt + "<<< - " + message.GetType().FullName);
  165. return false;
  166. }
  167. long pos = output.Position;
  168. mOutputStream.SetStream(output);
  169. mOutputStream.PutS32(typeInt);
  170. IMessage nm = (IMessage)message;
  171. if (nm is BattleMessage)
  172. {
  173. ((BattleMessage)nm).BeforeWrite(Templates);
  174. }
  175. nm.WriteExternal(mOutputStream);
  176. long len = output.Position - pos;
  177. Record rec;
  178. if (mTypeBytes.TryGetValue(type, out rec))
  179. {
  180. rec.Bytes += len;
  181. rec.Count++;
  182. mTypeBytes.Put(type, rec);
  183. }
  184. else
  185. {
  186. rec.Bytes = len;
  187. rec.Count = 1;
  188. mTypeBytes.Put(type, rec);
  189. }
  190. return true;
  191. }
  192. }
  193. public HashMap<Type, Record> GetSentTypeBytes()
  194. {
  195. lock (mOutputStream)
  196. {
  197. return new HashMap<Type, Record>(mTypeBytes);
  198. }
  199. }
  200. public struct Record
  201. {
  202. public long Bytes;
  203. public int Count;
  204. }
  205. }
  206. //-------------------------------------------------------------------------------------------------
  207. internal class SessionPlayer : IPlayer, ISessionListener
  208. {
  209. private static Logger log = LoggerFactory.GetLogger("SessionPlayer");
  210. private readonly ZoneNode node;
  211. private readonly Session session;
  212. private readonly SynchronizedBattleCodec codec;
  213. private readonly HashMap<string, object> mAttributes = new HashMap<string, object>();
  214. private Action<object> mRecvHandler;
  215. private EnterRoomRequestC2B login_data;
  216. private string player_uuid;
  217. private string display_name;
  218. private int unit_template_id;
  219. private int force;
  220. public SessionPlayer(Session session, ZoneNode node)
  221. {
  222. this.node = node;
  223. this.session = session;
  224. this.codec = new SynchronizedBattleCodec(node.Templates);
  225. }
  226. //----------------------------------------------------------------------------
  227. #region IPlayer
  228. public string PlayerUUID { get { return player_uuid; } }
  229. public string DisplayName { get { return display_name; } }
  230. public ZoneNode.PlayerClient BindingPlayer { get; set; }
  231. bool IPlayer.IsAttribute(string key)
  232. {
  233. return mAttributes.ContainsKey(key);
  234. }
  235. void IPlayer.SetAttribute(string key, object value)
  236. {
  237. mAttributes.Put(key, value);
  238. }
  239. object IPlayer.GetAttribute(string key)
  240. {
  241. return mAttributes.Get(key);
  242. }
  243. void IPlayer.Send(IMessage msg)
  244. {
  245. session.Send(msg);
  246. }
  247. void IPlayer.Listen(Action<object> handler)
  248. {
  249. mRecvHandler = handler;
  250. }
  251. void IPlayer.OnConnected(ZoneNode.PlayerClient binding)
  252. {
  253. }
  254. void IPlayer.OnDisconnect(ZoneNode.PlayerClient binding)
  255. {
  256. mRecvHandler = null;
  257. }
  258. #endregion
  259. //----------------------------------------------------------------------------
  260. #region ISessionListener
  261. void ISessionListener.OnConnected(ISession session)
  262. {
  263. }
  264. void ISessionListener.OnDisconnected(ISession session, bool force, string reason)
  265. {
  266. if (node != null)
  267. {
  268. node.PlayerLeave(this.BindingPlayer.Actor, (c) => { }, (e) => { }, true);
  269. }
  270. }
  271. void ISessionListener.OnError(ISession session, Exception err)
  272. {
  273. }
  274. void ISessionListener.OnSentMessage(ISession session, object message)
  275. {
  276. }
  277. void ISessionListener.OnReceivedMessage(ISession session, object message)
  278. {
  279. try
  280. {
  281. if (message is EnterRoomRequestC2B)
  282. {
  283. do_EnterRoomResponseB2C(message as EnterRoomRequestC2B);
  284. }
  285. else if (message is LeaveRoomRequestC2B)
  286. {
  287. do_LeaveRoomRequestC2B(message as LeaveRoomRequestC2B);
  288. }
  289. else if (mRecvHandler != null)
  290. {
  291. mRecvHandler(message);
  292. }
  293. }
  294. catch (Exception err)
  295. {
  296. log.Error(err.Message, err);
  297. }
  298. }
  299. #endregion
  300. private void do_EnterRoomResponseB2C(EnterRoomRequestC2B req)
  301. {
  302. this.login_data = req;
  303. this.player_uuid = req.PlayerUUID;
  304. this.display_name = req.TestToken.PlayerDisplayName;
  305. this.unit_template_id = req.TestToken.Data.UnitTemplateID;
  306. this.force = req.TestToken.Data.Force;
  307. var temp = node.Templates.getUnit(unit_template_id);
  308. node.PlayerEnter(this, temp, force, 0, 0, null,0, (c) => { }, (e)=> { });
  309. }
  310. private void do_LeaveRoomRequestC2B(LeaveRoomRequestC2B req)
  311. {
  312. this.login_data = null;
  313. node.PlayerLeave(this.BindingPlayer.Actor, (c) => { }, (e) => { }, false);
  314. }
  315. }
  316. }