/// <summary> /// Ticks the VM one step. /// Should be called once every loop. /// </summary> public void Tick() { foreach (VirtualThread Thread in m_Threads) { Thread.Tick(); } m_TickCounter++; if (m_TickCounter == 4) { //TODO: Change ID... PacketStream SimulationStatePacket = new PacketStream(0x10, 0x00); SimulationStatePacket.WriteByte(0x10); //TODO: Change ID SimulationStatePacket.WriteByte((byte)m_TickCounter); //Number of ticks since last update. SimulationStatePacket.WriteInt32(m_Threads.Count); //Number of objects in this VM. BinaryFormatter BinFormatter = new BinaryFormatter(); foreach (VirtualThread VThread in m_Threads) BinFormatter.Serialize(SimulationStatePacket, VThread); //TODO: Compress packet... NewSimulationStateEvent(SimulationStatePacket); m_TickCounter = 0; } }
/// <summary> /// Sends a CharacterCreate packet to a CityServer. /// </summary> /// <param name="LoginArgs">Arguments used to log onto the CityServer.</param> /// <param name="Character">The character to create on the CityServer.</param> public static void SendCharacterCreateCity(NetworkClient Client, UISim Character) { PacketStream Packet = new PacketStream((byte)PacketType.CHARACTER_CREATE_CITY, 0); MemoryStream PacketData = new MemoryStream(); BinaryWriter Writer = new BinaryWriter(PacketData); Writer.Write((byte)Client.ClientEncryptor.Username.Length); Writer.Write(Encoding.ASCII.GetBytes(Client.ClientEncryptor.Username), 0, Encoding.ASCII.GetBytes(Client.ClientEncryptor.Username).Length); Writer.Write(PlayerAccount.CityToken); Writer.Write(Character.Timestamp); Writer.Write(Character.Name); Writer.Write(Character.Sex); Writer.Write(Character.Description); Writer.Write((ulong)Character.HeadOutfitID); Writer.Write((ulong)Character.BodyOutfitID); Writer.Write((byte)Character.Avatar.Appearance); Packet.WriteBytes(PacketData.ToArray()); Writer.Close(); Client.SendEncrypted((byte)PacketType.CHARACTER_CREATE_CITY, Packet.ToArray()); }
/// <summary> /// Requests a token from the LoginServer, that can be used to log into a CityServer. /// </summary> /// <param name="Client">A NetworkClient instance.</param> public static void RequestCityToken(NetworkClient Client, UISim SelectedCharacter) { PacketStream Packet = new PacketStream((byte)PacketType.REQUEST_CITY_TOKEN, 0); Packet.WriteString(Client.ClientEncryptor.Username); Packet.WriteString(SelectedCharacter.ResidingCity.UUID); Packet.WriteString(SelectedCharacter.GUID.ToString()); Client.SendEncrypted((byte)PacketType.REQUEST_CITY_TOKEN, Packet.ToArray()); }
public static void ReceivedUnEncryptedPacket(NetworkClient Client, PacketStream Packet) { //NOTE: Normally, the client would only send its username, and that would be // used to lookup the password from the database. string Password = Packet.ReadPascalString(); Console.WriteLine("Received password from client: " + Password); //TODO: Client should be passed by ref? //ClientEncryptor must be initialized in order to decrypt encrypted messages! Client.ClientEncryptor = new ARC4Encryptor(Password); }
/// <summary> /// A client requested login. /// </summary> /// <param name="Client">NetworkClient instance.</param> /// <param name="Packet">ProcessedPacket instance.</param> public static void InitialClientConnect(NetworkClient Client, ProcessedPacket Packet) { Console.WriteLine("Server receives data - test 1"); PacketStream EncryptedPacket = new PacketStream(0x02, 0); EncryptedPacket.WriteHeader(); ClientPublicKey = Packet.ReadBytes((Packet.ReadByte())); AESEncryptor Enc = (AESEncryptor)Client.ClientEncryptor; Enc.NOnce = Packet.ReadBytes((Packet.ReadByte())); Enc.PublicKey = ClientPublicKey; Enc.PrivateKey = ServerPrivateKey; Client.ClientEncryptor = Enc; //THIS IS IMPORTANT - public key must be derived from private! ServerPublicKey = ServerPrivateKey.PublicKey.ToByteArray(); ChallengeResponse = new byte[16]; m_Random.GetNonZeroBytes(ChallengeResponse); MemoryStream StreamToEncrypt = new MemoryStream(); BinaryWriter Writer = new BinaryWriter(StreamToEncrypt); Writer.Write(ChallengeResponse, 0, ChallengeResponse.Length); Writer.Flush(); byte[] EncryptedData = StaticStaticDiffieHellman.Encrypt(ServerPrivateKey, ECDiffieHellmanCngPublicKey.FromByteArray(ClientPublicKey, CngKeyBlobFormat.EccPublicBlob), Enc.NOnce, StreamToEncrypt.ToArray()); EncryptedPacket.WriteUInt16((ushort)(PacketHeaders.UNENCRYPTED + (1 + ServerPublicKey.Length) + (1 + EncryptedData.Length))); EncryptedPacket.WriteByte((byte)ServerPublicKey.Length); EncryptedPacket.WriteBytes(ServerPublicKey); EncryptedPacket.WriteByte((byte)EncryptedData.Length); EncryptedPacket.WriteBytes(EncryptedData); Client.Send(EncryptedPacket.ToArray()); NetworkFacade.Listener.UpdateClient(Client); Console.WriteLine("Test 1: passed!"); }
//First packet sent from client to server. public static void SendInitialConnectPacket(NetworkClient Client, string Username) { PacketStream InitialPacket = new PacketStream(0x01, 0); InitialPacket.WriteHeader(); ECDiffieHellmanCng PrivateKey = Client.ClientEncryptor.GetDecryptionArgsContainer().AESDecryptArgs.PrivateKey; //IMPORTANT: Public key must derive from the private key! PacketHandlers.ClientPublicKey = PrivateKey.PublicKey.ToByteArray(); byte[] NOnce = Client.ClientEncryptor.GetDecryptionArgsContainer().AESDecryptArgs.NOnce; InitialPacket.WriteUInt16((ushort)((byte)PacketHeaders.UNENCRYPTED + (PacketHandlers.ClientPublicKey.Length + 1) + (NOnce.Length + 1))); InitialPacket.WriteByte((byte)PacketHandlers.ClientPublicKey.Length); InitialPacket.WriteBytes(PacketHandlers.ClientPublicKey); InitialPacket.WriteByte((byte)NOnce.Length); InitialPacket.WriteBytes(NOnce); Client.Send(InitialPacket.ToArray()); }
/// <summary> /// Sends a CharacterCreate packet to the LoginServer. /// </summary> /// <param name="Character">The character to create.</param> /// <param name="TimeStamp">The timestamp of when this character was created.</param> public static void SendCharacterCreate(UISim Character, string TimeStamp) { PacketStream Packet = new PacketStream((byte)PacketType.CHARACTER_CREATE, 0); Packet.WriteString(NetworkFacade.Client.ClientEncryptor.Username); Packet.WriteString(TimeStamp); Packet.WriteString(Character.Name); Packet.WriteString(Character.Sex); Packet.WriteString(Character.Description); Packet.WriteUInt64(Character.HeadOutfitID); Packet.WriteUInt64(Character.BodyOutfitID); Packet.WriteByte((byte)Character.Avatar.Appearance); Packet.WriteString(Character.ResidingCity.Name); Packet.WriteUInt64(Character.ResidingCity.Thumbnail); Packet.WriteString(Character.ResidingCity.UUID); Packet.WriteUInt64(Character.ResidingCity.Map); Packet.WriteString(Character.ResidingCity.IP); Packet.WriteInt32(Character.ResidingCity.Port); byte[] PacketData = Packet.ToArray(); NetworkFacade.Client.SendEncrypted((byte)PacketType.CHARACTER_CREATE, PacketData); }
/// <summary> /// Sends a CharacterRetirement packet to the LoginServer, retiring a specific character. /// </summary> /// <param name="Character">The character to retire.</param> public static void SendCharacterRetirement(UISim Character) { PacketStream Packet = new PacketStream((byte)PacketType.RETIRE_CHARACTER, 0); Packet.WriteString(PlayerAccount.Username); Packet.WriteString(Character.GUID.ToString()); NetworkFacade.Client.SendEncrypted((byte)PacketType.RETIRE_CHARACTER, Packet.ToArray()); }
private void SendState(VM vm) { if (ClientsToSync.Count == 0) return; var state = vm.Save(); var cmd = new VMNetCommand(new VMStateSyncCmd { State = state }); //currently just hack this on the tick system. will change when we switch to not gonzonet var ticks = new VMNetTickList { Ticks = new List<VMNetTick> { new VMNetTick { Commands = new List<VMNetCommand> { cmd }, RandomSeed = 0, //will be restored by client from cmd TickID = TickID } } }; byte[] data; using (var stream = new MemoryStream()) { using (var writer = new BinaryWriter(stream)) { ticks.SerializeInto(writer); } data = stream.ToArray(); } using (var stream = new PacketStream((byte)PacketType.VM_PACKET, 0)) { stream.WriteHeader(); stream.WriteInt32(data.Length + (int)PacketHeaders.UNENCRYPTED); stream.WriteBytes(data); var packet = stream.ToArray(); foreach (var client in ClientsToSync) client.Send(packet); } ClientsToSync.Clear(); }
protected virtual void ReceiveCallback(IAsyncResult AR) { try { Socket Sock = (Socket)AR.AsyncState; int NumBytesRead = Sock.EndReceive(AR); /** Cant do anything with this! **/ if (NumBytesRead == 0) { return; } byte[] TmpBuf = new byte[NumBytesRead]; Buffer.BlockCopy(m_RecvBuf, 0, TmpBuf, 0, NumBytesRead); //The packet is given an ID of 0x00 because its ID is currently unknown. PacketStream TempPacket = new PacketStream(0x00, (ushort)NumBytesRead, TmpBuf); byte ID = TempPacket.PeekByte(0); Logger.Log("Received packet: " + ID, LogLevel.info); ushort PacketLength = 0; var handler = FindPacketHandler(ID); if (handler != null) { PacketLength = handler.Length; Logger.Log("Found matching PacketID!\r\n\r\n", LogLevel.info); if (NumBytesRead == PacketLength) { Logger.Log("Got packet - exact length!\r\n\r\n", LogLevel.info); m_RecvBuf = new byte[11024]; OnPacket(new ProcessedPacket(ID, handler.Encrypted, handler.VariableLength, PacketLength, ClientEncryptor, TempPacket.ToArray()), handler); } else if (NumBytesRead < PacketLength) { m_TempPacket = new PacketStream(ID, PacketLength); byte[] TmpBuffer = new byte[NumBytesRead]; //Store the number of bytes that were read in the temporary buffer. Logger.Log("Got data, but not a full packet - stored " + NumBytesRead.ToString() + "bytes!\r\n\r\n", LogLevel.info); Buffer.BlockCopy(m_RecvBuf, 0, TmpBuffer, 0, NumBytesRead); m_TempPacket.WriteBytes(TmpBuffer); //And reset the buffers! m_RecvBuf = new byte[11024]; TmpBuffer = null; } else if (PacketLength == 0) { Logger.Log("Received variable length packet!\r\n", LogLevel.info); if (NumBytesRead > (int)PacketHeaders.UNENCRYPTED) //Header is 3 bytes. { PacketLength = TempPacket.PeekUShort(1); if (NumBytesRead == PacketLength) { Logger.Log("Received exact number of bytes for packet!\r\n", LogLevel.info); m_RecvBuf = new byte[11024]; m_TempPacket = null; OnPacket(new ProcessedPacket(ID, handler.Encrypted, handler.VariableLength, PacketLength, ClientEncryptor, TempPacket.ToArray()), handler); } else if (NumBytesRead < PacketLength) { Logger.Log("Didn't receive entire packet - stored: " + PacketLength + " bytes!\r\n", LogLevel.info); TempPacket.SetLength(PacketLength); m_TempPacket = TempPacket; m_RecvBuf = new byte[11024]; } else if (NumBytesRead > PacketLength) { Logger.Log("Received more bytes than needed for packet. Excess: " + (NumBytesRead - PacketLength) + "\r\n", LogLevel.info); byte[] TmpBuffer = new byte[NumBytesRead - PacketLength]; Buffer.BlockCopy(TempPacket.ToArray(), 0, TmpBuffer, 0, TmpBuffer.Length); m_TempPacket = new PacketStream(TmpBuffer[0], (ushort)(NumBytesRead - PacketLength), TmpBuffer); byte[] PacketBuffer = new byte[PacketLength]; Buffer.BlockCopy(TempPacket.ToArray(), 0, PacketBuffer, 0, PacketBuffer.Length); m_RecvBuf = new byte[11024]; OnPacket(new ProcessedPacket(ID, handler.Encrypted, handler.VariableLength, PacketLength, ClientEncryptor, PacketBuffer), handler); } } } } else { if (m_TempPacket != null) { if (m_TempPacket.Length < m_TempPacket.BufferLength) { //Received the exact number of bytes needed to complete the stored packet. if ((m_TempPacket.BufferLength + NumBytesRead) == m_TempPacket.Length) { byte[] TmpBuffer = new byte[NumBytesRead]; Buffer.BlockCopy(m_RecvBuf, 0, TmpBuffer, 0, NumBytesRead); m_RecvBuf = new byte[11024]; TmpBuffer = null; } //Received more than the number of bytes needed to complete the packet! else if ((m_TempPacket.BufferLength + NumBytesRead) > m_TempPacket.Length) { ushort Target = (ushort)((m_TempPacket.BufferLength + NumBytesRead) - m_TempPacket.Length); byte[] TmpBuffer = new byte[Target]; Buffer.BlockCopy(m_RecvBuf, 0, TmpBuffer, 0, Target); m_TempPacket.WriteBytes(TmpBuffer); //Now we have a full packet, so call the received event! OnPacket(new ProcessedPacket(m_TempPacket.PacketID, handler.Encrypted, handler.VariableLength, (ushort)m_TempPacket.Length, ClientEncryptor, m_TempPacket.ToArray()), handler); //Copy the remaining bytes in the receiving buffer. TmpBuffer = new byte[NumBytesRead - Target]; Buffer.BlockCopy(m_RecvBuf, Target, TmpBuffer, 0, (NumBytesRead - Target)); //Give the temporary packet an ID of 0x00 since we don't know its ID yet. TempPacket = new PacketStream(0x00, (ushort)(NumBytesRead - Target), TmpBuffer); ID = TempPacket.PeekByte(0); handler = FindPacketHandler(ID); //This SHOULD be an existing ID, but let's sanity-check it... if (handler != null) { m_TempPacket = new PacketStream(ID, handler.Length, TempPacket.ToArray()); //Congratulations, you just received another packet! if (m_TempPacket.Length == m_TempPacket.BufferLength) { OnPacket(new ProcessedPacket(m_TempPacket.PacketID, handler.Encrypted, handler.VariableLength, (ushort)m_TempPacket.Length, ClientEncryptor, m_TempPacket.ToArray()), handler); //No more data to store on this read, so reset everything... m_TempPacket = null; TmpBuffer = null; m_RecvBuf = new byte[11024]; } } else { //Houston, we have a problem (this should never occur)! } } } } } m_Sock.BeginReceive(m_RecvBuf, 0, m_RecvBuf.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), m_Sock); } catch (SocketException) { Disconnect(); } }
/// <summary> /// Sends a request to purchase a lot. /// </summary> /// <param name="Client">NetworkClient instance connected to city server.</param> /// <param name="X">X-coordinate of lot.</param> /// <param name="Y">Y-coordinate of lot.</param> public static void SendLotPurchaseRequest(NetworkClient Client, short X, short Y) { PacketStream Packet = new PacketStream((byte)PacketType.LOT_PURCHASE_REQUEST, 0); Packet.WriteUInt16((ushort)X); Packet.WriteUInt16((ushort)Y); Client.SendEncrypted((byte)PacketType.LOT_PURCHASE_REQUEST, Packet.ToArray()); }
protected virtual void ReceiveCallback(IAsyncResult AR) { Socket Sock = (Socket)AR.AsyncState; int NumBytesRead = 0; try { NumBytesRead = Sock.EndReceive(AR); } catch (SocketException) { Disconnect(); return; } if (NumBytesRead == 0) { Disconnect(); return; } byte[] TmpBuf = new byte[NumBytesRead]; Buffer.BlockCopy(m_RecvBuf, 0, TmpBuf, 0, NumBytesRead); int Offset = 0; while (Offset < NumBytesRead) { if (m_TempPacket == null) { byte ID = TmpBuf[Offset++]; PacketStream TempPacket = new PacketStream(ID, 0); TempPacket.WriteByte(ID); m_HeaderBuild = new List<byte>(); while (Offset < NumBytesRead && m_HeaderBuild.Count < 4) { m_HeaderBuild.Add(TmpBuf[Offset++]); } if (m_HeaderBuild.Count < 4) { m_TempPacket = TempPacket; //length got fragmented. } else { int Length = BitConverter.ToInt32(m_HeaderBuild.ToArray(), 0); TempPacket.SetLength(Length); TempPacket.WriteInt32(Length); m_HeaderBuild = null; byte[] TmpBuffer = new byte[Math.Min(NumBytesRead - Offset, TempPacket.Length-TempPacket.BufferLength)]; Buffer.BlockCopy(TmpBuf, Offset, TmpBuffer, 0, TmpBuffer.Length); Offset += TmpBuffer.Length; TempPacket.WriteBytes(TmpBuffer); m_TempPacket = TempPacket; } } else //fragmented, continue from last { if (m_HeaderBuild != null) { //we can safely assume that resuming from a fragmented length, it cannot get fragmented again. while (m_HeaderBuild.Count < 4) { m_HeaderBuild.Add(TmpBuf[Offset++]); } int Length = BitConverter.ToInt32(m_HeaderBuild.ToArray(), 0); m_TempPacket.SetLength(Length); m_TempPacket.WriteInt32(Length); m_HeaderBuild = null; } byte[] TmpBuffer = new byte[Math.Min(NumBytesRead - Offset, m_TempPacket.Length - m_TempPacket.BufferLength)]; Buffer.BlockCopy(TmpBuf, Offset, TmpBuffer, 0, TmpBuffer.Length); Offset += TmpBuffer.Length; m_TempPacket.WriteBytes(TmpBuffer); } if (m_TempPacket != null && m_TempPacket.BufferLength == m_TempPacket.Length) { var handler = FindPacketHandler(m_TempPacket.PacketID); if (handler != null) { OnPacket(new ProcessedPacket(m_TempPacket.PacketID, handler.Encrypted, handler.VariableLength, (int)m_TempPacket.Length, m_ClientEncryptor, m_TempPacket.ToArray()), handler); } m_TempPacket = null; } } try { m_Sock.BeginReceive(m_RecvBuf, 0, m_RecvBuf.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), m_Sock); } catch (SocketException) { Disconnect(); return; } }
/// <summary> /// LoginServer sent information about the player's characters. /// </summary> /// <param name="Packet">The packet that was received.</param> public static void OnCharacterInfoResponse(ProcessedPacket Packet, NetworkClient Client) { byte NumCharacters = (byte)Packet.ReadByte(); byte NewCharacters = (byte)Packet.ReadByte(); List<UISim> FreshSims = new List<UISim>(); for (int i = 0; i < NewCharacters; i++) { int CharacterID = Packet.ReadInt32(); UISim FreshSim = new UISim(Packet.ReadString(), false); FreshSim.CharacterID = CharacterID; FreshSim.Timestamp = Packet.ReadString(); FreshSim.Name = Packet.ReadString(); FreshSim.Sex = Packet.ReadString(); FreshSim.Description = Packet.ReadString(); FreshSim.HeadOutfitID = Packet.ReadUInt64(); FreshSim.BodyOutfitID = Packet.ReadUInt64(); FreshSim.Avatar.Appearance = (AppearanceType)Packet.ReadByte(); FreshSim.ResidingCity = new CityInfo(false); FreshSim.ResidingCity.Name = Packet.ReadString(); FreshSim.ResidingCity.Thumbnail = Packet.ReadUInt64(); FreshSim.ResidingCity.UUID = Packet.ReadString(); FreshSim.ResidingCity.Map = Packet.ReadUInt64(); FreshSim.ResidingCity.IP = Packet.ReadString(); FreshSim.ResidingCity.Port = Packet.ReadInt32(); FreshSims.Add(FreshSim); } lock (NetworkFacade.Avatars) { if ((NumCharacters < 3) && (NewCharacters > 0)) { FreshSims = Cache.LoadCachedSims(FreshSims); NetworkFacade.Avatars = FreshSims; Cache.CacheSims(FreshSims); } if (NewCharacters == 0 && NumCharacters > 0) NetworkFacade.Avatars = Cache.LoadAllSims(); else if (NewCharacters == 3 && NumCharacters == 3) { NetworkFacade.Avatars = FreshSims; Cache.CacheSims(FreshSims); } else if (NewCharacters == 0 && NumCharacters == 0) { //Make sure if sims existed in the cache, they are deleted (because they didn't exist in DB). Cache.DeleteCache(); } else if (NumCharacters == 3 && NewCharacters == 3) { NetworkFacade.Avatars = FreshSims; } } PacketStream CityInfoRequest = new PacketStream(0x06, 0); CityInfoRequest.WriteByte(0x00); //Dummy Client.SendEncrypted((byte)PacketType.CITY_LIST, CityInfoRequest.ToArray()); }
//uh, this is a little silly. private void SendOneOff(NetworkClient client, VMNetTick tick) { var ticks = new VMNetTickList { Ticks = new List<VMNetTick>() { tick }, ImmediateMode = true }; byte[] data; using (var stream = new MemoryStream()) { using (var writer = new BinaryWriter(stream)) { ticks.SerializeInto(writer); } data = stream.ToArray(); } using (var stream = new PacketStream((byte)PacketType.VM_PACKET, 0)) { stream.WriteHeader(); stream.WriteInt32(data.Length + (int)PacketHeaders.UNENCRYPTED); stream.WriteBytes(data); client.Send(stream.ToArray()); } }
private void SendState(VM vm) { if (ClientsToSync.Count == 0) return; //Console.WriteLine("== SERIAL: Sending State to Client... =="); var watch = new Stopwatch(); watch.Start(); var state = vm.Save(); //Console.WriteLine("== STATE: Intermediate - after save... " + watch.ElapsedMilliseconds + " ms. =="); var cmd = new VMNetCommand(new VMStateSyncCmd { State = state }); //currently just hack this on the tick system. will change when we switch to not gonzonet var ticks = new VMNetTickList { Ticks = new List<VMNetTick> { new VMNetTick { Commands = new List<VMNetCommand> { cmd }, RandomSeed = 0, //will be restored by client from cmd TickID = TickID } } }; byte[] data; using (var stream = new MemoryStream()) { //Console.WriteLine("== STATE: Intermediate - before serialize... " + watch.ElapsedMilliseconds + " ms. =="); using (var writer = new BinaryWriter(stream)) { ticks.SerializeInto(writer); } //Console.WriteLine("== STATE: Intermediate - before toArray... " + watch.ElapsedMilliseconds + " ms. =="); data = stream.ToArray(); } //Console.WriteLine("== STATE: Intermediate - before send... " + watch.ElapsedMilliseconds + " ms. =="); byte[] packet; using (var stream = new PacketStream((byte)PacketType.VM_PACKET, 0)) { stream.WriteHeader(); stream.WriteInt32(data.Length + (int)PacketHeaders.UNENCRYPTED); stream.WriteBytes(data); packet = stream.ToArray(); } foreach (var client in ClientsToSync) client.Send(packet); ClientsToSync.Clear(); watch.Stop(); //Console.WriteLine("== SERIAL: DONE! State send took "+watch.ElapsedMilliseconds+" ms. =="); }
public static void SendCharacterInfoRequest(string TimeStamp) { PacketStream Packet = new PacketStream((byte)PacketType.CHARACTER_LIST, 0); //If this timestamp is newer than the server's timestamp, it means //the client doesn't have a charactercache. If it's older, it means //the cache needs to be updated. If it matches, the server sends an //empty responsepacket. //Packet.WriteString(TimeStamp); Packet.WriteString(TimeStamp); byte[] PacketData = Packet.ToArray(); NetworkFacade.Client.SendEncrypted((byte)PacketType.CHARACTER_LIST, PacketData); }
protected virtual void ReceiveCallback(IAsyncResult AR) { Socket Sock = (Socket)AR.AsyncState; int NumBytesRead = 0; try { NumBytesRead = Sock.EndReceive(AR); } catch (SocketException) { Disconnect(); return; } if (NumBytesRead == 0) { Disconnect(); return; } byte[] TmpBuf = new byte[NumBytesRead]; Buffer.BlockCopy(m_RecvBuf, 0, TmpBuf, 0, NumBytesRead); int Offset = 0; while (Offset < NumBytesRead) { if (m_TempPacket == null) { byte ID = TmpBuf[Offset++]; PacketStream TempPacket = new PacketStream(ID, 0); TempPacket.WriteByte(ID); m_HeaderBuild = new List <byte>(); while (Offset < NumBytesRead && m_HeaderBuild.Count < 4) { m_HeaderBuild.Add(TmpBuf[Offset++]); } if (m_HeaderBuild.Count < 4) { m_TempPacket = TempPacket; //length got fragmented. } else { int Length = BitConverter.ToInt32(m_HeaderBuild.ToArray(), 0); TempPacket.SetLength(Length); TempPacket.WriteInt32(Length); m_HeaderBuild = null; byte[] TmpBuffer = new byte[Math.Min(NumBytesRead - Offset, TempPacket.Length - TempPacket.BufferLength)]; Buffer.BlockCopy(TmpBuf, Offset, TmpBuffer, 0, TmpBuffer.Length); Offset += TmpBuffer.Length; TempPacket.WriteBytes(TmpBuffer); m_TempPacket = TempPacket; } } else //fragmented, continue from last { if (m_HeaderBuild != null) { //we can safely assume that resuming from a fragmented length, it cannot get fragmented again. while (m_HeaderBuild.Count < 4) { m_HeaderBuild.Add(TmpBuf[Offset++]); } int Length = BitConverter.ToInt32(m_HeaderBuild.ToArray(), 0); m_TempPacket.SetLength(Length); m_TempPacket.WriteInt32(Length); m_HeaderBuild = null; } byte[] TmpBuffer = new byte[Math.Min(NumBytesRead - Offset, m_TempPacket.Length - m_TempPacket.BufferLength)]; Buffer.BlockCopy(TmpBuf, Offset, TmpBuffer, 0, TmpBuffer.Length); Offset += TmpBuffer.Length; m_TempPacket.WriteBytes(TmpBuffer); } if (m_TempPacket != null && m_TempPacket.BufferLength == m_TempPacket.Length) { var handler = FindPacketHandler(m_TempPacket.PacketID); if (handler != null) { OnPacket(new ProcessedPacket(m_TempPacket.PacketID, handler.Encrypted, handler.VariableLength, (int)m_TempPacket.Length, m_ClientEncryptor, m_TempPacket.ToArray()), handler); } m_TempPacket = null; } } try { m_Sock.BeginReceive(m_RecvBuf, 0, m_RecvBuf.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), m_Sock); } catch (SocketException) { Disconnect(); return; } }
private void SendTickBuffer() { var ticks = new VMNetTickList { Ticks = TickBuffer }; byte[] data; using (var stream = new MemoryStream()) { using (var writer = new BinaryWriter(stream)) { ticks.SerializeInto(writer); } data = stream.ToArray(); } using (var stream = new PacketStream((byte)PacketType.VM_PACKET, 0)) { stream.WriteHeader(); stream.WriteInt32(data.Length + (int)PacketHeaders.UNENCRYPTED); stream.WriteBytes(data); Broadcast(stream.ToArray(), ClientsToSync); } TickBuffer.Clear(); }
protected virtual void ReceiveCallback(IAsyncResult AR) { try { Socket Sock = (Socket)AR.AsyncState; int NumBytesRead = Sock.EndReceive(AR); /** Cant do anything with this! **/ if (NumBytesRead == 0) { return; } byte[] TmpBuf = new byte[NumBytesRead]; Buffer.BlockCopy(m_RecvBuf, 0, TmpBuf, 0, NumBytesRead); m_RecvBuf = new byte[11024]; //Clear, to make sure this buffer is always fresh. if (m_TempPacket == null) //No temporary data was stored - beginning of new packet! { //The packet is given an ID of 0x00 because its ID is currently unknown. PacketStream UnknownPacket = new PacketStream(0x00, (ushort)NumBytesRead, TmpBuf); byte ID = UnknownPacket.PeekByte(0); Logger.Log("Received packet: " + ID, LogLevel.info); ushort PacketLength = 0; m_Handler = FindPacketHandler(ID); PacketLength = m_Handler.Length; if (PacketLength == 0) //Variable length! { if (NumBytesRead >= (int)PacketHeaders.ENCRYPTED) PacketLength = UnknownPacket.PeekUShort(1); } else { if (m_TempPacket == null) m_TempPacket = new PacketStream(ID, PacketLength); byte[] TmpBuffer = new byte[NumBytesRead]; //Store the number of bytes that were read in the temporary buffer. Logger.Log("Got data, but not a full header - stored " + NumBytesRead.ToString() + "bytes!\r\n\r\n", LogLevel.info); Buffer.BlockCopy(m_RecvBuf, 0, TmpBuffer, 0, NumBytesRead); m_TempPacket.WriteBytes(TmpBuffer); TmpBuffer = null; } if (PacketLength != 0) { if (NumBytesRead == PacketLength) { Logger.Log("Got packet - exact length!\r\n\r\n", LogLevel.info); OnPacket(new ProcessedPacket(ID, m_Handler.Encrypted, m_Handler.VariableLength, PacketLength, m_ClientEncryptor, UnknownPacket.ToArray()), m_Handler); } else if (NumBytesRead < PacketLength) { if (m_TempPacket == null) m_TempPacket = new PacketStream(ID, PacketLength); byte[] TmpBuffer = new byte[NumBytesRead]; //Store the number of bytes that were read in the temporary buffer. Logger.Log("Got data, but not a full packet - stored " + NumBytesRead.ToString() + "bytes!\r\n\r\n", LogLevel.info); Buffer.BlockCopy(m_RecvBuf, 0, TmpBuffer, 0, NumBytesRead); m_TempPacket.WriteBytes(TmpBuffer); TmpBuffer = null; } else if (NumBytesRead > PacketLength) { Logger.Log("Received more bytes than needed for packet. Excess: " + (NumBytesRead - PacketLength) + "\r\n", LogLevel.info); PacketHandler OldHandler = m_Handler; byte[] PacketBuffer = new byte[PacketLength]; Buffer.BlockCopy(UnknownPacket.ToArray(), 0, PacketBuffer, 0, PacketBuffer.Length); OnPacket(new ProcessedPacket(ID, OldHandler.Encrypted, OldHandler.VariableLength, OldHandler.Length, m_ClientEncryptor, PacketBuffer), OldHandler); byte[] TmpBuffer = new byte[NumBytesRead - PacketLength]; Buffer.BlockCopy(UnknownPacket.ToArray(), (NumBytesRead - PacketLength) - 1, TmpBuffer, 0, TmpBuffer.Length); m_TempPacket = new PacketStream(TmpBuffer[0], (ushort)(NumBytesRead - PacketLength), TmpBuffer); m_TempPacket.WriteBytes(TmpBuffer); m_Handler = FindPacketHandler(ID); PacketLength = m_Handler.Length; if (PacketLength == 0) //Variable length! { if (m_TempPacket.BufferLength >= (int)PacketHeaders.ENCRYPTED) { PacketLength = UnknownPacket.PeekUShort(1); m_TempPacket.SetLength(PacketLength); } } TmpBuffer = null; } } } else { m_TempPacket.WriteBytes(TmpBuf); if (m_TempPacket.Length == 0) //Variable length! { if (NumBytesRead >= (int)PacketHeaders.ENCRYPTED) m_TempPacket.SetLength(m_TempPacket.PeekUShort(1)); else { byte[] TmpBuffer = new byte[NumBytesRead]; //Store the number of bytes that were read in the temporary buffer. Logger.Log("Got data, but not a full header - stored " + NumBytesRead.ToString() + "bytes!\r\n\r\n", LogLevel.info); Buffer.BlockCopy(m_RecvBuf, 0, TmpBuffer, 0, NumBytesRead); m_TempPacket.WriteBytes(TmpBuffer); BeginReceive(); TmpBuffer = null; } } if (m_TempPacket.BufferLength == m_TempPacket.Length) { Logger.Log("Got packet - exact length!\r\n\r\n", LogLevel.info); OnPacket(new ProcessedPacket(m_TempPacket.PacketID, m_Handler.Encrypted, m_Handler.VariableLength, (ushort)m_TempPacket.Length, m_ClientEncryptor, m_TempPacket.ToArray()), m_Handler); } else if (m_TempPacket.BufferLength < m_TempPacket.Length) { byte[] TmpBuffer = new byte[NumBytesRead]; //Store the number of bytes that were read in the temporary buffer. Logger.Log("Got data, but not a full packet - stored " + NumBytesRead.ToString() + "bytes!\r\n\r\n", LogLevel.info); Buffer.BlockCopy(m_RecvBuf, 0, TmpBuffer, 0, NumBytesRead); m_TempPacket.WriteBytes(TmpBuffer); TmpBuffer = null; } else if (m_TempPacket.BufferLength > m_TempPacket.Length) { Logger.Log("Received more bytes than needed for packet. Excess: " + (m_TempPacket.BufferLength - m_TempPacket.Length) + "\r\n", LogLevel.info); PacketHandler OldHandler = m_Handler; byte[] PacketBuffer = new byte[m_TempPacket.Length]; Buffer.BlockCopy(m_TempPacket.ToArray(), 0, PacketBuffer, 0, PacketBuffer.Length); OnPacket(new ProcessedPacket(OldHandler.ID, OldHandler.Encrypted, OldHandler.VariableLength, OldHandler.Length, m_ClientEncryptor, PacketBuffer), OldHandler); byte[] TmpBuffer = new byte[m_TempPacket.BufferLength - m_TempPacket.Length]; Buffer.BlockCopy(m_TempPacket.ToArray(), ((int)m_TempPacket.BufferLength - (int)m_TempPacket.Length), TmpBuffer, 0, TmpBuffer.Length); m_TempPacket = new PacketStream(TmpBuffer[0], (ushort)(m_TempPacket.BufferLength - m_TempPacket.Length), TmpBuffer); m_Handler = FindPacketHandler(m_TempPacket.PacketID); ushort PacketLength = m_Handler.Length; if (PacketLength == 0) //Variable length! { if (m_TempPacket.BufferLength >= (int)PacketHeaders.ENCRYPTED) { PacketLength = m_TempPacket.PeekUShort(1); m_TempPacket.SetLength(PacketLength); } } } } m_Sock.BeginReceive(m_RecvBuf, 0, m_RecvBuf.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), m_Sock); } catch (SocketException) { Disconnect(); } }
/// <summary> /// Sends a token to a CityServer, as received by a LoginServer. /// </summary> /// <param name="Client">A NetworkClient instance.</param> public static void SendCityToken(NetworkClient Client) { PacketStream Packet = new PacketStream((byte)PacketType.CITY_TOKEN, 0); MemoryStream PacketData = new MemoryStream(); BinaryWriter Writer = new BinaryWriter(PacketData); Writer.Write(PlayerAccount.CityToken); Packet.WriteBytes(PacketData.ToArray()); Writer.Close(); Client.SendEncrypted((byte)PacketType.CITY_TOKEN, Packet.ToArray()); }
public static void SendLetter(NetworkClient Client, string Msg, string Subject, string GUID) { PacketStream Packet = new PacketStream((byte)PacketType.PLAYER_SENT_LETTER, 0); Packet.WriteString(GUID); Packet.WriteString(Subject); Packet.WriteString(Msg); Client.SendEncrypted((byte)PacketType.PLAYER_SENT_LETTER, Packet.ToArray()); }
public static void SendLoginRequest(LoginArgsContainer Args) { PacketStream InitialPacket = new PacketStream((byte)PacketType.LOGIN_REQUEST, 0); InitialPacket.WriteHeader(); //ECDiffieHellmanCng PrivateKey = Args.Client.ClientEncryptor.GetDecryptionArgsContainer() // .AESDecryptArgs.PrivateKey; //IMPORTANT: Public key must derive from the private key! //byte[] ClientPublicKey = PrivateKey.PublicKey.ToByteArray(); byte[] NOnce = Args.Client.ClientEncryptor.GetDecryptionArgsContainer().AESDecryptArgs.NOnce; //InitialPacket.WriteInt32(((byte)PacketHeaders.UNENCRYPTED + // /*4 is for version*/ 4 + (ClientPublicKey.Length + 1) + (NOnce.Length + 1))); SaltedHash Hash = new SaltedHash(new SHA512Managed(), Args.Username.Length); byte[] HashBuf = Hash.ComputePasswordHash(Args.Username, Args.Password); PlayerAccount.Hash = HashBuf; string[] Version = GlobalSettings.Default.ClientVersion.Split('.'); InitialPacket.WriteByte((byte)int.Parse(Version[0])); //Version 1 InitialPacket.WriteByte((byte)int.Parse(Version[1])); //Version 2 InitialPacket.WriteByte((byte)int.Parse(Version[2])); //Version 3 InitialPacket.WriteByte((byte)int.Parse(Version[3])); //Version 4 //InitialPacket.WriteByte((byte)ClientPublicKey.Length); //InitialPacket.WriteBytes(ClientPublicKey); InitialPacket.WriteByte((byte)NOnce.Length); InitialPacket.WriteBytes(NOnce); Args.Client.Send(InitialPacket.ToArray()); }
protected virtual void ReceiveCallback(IAsyncResult AR) { try { Socket Sock = (Socket)AR.AsyncState; int NumBytesRead = Sock.EndReceive(AR); /** Cant do anything with this! **/ if (NumBytesRead == 0) { return; } byte[] TmpBuf = new byte[NumBytesRead]; Buffer.BlockCopy(m_RecvBuf, 0, TmpBuf, 0, NumBytesRead); //The packet is given an ID of 0x00 because its ID is currently unknown. PacketStream TempPacket = new PacketStream(0x00, (ushort)NumBytesRead, TmpBuf); byte ID = TempPacket.PeekByte(0); Logger.Log("Received packet: " + ID, LogLevel.info); ushort PacketLength = 0; var handler = FindPacketHandler(ID); if (handler != null) { PacketLength = handler.Length; Logger.Log("Found matching PacketID!\r\n\r\n", LogLevel.info); if (NumBytesRead == PacketLength) { Logger.Log("Got packet - exact length!\r\n\r\n", LogLevel.info); m_RecvBuf = new byte[11024]; OnPacket(new ProcessedPacket(ID, handler.Encrypted, handler.VariableLength, PacketLength, m_ClientEncryptor, TempPacket.ToArray()), handler); } else if (NumBytesRead < PacketLength) { m_TempPacket = new PacketStream(ID, PacketLength); byte[] TmpBuffer = new byte[NumBytesRead]; //Store the number of bytes that were read in the temporary buffer. Logger.Log("Got data, but not a full packet - stored " + NumBytesRead.ToString() + "bytes!\r\n\r\n", LogLevel.info); Buffer.BlockCopy(m_RecvBuf, 0, TmpBuffer, 0, NumBytesRead); m_TempPacket.WriteBytes(TmpBuffer); //And reset the buffers! m_RecvBuf = new byte[11024]; TmpBuffer = null; } else if (PacketLength == 0) { Logger.Log("Received variable length packet!\r\n", LogLevel.info); if (NumBytesRead > (int)PacketHeaders.UNENCRYPTED) //Header is 3 bytes. { PacketLength = TempPacket.PeekUShort(1); if (NumBytesRead == PacketLength) { Logger.Log("Received exact number of bytes for packet!\r\n", LogLevel.info); m_RecvBuf = new byte[11024]; m_TempPacket = null; OnPacket(new ProcessedPacket(ID, handler.Encrypted, handler.VariableLength, PacketLength, m_ClientEncryptor, TempPacket.ToArray()), handler); } else if (NumBytesRead < PacketLength) { Logger.Log("Didn't receive entire packet - stored: " + PacketLength + " bytes!\r\n", LogLevel.info); TempPacket.SetLength(PacketLength); m_TempPacket = TempPacket; m_RecvBuf = new byte[11024]; } else if (NumBytesRead > PacketLength) { Logger.Log("Received more bytes than needed for packet. Excess: " + (NumBytesRead - PacketLength) + "\r\n", LogLevel.info); byte[] TmpBuffer = new byte[NumBytesRead - PacketLength]; Buffer.BlockCopy(TempPacket.ToArray(), 0, TmpBuffer, 0, TmpBuffer.Length); m_TempPacket = new PacketStream(TmpBuffer[0], (ushort)(NumBytesRead - PacketLength), TmpBuffer); byte[] PacketBuffer = new byte[PacketLength]; Buffer.BlockCopy(TempPacket.ToArray(), 0, PacketBuffer, 0, PacketBuffer.Length); m_RecvBuf = new byte[11024]; OnPacket(new ProcessedPacket(ID, handler.Encrypted, handler.VariableLength, PacketLength, m_ClientEncryptor, PacketBuffer), handler); } } } } else { if (m_TempPacket != null) { if (m_TempPacket.Length < m_TempPacket.BufferLength) { //Received the exact number of bytes needed to complete the stored packet. if ((m_TempPacket.BufferLength + NumBytesRead) == m_TempPacket.Length) { byte[] TmpBuffer = new byte[NumBytesRead]; Buffer.BlockCopy(m_RecvBuf, 0, TmpBuffer, 0, NumBytesRead); m_RecvBuf = new byte[11024]; TmpBuffer = null; } //Received more than the number of bytes needed to complete the packet! else if ((m_TempPacket.BufferLength + NumBytesRead) > m_TempPacket.Length) { ushort Target = (ushort)((m_TempPacket.BufferLength + NumBytesRead) - m_TempPacket.Length); byte[] TmpBuffer = new byte[Target]; Buffer.BlockCopy(m_RecvBuf, 0, TmpBuffer, 0, Target); m_TempPacket.WriteBytes(TmpBuffer); //Now we have a full packet, so call the received event! OnPacket(new ProcessedPacket(m_TempPacket.PacketID, handler.Encrypted, handler.VariableLength, (ushort)m_TempPacket.Length, m_ClientEncryptor, m_TempPacket.ToArray()), handler); //Copy the remaining bytes in the receiving buffer. TmpBuffer = new byte[NumBytesRead - Target]; Buffer.BlockCopy(m_RecvBuf, Target, TmpBuffer, 0, (NumBytesRead - Target)); //Give the temporary packet an ID of 0x00 since we don't know its ID yet. TempPacket = new PacketStream(0x00, (ushort)(NumBytesRead - Target), TmpBuffer); ID = TempPacket.PeekByte(0); handler = FindPacketHandler(ID); //This SHOULD be an existing ID, but let's sanity-check it... if (handler != null) { m_TempPacket = new PacketStream(ID, handler.Length, TempPacket.ToArray()); //Congratulations, you just received another packet! if (m_TempPacket.Length == m_TempPacket.BufferLength) { OnPacket(new ProcessedPacket(m_TempPacket.PacketID, handler.Encrypted, handler.VariableLength, (ushort)m_TempPacket.Length, m_ClientEncryptor, m_TempPacket.ToArray()), handler); //No more data to store on this read, so reset everything... m_TempPacket = null; TmpBuffer = null; m_RecvBuf = new byte[11024]; } } else { //Houston, we have a problem (this should never occur)! this.Disconnect(); } } } } } m_Sock.BeginReceive(m_RecvBuf, 0, m_RecvBuf.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), m_Sock); } catch (SocketException) { Disconnect(); } }
public static void SendLoginRequestCity(LoginArgsContainer Args) { PacketStream Packet = new PacketStream((byte)PacketType.LOGIN_REQUEST_CITY, 0); Packet.WriteHeader(); //ECDiffieHellmanCng PrivateKey = Args.Client.ClientEncryptor.GetDecryptionArgsContainer() // .AESDecryptArgs.PrivateKey; //IMPORTANT: Public key must derive from the private key! //byte[] ClientPublicKey = PrivateKey.PublicKey.ToByteArray(); byte[] NOnce = Args.Client.ClientEncryptor.GetDecryptionArgsContainer().AESDecryptArgs.NOnce; //Packet.WriteInt32(((byte)PacketHeaders.UNENCRYPTED + // (ClientPublicKey.Length + 1) + (NOnce.Length + 1))); //Packet.WriteByte((byte)ClientPublicKey.Length); //Packet.WriteBytes(ClientPublicKey); Packet.WriteByte((byte)NOnce.Length); Packet.WriteBytes(NOnce); Args.Client.Send(Packet.ToArray()); }
private void SendToServer(VMNetCommandBodyAbstract cmd) { byte[] data; using (var stream = new MemoryStream()) { var cmd2 = new VMNetCommand(cmd); using (var writer = new BinaryWriter(stream)) { cmd2.SerializeInto(writer); } data = stream.ToArray(); } using (var stream = new PacketStream((byte)PacketType.VM_PACKET, 0)) { stream.WriteHeader(); stream.WriteInt32(data.Length + (int)PacketHeaders.UNENCRYPTED); stream.WriteBytes(data); Client.Send(stream.ToArray()); } }
public static void ReceivedEncryptedPacket(NetworkClient Client, PacketStream Packet) { Console.WriteLine("Received encrypted message: " + Packet.ReadPascalString()); }