public static void DecodeBundledPacket(NetState state, PacketReader pvSrc) { int packetID = pvSrc.ReadByte(); PacketHandler ph = GetHandler(packetID); if (ph != null) { if (ph.Ingame && state.Mobile == null) { Utility.PushColor(ConsoleColor.DarkRed); Console.WriteLine("Client: {0}: Sent ingame packet (0xF0x{1:X2}) before having been attached to a mobile", state, packetID); Utility.PopColor(); state.Dispose(); } else if (ph.Ingame && state.Mobile.Deleted) { state.Dispose(); } else { ph.OnReceive(state, pvSrc); } } }
public void RejectNoEncryption(NetState ns) { // Log it on the console Console.WriteLine("Client: {0}: Unencrypted client detected, disconnected", ns); // Send the client the typical "Bad communication" packet and also a sysmessage stating the error ns.Send(new AsciiMessage(Server.Serial.MinusOne, -1, MessageType.Label, 0x35, 3, "System", "Unencrypted connections are not allowed on this server.")); ns.Send(new AccountLoginRej(ALRReason.BadComm)); // Disconnect the client ns.Dispose(true); }
public static void DecodeBundledPacket( NetState state, PacketReader pvSrc ) { int packetID = pvSrc.ReadByte(); PacketHandler ph = GetHandler( packetID ); if ( ph != null ) { if ( ph.Ingame && state.Mobile == null ) { log.Warn(String.Format("Client: {0}: Sent ingame packet (0xF0x{1:X2}) before having been attached to a mobile", state, packetID)); state.Dispose(); } else if ( ph.Ingame && state.Mobile.Deleted ) { state.Dispose(); } else { ph.OnReceive( state, pvSrc ); } } }
public static void EncodedCommand( NetState state, PacketReader pvSrc ) { IEntity e = World.FindEntity( pvSrc.ReadInt32() ); int packetID = pvSrc.ReadUInt16(); EncodedPacketHandler ph = GetEncodedHandler( packetID ); if ( ph != null ) { if ( ph.Ingame && state.Mobile == null ) { Console.WriteLine( "Client: {0}: Sent ingame packet (0xD7x{1:X2}) before having been attached to a mobile", state, packetID ); state.Dispose(); } else if ( ph.Ingame && state.Mobile.Deleted ) { state.Dispose(); } else { ph.OnReceive( state, e, new EncodedReader( pvSrc ) ); } } else { pvSrc.Trace( state ); } }
public static void AccountLogin_ReplyAck( NetState state ) { ServerListEventArgs e = new ServerListEventArgs( state, state.Account ); EventSink.InvokeServerList( e ); if ( e.Rejected ) { state.Account = null; state.Send( new AccountLoginRej( ALRReason.BadComm ) ); state.Dispose(); } else { ServerInfo[] info = e.Servers.ToArray(); state.ServerInfo = info; state.Send( new AccountLoginAck( info ) ); } }
public static void LoginServerSeed( NetState state, PacketReader pvSrc ) { state.m_Seed = pvSrc.ReadInt32(); state.Seeded = true; if ( state.m_Seed == 0 ) { Console.WriteLine("Login: {0}: Invalid client detected, disconnecting", state); state.Dispose(); return; } int clientMaj = pvSrc.ReadInt32(); int clientMin = pvSrc.ReadInt32(); int clientRev = pvSrc.ReadInt32(); int clientPat = pvSrc.ReadInt32(); state.Version = new ClientVersion( clientMaj, clientMin, clientRev, clientPat ); }
public static void GameLogin( NetState state, PacketReader pvSrc ) { if ( state.SentFirstPacket ) { state.Dispose(); return; } state.SentFirstPacket = true; int authID = pvSrc.ReadInt32(); if ( m_AuthIDWindow.ContainsKey( authID ) ) { AuthIDPersistence ap = m_AuthIDWindow[authID]; m_AuthIDWindow.Remove( authID ); state.Version = ap.Version; } else if ( m_ClientVerification ) { Console.WriteLine( "Login: {0}: Invalid client detected, disconnecting", state ); state.Dispose(); return; } if ( state.m_AuthID != 0 && authID != state.m_AuthID ) { Console.WriteLine( "Login: {0}: Invalid client detected, disconnecting", state ); state.Dispose(); return; } else if ( state.m_AuthID == 0 && authID != state.m_Seed ) { Console.WriteLine( "Login: {0}: Invalid client detected, disconnecting", state ); state.Dispose(); return; } string username = pvSrc.ReadString( 30 ); string password = pvSrc.ReadString( 30 ); GameLoginEventArgs e = new GameLoginEventArgs( state, username, password ); EventSink.InvokeGameLogin( e ); if ( e.Accepted ) { state.CityInfo = e.CityInfo; state.CompressionEnabled = true; state.Send( SupportedFeatures.Instantiate( state ) ); if ( state.NewCharacterList ) { state.Send( new CharacterList( state.Account, state.CityInfo ) ); } else { state.Send( new CharacterListOld( state.Account, state.CityInfo ) ); } } else { state.Dispose(); } }
public static void PlayCharacter( NetState state, PacketReader pvSrc ) { pvSrc.ReadInt32(); // 0xEDEDEDED string name = pvSrc.ReadString( 30 ); pvSrc.Seek( 2, SeekOrigin.Current ); int flags = pvSrc.ReadInt32(); if ( FeatureProtection.DisabledFeatures != 0 && ThirdPartyAuthCallback != null ) { bool authOK = false; ulong razorFeatures = (((ulong)pvSrc.ReadUInt32())<<32) | ((ulong)pvSrc.ReadUInt32()); if ( razorFeatures == (ulong)FeatureProtection.DisabledFeatures ) { bool match = true; for ( int i=0; match && i < m_ThirdPartyAuthKey.Length; i++ ) match = match && pvSrc.ReadByte() == m_ThirdPartyAuthKey[i]; if ( match ) authOK = true; } else { pvSrc.Seek( 16, SeekOrigin.Current ); } ThirdPartyAuthCallback( state, authOK ); } else { pvSrc.Seek( 24, SeekOrigin.Current ); } if ( ThirdPartyHackedCallback != null ) { pvSrc.Seek( -2, SeekOrigin.Current ); if ( pvSrc.ReadUInt16() == 0xDEAD ) ThirdPartyHackedCallback( state, true ); } if ( !state.Running ) return; int charSlot = pvSrc.ReadInt32(); int clientIP = pvSrc.ReadInt32(); IAccount a = state.Account; if ( a == null || charSlot < 0 || charSlot >= a.Length ) { state.Dispose(); } else { Mobile m = a[charSlot]; // Check if anyone is using this account for ( int i = 0; i < a.Length; ++i ) { Mobile check = a[i]; if ( check != null && check.Map != Map.Internal && check != m ) { Console.WriteLine( "Login: {0}: Account in use", state ); state.Send( new PopupMessage( PMMessage.CharInWorld ) ); return; } } if ( m == null ) { state.Dispose(); } else { if ( m.NetState != null ) m.NetState.Dispose(); NetState.ProcessDisposedQueue(); state.Send( new ClientVersionReq() ); state.BlockAllPackets = true; state.Flags = (ClientFlags)flags; state.Mobile = m; m.NetState = state; new LoginTimer( state, m ).Start(); } } }
public static void DisplayGumpResponse( NetState state, PacketReader pvSrc ) { int serial = pvSrc.ReadInt32(); int typeID = pvSrc.ReadInt32(); int buttonID = pvSrc.ReadInt32(); foreach ( Gump gump in state.Gumps ) { if ( gump.Serial == serial && gump.TypeID == typeID ) { int switchCount = pvSrc.ReadInt32(); if ( switchCount < 0 || switchCount > gump.m_Switches ) { state.WriteConsole( "Invalid gump response, disconnecting..." ); state.Dispose(); return; } int[] switches = new int[switchCount]; for ( int j = 0; j < switches.Length; ++j ) switches[j] = pvSrc.ReadInt32(); int textCount = pvSrc.ReadInt32(); if ( textCount < 0 || textCount > gump.m_TextEntries ) { state.WriteConsole( "Invalid gump response, disconnecting..." ); state.Dispose(); return; } TextRelay[] textEntries = new TextRelay[textCount]; for ( int j = 0; j < textEntries.Length; ++j ) { int entryID = pvSrc.ReadUInt16(); int textLength = pvSrc.ReadUInt16(); if ( textLength > 239 ) { state.WriteConsole( "Invalid gump response, disconnecting..." ); state.Dispose(); return; } string text = pvSrc.ReadUnicodeStringSafe( textLength ); textEntries[j] = new TextRelay( entryID, text ); } state.RemoveGump( gump ); GumpProfile prof = GumpProfile.Acquire( gump.GetType() ); if ( prof != null ) { prof.Start(); } gump.OnResponse( state, new RelayInfo( buttonID, switches, textEntries ) ); if ( prof != null ) { prof.Finish(); } return; } } if ( typeID == 461 ) { // Virtue gump int switchCount = pvSrc.ReadInt32(); if ( buttonID == 1 && switchCount > 0 ) { Mobile beheld = World.FindMobile( pvSrc.ReadInt32() ); if ( beheld != null ) { EventSink.InvokeVirtueGumpRequest( new VirtueGumpRequestEventArgs( state.Mobile, beheld ) ); } } else { Mobile beheld = World.FindMobile( serial ); if ( beheld != null ) { EventSink.InvokeVirtueItemRequest( new VirtueItemRequestEventArgs( state.Mobile, beheld, buttonID ) ); } } } }
// Try to decrypt incoming data. public void DecodeIncomingPacket(NetState from, ref byte[] buffer, ref int length) { #region m_Encryption != null if (m_Encryption != null) { // If we're decrypting using LoginCrypt and we've already been relayed, // only decrypt a single packet using logincrypt and then disable it if (m_AlreadyRelayed && m_Encryption is LoginEncryption) { uint newSeed = ((((LoginEncryption)(m_Encryption)).Key1 + 1) ^ ((LoginEncryption)(m_Encryption)).Key2); // Swap the seed newSeed = ((newSeed >> 24) & 0xFF) | ((newSeed >> 8) & 0xFF00) | ((newSeed << 8) & 0xFF0000) | ((newSeed << 24) & 0xFF000000); // XOR it with the old seed newSeed ^= m_Seed; IClientEncryption newEncryption = new GameEncryption(newSeed); // Game Encryption comes first newEncryption.clientDecrypt(ref buffer, length); // The login encryption is still used for this one packet m_Encryption.clientDecrypt(ref buffer, length); // Swap the encryption schemes m_Encryption = newEncryption; m_Seed = newSeed; return; } m_Encryption.clientDecrypt(ref buffer, length); return; } #endregion #region Port Scan //11JUN2008 GOW SVN fix ** START *** // If the client did not connect on the game server port, // it's not our business to handle encryption for it //if (((IPEndPoint)from.Socket.LocalEndPoint).Port != Listener.Port) //{ // m_Encryption = new NoEncryption(); // return; //} bool handle = false; for (int i = 0; i < Listener.EndPoints.Length; i++) { IPEndPoint ipep = (IPEndPoint)Listener.EndPoints[i]; if (((IPEndPoint)from.Socket.LocalEndPoint).Port == ipep.Port) handle = true; } if (!handle) { m_Encryption = new NoEncryption(); return; } #endregion #region !m_Seeded // For simplicities sake, enqueue what we just received as long as we're not initialized m_Buffer.Enqueue(buffer, 0, length); // Clear the array length = 0; // If we didn't receive the seed yet, queue data until we can read the seed //if (!m_Seeded) //{ // // Now check if we have at least 4 bytes to get the seed // if (m_Buffer.Length >= 4) // { // byte[] m_Peek = new byte[m_Buffer.Length]; // m_Buffer.Dequeue( m_Peek, 0, m_Buffer.Length ); // Dequeue everything // m_Seed = (uint)((m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]); // m_Seeded = true; // Buffer.BlockCopy(m_Peek, 0, buffer, 0, 4); // length = 4; // } // else // { // return; // } //} //http://uodev.de/viewtopic.php?t=5097&postdays=0&postorder=asc&start=15&sid=dfb8e6c73b9e3eb95c1634ca3586e8a7 //if (!m_Seeded) //{ // int seed_length = m_Buffer.GetSeedLength(); // if (m_Buffer.Length >= seed_length) // { // byte[] m_Peek = new byte[m_Buffer.Length]; // m_Buffer.Dequeue(m_Peek, 0, seed_length); // if (seed_length == 4) // m_Seed = (uint)((m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]); // else if (seed_length == 21) // m_Seed = (uint)((m_Peek[1] << 24) | (m_Peek[2] << 16) | (m_Peek[3] << 8) | m_Peek[4]); // m_Seeded = true; // Buffer.BlockCopy(m_Peek, 0, buffer, 0, seed_length); // length = seed_length; // } // else // { // return; // } //} //11JUN2008 My Version if (!m_Seeded) { if (m_Buffer.Length <= 3) //Short Length, try again. { Console.WriteLine("Encryption: Failed - Short Lenght"); return; } //else if ((m_Buffer.Length == 83) && (m_Buffer.GetPacketID() == 239)) //New Client //{ // byte[] m_Peek = new byte[21]; // m_Buffer.Dequeue(m_Peek, 0, 21); // m_Seed = (uint)((m_Peek[1] << 24) | (m_Peek[2] << 16) | (m_Peek[3] << 8) | m_Peek[4]); // m_Seeded = true; // Buffer.BlockCopy(m_Peek, 0, buffer, 0, 21); // length = 21; // Console.WriteLine("Encryption: Passed - New Client"); //} //05MAR2009 Smjert's fix for double log in. *** START *** else if ((m_Buffer.Length == 83 || m_Buffer.Length == 21) && (m_Buffer.GetPacketID() == 239)) //New Client { length = m_Buffer.Length; byte[] m_Peek = new byte[21]; m_Buffer.Dequeue(m_Peek, 0, 21); m_Seed = (uint)((m_Peek[1] << 24) | (m_Peek[2] << 16) | (m_Peek[3] << 8) | m_Peek[4]); m_Seeded = true; Buffer.BlockCopy(m_Peek, 0, buffer, 0, 21); Console.WriteLine("Encryption: Passed - New Client"); // We need to wait the next packet if (length == 21) return; length = 21; } else if (m_Buffer.Length >= 4) //Old Client //05MAR2009 Smjert's fix for double log in. *** END *** { byte[] m_Peek = new byte[4]; m_Buffer.Dequeue(m_Peek, 0, 4); m_Seed = (uint)((m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]); m_Seeded = true; Buffer.BlockCopy(m_Peek, 0, buffer, 0, 4); length = 4; Console.WriteLine("Encryption: Passed - Old Client"); } else //It should never reach here. { Console.WriteLine("Encryption: Failed - It should never reach here"); return; } } #endregion // If the context isn't initialized yet, that means we haven't decided on an encryption method yet #region m_Encryption == null if (m_Encryption == null) { int packetLength = m_Buffer.Length; int packetOffset = length; m_Buffer.Dequeue(buffer, length, packetLength); // Dequeue everything length += packetLength; // This is special handling for the "special" UOG packet if (packetLength >= 3) { if (buffer[packetOffset] == 0xf1 && buffer[packetOffset + 1] == ((packetLength >> 8) & 0xFF) && buffer[packetOffset + 2] == (packetLength & 0xFF)) { m_Encryption = new NoEncryption(); return; } } // Check if the current buffer contains a valid login packet (62 byte + 4 byte header) // Please note that the client sends these in two chunks. One 4 byte and one 62 byte. if (packetLength == 62) { Console.WriteLine("Checking packetLength 62 == " + packetLength); // Check certain indices in the array to see if the given data is unencrypted if (buffer[packetOffset] == 0x80 && buffer[packetOffset + 30] == 0x00 && buffer[packetOffset + 60] == 0x00) { if (Configuration.AllowUnencryptedClients) { m_Encryption = new NoEncryption(); } else { RejectNoEncryption(from); from.Dispose(); return; } } else { LoginEncryption encryption = new LoginEncryption(); if (encryption.init(m_Seed, buffer, packetOffset, packetLength)) { Console.WriteLine("Client: {0}: Encrypted client detected, using keys of client {1}", from, encryption.Name); m_Encryption = encryption; Console.WriteLine("Encryption: Check 1"); byte[] packet = new byte[packetLength]; Console.WriteLine("Encryption: Check 2"); Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength); Console.WriteLine("Encryption: Check 3"); encryption.clientDecrypt(ref packet, packet.Length); Console.WriteLine("Encryption: Check 4"); Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength); Console.WriteLine("Encryption: Check 5"); //return; //Just throwing this in. } else { Console.WriteLine("Detected an unknown client."); } } } else if (packetLength == 65) { Console.WriteLine("Checking packetLength 65 == " + packetLength); // If its unencrypted, use the NoEncryption class if (buffer[packetOffset] == '\x91' && buffer[packetOffset + 1] == ((m_Seed >> 24) & 0xFF) && buffer[packetOffset + 2] == ((m_Seed >> 16) & 0xFF) && buffer[packetOffset + 3] == ((m_Seed >> 8) & 0xFF) && buffer[packetOffset + 4] == (m_Seed & 0xFF)) { if (Configuration.AllowUnencryptedClients) { m_Encryption = new NoEncryption(); } else { RejectNoEncryption(from); from.Dispose(); } } else { // If it's not an unencrypted packet, simply assume it's encrypted with the seed m_Encryption = new GameEncryption(m_Seed); byte[] packet = new byte[packetLength]; Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength); m_Encryption.clientDecrypt(ref packet, packet.Length); Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength); } } // If it's still not initialized, copy the data back to the queue and wait for more if (m_Encryption == null) { Console.WriteLine("Encryption: Check - Waiting"); m_Buffer.Enqueue(buffer, packetOffset, packetLength); length -= packetLength; return; } } #endregion }
public static bool VerifyGC( NetState state ) { if ( state.Mobile == null || state.Mobile.AccessLevel <= AccessLevel.Counselor ) { if ( state.Running ) log.WarnFormat("Player {0} using godclient, disconnecting", state); state.Dispose(); return false; } else { return true; } }
public override void OnResponse( NetState sender, RelayInfo info ) { PlayerMobile pm = m_Entry.Player; m_CloseTimer.Stop(); if ( Campfire.GetEntry( pm ) != m_Entry ) return; if ( info.ButtonID == 1 && m_Entry.Safe && m_Bedroll.Parent == null && m_Bedroll.IsAccessibleTo( pm ) && m_Bedroll.VerifyMove( pm ) && m_Bedroll.Map == pm.Map && pm.InRange( m_Bedroll, 2 ) ) { pm.PlaceInBackpack( m_Bedroll ); pm.BedrollLogout = true; sender.Dispose(); } Campfire.RemoveEntry( m_Entry ); }
public bool HandleReceive(NetState ns) { ByteQueue queue1; int num1; int num2; int num3; PacketHandler handler1; byte[] buffer1; int num4; ThrottlePacketCallback callback1; PacketProfile profile1; DateTime time1; PacketReader reader1; NetState state1 = ns; lock (ns) { queue1 = ns.Buffer; if (queue1 == null) { return(true); } num1 = queue1.Length; if (ns.Seeded) { goto Label_0250; } if (num1 >= 4) { queue1.Dequeue(this.m_Peek, 0, 4); num2 = ((((this.m_Peek[0] << 24) | (this.m_Peek[1] << 16)) | (this.m_Peek[2] << 8)) | this.m_Peek[3]); if (num2 == 0) { Console.WriteLine("Login: {0}: Invalid client detected, disconnecting", ns); ns.Dispose(); return(false); } ns.m_Seed = num2; ns.Seeded = true; } return(true); Label_009D: queue1.Peek(this.m_Peek, 0, 1); num3 = this.m_Peek[0]; if (((!ns.SentFirstPacket && (num3 != 241)) && ((num3 != 207) && (num3 != 128))) && ((num3 != 145) && (num3 != 164))) { Console.WriteLine("Client: {0}: Encrypted client detected, disconnecting", ns); ns.Dispose(); goto Label_0269; } handler1 = PacketHandlers.GetHandler(num3); if (handler1 == null) { buffer1 = queue1.Dequeue(num1); new PacketReader(buffer1, 0).Trace(ns); goto Label_0269; } num4 = handler1.Length; if (num4 <= 0) { if (num1 < 3) { goto Label_0269; } queue1.Peek(this.m_Peek, 0, 3); num4 = ((this.m_Peek[1] << 8) | this.m_Peek[2]); if (num4 < 3) { ns.Dispose(); goto Label_0269; } } if (num1 < num4) { goto Label_0269; } if (handler1.Ingame && (ns.Mobile == null)) { Console.WriteLine("Client: {0}: Sent ingame packet (0x{1:X2}) before having been attached to a mobile", ns, num3); ns.Dispose(); goto Label_0269; } if (handler1.Ingame && ns.Mobile.Deleted) { ns.Dispose(); goto Label_0269; } callback1 = handler1.ThrottleCallback; if ((callback1 != null) && !callback1.Invoke(ns)) { this.m_Throttled.Enqueue(ns); return(false); } profile1 = PacketProfile.GetIncomingProfile(num3); time1 = ((profile1 == null) ? DateTime.MinValue : DateTime.Now); reader1 = new PacketReader(queue1.Dequeue(num4), (handler1.Length != 0)); handler1.OnReceive(ns, reader1); num1 = queue1.Length; if (profile1 != null) { profile1.Record(num4, ((TimeSpan)(DateTime.Now - time1))); } Label_0250: if (num1 > 0) { if (ns.Running) { goto Label_009D; } } } Label_0269: return(true); }
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 = ns.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; } } }
public 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]; //Console.WriteLine( "Login: {0}: Seed is 0x{1:X8}", ns, seed ); if (seed == 0) { Console.WriteLine("Login: {0}: Invalid client detected, disconnecting", ns); ns.Dispose(); return(false); } ns.m_Seed = seed; ns.Seeded = true; } return(true); } //Console.WriteLine( "{" ); while (length > 0 && ns.Running) { int packetID = buffer.GetPacketID(); if (!ns.SentFirstPacket && packetID != 0xF1 && packetID != 0xCF && packetID != 0x80 && packetID != 0x91 && packetID != 0xA4 && packetID != 0xBF) { 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); //Console.WriteLine( "}" ); return(false); } //Console.WriteLine( handler.OnReceive.Method.Name ); PacketProfile profile = PacketProfile.GetIncomingProfile(packetID); DateTime start = (profile == null ? DateTime.MinValue : DateTime.Now); 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) { Console.WriteLine("Exception disarmed in HandleReceive from {0}: {1}", ns.Address, e); } length = buffer.Length; if (BufferSize >= packetLength) { m_Buffers.ReleaseBuffer(packetBuffer); } if (profile != null) { profile.Record(packetLength, DateTime.Now - start); } //Console.WriteLine( "Client: {0}: Unhandled packet 0x{1:X2}", ns, packetID ); //Utility.FormatBuffer( Console.Out, new System.IO.MemoryStream( r.Buffer ), r.Buffer.Length ); } } else { break; } } //Console.WriteLine( "}" ); } return(true); }
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 static void DisplayGumpResponse(NetState state, CircularBufferReader reader) { var serial = reader.ReadUInt32(); var typeID = reader.ReadInt32(); var buttonID = reader.ReadInt32(); foreach (var gump in state.Gumps) { if (gump.Serial != serial || gump.TypeID != typeID) { continue; } var buttonExists = buttonID == 0; // 0 is always 'close' if (!buttonExists) { foreach (var e in gump.Entries) { if (e is GumpButton button && button.ButtonID == buttonID) { buttonExists = true; break; } if (e is GumpImageTileButton tileButton && tileButton.ButtonID == buttonID) { buttonExists = true; break; } } } if (!buttonExists) { state.WriteConsole("Invalid gump response, disconnecting..."); state.Dispose(); return; } var switchCount = reader.ReadInt32(); if (switchCount < 0 || switchCount > gump.m_Switches) { state.WriteConsole("Invalid gump response, disconnecting..."); state.Dispose(); return; } var switches = new int[switchCount]; for (var j = 0; j < switches.Length; ++j) { switches[j] = reader.ReadInt32(); } var textCount = reader.ReadInt32(); if (textCount < 0 || textCount > gump.m_TextEntries) { state.WriteConsole("Invalid gump response, disconnecting..."); state.Dispose(); return; } var textEntries = new TextRelay[textCount]; for (var j = 0; j < textEntries.Length; ++j) { int entryID = reader.ReadUInt16(); int textLength = reader.ReadUInt16(); if (textLength > 239) { state.WriteConsole("Invalid gump response, disconnecting..."); state.Dispose(); return; } var text = reader.ReadBigUniSafe(textLength); textEntries[j] = new TextRelay(entryID, text); } state.RemoveGump(gump); var prof = GumpProfile.Acquire(gump.GetType()); prof?.Start(); gump.OnResponse(state, new RelayInfo(buttonID, switches, textEntries)); prof?.Finish(); return; } if (typeID == 461) { // Virtue gump var switchCount = reader.ReadInt32(); if (buttonID == 1 && switchCount > 0) { var beheld = World.FindMobile(reader.ReadUInt32()); if (beheld != null) { EventSink.InvokeVirtueGumpRequest(state.Mobile, beheld); } } else { var beheld = World.FindMobile(serial); if (beheld != null) { EventSink.InvokeVirtueItemRequest(state.Mobile, beheld, buttonID); } } } }
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 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) { Utility.WriteConsole(ConsoleColor.Yellow, "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)) { 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 static void AccountLogin( NetState state, PacketReader pvSrc ) { if ( state.SentFirstPacket ) { state.Dispose(); return; } state.SentFirstPacket = true; string username = pvSrc.ReadString( 30 ); string password = pvSrc.ReadString( 30 ); AccountLoginEventArgs e = new AccountLoginEventArgs( state, username, password ); try { EventSink.InvokeAccountLogin(e); } catch (Exception ex) { Console.WriteLine("Exception disarmed in AccountLogin {0}: {1}", username, ex); } if ( e.Accepted ) AccountLogin_ReplyAck( state ); else AccountLogin_ReplyRej( state, e.RejectReason ); }
public static void DisplayGumpResponse( NetState state, PacketReader pvSrc ) { int serial = pvSrc.ReadInt32(); int typeID = pvSrc.ReadInt32(); int buttonID = pvSrc.ReadInt32(); foreach ( Gump gump in state.Gumps ) { if ( gump.Serial == serial && gump.TypeID == typeID ) { int switchCount = pvSrc.ReadInt32(); if ( switchCount < 0 || switchCount > gump.m_Switches ) { log.InfoFormat("Client: {0}: Invalid gump response, disconnecting...", state); state.Dispose(); return; } int[] switches = new int[switchCount]; for ( int j = 0; j < switches.Length; ++j ) switches[j] = pvSrc.ReadInt32(); int textCount = pvSrc.ReadInt32(); if ( textCount < 0 || textCount > gump.m_TextEntries ) { log.InfoFormat("Client: {0}: Invalid gump response, disconnecting...", state ); state.Dispose(); return; } TextRelay[] textEntries = new TextRelay[textCount]; for ( int j = 0; j < textEntries.Length; ++j ) { int entryID = pvSrc.ReadUInt16(); int textLength = pvSrc.ReadUInt16(); if ( textLength > 239 ) return; string text = pvSrc.ReadUnicodeStringSafe( textLength ); textEntries[j] = new TextRelay( entryID, text ); } state.RemoveGump( gump ); try { gump.OnResponse( state, new RelayInfo( buttonID, switches, textEntries ) ); } catch (Exception e) { log.Fatal(String.Format("Exception disarmed in gump response of {0}", gump), e); } return; } } if ( typeID == 461 ) // Virtue gump { int switchCount = pvSrc.ReadInt32(); if ( buttonID == 1 && switchCount > 0 ) { Mobile beheld = World.FindMobile( pvSrc.ReadInt32() ); if ( beheld != null ) EventSink.InvokeVirtueGumpRequest( new VirtueGumpRequestEventArgs( state.Mobile, beheld ) ); } else { Mobile beheld = World.FindMobile( serial ); if ( beheld != null ) EventSink.InvokeVirtueItemRequest( new VirtueItemRequestEventArgs( state.Mobile, beheld, buttonID ) ); } } }
public static void PlayCharacter( NetState state, PacketReader pvSrc ) { pvSrc.ReadInt32(); // 0xEDEDEDED /*string name = */pvSrc.ReadString( 30 ); pvSrc.Seek( 2, SeekOrigin.Current ); int flags = pvSrc.ReadInt32(); pvSrc.Seek( 24, SeekOrigin.Current ); int charSlot = pvSrc.ReadInt32(); /*int clientIP = */pvSrc.ReadInt32(); IAccount a = state.Account; if ( a == null || charSlot < 0 || charSlot >= a.Length ) { state.Dispose(); } else { Mobile m = a[charSlot]; // Check if anyone is using this account for ( int i = 0; i < a.Length; ++i ) { Mobile check = a[i]; if ( check != null && check.Map != Map.Internal && check != m ) { log.InfoFormat("Login: {0}: Account in use", state); state.Send( new PopupMessage( PMMessage.CharInWorld ) ); return; } } if ( m == null ) { state.Dispose(); } else { if ( m.NetState != null ) m.NetState.Dispose(); NetState.ProcessDisposedQueue(); state.Send( new ClientVersionReq() ); state.BlockAllPackets = true; state.Flags = flags; state.Mobile = m; m.NetState = state; new LoginTimer( state, m ).Start(); } } }
public 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]; //Console.WriteLine( "Login: {0}: Seed is 0x{1:X8}", ns, seed ); if ( seed == 0 ) { Console.WriteLine( "Login: {0}: Invalid client detected, disconnecting", ns ); ns.Dispose(); return false; } ns.m_Seed = seed; ns.Seeded = true; } return true; } //Console.WriteLine( "{" ); 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 ); //Console.WriteLine( "}" ); return false; } //Console.WriteLine( handler.OnReceive.Method.Name ); PacketProfile profile = PacketProfile.GetIncomingProfile( packetID ); DateTime start = ( profile == null ? DateTime.MinValue : DateTime.Now ); 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 ); handler.OnReceive( ns, r ); length = buffer.Length; if ( BufferSize >= packetLength ) m_Buffers.ReleaseBuffer( packetBuffer ); if ( profile != null ) profile.Record( packetLength, DateTime.Now - start ); //Console.WriteLine( "Client: {0}: Unhandled packet 0x{1:X2}", ns, packetID ); //Utility.FormatBuffer( Console.Out, new System.IO.MemoryStream( r.Buffer ), r.Buffer.Length ); } } else { break; } } //Console.WriteLine( "}" ); } return true; }
public static void CreateCharacter( NetState state, PacketReader pvSrc ) { /*int unk1 = */pvSrc.ReadInt32(); /*int unk2 = */pvSrc.ReadInt32(); /*int unk3 = */pvSrc.ReadByte(); string name = pvSrc.ReadString( 30 ); pvSrc.Seek( 2, SeekOrigin.Current ); int flags = pvSrc.ReadInt32(); pvSrc.Seek( 8, SeekOrigin.Current ); int prof = pvSrc.ReadByte(); pvSrc.Seek( 15, SeekOrigin.Current ); bool female = pvSrc.ReadByte() > 0 ? true : false; /*int genderRace = pvSrc.ReadByte();*/ int str = pvSrc.ReadByte(); int dex = pvSrc.ReadByte(); int intl= pvSrc.ReadByte(); int is1 = pvSrc.ReadByte(); int vs1 = pvSrc.ReadByte(); int is2 = pvSrc.ReadByte(); int vs2 = pvSrc.ReadByte(); int is3 = pvSrc.ReadByte(); int vs3 = pvSrc.ReadByte(); int hue = pvSrc.ReadUInt16(); int hairVal = pvSrc.ReadInt16(); int hairHue = pvSrc.ReadInt16(); int hairValf= pvSrc.ReadInt16(); int hairHuef= pvSrc.ReadInt16(); pvSrc.ReadByte(); int cityIndex = pvSrc.ReadByte(); /*int charSlot = */pvSrc.ReadInt32(); /*int clientIP = */pvSrc.ReadInt32(); int shirtHue = pvSrc.ReadInt16(); int pantsHue = pvSrc.ReadInt16(); CityInfo[] info = state.CityInfo; IAccount a = state.Account; if ( info == null || a == null || cityIndex < 0 || cityIndex >= info.Length ) { state.Dispose(); } else { // Check if anyone is using this account for ( int i = 0; i < a.Length; ++i ) { Mobile check = a[i]; if ( check != null && check.Map != Map.Internal ) { log.InfoFormat("Login: {0}: Account in use", state); state.Send( new PopupMessage( PMMessage.CharInWorld ) ); return; } } state.Flags = flags; CharacterCreatedEventArgs args = new CharacterCreatedEventArgs( state, a, name, female, hue, str, dex, intl, info[cityIndex], new SkillNameValue[3] { new SkillNameValue( (SkillName)is1, vs1 ), new SkillNameValue( (SkillName)is2, vs2 ), new SkillNameValue( (SkillName)is3, vs3 ), }, shirtHue, pantsHue, hairVal, hairHue, hairValf, hairHuef, prof ); state.Send( new ClientVersionReq() ); state.BlockAllPackets = true; try { EventSink.InvokeCharacterCreated(args); } catch (Exception ex) { log.Fatal(String.Format("Exception disarmed in CharacterCreated {0}", name), ex); } Mobile m = args.Mobile; if ( m != null ) { state.Mobile = m; m.NetState = state; new LoginTimer( state, m ).Start(); } else { state.BlockAllPackets = false; state.Dispose(); } } }
public static void ExtendedCommand( NetState state, PacketReader pvSrc ) { int packetID = pvSrc.ReadUInt16(); PacketHandler ph = GetExtendedHandler( packetID ); if ( ph != null ) { if ( ph.Ingame && state.Mobile == null ) { Console.WriteLine( "Client: {0}: Sent ingame packet (0xBFx{1:X2}) before having been attached to a mobile", state, packetID ); state.Dispose(); } else if ( ph.Ingame && state.Mobile.Deleted ) { state.Dispose(); } else { ph.OnReceive( state, pvSrc ); } } else { pvSrc.Trace( state ); } }
private static void GameLoginInternal(NetState state, string username, string password, bool compressionEnabled) { GameLoginEventArgs e = new GameLoginEventArgs( state, username, password ); try { EventSink.InvokeGameLogin(e); } catch (Exception ex) { log.Fatal(String.Format("Exception disarmed in GameLogin {0}", username), ex); } if ( e.Accepted ) { if (state.Account == null) { log.ErrorFormat("BUG: GameLogin state.Account==null (username {0})", username); state.Dispose(); return; } state.CityInfo = e.CityInfo; state.CompressionEnabled = compressionEnabled; if ( Core.AOS ) state.Send( SupportedFeatures.Instantiate( state.Account ) ); state.Send( new CharacterList( state.Account, state.CityInfo ) ); } else { state.Dispose(); } }
public static void CreateCharacter70160( NetState state, PacketReader pvSrc ) { int unk1 = pvSrc.ReadInt32(); int unk2 = pvSrc.ReadInt32(); int unk3 = pvSrc.ReadByte(); string name = pvSrc.ReadString( 30 ); pvSrc.Seek( 2, SeekOrigin.Current ); int flags = pvSrc.ReadInt32(); pvSrc.Seek( 8, SeekOrigin.Current ); int prof = pvSrc.ReadByte(); pvSrc.Seek( 15, SeekOrigin.Current ); int genderRace = pvSrc.ReadByte(); int str = pvSrc.ReadByte(); int dex = pvSrc.ReadByte(); int intl= pvSrc.ReadByte(); int is1 = pvSrc.ReadByte(); int vs1 = pvSrc.ReadByte(); int is2 = pvSrc.ReadByte(); int vs2 = pvSrc.ReadByte(); int is3 = pvSrc.ReadByte(); int vs3 = pvSrc.ReadByte(); int is4 = pvSrc.ReadByte(); int vs4 = pvSrc.ReadByte(); int hue = pvSrc.ReadUInt16(); int hairVal = pvSrc.ReadInt16(); int hairHue = pvSrc.ReadInt16(); int hairValf= pvSrc.ReadInt16(); int hairHuef= pvSrc.ReadInt16(); pvSrc.ReadByte(); int cityIndex = pvSrc.ReadByte(); int charSlot = pvSrc.ReadInt32(); int clientIP = pvSrc.ReadInt32(); int shirtHue = pvSrc.ReadInt16(); int pantsHue = pvSrc.ReadInt16(); /* 0x00, 0x01 0x02, 0x03 -> Human Male, Human Female 0x04, 0x05 -> Elf Male, Elf Female 0x05, 0x06 -> Gargoyle Male, Gargoyle Female */ bool female = ((genderRace % 2) != 0); Race race = null; byte raceID = (byte)(genderRace < 4 ? 0 : ((genderRace / 2) - 1)); race = Race.Races[raceID]; if( race == null ) race = Race.DefaultRace; CityInfo[] info = state.CityInfo; IAccount a = state.Account; if ( info == null || a == null || cityIndex < 0 || cityIndex >= info.Length ) { state.Dispose(); } else { // Check if anyone is using this account for ( int i = 0; i < a.Length; ++i ) { Mobile check = a[i]; if ( check != null && check.Map != Map.Internal ) { Console.WriteLine( "Login: {0}: Account in use", state ); state.Send( new PopupMessage( PMMessage.CharInWorld ) ); return; } } state.Flags = (ClientFlags)flags; CharacterCreatedEventArgs args = new CharacterCreatedEventArgs( state, a, name, female, hue, str, dex, intl, info[cityIndex], new SkillNameValue[4] { new SkillNameValue( (SkillName)is1, vs1 ), new SkillNameValue( (SkillName)is2, vs2 ), new SkillNameValue( (SkillName)is3, vs3 ), new SkillNameValue( (SkillName)is4, vs4 ), }, shirtHue, pantsHue, hairVal, hairHue, hairValf, hairHuef, prof, race ); state.Send( new ClientVersionReq() ); state.BlockAllPackets = true; EventSink.InvokeCharacterCreated( args ); Mobile m = args.Mobile; if ( m != null ) { state.Mobile = m; m.NetState = state; new LoginTimer( state, m ).Start(); } else { state.BlockAllPackets = false; state.Dispose(); } } }
public static void GameLogin( NetState state, PacketReader pvSrc ) { if ( state.SentFirstPacket ) { state.Dispose(); return; } state.SentFirstPacket = true; int authID = pvSrc.ReadInt32(); if (Core.Config.Login.IgnoreAuthID) AddAuthID(authID); if ( !IsValidAuthID( authID ) ) { log.WarnFormat("Login: {0}: Invalid client detected, disconnecting", state); state.Dispose(); return; } else if ( state.m_AuthID != 0 && authID != state.m_AuthID ) { log.WarnFormat("Login: {0}: Invalid client detected, disconnecting", state); state.Dispose(); return; } else if ( state.m_AuthID == 0 && authID != state.m_Seed ) { log.WarnFormat("Login: {0}: Invalid client detected, disconnecting", state); state.Dispose(); return; } string username = pvSrc.ReadString( 30 ); string password = pvSrc.ReadString( 30 ); GameLoginInternal(state, username, password, true); }
public static void PlayServer( NetState state, PacketReader pvSrc ) { int index = pvSrc.ReadInt16(); ServerInfo[] info = state.ServerInfo; IAccount a = state.Account; if ( info == null || a == null || index < 0 || index >= info.Length ) { state.Dispose(); } else { ServerInfo si = info[index]; state.m_AuthID = PlayServerAck.m_AuthID = GenerateAuthID( state ); state.SentFirstPacket = false; state.Send( new PlayServerAck( si ) ); } }
public static void PlayServer( NetState state, PacketReader pvSrc ) { int index = pvSrc.ReadInt16(); ServerInfo[] info = state.ServerInfo; IAccount a = state.Account; if ( info == null || a == null || index < 0 || index >= info.Length ) { state.Dispose(); } else { ServerInfo si = info[index]; if (state.Username != null && state.Password != null && Core.Config.Features["quick-local-connect"] && si.Address.ToString() == state.Socket.LocalEndPoint.ToString()) { /* local connect to this game server which is login server at the same time: re-use this connection, emulate a GameLogin packet */ GameLoginInternal(state, state.Username, state.Password, false); return; } // send relay packet to client state.m_AuthID = PlayServerAck.m_AuthID = GenerateAuthID(); state.SentFirstPacket = false; state.Send( new PlayServerAck( si ) ); } }
public static void AccountLogin( NetState state, PacketReader pvSrc ) { if ( state.SentFirstPacket ) { state.Dispose(); return; } state.SentFirstPacket = true; string username = pvSrc.ReadString( 30 ); string password = pvSrc.ReadString( 30 ); AccountLoginEventArgs e = new AccountLoginEventArgs( state, username, password ); EventSink.InvokeAccountLogin( e ); if ( e.Accepted ) AccountLogin_ReplyAck( state ); else AccountLogin_ReplyRej( state, e.RejectReason ); }
public static void AccountLogin( NetState state, PacketReader pvSrc ) { if ( state.SentFirstPacket ) { state.Dispose(); return; } state.SentFirstPacket = true; string username = pvSrc.ReadString( 30 ); string password = pvSrc.ReadString( 30 ); AccountLoginEventArgs e = new AccountLoginEventArgs( state, username, password ); try { EventSink.InvokeAccountLogin(e); } catch (Exception ex) { log.Fatal(String.Format("Exception disarmed in AccountLogin {0}", username), ex); } if (e.Accepted && Core.Config.Features["quick-local-connect"]) { /* we have to remember username+password, because it is required to emulate a GameLogin packet */ state.Username = username; state.Password = password; } if ( e.Accepted ) AccountLogin_ReplyAck( state ); else AccountLogin_ReplyRej( state, e.RejectReason ); }
public static void AccountLogin_ReplyRej( NetState state, ALRReason reason ) { state.Send( new AccountLoginRej( reason ) ); state.Dispose(); }
public static void AccountLogin_ReplyAck( NetState state ) { ServerListEventArgs e = new ServerListEventArgs( state, state.Account ); try { EventSink.InvokeServerList(e); } catch (Exception ex) { log.Fatal("Exception disarmed in ServerList", ex); e.Rejected = true; } if ( e.Rejected ) { state.Account = null; state.Send( new AccountLoginRej( ALRReason.BadComm ) ); state.Dispose(); } else { ServerInfo[] info = (ServerInfo[])e.Servers.ToArray( typeof( ServerInfo ) ); state.ServerInfo = info; state.Send( new AccountLoginAck( info ) ); } }
public static bool VerifyGC( NetState state ) { if ( state.Mobile == null || state.Mobile.AccessLevel <= AccessLevel.Counselor ) { if ( state.Running ) Console.WriteLine( "Warning: {0}: Player using godclient, disconnecting", state ); state.Dispose(); return false; } else { return true; } }
private static void OnAddAuthID( NetState state, PacketReader pvSrc ) { if (!state.Super) { log.WarnFormat("Client {0} attempted to inject an AuthID", state); state.Dispose(false); return; } int authID = pvSrc.ReadInt32(); /*String username =*/ pvSrc.ReadString(30); AddAuthID(authID); state.Send(new AddAuthIDAck(authID)); }
public static void DisplayGumpResponse(NetState state, PacketReader pvSrc) { int serial = pvSrc.ReadInt32(); int typeID = pvSrc.ReadInt32(); int buttonID = pvSrc.ReadInt32(); List<Gump> gumps = state.Gumps; for (int i = 0; i < gumps.Count; ++i) { Gump gump = gumps[i]; if (gump.Serial == serial && gump.TypeID == typeID) { int switchCount = pvSrc.ReadInt32(); if (switchCount < 0) { Console.WriteLine("Client: {0}: Invalid gump response, disconnecting...", state); state.Dispose(); return; } int[] switches = new int[switchCount]; for (int j = 0; j < switches.Length; ++j) switches[j] = pvSrc.ReadInt32(); int textCount = pvSrc.ReadInt32(); if (textCount < 0) { Console.WriteLine("Client: {0}: Invalid gump response, disconnecting...", state); state.Dispose(); return; } TextRelay[] textEntries = new TextRelay[textCount]; for (int j = 0; j < textEntries.Length; ++j) { int entryID = pvSrc.ReadUInt16(); int textLength = pvSrc.ReadUInt16(); if (textLength > 239) return; string text = pvSrc.ReadUnicodeStringSafe(textLength); textEntries[j] = new TextRelay(entryID, text); } state.RemoveGump(i); if (!CheckResponse(gump, state.Mobile, buttonID)) return; gump.OnResponse(state, new RelayInfo(buttonID, switches, textEntries)); return; } } if (typeID == 461) // Virtue gump { int switchCount = pvSrc.ReadInt32(); if (buttonID == 1 && switchCount > 0) { Mobile beheld = World.FindMobile(pvSrc.ReadInt32()); if (beheld != null) EventSink.InvokeVirtueGumpRequest(new VirtueGumpRequestEventArgs(state.Mobile, beheld)); } else { Mobile beheld = World.FindMobile(serial); if (beheld != null) EventSink.InvokeVirtueItemRequest(new VirtueItemRequestEventArgs(state.Mobile, beheld, buttonID)); } } }
public static void AccountLogin_ReplyRej(NetState state, ALRReason reason) { state.Send(new AccountLoginRej(reason)); state.Dispose(); }