using System;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Threading;
using Holo.Virtual.Users;
using System.Collections;
using Holo.Source.Managers;
using Holo.Source.GameConnectionSystem;
using Holo.Managers;
namespace Holo.GameConnectionSystem
{
///
/// Asynchronous socket server for the game connections.
///
public static class gameSocketServer
{
#region Declares
private static Socket socketHandler;
private static int _Port;
private static int _maxConnections;
private static int _acceptedConnections;
private static HashSet _activeConnections;
//private static Hashtable connections = new Hashtable(2);
public static bool AcceptConnections = true;
#endregion
#region Methods
internal static void SetupSocket()
{
AcceptConnections = true;
if (_activeConnections != null)
_activeConnections.Clear();
_activeConnections = new HashSet();
_Port = int.Parse(Config.getTableEntry("server_game_port"));
_maxConnections = int.Parse(Config.getTableEntry("server_game_maxconnections"));
Out.WriteLine("Setting up socket on port " + _Port);
StartListening();
}
internal static void Destroy()
{
AcceptConnections = false;
HashSet Data = _activeConnections;
if (Data == null)
return;
foreach (int ConnectionID in Data)
{
freeConnection(ConnectionID);
}
}
internal static void StartListening()
{
try
{
if (_Port == 0 || _maxConnections == 0)
throw new NullReferenceException();
else
{
socketHandler = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint Endpoint = new IPEndPoint(IPAddress.Any, _Port);
socketHandler.Bind(Endpoint);
socketHandler.Listen(1000);
while (!AcceptConnections)
{
socketHandler.BeginAccept(new AsyncCallback(InncommingDataRequest), socketHandler);
}
}
}
catch (Exception e)
{
Out.WriteError("Fatal error during socket setup:\r" + e.ToString());
Holo.Eucalypt.Shutdown();
}
finally
{
socketHandler.BeginAccept(new AsyncCallback(InncommingDataRequest), socketHandler);
Out.WriteLine("Socket is ready");
}
}
internal static void InncommingDataRequest(IAsyncResult iAr)
{
try
{
Socket ReplyFromComputer = ((Socket)iAr.AsyncState).EndAccept(iAr);
string IP = ReplyFromComputer.RemoteEndPoint.ToString().Split(':')[0];
//int amount = GetConnectionAmount(IP);
if (userManager._Users.Count >= maxConnections || AcceptConnections == false)
{
ReplyFromComputer.Shutdown(SocketShutdown.Both);
ReplyFromComputer.Close();
return;
}
else if (connectionHelper.IpIsBanned(IP) == true)
{
Out.WriteRedText("Denied connection from [" + IP + "]");
ReplyFromComputer.Shutdown(SocketShutdown.Both);
ReplyFromComputer.Close();
}
else
{
int ConnectionRequestID = NewConnectionRequestID();
if (ConnectionRequestID > 0)
{
Out.WriteLine("Accepted connection: [" + ConnectionRequestID + "] from [" + IP + "]");
new gameConnection(ReplyFromComputer, ConnectionRequestID, IP);
}
}
}
catch { }
socketHandler.BeginAccept(new AsyncCallback(InncommingDataRequest), socketHandler);
}
internal static int NewConnectionRequestID()
{
_acceptedConnections++;
_activeConnections.Add(_acceptedConnections);
return _acceptedConnections;
}
///
/// Flags a connection as free.
///
/// The ID of the connection.
internal static void freeConnection(int connectionID)
{
if (_activeConnections.Contains(connectionID))
{
_activeConnections.Remove(connectionID);
Out.WriteLine("Flagged connection [" + connectionID + "] as free.");
_acceptedConnections--;
}
}
#endregion
#region Properities
//private static int GetConnectionAmount(string IP)
//{
// if (connections.ContainsKey(IP) == true)
// {
// return ((int)connections[IP]);
// }
// else
// {
// return 0;
// }
//}
internal static int maxConnections
{
///
/// Gets or set an Integer for the maximum amount of connections at the same time.
///
set
{
_maxConnections = value;
}
get
{
return _maxConnections;
}
}
internal static int acceptedConnections
{
///
/// Returns as integer of the accepted connections count since init.
///
get { return _acceptedConnections; }
}
#endregion
}
}