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); } 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 } }