using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using Holo.Virtual.Users;
using Holo.Socketservers;
using Holo.GameConnectionSystem;
using Holo.Source.Socket_servers.Game_Socketsystem;
using System.Threading;
namespace Holo.Source.GameConnectionSystem
{
public class gameConnection
{
#region Declares
private AsyncCallback ReceiveCallback;
private AsyncCallback SendCallback;
private bool SocketClosed = false;
private byte[] dataBuffer = new byte[1024];
private int _ConnectionID;
private messageHandler Handler;
private Socket ClientSocket;
private virtualUser ConnectedUser;
private string LastReceivedPacket = "";
private string LastSentPacket = "";
private string IPForPrivateUse = "";
public bool FlashON;
#endregion
#region Constructor
public gameConnection(Socket _ClientSocket, int _ConnectionID)
{
this.Handler = new messageHandler(this);
this.ConnectedUser = new virtualUser(this);
Handler.SetUser(ConnectedUser);
ConnectedUser.SetHandler(Handler);
this.ClientSocket = _ClientSocket;
this._ConnectionID = _ConnectionID;
IPForPrivateUse = connectionRemoteIP;
ConnectedUser.pingOK = true;
ReceiveCallback = new AsyncCallback(ReceivedData);
SendCallback = new AsyncCallback(sentData);
WaitForData();
Ping();
//connectionHelper.AddConnection(this, _ConnectionID);
}
#endregion
#region Properities
internal string connectionRemoteIP
{
get
{
return ClientSocket.RemoteEndPoint.ToString().Split(':')[0];
}
}
internal messageHandler RemoteHandler
{
get
{
return Handler;
}
}
internal bool IsActive
{
get
{
try
{
return (bool)ClientSocket.Connected;
}
catch
{
return false;
}
}
}
internal int ConnectionID
{
get
{
return this._ConnectionID;
}
}
#endregion
#region Methods
private void WaitForData()
{
try
{
ClientSocket.BeginReceive(dataBuffer, 0, dataBuffer.Length, SocketFlags.None, ReceiveCallback, ClientSocket);
}
catch
{
Close();
}
}
internal void Ping()
{
if (!ClientSocket.Connected)
Close();
//else
//sendData("@@");
}
private void ReceivedData(IAsyncResult iAr)
{
try
{
int bytesReceived = new int();
try
{
bytesReceived = ClientSocket.EndReceive(iAr);
}
catch
{
Close();
return;
}
StringBuilder DataBuffer = new StringBuilder();
DataBuffer.Append(System.Text.Encoding.Default.GetString(dataBuffer, 0, bytesReceived));
string connectionData = System.Text.Encoding.Default.GetString(dataBuffer, 0, bytesReceived);
if (connectionData == "" + Convert.ToChar(0))
{
Out.WriteLine("[Packet] [XML] [FLASH]");
this.sendPolicy("" + "\r\n" + "" + "\r\n" + "" + "\r\n" + " " + "\r\n" + "" + Convert.ToChar(0));
}
//while (connectionData != "")
//{
// Out.WriteLine("[RECV]" + connectionData.Substring(3, 2));
// int v = Encoding.decodeB64(connectionData.Substring(1, 2));
// Handler.ProcessPacket(connectionData.Substring(3, v));
// connectionData = connectionData.Substring(v + 3);
// Out.WriteTrace("Processing packet part");
//}
if (connectionData.ToString() == "" || DataBuffer.ToString().Contains("\x01") || DataBuffer.ToString().Contains("\x02") || DataBuffer.ToString().Contains("\x05") || DataBuffer.ToString().Contains("\x09"))
{
Close();
return;
}
while (connectionData.Length > 0)
{
//int v = Encoding.decodeB64(DataBuffer.ToString().Substring(1, 2));
//string Packet = DataBuffer.ToString().Substring(3, v);
//LastReceivedPacket = Packet;
//try { Handler.ProcessPacket(Packet); }
//catch (Exception Bug) { HandleException(Bug); }
//DataBuffer.Remove(0, 3 + v);
Out.WriteLine("[Packet] " + connectionData.Substring(3, 2));
int v = Encoding.decodeB64(connectionData.Substring(1, 2));
Handler.ProcessPacket(connectionData.Substring(3, v));
connectionData = connectionData.Substring(v + 3);
}
}
catch (Exception e)
{
//Out.WriteDCError(e.ToString());
CreateDCReport(true, e);
Close();
}
finally
{
WaitForData();
}
}
private void HandleException(Exception e)
{
try
{
if (ConnectedUser == null)
Close();
else if (ConnectedUser.Room == null)
Close();
else
ConnectedUser.leaveCurrentRoom("An error occurred, please reload the room", false);
}
catch { Close(); }
CreateDCReport(true, e);
}
internal void Close()
{
if (!SocketClosed)
{
SocketClosed = true;
try
{
ClientSocket.Shutdown(SocketShutdown.Both);
ClientSocket.Close();
}
catch { }
Handler.Clear();
ConnectedUser.Reset();
//connectionHelper.RemoveConnection(_ConnectionID);
gameSocketServer.freeConnection(_ConnectionID);
Crash();
}
}
internal void sendData(string Data)
{
try
{
LastSentPacket = Data;
Out.WriteError("Packet :: [" + Data + "]");
//Out.WriteSpecialLine(Data.Replace("\r", @"\r"), Out.logFlags.MehAction, ConsoleColor.White, ConsoleColor.DarkCyan, "> []", 2, ConsoleColor.Cyan);
byte[] dataBytes = System.Text.Encoding.Default.GetBytes(Data + Convert.ToChar(1));
ClientSocket.BeginSend(dataBytes, 0, dataBytes.Length, 0, SendCallback, ClientSocket);
}
catch
{
Close();
}
}
internal void sendPolicy(string Data)
{
try
{
byte[] dataBytes = System.Text.Encoding.Default.GetBytes(Data);
ClientSocket.BeginSend(dataBytes, 0, dataBytes.Length, 0, new AsyncCallback(sentData), null);
Out.WriteSpecialLine(Data.Replace(Convert.ToChar(13).ToString(), "{13}"), Out.logFlags.MehAction, ConsoleColor.White, ConsoleColor.DarkYellow, "> [" + Thread.GetDomainID() + "]", 2, ConsoleColor.Yellow);
}
catch
{
Close();
}
}
private void sentData(IAsyncResult iAr)
{
try { ClientSocket.EndSend(iAr); }
catch
{
Close();
}
}
private void Crash()
{
ClientSocket = null;
dataBuffer = null;
_ConnectionID = 0;
ConnectedUser = null;
Handler = null;
SocketClosed = true;
ReceiveCallback = null;
}
private void CreateDCReport(bool RandomDC, Exception _Exception)
{
bool UserKickable = false;
if (ConnectedUser != null)
UserKickable = (ConnectedUser.Room != null);
StringBuilder Report = new StringBuilder();
DateTime Now = DateTime.Now;
string NewLine = "\r\n";
Report.Append("Event ocurred: " + Now.ToString() + NewLine);
Report.Append("DC was random: " + RandomDC.ToString() + NewLine);
if (ConnectedUser != null)
{
Report.Append("UserID: " + ConnectedUser.userID + NewLine);
if (UserKickable)
Report.Append("User was in room: " + ConnectedUser.Room.roomID + NewLine);
}
Report.Append("IP: " + IPForPrivateUse + NewLine);
Report.Append("Socketdata:" + NewLine);
Report.Append("Last received data: " + LastReceivedPacket + NewLine);
Report.Append("Last sent data: " + LastSentPacket + NewLine);
if (ClientSocket != null)
Report.Append("Socketstatus: " + ClientSocket.Connected.ToString() + NewLine);
Report.Append("Exception:" + NewLine + _Exception.ToString() + NewLine);
Out.PrimaryErrorWriter(Report.ToString());
if (UserKickable)
{
ConnectedUser.leaveCurrentRoom("An error ocurred, please reload the room", false);
WaitForData();
}
else
Close();
}
internal void SendRawData(byte[] PacketData)
{
ClientSocket.Send(PacketData);
}
#endregion
}
}