public NetState(Socket socket, MessagePump messagePump) { m_Socket = socket; m_Buffer = new ByteQueue(); m_Seeded = false; m_Running = false; m_RecvBuffer = m_ReceiveBufferPool.AcquireBuffer(); m_MessagePump = messagePump; m_Gumps = new List <Gump>(); m_HuePickers = new List <HuePicker>(); m_Menus = new List <IMenu>(); m_Trades = new List <SecureTrade>(); m_SendQueue = new SendQueue(); m_NextCheckActivity = DateTime.Now + TimeSpan.FromMinutes(0.5); m_Instances.Add(this); try { m_Address = Utility.Intern((( IPEndPoint )m_Socket.RemoteEndPoint).Address); m_ToString = m_Address.ToString(); } catch (Exception ex) { TraceException(ex); m_Address = IPAddress.None; m_ToString = "(error)"; } m_ConnectedOn = DateTime.Now; if (m_CreatedCallback != null) { m_CreatedCallback(this); } }
/** client constructor, used to connect to other UO servers */ public NetState(IPEndPoint connectTo, MessagePump messagePump) { m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); m_EndPoint = connectTo; m_Buffer = new ByteQueue(); m_Seeded = true; m_Running = false; m_Client = true; m_RecvBuffer = m_ReceiveBufferPool.AquireBuffer(); m_MessagePump = messagePump; m_SendQueue = new SendQueue(); m_NextCheckActivity = DateTime.Now + TimeSpan.FromMinutes(0.5); m_Instances.Add(this); try { m_Address = m_EndPoint.Address; m_ToString = "[To GameServer " + m_EndPoint.ToString() + "]"; } catch { m_Address = IPAddress.None; m_ToString = "(error)"; } if (m_CreatedCallback != null) { m_CreatedCallback(this); } }
public NetState(Socket socket, MessagePump messagePump) { m_Socket = socket; m_Buffer = new ByteQueue(); m_Seeded = false; m_Running = false; m_RecvBuffer = m_ReceiveBufferPool.AquireBuffer(); m_MessagePump = messagePump; m_SendQueue = new SendQueue(); m_NextCheckActivity = DateTime.Now + TimeSpan.FromMinutes(0.5); m_Instances.Add(this); try{ m_Address = ((IPEndPoint)m_Socket.RemoteEndPoint).Address; m_ToString = m_Address.ToString(); } catch { m_Address = IPAddress.None; m_ToString = "(error)"; } m_Super = Core.Config.Login.IsSuperClient(m_ToString); if (m_CreatedCallback != null) { m_CreatedCallback(this); } }
public NetState( Socket socket, NetServer netServer ) { m_Socket = socket; m_NetServer = netServer; m_Buffer = new ByteQueue(); m_Running = false; m_RecvBuffer = m_ReceiveBufferPool.AcquireBuffer(); m_SendQueue = new SendQueue(); m_NextCheckActivity = DateTime.Now + TimeSpan.FromMinutes( 0.5 ); try { m_Address = ( (IPEndPoint) m_Socket.RemoteEndPoint ).Address; m_ToString = m_Address.ToString(); } catch ( Exception ex ) { TraceException( ex ); m_Address = IPAddress.None; m_ToString = "(error)"; } if ( m_CreatedCallback != null ) m_CreatedCallback( this ); }
private static bool HandleSeed(NetState ns, ByteQueue buffer) { if (buffer.GetPacketID() == 0xEF) { // new packet in client 6.0.5.0 replaces the traditional seed method with a seed packet // 0xEF = 239 = multicast IP, so this should never appear in a normal seed. So this is backwards compatible with older clients. ns.Seeded = true; return(true); } else if (buffer.Length >= 4) { byte[] m_Peek = new byte[4]; buffer.Dequeue(m_Peek, 0, 4); int seed = (m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]; if (seed == 0) { Utility.WriteConsole(ConsoleColor.Yellow, "Login: {0}: Invalid client detected, disconnecting", ns); ns.Dispose(); return(false); } ns.m_Seed = seed; ns.Seeded = true; return(true); } else { return(false); } }
private void InvokeReceived(NetState ns, ByteQueue buffer, out bool throttle) { throttle = false; if (Received != null) { Received(ns, buffer, out throttle); } }
public virtual void Dispose(bool flush) { if (m_Socket == null || m_Disposing) { return; } m_Disposing = true; if (flush) { flush = Flush(); } try { m_Socket.Shutdown(SocketShutdown.Both); } catch (SocketException ex) { TraceException(ex); } try { m_Socket.Close(); } catch (SocketException ex) { TraceException(ex); } if (m_RecvBuffer != null) { lock (m_ReceiveBufferPool) m_ReceiveBufferPool.ReleaseBuffer(m_RecvBuffer); } m_Socket = null; m_Buffer = null; m_RecvBuffer = null; #if NewAsyncSockets m_ReceiveEventArgs = null; m_SendEventArgs = null; #else m_OnReceive = null; m_OnSend = null; #endif m_Running = false; lock (m_Disposed) m_Disposed.Enqueue(this); lock (m_SendQueue) if (/*!flush &&*/ !m_SendQueue.IsEmpty) { m_SendQueue.Clear(); } }
public virtual void Dispose(bool flush) { // Genova: Usuário desconectando do servidor... if (m_Mobile is Mobile) { ControladorODBC.ODBCDispose(m_Mobile); } if (m_Socket == null || m_Disposing) { return; } m_Disposing = true; if (flush) { flush = Flush(); } try { m_Socket.Shutdown(SocketShutdown.Both); } catch (SocketException ex) { TraceException(ex); } try { m_Socket.Close(); SocketPool.ReleaseSocket(m_Socket); } catch (SocketException ex) { TraceException(ex); } if (m_RecvBuffer != null) { m_ReceiveBufferPool.ReleaseBuffer(m_RecvBuffer); } m_Socket = null; m_Buffer = null; m_RecvBuffer = null; m_OnReceive = null; m_OnSend = null; m_Running = false; m_Disposed.Enqueue(this); if (/*!flush &&*/ !m_SendQueue.IsEmpty) { lock (m_SendQueue) m_SendQueue.Clear(); } }
public void FinishDispose() { if (m_DisposeFinished) { return; } m_DisposeFinished = true; try { m_Socket.Shutdown(SocketShutdown.Both); } catch (SocketException ex) { TraceException(ex); } try { m_Socket.Close(); } catch (SocketException ex) { TraceException(ex); } if (m_RecvBuffer != null) { m_ReceiveBufferPool.ReleaseBuffer(m_RecvBuffer); } m_Socket = null; m_Buffer = null; m_RecvBuffer = null; m_Running = false; m_NetServer.OnDisposed(this); if (!m_SendQueue.IsEmpty) { lock (m_SendQueue) m_SendQueue.Clear(); } }
private bool HandleSeed(NetState ns, ByteQueue buffer) { #region Enhance Client if (buffer.GetPacketID() == 0xFF) { // Packet 255 = 0xFF = Client KR. ns.IsKRClient = true; Console.WriteLine("KR-Client detected", ns); } #endregion if (buffer.GetPacketID() == 0xEF) { // new packet in client 6.0.5.0 replaces the traditional seed method with a seed packet // 0xEF = 239 = multicast IP, so this should never appear in a normal seed. So this is backwards compatible with older clients. ns.Seeded = true; return(true); } else if (buffer.Length >= 4) { var m_Peek = new byte[4]; buffer.Dequeue(m_Peek, 0, 4); int seed = (m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]; if (seed == 0) { Utility.PushColor(ConsoleColor.Green); Console.WriteLine("Login: {0}: Invalid client detected, disconnecting", ns); Utility.PopColor(); ns.Dispose(); return(false); } ns.m_Seed = seed; ns.Seeded = true; return(true); } else { return(false); } }
public NetState(Socket socket, MessagePump messagePump) { Socket = socket; m_Buffer = new ByteQueue(); m_Running = false; m_RecvBuffer = m_ReceiveBufferPool.AcquireBuffer(); m_MessagePump = messagePump; m_Gumps = new List <Gump>(); m_HuePickers = new List <HuePicker>(); m_Menus = new List <IMenu>(); m_Trades = new List <SecureTrade>(); m_SendQueue = new SendQueue(); m_NextCheckActivity = Core.TickCount + 30000; m_Instances.Add(this); try { m_Address = Utility.Intern(((IPEndPoint)Socket.RemoteEndPoint).Address); m_ToString = m_Address.ToString(); } catch (Exception ex) { TraceException(ex); m_Address = IPAddress.None; m_ToString = "(error)"; } m_ConnectedOn = DateTime.UtcNow; UpdateRange = Core.GlobalUpdateRange; if (CreatedCallback != null) { CreatedCallback(this); } }
private void HandlePending() { lock ( m_PendingQueue ) { while (m_PendingQueue.Count > 0) { NetState ns = m_PendingQueue.Dequeue(); if (ns.Running) { ByteQueue buffer = ns.Buffer; bool throttle = false; if (buffer != null && buffer.Length > 0) { lock ( buffer ) { InvokeReceived(ns, buffer, out throttle); } } if (ns.Running) { if (throttle) { m_ThrottledQueue.Enqueue(ns); } else { ns.Continue(); } } } } while (m_ThrottledQueue.Count > 0) { m_PendingQueue.Enqueue(m_ThrottledQueue.Dequeue()); } } }
public void Dispose(bool flush) { if (m_Socket == null || m_Disposing) { return; } m_Disposing = true; if (flush) { flush = Flush(); } try { m_Socket.Shutdown(SocketShutdown.Both); } catch {} try { m_Socket.Close(); } catch {} if (m_RecvBuffer != null) { m_ReceiveBufferPool.ReleaseBuffer(m_RecvBuffer); } m_Socket = null; m_Buffer = null; m_RecvBuffer = null; m_OnReceive = null; m_OnSend = null; m_Running = false; m_Disposed.Enqueue(this); if (/*!flush &&*/ !m_SendQueue.IsEmpty) { lock (m_SendQueue) m_SendQueue.Clear(); } }
private void FinishDisposeNoLock() { if (m_DisposeFinished) { return; } m_DisposeFinished = true; try { m_Socket.Shutdown(SocketShutdown.Both); } catch {} try { m_Socket.Close(); } catch {} if (m_RecvBuffer != null) { m_ReceiveBufferPool.ReleaseBuffer(m_RecvBuffer); } m_Socket = null; m_Buffer = null; m_RecvBuffer = null; m_OnReceive = null; m_OnSend = null; m_Running = false; lock (m_Disposed) m_Disposed.Enqueue(this); if (/*!flush &&*/ !m_SendQueue.IsEmpty) { lock (m_SendQueue) m_SendQueue.Clear(); } }
public static bool HandleSeed(NetState ns, ByteQueue buffer) { if (buffer.GetPacketID() == 0xEF) { // new packet in client 6.0.5.0 replaces the traditional seed method with a seed packet // 0xEF = 239 = multicast IP, so this should never appear in a normal seed. So this is backwards compatible with older clients. ns.Seeded = true; return(true); } if (buffer.Length >= 4) { byte[] m_Peek = new byte[4]; buffer.Dequeue(m_Peek, 0, 4); uint seed = (uint)((m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]); if (seed == 0) { Utility.PushColor(ConsoleColor.Red); Console.WriteLine("Login: {0}: Invalid Client", ns); Utility.PopColor(); ns.Dispose(); return(false); } ns.Seed = seed; ns.Seeded = true; return(true); } return(false); }
public bool HandleReceive(NetState ns) { ByteQueue buffer = ns.Buffer; if (buffer == null || buffer.Length <= 0) { return(true); } lock ( buffer ) { int length = buffer.Length; if (!ns.Seeded) { if (buffer.GetPacketID() == 0xEF) { // new packet in client 6.0.5.0 replaces the traditional seed method with a seed packet // 0xEF = 239 = multicast IP, so this should never appear in a normal seed. So this is backwards compatible with older clients. ns.Seeded = true; } else if (buffer.Length >= 4) { buffer.Dequeue(m_Peek, 0, 4); int seed = (m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]; if (seed == 0) { Console.WriteLine("Login: {0}: Invalid client detected, disconnecting", ns); ns.Dispose(); return(false); } ns.m_Seed = seed; ns.Seeded = true; length = buffer.Length; } else { return(true); } } while (length > 0 && ns.Running) { int packetID = buffer.GetPacketID(); if (!ns.SentFirstPacket && packetID != 0xF0 && packetID != 0xF1 && packetID != 0xCF && packetID != 0x80 && packetID != 0x91 && packetID != 0xA4 && packetID != 0xEF) { Console.WriteLine("Client: {0}: Encrypted client detected, disconnecting", ns); ns.Dispose(); break; } PacketHandler handler = ns.GetHandler(packetID); if (handler == null) { byte[] data = new byte[length]; length = buffer.Dequeue(data, 0, length); new PacketReader(data, length, false).Trace(ns); break; } int packetLength = handler.Length; if (packetLength <= 0) { if (length >= 3) { packetLength = buffer.GetPacketLength(); if (packetLength < 3) { ns.Dispose(); break; } } else { break; } } if (length >= packetLength) { if (handler.Ingame && ns.Mobile == null) { Console.WriteLine("Client: {0}: Sent ingame packet (0x{1:X2}) before having been attached to a mobile", ns, packetID); ns.Dispose(); break; } else if (handler.Ingame && ns.Mobile.Deleted) { ns.Dispose(); break; } else { ThrottlePacketCallback throttler = handler.ThrottleCallback; if (throttler != null && !throttler(ns)) { m_Throttled.Enqueue(ns); return(false); } PacketReceiveProfile prof = PacketReceiveProfile.Acquire(packetID); if (prof != null) { prof.Start(); } byte[] packetBuffer; if (BufferSize >= packetLength) { packetBuffer = m_Buffers.AcquireBuffer(); } else { packetBuffer = new byte[packetLength]; } packetLength = buffer.Dequeue(packetBuffer, 0, packetLength); PacketReader r = new PacketReader(packetBuffer, packetLength, handler.Length != 0); handler.OnReceive(ns, r); length = buffer.Length; if (BufferSize >= packetLength) { m_Buffers.ReleaseBuffer(packetBuffer); } if (prof != null) { prof.Finish(packetLength); } } } else { break; } } } return(true); }
public void HandleReceive(NetState ns) { ByteQueue buffer = ns.Buffer; if (buffer == null || buffer.Length <= 0) { return; } lock (buffer) { if (!ns.Seeded) { if (!HandleSeed(ns, buffer)) { return; } } int length = buffer.Length; while (length > 0 && ns.Running) { int packetID = buffer.GetPacketID(); if (CheckEncrypted(ns, packetID)) { break; } PacketHandler handler = ns.GetHandler(packetID); if (handler == null) { byte[] data = new byte[length]; length = buffer.Dequeue(data, 0, length); new PacketReader(data, length, false).Trace(ns); break; } int packetLength = handler.Length; if (packetLength <= 0) { if (length >= 3) { packetLength = buffer.GetPacketLength(); if (packetLength < 3) { ns.Dispose(); break; } } else { break; } } if (length >= packetLength) { if (handler.Ingame) { if (ns.Mobile == null) { Console.WriteLine("Client: {0}: Sent ingame packet (0x{1:X2}) before having been attached to a mobile", ns, packetID); ns.Dispose(); break; } else if (ns.Mobile.Deleted) { ns.Dispose(); break; } } ThrottlePacketCallback throttler = handler.ThrottleCallback; if (throttler != null && !throttler(ns)) { // must be one of the other throttled packets m_Throttled.Enqueue(ns); return; } PacketReceiveProfile prof = null; if (Core.Profiling) { prof = PacketReceiveProfile.Acquire(packetID); } if (prof != null) { prof.Start(); } byte[] packetBuffer; if (BufferSize >= packetLength) { packetBuffer = m_Buffers.AcquireBuffer(); } else { packetBuffer = new byte[packetLength]; } packetLength = buffer.Dequeue(packetBuffer, 0, packetLength); PacketReader r = new PacketReader(packetBuffer, packetLength, handler.Length != 0); handler.OnReceive(ns, r); length = buffer.Length; if (BufferSize >= packetLength) { m_Buffers.ReleaseBuffer(packetBuffer); } if (prof != null) { prof.Finish(packetLength); } } else { break; } } } }
public void HandleReceive(NetState ns) { ByteQueue buffer = ns.Buffer; if (buffer == null || buffer.Length <= 0) { return; } lock (buffer) { if (!ns.Seeded) { if (!HandleSeed(ns, buffer)) { return; } } int length = buffer.Length; while (length > 0 && ns.Running) { int packetID = buffer.GetPacketID(); if (CheckEncrypted(ns, packetID)) { break; } PacketHandler handler = ns.GetHandler(packetID); if (handler == null) { var data = new byte[length]; length = buffer.Dequeue(data, 0, length); new PacketReader(data, length, false).Trace(ns); break; } int packetLength = handler.Length; if (packetLength <= 0) { if (length >= 3) { packetLength = buffer.GetPacketLength(); if (packetLength < 3) { ns.Dispose(); break; } } else { break; } } if (length >= packetLength) { if (handler.Ingame) { if (ns.Mobile == null) { Utility.PushColor(ConsoleColor.DarkRed); Console.WriteLine( "Client: {0}: Sent ingame packet (0x{1:X2}) before having been attached to a mobile", ns, packetID); Utility.PopColor(); ns.Dispose(); break; } else if (ns.Mobile.Deleted) { ns.Dispose(); break; } } ThrottlePacketCallback throttler = handler.ThrottleCallback; if (throttler != null && !throttler(ns)) { m_Throttled.Enqueue(ns); return; } PacketReceiveProfile prof = null; if (Core.Profiling) { prof = PacketReceiveProfile.Acquire(packetID); } if (prof != null) { prof.Start(); } byte[] packetBuffer; if (BufferSize >= packetLength) { packetBuffer = m_Buffers.AcquireBuffer(); } else { packetBuffer = new byte[packetLength]; } packetLength = buffer.Dequeue(packetBuffer, 0, packetLength); PacketReader r = new PacketReader(packetBuffer, packetLength, handler.Length != 0); handler.OnReceive(ns, r); length = buffer.Length; if (BufferSize >= packetLength) { m_Buffers.ReleaseBuffer(packetBuffer); } if (prof != null) { prof.Finish(packetLength); } } else { break; } } } #region Enhance Client // Would be nicer to detect the enhanced client in clientversion.cs // It seems that UOKR-EH sends a version number bigger 66.0.0.0, UOSA-EH bigger 67.0.0.0 try { if (ns.Version.Major > 8) { ns.IsKRClient = true; } } //Standard classic client does not display version this early, so we can rule SA enhanced client out catch { ns.IsKRClient = false; } return; #endregion }
public bool HandleReceive(NetState ns) { ByteQueue buffer = ns.Buffer; if (buffer == null || buffer.Length <= 0) { return(true); } lock ( buffer ) { int length = buffer.Length; if (!ns.Seeded) { if (buffer.Length >= 4) { buffer.Dequeue(m_Peek, 0, 4); int seed = (m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]; if (seed == 0) { Console.WriteLine("Login: {0}: Invalid client detected, disconnecting", ns); ns.Dispose(); return(false); } ns.m_Seed = seed; ns.Seeded = true; length = buffer.Length; } else { return(true); } } while (length > 0 && ns.Running) { int packetID = buffer.GetPacketID(); if (!ns.SentFirstPacket && packetID != 0xF1 && packetID != 0xCF && packetID != 0x80 && packetID != 0x91 && packetID != 0xA4) { Console.WriteLine("Client: {0}: Encrypted client detected, disconnecting", ns); ns.Dispose(); break; } PacketHandler handler = PacketHandlers.GetHandler(packetID); if (handler == null) { byte[] data = new byte[length]; length = buffer.Dequeue(data, 0, length); new PacketReader(data, length, false).Trace(ns); break; } int packetLength = handler.Length; if (packetLength <= 0) { if (length >= 3) { packetLength = buffer.GetPacketLength(); if (packetLength < 3) { ns.Dispose(); break; } } else { break; } } if (length >= packetLength) { if (handler.Ingame && ns.Mobile == null) { Console.WriteLine("Client: {0}: Sent ingame packet (0x{1:X2}) before having been attached to a mobile", ns, packetID); ns.Dispose(); break; } else if (handler.Ingame && ns.Mobile.Deleted) { ns.Dispose(); break; } else { ThrottlePacketCallback throttler = handler.ThrottleCallback; if (throttler != null && !throttler(ns)) { m_Throttled.Enqueue(ns); return(false); } PacketProfile profile = PacketProfile.GetIncomingProfile(packetID); DateTime start = (profile == null ? DateTime.MinValue : DateTime.Now); byte[] packetBuffer; if (BufferSize >= packetLength) { packetBuffer = m_Buffers.AcquireBuffer(); } else { packetBuffer = new byte[packetLength]; } packetLength = buffer.Dequeue(packetBuffer, 0, packetLength); PacketReader r = new PacketReader(packetBuffer, packetLength, handler.Length != 0); handler.OnReceive(ns, r); length = buffer.Length; if (BufferSize >= packetLength) { m_Buffers.ReleaseBuffer(packetBuffer); } if (profile != null) { profile.Record(packetLength, DateTime.Now - start); } } } else { break; } } } return(true); }
private void OnReceived(NetState state, ByteQueue buffer, out bool throttle) { throttle = false; GameClient client; if (!m_Clients.TryGetValue(state, out client)) { Logger.Error("Inconsistent game server state: game client for {0} not found", state); return; } if (!client.Seeded) { if (buffer.GetPacketID() == 0xEF) { client.Seeded = true; } else if (buffer.Length >= 4) { byte[] peek = new byte[4]; buffer.Dequeue(peek, 0, 4); int seed = (peek[0] << 24) | (peek[1] << 16) | (peek[2] << 8) | peek[3]; if (seed == 0) { Console.WriteLine("Login: {0}: Invalid client detected, disconnecting", client); client.Dispose(); return; } client.m_Seed = seed; client.Seeded = true; } else { return; // Need at least 4 bytes for the seed } } int length = buffer.Length; while (length > 0 && buffer.Length > 0) { int packetID = buffer.GetPacketID(); if (!client.SentFirstPacket && packetID != 0xF1 && packetID != 0xCF && packetID != 0x80 && packetID != 0x91 && packetID != 0xA4 && packetID != 0xEF) { Console.WriteLine("Client: {0}: Encrypted client detected, disconnecting", client); client.Dispose(); return; } PacketHandler handler = m_Handlers.GetHandler(packetID); if (handler == null) { byte[] data = new byte[length]; length = buffer.Dequeue(data, 0, length); if (Environment.Logging) { PacketReader reader = PacketReader.CreateInstance(data, length, false); reader.Trace(client); PacketReader.ReleaseInstance(reader); } return; } int packetLength = handler.Length; if (packetLength == 0) { // Dynamic length packet. Need at leaset 3 bytes (1 packet cmd + 2 length) if (length >= 3) { packetLength = buffer.GetPacketLength(); if (packetLength < 3) { client.Dispose(); return; } } else { break; } } if (length >= packetLength) { if (handler.Ingame && client.Mobile == null) { Console.WriteLine("Client: {0}: Sent ingame packet (0x{1:X2}) before having been attached to a mobile", client, packetID); client.Dispose(); return; } else if (handler.Ingame && client.Mobile.Deleted) { client.Dispose(); return; } else { ThrottlePacketCallback throttler = handler.ThrottleCallback; if (throttler != null && !throttler(client)) { throttle = true; return; } PacketProfile profile = PacketProfile.GetIncomingProfile(packetID); DateTime start = (profile == null ? DateTime.MinValue : DateTime.Now); byte[] packetBuffer; if (BufferSize >= packetLength) { packetBuffer = m_Buffers.AcquireBuffer(); } else { packetBuffer = new byte[packetLength]; } packetLength = buffer.Dequeue(packetBuffer, 0, packetLength); PacketReader reader = PacketReader.CreateInstance(packetBuffer, packetLength, handler.Length != 0); try { handler.OnReceive(client, reader); } catch (Exception e) { Logger.Error("Exception disarmed in HandleReceive from {0}: {1}", client.Address, e); } PacketReader.ReleaseInstance(reader); length = buffer.Length; if (BufferSize >= packetLength) { m_Buffers.ReleaseBuffer(packetBuffer); } if (profile != null) { profile.Record(packetLength, DateTime.Now - start); } } } else { break; } } }
private void OnReceived( NetState state, ByteQueue buffer, out bool throttle ) { throttle = false; GameClient client; if ( !m_Clients.TryGetValue( state, out client ) ) { Logger.Error( "Inconsistent game server state: game client for {0} not found", state ); return; } if ( !client.Seeded ) { if ( buffer.GetPacketID() == 0xEF ) { client.Seeded = true; } else if ( buffer.Length >= 4 ) { byte[] peek = new byte[4]; buffer.Dequeue( peek, 0, 4 ); int seed = ( peek[0] << 24 ) | ( peek[1] << 16 ) | ( peek[2] << 8 ) | peek[3]; if ( seed == 0 ) { Console.WriteLine( "Login: {0}: Invalid client detected, disconnecting", client ); client.Dispose(); return; } client.m_Seed = seed; client.Seeded = true; } else { return; // Need at least 4 bytes for the seed } } int length = buffer.Length; while ( length > 0 && buffer.Length > 0 ) { int packetID = buffer.GetPacketID(); if ( !client.SentFirstPacket && packetID != 0xF1 && packetID != 0xCF && packetID != 0x80 && packetID != 0x91 && packetID != 0xA4 && packetID != 0xEF ) { Console.WriteLine( "Client: {0}: Encrypted client detected, disconnecting", client ); client.Dispose(); return; } PacketHandler handler = m_Handlers.GetHandler( packetID ); if ( handler == null ) { byte[] data = new byte[length]; length = buffer.Dequeue( data, 0, length ); if ( Environment.Logging ) { PacketReader reader = PacketReader.CreateInstance( data, length, false ); reader.Trace( client ); PacketReader.ReleaseInstance( reader ); } return; } int packetLength = handler.Length; if ( packetLength == 0 ) { // Dynamic length packet. Need at leaset 3 bytes (1 packet cmd + 2 length) if ( length >= 3 ) { packetLength = buffer.GetPacketLength(); if ( packetLength < 3 ) { client.Dispose(); return; } } else { break; } } if ( length >= packetLength ) { if ( handler.Ingame && client.Mobile == null ) { Console.WriteLine( "Client: {0}: Sent ingame packet (0x{1:X2}) before having been attached to a mobile", client, packetID ); client.Dispose(); return; } else if ( handler.Ingame && client.Mobile.Deleted ) { client.Dispose(); return; } else { ThrottlePacketCallback throttler = handler.ThrottleCallback; if ( throttler != null && !throttler( client ) ) { throttle = true; return; } PacketProfile profile = PacketProfile.GetIncomingProfile( packetID ); DateTime start = ( profile == null ? DateTime.MinValue : DateTime.Now ); byte[] packetBuffer; if ( BufferSize >= packetLength ) packetBuffer = m_Buffers.AcquireBuffer(); else packetBuffer = new byte[packetLength]; packetLength = buffer.Dequeue( packetBuffer, 0, packetLength ); PacketReader reader = PacketReader.CreateInstance( packetBuffer, packetLength, handler.Length != 0 ); try { handler.OnReceive( client, reader ); } catch ( Exception e ) { Logger.Error( "Exception disarmed in HandleReceive from {0}: {1}", client.Address, e ); } PacketReader.ReleaseInstance( reader ); length = buffer.Length; if ( BufferSize >= packetLength ) m_Buffers.ReleaseBuffer( packetBuffer ); if ( profile != null ) profile.Record( packetLength, DateTime.Now - start ); } } else { break; } } }
private bool HandleReceive(NetState ns) { lock ( ns ) { ByteQueue buffer = ns.Buffer; if (buffer == null) { return(true); } int length = buffer.Length; if (!ns.Seeded) { if (length >= 4) { buffer.Dequeue(m_Peek, 0, 4); int seed = (m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]; if (log.IsDebugEnabled) { log.DebugFormat("Login: {0}: Seed is 0x{1:X8}", ns, seed); } if (seed == 0) { log.WarnFormat("Login: {0}: Invalid client detected, disconnecting", ns); ns.Dispose(); return(false); } ns.m_Seed = seed; ns.Seeded = true; } return(true); } while (length > 0 && ns.Running) { int packetID = buffer.GetPacketID(); if (!ns.SentFirstPacket && packetID != 0xF0 && packetID != 0xF1 && packetID != 0xCF && packetID != 0x80 && packetID != 0x91 && packetID != 0xA4 && packetID != 0xBF) { log.WarnFormat("Client: {0}: Encrypted client detected, disconnecting", ns); ns.Dispose(); break; } PacketHandler handler = ns.GetHandler(packetID); if (handler == null) { byte[] data = new byte[length]; length = buffer.Dequeue(data, 0, length); new PacketReader(data, length, false).Trace(ns); break; } int packetLength = handler.Length; if (packetLength <= 0) { if (length >= 3) { packetLength = buffer.GetPacketLength(); if (packetLength < 3) { ns.Dispose(); break; } } else { break; } } if (length >= packetLength) { if (handler.Ingame && ns.Mobile == null) { log.WarnFormat("Client: {0}: Sent ingame packet (0x{1:X2}) before having been attached to a mobile", ns, packetID); ns.Dispose(); break; } else if (handler.Ingame && ns.Mobile.Deleted) { ns.Dispose(); break; } else { ThrottlePacketCallback throttler = handler.ThrottleCallback; if (throttler != null && !throttler(ns)) { m_Throttled.Enqueue(ns); return(false); } PacketProfile profile = PacketProfile.GetIncomingProfile(packetID); DateTime start = (profile == null ? DateTime.MinValue : DateTime.UtcNow); byte[] packetBuffer; if (BufferSize >= packetLength) { packetBuffer = m_Buffers.AquireBuffer(); } else { packetBuffer = new byte[packetLength]; } packetLength = buffer.Dequeue(packetBuffer, 0, packetLength); PacketReader r = new PacketReader(packetBuffer, packetLength, handler.Length != 0); try { handler.OnReceive(ns, r); } catch (Exception e) { log.Fatal(String.Format("Exception disarmed in HandleReceive from {0}", ns.Address), e); } length = buffer.Length; if (BufferSize >= packetLength) { m_Buffers.ReleaseBuffer(packetBuffer); } if (profile != null) { profile.Record(packetLength, DateTime.UtcNow - start); } } } else { break; } } } return(true); }
public virtual void Dispose(bool flush) { if (Socket == null || m_Disposing) { return; } m_Disposing = true; if (flush) { Flush(); } try { Socket.Shutdown(SocketShutdown.Both); } catch (SocketException ex) { TraceException(ex); } try { Socket.Close(); } catch (SocketException ex) { TraceException(ex); } if (m_RecvBuffer != null) { lock (m_ReceiveBufferPool) { m_ReceiveBufferPool.ReleaseBuffer(m_RecvBuffer); } } Socket = null; PacketEncoder = null; PacketEncryptor = null; m_Buffer = null; m_RecvBuffer = null; m_OnReceive = null; m_OnSend = null; m_Running = false; lock (m_Disposed) { m_Disposed.Enqueue(this); } lock (m_SendQueue) { if (!m_SendQueue.IsEmpty) { m_SendQueue.Clear(); } } }
private void InvokeReceived( NetState ns, ByteQueue buffer, out bool throttle ) { throttle = false; if ( Received != null ) Received( ns, buffer, out throttle ); }
public bool HandleReceive(NetState ns) { ByteQueue buffer = ns.Buffer; if (buffer == null || buffer.Length <= 0) { return(true); } lock (buffer) { int length = buffer.Length; if (!ns.Seeded) { #region Enhanced Client if (buffer.GetPacketID() == 0xFF) { // Packet 255 = 0xFF = Client KR. ns.IsKRClient = true; Console.WriteLine("KR-Client detected", ns); } #endregion if (buffer.GetPacketID() == 0xEF) { // new packet in client 6.0.5.0 replaces the traditional seed method with a seed packet // 0xEF = 239 = multicast IP, so this should never appear in a normal seed. So this is backwards compatible with older clients. ns.Seeded = true; } else if (buffer.Length >= 4) { buffer.Dequeue(m_Peek, 0, 4); int seed = (m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]; if (seed == 0) { Console.WriteLine("Login: {0}: Invalid client detected, disconnecting", ns); ns.Dispose(); return(false); } ns.m_Seed = seed; ns.Seeded = true; length = buffer.Length; } else { return(true); } } int[] seedablePackets = new int[] { 0xF0, //Unknown - hijacked by Krrios client for login level acknowledgement 0xF1, //Unknown, sent in reply to 0xF2 - also hijacked by some freeshard clients for listings 0xCF, //Login to login server (with username and password) (possibly unused by EA) 0x80, //Login to login server (with username and password) 0x91, //Login to game server (with username and password) 0xA4, //Hardware info 0xEF, //KR and 2D login seed with version 0xE4, //Enhanced Client (KR) encyrption response (to 0xE3 encryption request) 0xFF, // 0x52 //Post bulletin board message - did we hijack this by accident for remoting/region watcher? }; while (length > 0 && ns.Running) { int packetID = buffer.GetPacketID(); if (!ns.SentFirstPacket && Array.IndexOf <int>(seedablePackets, packetID) == -1) { Console.WriteLine("Client: {0}: Encrypted client detected, disconnecting", ns); ns.Dispose(); break; } PacketHandler handler = ns.GetHandler(packetID); if (handler == null) { byte[] data = new byte[length]; length = buffer.Dequeue(data, 0, length); new PacketReader(data, length, false).Trace(ns); break; } int packetLength = handler.Length; if (packetLength <= 0) { if (length >= 3) { packetLength = buffer.GetPacketLength(); if (packetLength < 3) { ns.Dispose(); break; } } else { break; } } if (length >= packetLength) { if (handler.Ingame && ns.Mobile == null) { Console.WriteLine("Client: {0}: Sent ingame packet (0x{1:X2}) before having been attached to a mobile", ns, packetID); ns.Dispose(); break; } else if (handler.Ingame && ns.Mobile.Deleted) { ns.Dispose(); break; } else { ThrottlePacketCallback throttler = handler.ThrottleCallback; if (throttler != null && !throttler(ns)) { m_Throttled.Enqueue(ns); return(false); } PacketReceiveProfile prof = PacketReceiveProfile.Acquire(packetID); if (prof != null) { prof.Start(); } byte[] packetBuffer; if (BufferSize >= packetLength) { packetBuffer = m_Buffers.AcquireBuffer(); } else { packetBuffer = new byte[packetLength]; } packetLength = buffer.Dequeue(packetBuffer, 0, packetLength); PacketReader r = new PacketReader(packetBuffer, packetLength, handler.Length != 0); handler.OnReceive(ns, r); length = buffer.Length; if (BufferSize >= packetLength) { m_Buffers.ReleaseBuffer(packetBuffer); } if (prof != null) { prof.Finish(packetLength); } } } else { break; } } } #region Enhanced Client // ToDo clean this up // Would be nicer to detect the enhanced client in clientversion.cs // It seems that UOKR-EH sends a version number bigger 66.0.0.0, UOSA-EH bigger 67.0.0.0 try { if (ns.Version.Major > 8) { ns.IsKRClient = true; } } catch { //Standard classic client does not display version this early, so we can rule SA enhanced client out ns.IsKRClient = false; } #endregion return(true); }
public virtual void Dispose(bool flush) { if (Socket == null || m_Disposing) { return; } m_Disposing = true; if (flush) { Flush(); } try { Socket.Shutdown(SocketShutdown.Both); } catch (SocketException ex) { TraceException(ex); } try { Socket.Close(); } catch (SocketException ex) { TraceException(ex); } Socket = null; if (m_RecvBuffer != null) { lock (m_ReceiveBufferPool) { m_ReceiveBufferPool.ReleaseBuffer(m_RecvBuffer); } } m_Buffer = null; m_RecvBuffer = null; m_OnReceive = null; m_OnSend = null; m_Running = false; /* * m_Trades = null; * m_Gumps = null; * m_Menus = null; * m_HuePickers = null; */ lock (m_Disposed) m_Disposed.Enqueue(this); lock (m_SendQueue) if (!m_SendQueue.IsEmpty) { m_SendQueue.Clear(); } }
public void FinishDispose() { if ( m_DisposeFinished ) return; m_DisposeFinished = true; try { m_Socket.Shutdown( SocketShutdown.Both ); } catch ( SocketException ex ) { TraceException( ex ); } try { m_Socket.Close(); } catch ( SocketException ex ) { TraceException( ex ); } if ( m_RecvBuffer != null ) m_ReceiveBufferPool.ReleaseBuffer( m_RecvBuffer ); m_Socket = null; m_Buffer = null; m_RecvBuffer = null; m_Running = false; m_NetServer.OnDisposed( this ); if ( !m_SendQueue.IsEmpty ) { lock ( m_SendQueue ) m_SendQueue.Clear(); } }
public void HandleReceive(NetState ns) { ByteQueue buffer = ns.Buffer; if (buffer == null || buffer.Length <= 0) { return; } lock (buffer) { if (!ns.Seeded && !HandleSeed(ns, buffer)) { return; } int length = buffer.Length; while (length > 0 && ns.Running) { int packetID = buffer.GetPacketID(); if (CheckEncrypted(ns, packetID)) { return; } PacketHandler handler = NetState.GetHandler(packetID); if (handler == null) { byte[] data = new byte[length]; length = buffer.Dequeue(data, 0, length); new PacketReader(data, length, false).Trace(ns); return; } int packetLength = handler.Length; if (packetLength <= 0) { if (length >= 3) { packetLength = buffer.GetPacketLength(); if (packetLength < 3) { ns.Dispose(); return; } } else { return; } } if (length < packetLength) { return; } if (handler.Ingame) { if (ns.Mobile == null) { Utility.PushColor(ConsoleColor.Red); Console.WriteLine("Client: {0}: Packet (0x{1:X2}) Requires State Mobile", ns, packetID); Utility.PopColor(); ns.Dispose(); return; } if (ns.Mobile.Deleted) { Utility.PushColor(ConsoleColor.Red); Console.WriteLine("Client: {0}: Packet (0x{1:X2}) Ivalid State Mobile", ns, packetID); Utility.PopColor(); ns.Dispose(); return; } } ThrottlePacketCallback throttler = handler.ThrottleCallback; if (throttler != null) { if (!throttler(ns, out bool drop)) { if (!drop) { m_Throttled.Enqueue(ns); } else { buffer.Dequeue(new byte[packetLength], 0, packetLength); } return; } } PacketReceiveProfile prof = null; if (Core.Profiling) { prof = PacketReceiveProfile.Acquire(packetID); } if (prof != null) { prof.Start(); } byte[] packetBuffer; if (BufferSize >= packetLength) { packetBuffer = m_Buffers.AcquireBuffer(); } else { packetBuffer = new byte[packetLength]; } packetLength = buffer.Dequeue(packetBuffer, 0, packetLength); if (packetBuffer != null && packetBuffer.Length > 0 && packetLength > 0) { PacketReader r = new PacketReader(packetBuffer, packetLength, handler.Length != 0); handler.OnReceive(ns, r); if (BufferSize >= packetLength) { m_Buffers.ReleaseBuffer(packetBuffer); } } if (prof != null) { prof.Finish(packetLength); } length = buffer.Length; } } }
private bool HandleSeed(NetState ns, ByteQueue buffer) { if (buffer.GetPacketID() == 0xEF) { // new packet in client 6.0.5.0 replaces the traditional seed method with a seed packet // 0xEF = 239 = multicast IP, so this should never appear in a normal seed. So this is backwards compatible with older clients. ns.Seeded = true; return true; } else if (buffer.Length >= 4) { var m_Peek = new byte[4]; buffer.Dequeue(m_Peek, 0, 4); int seed = (m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]; if (seed == 0) { Utility.PushColor(ConsoleColor.Green); Console.WriteLine("Login: {0}: Invalid client detected, disconnecting", ns); Utility.PopColor(); ns.Dispose(); return false; } ns.m_Seed = seed; ns.Seeded = true; return true; } else { return false; } }