/trunk/eradiKor/eradiKor/Network/Server.cs
C# | 245 lines | 214 code | 21 blank | 10 comment | 54 complexity | 6910181a0c3a7f272feaa7275c732ee1 MD5 | raw file
Possible License(s): GPL-3.0
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using Lidgren.Network;
-
- namespace eradiKor.Network
- {
- #region class Server
- public class Server
- {
- const float REQUEST_INTERVAL = 0.2f;
- const float PING_INTERVAL = 1f;
- //mode debug : chacun reçoit ses propres informations
- const bool SELF_SEND = false;
-
- #region Attributs
- private NetServer server;
- private NetBuffer netBuffer;
- private NetConfiguration netConf;
- private LinkedList<Network.Alien> aliens;
- private NetType type;
- private string map, player, waves;
- private bool started, paused;
- private int serverID;
- #endregion
-
- #region Constructeur
- public Server(NetConfiguration conf, NetType t, string strmap, string strplayer, string strwaves)
- {
- if (this.server != null)
- {
- this.dispose();
- this.server = null;
- }
- this.netConf = conf;
- this.netConf.MaxConnections = 128;
- this.server = new NetServer(this.netConf);
- this.server.SetMessageTypeEnabled(NetMessageType.ConnectionApproval, true);
- this.server.Start();
- this.netBuffer = this.server.CreateBuffer();
- this.aliens = new LinkedList<Alien>();
- this.type = t;
- this.started = false;
- this.paused = false;
- this.map = strmap;
- this.player = strplayer;
- this.waves = strwaves;
-
- Kore.Datas.OnQueryDone += new Kore.Datas.WebEventHandler(Datas_OnQueryDone);
- }
- #endregion
-
- #region Accesseur
- public bool Ready
- {
- get { return this.server != null; }
- }
- #endregion
-
- #region Méthodes
- public Queue<string> update(float elapsedTime)
- {
- NetConnection sender;
- NetMessageType messType;
- Queue<string> messages = new Queue<string>();
-
- #region réception de messages
- while (server.ReadMessage(netBuffer, out messType, out sender))
- {
- if (messType == NetMessageType.ConnectionApproval && !started)
- {
- aliens.AddLast(new Alien(sender, elapsedTime));
- sender.Approve();
- }
- else if (messType == NetMessageType.Data)
- {
- string msg = netBuffer.ReadString();
-
- NetMessage temp = NetParsers.fullParse(msg);
- if (temp.Type == MessageType.Ping)
- foreach (Alien a in aliens)
- {
- if (a.wire == sender)
- {
- a.transmitted = true;
- a.LastPing = (int)((elapsedTime - a.Ping.time) * 1000);
- a.Ping.answered = true;
- a.Ping.time = (float)elapsedTime;
- break;
- }
- }
- else if (temp.Type == MessageType.Start && !started)
- {
- foreach (Alien a in aliens)
- if (a.wire != sender)
- {
- NetBuffer outb = new NetBuffer(msg);
- a.wire.SendMessage(outb, NetChannel.ReliableInOrder1);
- }
-
- started = true;
-
- //On ferme le serveur
- (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();
- }
- else if (temp.Type == MessageType.Pause && started)
- {
- foreach (Alien a in aliens)
- if (a.wire != sender)
- {
- NetBuffer outb = new NetBuffer(msg);
- a.wire.SendMessage(outb, NetChannel.ReliableInOrder1);
- }
-
- paused = !paused;
- }
- else
- {
- foreach (Alien a in aliens)
- {
- if (sender != a.wire || SELF_SEND)
- {
- NetBuffer outBuffer = server.CreateBuffer();
- outBuffer.Write(msg);
- try
- {
- a.wire.SendMessage(outBuffer, NetChannel.ReliableInOrder1);
- }
- catch
- { }
- }
-
- if (sender == a.wire)
- { // mise ŕ jour de létat de lenvoyeur
- a.FullSend.answered = true;
- a.FullSend.time = (float)elapsedTime;
- }
- }
- }
- }
- //if (data)
- } //while (messages)
- #endregion
-
- #region envoie des différentes requętes
- Alien deleted = null;
- foreach (Alien a in aliens)
- {
- if (!a.transmitted && elapsedTime > a.Ping.time + PING_INTERVAL)
- {// ce client ne connait ni son nom ni son environnement !
- //envoie de lid via ping
- a.Ping.time = elapsedTime;
- NetBuffer temp = new NetBuffer((new NetMessage(MessageType.Ping, a.id, "")).NetString);
- a.wire.SendMessage(temp, NetChannel.ReliableInOrder1);
-
- //envoi de la map
- if (this.type == NetType.Multiplayer)
- {
- temp = new NetBuffer((new NetMessage(MessageType.Player, a.id, this.player)).NetString);
- a.wire.SendMessage(temp, NetChannel.ReliableInOrder1);
- temp = new NetBuffer((new NetMessage(MessageType.Map, a.id, this.map)).NetString);
- a.wire.SendMessage(temp, NetChannel.ReliableInOrder1);
- temp = new NetBuffer((new NetMessage(MessageType.WaveOrder, a.id, this.waves)).NetString);
- a.wire.SendMessage(temp, NetChannel.ReliableInOrder1);
- if (started)
- {
- temp = new NetBuffer((new NetMessage(MessageType.Start, 0, "")).NetString);
- a.wire.SendMessage(temp, NetChannel.ReliableInOrder1);
- }
- }
- }
- else
- {
- //Ping ?
- if (elapsedTime > a.Ping.time + PING_INTERVAL)
- {
- if (a.Ping.answered && a.wire.Status == NetConnectionStatus.Connected)
- {// toujours tester le status, risque dexception chez Lidgren
- a.Ping.time = elapsedTime;
- NetBuffer temp = new NetBuffer((new NetMessage(MessageType.Ping, a.id, "")).NetString);
- a.wire.SendMessage(temp, NetChannel.ReliableInOrder1);
- }
- else
- {
- NetBuffer buffle = new NetBuffer((new NetMessage(MessageType.System, a.id, NetParsers.convertSysAct(SystemActions.Disconnect).ToString() + ":0:Connexion perdue")).NetString);
- this.server.SendToAll(buffle, NetChannel.ReliableInOrder1);
- a.wire.Disconnect("Connexion perdue", 1);
- deleted = a;
- }
- }
-
- // plz, envoie moi tes infos
- if (this.type == NetType.Multiplayer && a.FullSend.answered && elapsedTime > a.FullSend.time + REQUEST_INTERVAL)
- {
- if (a.FullSend.answered && a.wire.Status == NetConnectionStatus.Connected)
- {
- a.FullSend.time = (float)elapsedTime;
- NetBuffer temp = new NetBuffer((new NetMessage(MessageType.RequestInfo, a.id, "")).NetString);
- a.wire.SendMessage(temp, NetChannel.ReliableInOrder1);
- temp = new NetBuffer((new NetMessage(MessageType.RequestMap, a.id, "")).NetString);
- a.wire.SendMessage(temp, NetChannel.ReliableInOrder1);
- }
- //else : il ram/lag ? on attends un peu.
- //Si il ne répond plus, il sera kické par le Ping.
- }
- }
- }
-
- if (deleted != null)
- aliens.Remove(deleted);
-
- #endregion
- return messages;
- }
-
- public void dispose()
- {
- if (this.server != null)
- {
- this.server.Shutdown("");
- this.server.Dispose();
- this.server = null;
-
- //On ferme le port ouvert par Upnp
- NAT.DeleteForwardingRule(this.netConf.Port, System.Net.Sockets.ProtocolType.Udp);
- }
- }
- #endregion
-
- #region Méthode événementielle
- void Datas_OnQueryDone(object sender, Kore.Events.WebEventArgs e)
- {
- if (e.Type == Kore.Events.RequeteType.setServer)
- {
- Kore.Datas.OnQueryDone -= Datas_OnQueryDone;
-
- if (!int.TryParse(e.Details, out this.serverID))
- this.serverID = -1;
- }
- }
- #endregion
- }
- #endregion
- }