I have programmed a Gaming Emulator in C# and I have a class to handle all the connection side of things for the player, here we continuously listen for packets (each packet has a ID like a number, from 1 - 300), I just wondered is there any way I could speed it up or make it better performance wise? It seems a bit messy at the moment..
using Faze.Other.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace Faze.Base.Game.Habbo.Players
{
class PlayerConnection
{
private readonly Socket connectionSocket;
private bool packetsActive;
private readonly byte[] connectionBuffer;
private bool isPlayerDisconnecting;
public PlayerConnection(Socket playerSocket)
{
connectionSocket = playerSocket;
connectionSocket.SendBufferSize = 8000;
connectionBuffer = new byte[8000];
}
public Socket PlayersSocket
{
get
{
return connectionSocket;
}
}
private void ListenForPackets()
{
if (packetsActive)
return;
packetsActive = true;
try
{
connectionSocket.BeginReceive(connectionBuffer, 0, connectionBuffer.Length, SocketFlags.None, OnPacketReceived, connectionSocket);
}
catch
{
CloseSocket();
}
}
private void CloseSocket()
{
try
{
if (!packetsActive)
return;
packetsActive = false;
if (SocketConnected(connectionSocket))
{
connectionSocket.Shutdown(SocketShutdown.Both);
connectionSocket.Close();
}
connectionSocket.Dispose();
}
catch
{
}
}
private bool SocketConnected(Socket socket)
{
bool part1 = socket.Poll(1000, SelectMode.SelectRead);
bool part2 = (socket.Available == 0);
if (part1 && part2)
return false;
else
return true;
}
private void OnPacketReceived(IAsyncResult asyncResult)
{
try
{
int bytesReceived;
if (isPlayerDisconnecting)
return;
bytesReceived = connectionSocket.EndReceive(asyncResult);
if (bytesReceived == 0 /*|| bytesReceived != typeof(int)*/)
{
CloseSocket();
return;
}
var packet = new byte[bytesReceived];
Array.Copy(connectionBuffer, packet, bytesReceived);
if (packet.Length == 0)
return;
if (packet[0] == 60)
{
SendData("<?xml version=\"1.0\"?>\r\n<!DOCTYPE cross-domain-policy SYSTEM \"/xml/dtds/cross-domain-policy.dtd\">\r\n<cross-domain-policy>\r\n<allow-access-from domain=\"*\" to-ports=\"1-31111\" />\r\n</cross-domain-policy>\x0");
}
else if (packet[0] != 67)
{
int packetPosition = 0;
for (packetPosition = 0; packetPosition < packet.Length;)
{
int packetLength = ClassHelper.DecodeInt32(new[]
{
packet[packetPosition++],
packet[packetPosition++],
packet[packetPosition++],
packet[packetPosition++]
});
if (packetLength < 2 || packetLength > 4096)
return;
uint packetId = ClassHelper.DecodeUInt32(new[]
{
packet[packetPosition++],
packet[packetPosition++]
});
byte[] packetContent = new byte[packetLength - 2];
for (int i = 0; i < packetContent.Length && packetPosition < packet.Length; i++)
packetContent[i] = packet[packetPosition++];
// Short packetId is the packet id, todo: handle it.
}
}
}
catch
{
CloseSocket();
return;
}
finally
{
try
{
connectionSocket.BeginReceive(connectionBuffer, 0, connectionBuffer.Length, SocketFlags.None, OnPacketReceived, connectionSocket);
}
catch
{
CloseSocket();
}
}
}
public void CloseConnection()
{
if (isPlayerDisconnecting)
return;
isPlayerDisconnecting = true;
}
public bool PlayerDisconnecting
{
get { return isPlayerDisconnecting; }
}
private void SendData(string Data)
{
SendData(Encoding.UTF8.GetBytes(Data));
}
private void SendData(byte[] data)
{
string packetData = Encoding.Default.GetString(data);
connectionSocket.BeginSend(data, 0, data.Length, 0, OnSentDataCallback, null);
}
private void OnSentDataCallback(IAsyncResult asyncResult)
{
try
{
connectionSocket.EndSend(asyncResult);
}
catch
{
CloseSocket();
}
}
}
}
ClassHelper class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Faze.Other.Util
{
public static class ClassHelper
{
public static int DecodeInt32(byte[] toDecode)
{
if ((((toDecode[0] | toDecode[1]) | toDecode[2]) | toDecode[3]) < 0)
return -1;
return ((((toDecode[0] << 0x18) + (toDecode[1] << 0x10)) + (toDecode[2] << 8)) + toDecode[3]);
}
public static uint DecodeUInt32(byte[] toDecode)
{
return (uint)DecodeInt32(toDecode);
}
}
}