PageRenderTime 53ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/eradiKor/eradiKor/Network/Server.cs

http://xe8tmw7c.googlecode.com/
C# | 245 lines | 214 code | 21 blank | 10 comment | 54 complexity | 6910181a0c3a7f272feaa7275c732ee1 MD5 | raw file
Possible License(s): GPL-3.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Lidgren.Network;
  6. namespace eradiKor.Network
  7. {
  8. #region class Server
  9. public class Server
  10. {
  11. const float REQUEST_INTERVAL = 0.2f;
  12. const float PING_INTERVAL = 1f;
  13. //mode debug : chacun reçoit ses propres informations
  14. const bool SELF_SEND = false;
  15. #region Attributs
  16. private NetServer server;
  17. private NetBuffer netBuffer;
  18. private NetConfiguration netConf;
  19. private LinkedList<Network.Alien> aliens;
  20. private NetType type;
  21. private string map, player, waves;
  22. private bool started, paused;
  23. private int serverID;
  24. #endregion
  25. #region Constructeur
  26. public Server(NetConfiguration conf, NetType t, string strmap, string strplayer, string strwaves)
  27. {
  28. if (this.server != null)
  29. {
  30. this.dispose();
  31. this.server = null;
  32. }
  33. this.netConf = conf;
  34. this.netConf.MaxConnections = 128;
  35. this.server = new NetServer(this.netConf);
  36. this.server.SetMessageTypeEnabled(NetMessageType.ConnectionApproval, true);
  37. this.server.Start();
  38. this.netBuffer = this.server.CreateBuffer();
  39. this.aliens = new LinkedList<Alien>();
  40. this.type = t;
  41. this.started = false;
  42. this.paused = false;
  43. this.map = strmap;
  44. this.player = strplayer;
  45. this.waves = strwaves;
  46. Kore.Datas.OnQueryDone += new Kore.Datas.WebEventHandler(Datas_OnQueryDone);
  47. }
  48. #endregion
  49. #region Accesseur
  50. public bool Ready
  51. {
  52. get { return this.server != null; }
  53. }
  54. #endregion
  55. #region Méthodes
  56. public Queue<string> update(float elapsedTime)
  57. {
  58. NetConnection sender;
  59. NetMessageType messType;
  60. Queue<string> messages = new Queue<string>();
  61. #region réception de messages
  62. while (server.ReadMessage(netBuffer, out messType, out sender))
  63. {
  64. if (messType == NetMessageType.ConnectionApproval && !started)
  65. {
  66. aliens.AddLast(new Alien(sender, elapsedTime));
  67. sender.Approve();
  68. }
  69. else if (messType == NetMessageType.Data)
  70. {
  71. string msg = netBuffer.ReadString();
  72. NetMessage temp = NetParsers.fullParse(msg);
  73. if (temp.Type == MessageType.Ping)
  74. foreach (Alien a in aliens)
  75. {
  76. if (a.wire == sender)
  77. {
  78. a.transmitted = true;
  79. a.LastPing = (int)((elapsedTime - a.Ping.time) * 1000);
  80. a.Ping.answered = true;
  81. a.Ping.time = (float)elapsedTime;
  82. break;
  83. }
  84. }
  85. else if (temp.Type == MessageType.Start && !started)
  86. {
  87. foreach (Alien a in aliens)
  88. if (a.wire != sender)
  89. {
  90. NetBuffer outb = new NetBuffer(msg);
  91. a.wire.SendMessage(outb, NetChannel.ReliableInOrder1);
  92. }
  93. started = true;
  94. //On ferme le serveur
  95. (new HTTP.Requetes(Kore.Events.RequeteType.closeServer, System.Reflection.Assembly.GetExecutingAssembly().FullName.Split(',')[1].Replace("Version=", "").Trim(), new Dictionary<string, string>() { { "ip", NAT.GetExternalIP().ToString() }, { "id", this.serverID.ToString() } })).requete();
  96. }
  97. else if (temp.Type == MessageType.Pause && started)
  98. {
  99. foreach (Alien a in aliens)
  100. if (a.wire != sender)
  101. {
  102. NetBuffer outb = new NetBuffer(msg);
  103. a.wire.SendMessage(outb, NetChannel.ReliableInOrder1);
  104. }
  105. paused = !paused;
  106. }
  107. else
  108. {
  109. foreach (Alien a in aliens)
  110. {
  111. if (sender != a.wire || SELF_SEND)
  112. {
  113. NetBuffer outBuffer = server.CreateBuffer();
  114. outBuffer.Write(msg);
  115. try
  116. {
  117. a.wire.SendMessage(outBuffer, NetChannel.ReliableInOrder1);
  118. }
  119. catch
  120. { }
  121. }
  122. if (sender == a.wire)
  123. { // mise ŕ jour de l’état de l’envoyeur
  124. a.FullSend.answered = true;
  125. a.FullSend.time = (float)elapsedTime;
  126. }
  127. }
  128. }
  129. }
  130. //if (data)
  131. } //while (messages)
  132. #endregion
  133. #region envoie des différentes requętes
  134. Alien deleted = null;
  135. foreach (Alien a in aliens)
  136. {
  137. if (!a.transmitted && elapsedTime > a.Ping.time + PING_INTERVAL)
  138. {// ce client ne connait ni son nom ni son environnement !
  139. //envoie de l’id via ping
  140. a.Ping.time = elapsedTime;
  141. NetBuffer temp = new NetBuffer((new NetMessage(MessageType.Ping, a.id, "")).NetString);
  142. a.wire.SendMessage(temp, NetChannel.ReliableInOrder1);
  143. //envoi de la map
  144. if (this.type == NetType.Multiplayer)
  145. {
  146. temp = new NetBuffer((new NetMessage(MessageType.Player, a.id, this.player)).NetString);
  147. a.wire.SendMessage(temp, NetChannel.ReliableInOrder1);
  148. temp = new NetBuffer((new NetMessage(MessageType.Map, a.id, this.map)).NetString);
  149. a.wire.SendMessage(temp, NetChannel.ReliableInOrder1);
  150. temp = new NetBuffer((new NetMessage(MessageType.WaveOrder, a.id, this.waves)).NetString);
  151. a.wire.SendMessage(temp, NetChannel.ReliableInOrder1);
  152. if (started)
  153. {
  154. temp = new NetBuffer((new NetMessage(MessageType.Start, 0, "")).NetString);
  155. a.wire.SendMessage(temp, NetChannel.ReliableInOrder1);
  156. }
  157. }
  158. }
  159. else
  160. {
  161. //Ping ?
  162. if (elapsedTime > a.Ping.time + PING_INTERVAL)
  163. {
  164. if (a.Ping.answered && a.wire.Status == NetConnectionStatus.Connected)
  165. {// toujours tester le status, risque d’exception chez Lidgren
  166. a.Ping.time = elapsedTime;
  167. NetBuffer temp = new NetBuffer((new NetMessage(MessageType.Ping, a.id, "")).NetString);
  168. a.wire.SendMessage(temp, NetChannel.ReliableInOrder1);
  169. }
  170. else
  171. {
  172. NetBuffer buffle = new NetBuffer((new NetMessage(MessageType.System, a.id, NetParsers.convertSysAct(SystemActions.Disconnect).ToString() + ":0:Connexion perdue")).NetString);
  173. this.server.SendToAll(buffle, NetChannel.ReliableInOrder1);
  174. a.wire.Disconnect("Connexion perdue", 1);
  175. deleted = a;
  176. }
  177. }
  178. // plz, envoie moi tes infos
  179. if (this.type == NetType.Multiplayer && a.FullSend.answered && elapsedTime > a.FullSend.time + REQUEST_INTERVAL)
  180. {
  181. if (a.FullSend.answered && a.wire.Status == NetConnectionStatus.Connected)
  182. {
  183. a.FullSend.time = (float)elapsedTime;
  184. NetBuffer temp = new NetBuffer((new NetMessage(MessageType.RequestInfo, a.id, "")).NetString);
  185. a.wire.SendMessage(temp, NetChannel.ReliableInOrder1);
  186. temp = new NetBuffer((new NetMessage(MessageType.RequestMap, a.id, "")).NetString);
  187. a.wire.SendMessage(temp, NetChannel.ReliableInOrder1);
  188. }
  189. //else : il ram/lag ? on attends un peu.
  190. //Si il ne répond plus, il sera kické par le Ping.
  191. }
  192. }
  193. }
  194. if (deleted != null)
  195. aliens.Remove(deleted);
  196. #endregion
  197. return messages;
  198. }
  199. public void dispose()
  200. {
  201. if (this.server != null)
  202. {
  203. this.server.Shutdown("");
  204. this.server.Dispose();
  205. this.server = null;
  206. //On ferme le port ouvert par Upnp
  207. NAT.DeleteForwardingRule(this.netConf.Port, System.Net.Sockets.ProtocolType.Udp);
  208. }
  209. }
  210. #endregion
  211. #region Méthode événementielle
  212. void Datas_OnQueryDone(object sender, Kore.Events.WebEventArgs e)
  213. {
  214. if (e.Type == Kore.Events.RequeteType.setServer)
  215. {
  216. Kore.Datas.OnQueryDone -= Datas_OnQueryDone;
  217. if (!int.TryParse(e.Details, out this.serverID))
  218. this.serverID = -1;
  219. }
  220. }
  221. #endregion
  222. }
  223. #endregion
  224. }