/// <summary> /// The function which is used to proceed an incoming packet to the active TCPConnection /// </summary> /// <param name="con">The connection which received the packet</param> /// <param name="buf">byte[] array containing the raw content of the received packet</param> /// <param name="start">Start of the content in buf, usually 0</param> /// <param name="size">Size of the packet (minus start)</param> /// <returns>PacketIn -> Converted raw package to MemoryStream based PacketIn</returns> public PacketIn ProcessPacket(TCPConnection con, byte[] buf, int start, int size) { PacketIn packet = new PacketIn( buf, start, size ); switch ( packet.ID ) { case 0: // ResultMsg var res = new AUTH_PACKETS.RESULT( packet.ReadUInt16(), packet.ReadUInt16(), packet.ReadInt32() ); if ( res.nRequestPacket == 2005 ) { if ( res.nResult == 0 ) { con.SendTCP( CreateReportPacket() ); con.SendTCP( CreateCharacterListPacket() ); } else { con.Disconnect(); XLog.Log( "Can't connect to game server. Result: {0} - disconnecting...", res.nResult ); } } break; case 2004: // CharacterList m_iGameCharacterList = new GAME_PACKETS.CharacterList( packet ); XLog.Log( "Character selection. Please use /use ID to select a character." ); for ( int i = 0; i < m_iGameCharacterList.nCount; i++ ) { XLog.Log( "-> Character {0}: {1}", i + 1, m_iGameCharacterList.nList[i].szName ); } break; case 21: // ChatLocal var tmp = packet.ReadInt32(); string szSource = m_dHandles.ContainsKey( tmp ) ? m_dHandles[tmp] : "INVALID-HANDLE:" + tmp; int nLen = packet.ReadByte(); int nType = packet.ReadByte(); XLog.AddMessage( szSource, packet.ReadString( nLen ), nType ); break; case 22: // ChatMsg var pMessage = new GAME_PACKETS.ChatMessage( packet ); XLog.AddMessage( pMessage.szName, pMessage.szMessage, pMessage.nType ); break; case 3: // Enter: Handle -> Name, small hack so we don't have to read the full packet (which is f*****g large) if ( packet.ReadByte() == 0 ) { int key = packet.ReadInt32(); if ( m_dHandles.ContainsKey( key ) ) { m_dHandles.Remove( key ); } packet.Seek( 77, System.IO.SeekOrigin.Current ); string value = packet.ReadString( 19 ); m_dHandles.Add( key, value ); } break; case 507: // Property: Own Name -> Handle if ( m_dHandles.ContainsKey( 0 ) && m_tPingThread == null) { var szName = m_dHandles[0]; m_dHandles.Remove( 0 ); m_dHandles.Add( packet.ReadInt32(), szName ); m_tPingThread = new System.Threading.Thread( new System.Threading.ThreadStart( SendPingPacket ) ); m_tPingThread.IsBackground = true; m_tPingThread.Start(); } break; default: break; } return packet; }
/// <summary> /// Mostly unused method here, getting called when the socket is connected. /// </summary> /// <param name="id">ID</param> /// <param name="connection">Socket/TCPConnection</param> /// <returns>Nothing</returns> public void onConnect(int id, TCPConnection connection) { XLog.Log( "Connected to Game Server" ); }
/// <summary> /// Mostly unused method here, getting called when the socket is disconnected. /// </summary> /// <param name="id">ID</param> /// <param name="connection">Socket/TCPConnection</param> /// <returns>Nothing</returns> public void onDisconnect(int id, TCPConnection connection) { XLog.Log( "Disconnected from Game Server"); }
private void GenerateLoginPacket(byte[] key, TCPConnection con) { PacketOut o = new PacketOut( 10010 ); var a = EncryptAES( key, m_szPassword ); o.FillString( m_szName, 61 ); o.WriteInt32( a.Length ); o.Write( a, 0, a.Length ); o.Fill( 0, 61 - a.Length ); con.SendTCP( o ); }
public XClientGameEmulator(Config.ConfigNet conf, TCPManager man, XChat.XClientEmulator pBase, string pAccount, PacketOut pOut) { m_szAccount = pAccount; m_cGameConnection = new TCPConnection( man, null, this, conf ); try { m_cGameConnection.Start(); m_cGameConnection.SendTCP(CreateVersionPacket()); m_cGameConnection.SendTCP( pOut ); } catch { XLog.Log( "Can't connect to Game Server!" ); } }
/// <summary> /// Mostly unused method here, getting called when the socket is disconnected. /// </summary> /// <param name="id">ID</param> /// <param name="connection">Socket/TCPConnection</param> /// <returns>Nothing</returns> public void onDisconnect(int id, TCPConnection connection) { XLog.Log( "Disconnected from Authentication server." ); }
public PacketIn ProcessPacket(TCPConnection con, byte[] buf, int start, int size) { PacketIn packet = new PacketIn( buf, start, size ); switch ( packet.ID ) { case 72: // TS_AC_AES_KEY_IV var pAES = new AUTH_PACKETS.AES_KEY_IV( packet ); m_pAES_KEY = m_cRSA.PrivateDecrypt( pAES.nKey, OpenSSL.Crypto.RSA.Padding.PKCS1 ); GenerateLoginPacket( m_pAES_KEY, con ); break; case 10000: // TS_AC_RESULT var pResult = new AUTH_PACKETS.RESULT( packet.ReadUInt16(), packet.ReadUInt16(), packet.ReadInt32() ); if ( pResult.nLoginFlag == 1 ) { PacketOut o = new PacketOut( 10021 ); con.SendTCP( o ); } else { m_cAuthConnection.Disconnect(); XLog.Log( "Login failed. Result: {0} - Disconnecting...", pResult.nResult ); } m_szPassword = string.Empty; break; case 10022: // TS_AC_SERVER_LIST m_iAuthServerList = new AUTH_PACKETS.SERVER_LIST( packet ); XLog.Log( "Server selection. Please use /select ID to connect to one of the listed servers below." ); for ( int i = 0; i < m_iAuthServerList.count; i++ ) { XLog.Log( string.Format( "-> Server {0}: {1}", i + 1, m_iAuthServerList.list[i].server_name ) ); } break; case 10024: // TS_AC_SELECT_SERVER con.Disconnect(); var pSelectServer = new AUTH_PACKETS.SELECT_SERVER( packet, ref m_pAES_KEY ); Config.ConfigNet conf = new Config.ConfigNet(); conf.Port = m_iAuthServerList.list[m_nSelectedServerIdx].server_port; conf.ListenIp = System.Net.IPAddress.Parse( m_iAuthServerList.list[m_nSelectedServerIdx].server_ip ); PacketOut oEncrypt = new PacketOut( 2005 ); oEncrypt.FillString( m_szName, 61 ); oEncrypt.Write( pSelectServer.encrypted_data, 0, pSelectServer.encrypted_data.Length ); oEncrypt.FinalizeLengthAndChecksum(); con.Close(); m_cClientBase.CreateGameServerSession( oEncrypt, conf, m_szName ); break; default: break; } return packet; }
public XClientAuthEmulator(TCPManager man, Config.ConfigNet conf, string pAccount, string pPassword, XChat.XClientEmulator cBase) { m_szName = pAccount; m_szPassword = pPassword; m_cClientBase = cBase; try { m_cAuthConnection = new TCPConnection( man, null, this, conf ); m_cAuthConnection.Start(); m_cAuthConnection.SendTCP( this.CreateVersionPacket() ); m_cAuthConnection.SendTCP( this.CreateAESPacket() ); } catch { XLog.Log( "Can't connect to Authentication Server!" ); } }
/// <summary> /// Mostly unused method here, getting called when the socket is connected. /// </summary> /// <param name="id">ID</param> /// <param name="connection">Socket/TCPConnection</param> /// <returns>Nothing</returns> public void onConnect(int id, TCPConnection connection) { XLog.Log( "Connected to Authentication server." ); }
private void Disconnect(SocketAsyncEventArgs e) { TCPConnection token = e.UserToken as TCPConnection; token.Disconnect(); }
// This method is invoked when an asynchronous send operation completes. // The method issues another receive on the socket to read any additional // data sent from the client // // <param name="e"></param> private void ProcessSend(SocketAsyncEventArgs e) { TCPConnection token = e.UserToken as TCPConnection; if (e.SocketError == SocketError.Success) { try { Queue <byte[]> q = token.m_tcpQueue; int sent = e.BytesTransferred; int count = 0; byte[] data = e.Buffer; if (data == null) { return; } lock (q) { if (q.Count > 0) { // Log.WarnFormat("async sent {0} bytes, sending queued packets count: {1}", sent, q.Count); count = CombinePackets(data, q, data.Length, token); } if (count <= 0) { // Log.WarnFormat("async sent {0} bytes", sent); token.m_sendingTcp = false; return; } } int start = Environment.TickCount; token.m_writeEventArgs.SetBuffer(0, count); token.Socket.SendAsync(token.m_writeEventArgs); int took = Environment.TickCount - start; if (took > 100) { Console.WriteLine("{0} - ProcessSend took {0}ms! (TCP to client: {1})", "lol", took, token.ToString()); } } catch (ObjectDisposedException) { Console.WriteLine("Packet processor: ObjectDisposedException"); } catch (System.Net.Sockets.SocketException ex) { Console.WriteLine("Packet processor: SocketException: {0}", ex.SocketErrorCode); //GameServer.Instance.Disconnect(client); } catch (Exception ex) { // assure that no exception is thrown into the upper layers and interrupt game loops! Console.WriteLine("AsyncSendCallback. client: " + token + ", Exception: {0}", ex); //GameServer.Instance.Disconnect(client); } } else { token.Disconnect(); } }
private void ProcessAccept(SocketAsyncEventArgs e) { // Interlocked.Increment(ref m_numConnectedSockets); // Console.WriteLine("Client connection accepted. There are {0} clients connected to the server", // m_numConnectedSockets); // create a new connection object for this incoming connection Socket sock = null; try { if (m_listen == null) { return; } sock = e.AcceptSocket; // sock.SendBufferSize = m_iocp.BufferSize; // sock.ReceiveBufferSize = m_iocp.BufferSize; // sock.NoDelay = Constants.UseNoDelay; TCPConnection baseSocket = null; try { string ip = sock.Connected ? sock.RemoteEndPoint.ToString() : "socket disconnected"; //Globals.Log.Debug("{0} - Incoming connection from {1}", m_config.Name, ip); baseSocket = new TCPConnection(m_iocp, sock, m_networkHandler, m_config); baseSocket.Tag = new ConnectionTag(); // lock (_clients) // _clients.Add(baseSocket); baseSocket.OnConnect(); baseSocket.StartReceive(); } catch (SocketException) { //Globals.Log.Error("BaseServer SocketException"); if (baseSocket != null) { baseSocket.Disconnect(); } } catch (Exception ex) { //Globals.Log.Error("Client creation", ex); if (baseSocket != null) { baseSocket.Disconnect(); } } } catch { //Globals.Log.Error("AcceptCallback: Catch"); if (sock != null) // don't leave the socket open on exception { try { sock.Close(); } catch { } } } finally { if (m_listen != null) { // e.AcceptSocket = null; StartAccept(e); } } }
/// <summary> /// Combines queued packets in one stream. /// </summary> /// <param name="buf">The target buffer.</param> /// <param name="q">The queued packets.</param> /// <param name="length">The max stream len.</param> /// <param name="client">The client.</param> /// <returns>The count of bytes writen.</returns> private int CombinePackets(byte[] buf, Queue<byte[]> q, int length, TCPConnection client) { int i = 0; do { var pak = q.Peek(); if (i + pak.Length > buf.Length) { if (i == 0) { //Globals.Log.Warning("packet size {0} > buf size {1}, ignored; client: {2}\n{3}", pak.Length, buf.Length, client, //Marshal.ToHexDump("packet data:", pak)); q.Dequeue(); continue; } break; } Buffer.BlockCopy(m_encoding.Encode(pak), 0, buf, i, pak.Length); i += pak.Length; q.Dequeue(); } while (q.Count > 0); return i; }
private void ProcessAccept(SocketAsyncEventArgs e) { // Interlocked.Increment(ref m_numConnectedSockets); // Console.WriteLine("Client connection accepted. There are {0} clients connected to the server", // m_numConnectedSockets); // create a new connection object for this incoming connection Socket sock = null; try { if (m_listen == null) return; sock = e.AcceptSocket; // sock.SendBufferSize = m_iocp.BufferSize; // sock.ReceiveBufferSize = m_iocp.BufferSize; // sock.NoDelay = Constants.UseNoDelay; TCPConnection baseSocket = null; try { string ip = sock.Connected ? sock.RemoteEndPoint.ToString() : "socket disconnected"; //Globals.Log.Debug("{0} - Incoming connection from {1}", m_config.Name, ip); baseSocket = new TCPConnection(m_iocp, sock, m_networkHandler, m_config); baseSocket.Tag = new ConnectionTag(); // lock (_clients) // _clients.Add(baseSocket); baseSocket.OnConnect(); baseSocket.StartReceive(); } catch (SocketException) { //Globals.Log.Error("BaseServer SocketException"); if (baseSocket != null) baseSocket.Disconnect(); } catch (Exception ex) { //Globals.Log.Error("Client creation", ex); if (baseSocket != null) baseSocket.Disconnect(); } } catch { //Globals.Log.Error("AcceptCallback: Catch"); if (sock != null) // don't leave the socket open on exception { try { sock.Close(); } catch { } } } finally { if (m_listen != null) { // e.AcceptSocket = null; StartAccept(e); } } }