using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using xServer.Core.Packets; namespace xServer.Core { public class Server { public long BytesReceived { get; set; } public long BytesSent { get; set; } public event ServerStateEventHandler ServerState; public delegate void ServerStateEventHandler(Server s, bool listening); private void OnServerState(bool listening) { if (ServerState != null) { ServerState(this, listening); } } public event ClientStateEventHandler ClientState; public delegate void ClientStateEventHandler(Server s, Client c, bool connected); private void OnClientState(Client c, bool connected) { if (ClientState != null) { ClientState(this, c, connected); } } public event ClientReadEventHandler ClientRead; public delegate void ClientReadEventHandler(Server s, Client c, IPacket packet); private void OnClientRead(Client c, IPacket packet) { if (ClientRead != null) { ClientRead(this, c, packet); } } public event ClientWriteEventHandler ClientWrite; public delegate void ClientWriteEventHandler(Server s, Client c, IPacket packet, long length); private void OnClientWrite(Client c, IPacket packet, long length, byte[] rawData) { if (ClientWrite != null) { ClientWrite(this, c, packet, length); } } private Socket _handle; private SocketAsyncEventArgs _item; private bool Processing { get; set; } public bool Listening { get; private set; } private List _clients; public Client[] Clients { get { return Listening ? _clients.ToArray() : new Client[0]; } } public int ConnectedClients { get; set; } public Dictionary AllTimeConnectedClients { get; set; } private List PacketTypes { get; set; } public Server() { PacketTypes = new List(); AllTimeConnectedClients = new Dictionary(); } public void Listen(ushort port) { try { if (!Listening) { _clients = new List(); _item = new SocketAsyncEventArgs(); _item.Completed += Process; if (_handle != null) { try { _handle.Close(); } catch { } } _handle = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _handle.Bind(new IPEndPoint(IPAddress.Any, port)); _handle.Listen(1000); Processing = false; Listening = true; OnServerState(true); if (!_handle.AcceptAsync(_item)) Process(null, _item); } } catch (Exception) { Disconnect(); } } /// /// Adds a Type to the serializer so a message can be properly serialized. /// /// The parent type, i.e.: IPacket /// Type to be added public void AddTypeToSerializer(Type parent, Type type) { if (type == null || parent == null) throw new ArgumentNullException(); PacketTypes.Add(type); } public void AddTypesToSerializer(Type parent, params Type[] types) { foreach (Type type in types) AddTypeToSerializer(parent, type); } private void Process(object s, SocketAsyncEventArgs e) { try { if (e.SocketError == SocketError.Success) { Client T = new Client(this, e.AcceptSocket, PacketTypes.ToArray()); lock (_clients) { _clients.Add(T); T.ClientState += HandleState; T.ClientRead += OnClientRead; T.ClientWrite += OnClientWrite; OnClientState(T, true); } e.AcceptSocket = null; if (!_handle.AcceptAsync(e)) Process(null, e); } else Disconnect(); } catch { Disconnect(); } } public void Disconnect() { if (Processing) return; Processing = true; if (_handle != null) _handle.Close(); lock (_clients) { while (_clients.Count != 0) { _clients[0].Disconnect(); try { _clients.RemoveAt(0); } catch { } } } Listening = false; OnServerState(false); } private void HandleState(Client s, bool open) { lock (_clients) { _clients.Remove(s); OnClientState(s, false); s.Value.DisposeForms(); } } } }