/// <summary> /// Initial response from server to client. /// </summary> /// <param name="Client">A NetworkClient instance.</param> /// <param name="Packet">A ProcessedPacket instance.</param> public static void HandleServerChallenge(NetworkClient Client, ProcessedPacket Packet) { Console.WriteLine("Client receives encrypted data - test 2"); ServerPublicKey = Packet.ReadBytes(Packet.ReadByte()); byte[] EncryptedData = Packet.ReadBytes(Packet.ReadByte()); AESEncryptor Enc = (AESEncryptor)Client.ClientEncryptor; Enc.PublicKey = ServerPublicKey; Client.ClientEncryptor = Enc; NetworkFacade.Client.ClientEncryptor = Enc; ECDiffieHellmanCng PrivateKey = Client.ClientEncryptor.GetDecryptionArgsContainer().AESDecryptArgs.PrivateKey; byte[] NOnce = Client.ClientEncryptor.GetDecryptionArgsContainer().AESDecryptArgs.NOnce; byte[] ChallengeResponse = StaticStaticDiffieHellman.Decrypt(PrivateKey, ECDiffieHellmanCngPublicKey.FromByteArray(ServerPublicKey, CngKeyBlobFormat.EccPublicBlob), NOnce, EncryptedData); MemoryStream StreamToEncrypt = new MemoryStream(); BinaryWriter Writer = new BinaryWriter(StreamToEncrypt); Writer.Write((byte)ChallengeResponse.Length); Writer.Write(ChallengeResponse, 0, ChallengeResponse.Length); Writer.Write(Client.ClientEncryptor.Username); Writer.Write((byte)PasswordHash.Length); Writer.Write(PasswordHash); Writer.Flush(); Client.SendEncrypted(0x03, StreamToEncrypt.ToArray()); Console.WriteLine("Test 2: passed!"); }
public static void HandleLoginNotify(NetworkClient Client, ProcessedPacket Packet) { //Should this be stored for permanent access? byte[] ServerPublicKey = Packet.ReadBytes(Packet.ReadByte()); byte[] EncryptedData = Packet.ReadBytes(Packet.ReadByte()); AESEncryptor Enc = (AESEncryptor)Client.ClientEncryptor; Enc.PublicKey = ServerPublicKey; Client.ClientEncryptor = Enc; NetworkFacade.Client.ClientEncryptor = Enc; ECDiffieHellmanCng PrivateKey = Client.ClientEncryptor.GetDecryptionArgsContainer().AESDecryptArgs.PrivateKey; byte[] NOnce = Client.ClientEncryptor.GetDecryptionArgsContainer().AESDecryptArgs.NOnce; byte[] ChallengeResponse = StaticStaticDiffieHellman.Decrypt(PrivateKey, ECDiffieHellmanCngPublicKey.FromByteArray(ServerPublicKey, CngKeyBlobFormat.EccPublicBlob), NOnce, EncryptedData); MemoryStream StreamToEncrypt = new MemoryStream(); BinaryWriter Writer = new BinaryWriter(StreamToEncrypt); Writer.Write((byte)ChallengeResponse.Length); Writer.Write(ChallengeResponse, 0, ChallengeResponse.Length); Writer.Write(Client.ClientEncryptor.Username); Writer.Write((byte)PlayerAccount.Hash.Length); Writer.Write(PlayerAccount.Hash); Writer.Flush(); //Encrypt data using key and IV from server, hoping that it'll be decrypted correctly at the other end... Client.SendEncrypted((byte)PacketType.CHALLENGE_RESPONSE, StreamToEncrypt.ToArray()); }
public static void OnChallengeRecieved(NetworkClient Client, ProcessedPacket Packet) { byte[] CResponse = Packet.ReadBytes(Packet.ReadByte()); if (CResponse.SequenceEqual(ChallengeResponse)) Console.WriteLine("Received correct challenge response, client was authenticated!"); else Console.WriteLine("Received incorrect challenge response, client was NOT authenticated!"); string Username = Packet.ReadString(); Console.WriteLine("Username: " + Username); byte[] PasswordHash = Packet.ReadBytes(Packet.ReadByte()); Client.Disconnect(); }
public static void HandleChallengeResponse(NetworkClient Client, ProcessedPacket P) { PacketStream OutPacket; if (P.DecryptedSuccessfully) { int Length = P.ReadByte(); byte[] CResponse; if (P.BufferLength >= Length) CResponse = P.ReadBytes(Length); else { //Authentication failed, so send this packet unencrypted. OutPacket = new PacketStream((byte)PacketType.LOGIN_FAILURE_CITY, 0); OutPacket.WriteHeader(); OutPacket.WriteUInt16((ushort)(PacketHeaders.UNENCRYPTED + 1)); OutPacket.WriteByte(0x03); //Bad challenge response. Client.Send(OutPacket.ToArray()); Logger.LogInfo("Sent LOGIN_FAILURE_CITY!"); return; } AESDecryptionArgs DecryptionArgs = Client.ClientEncryptor.GetDecryptionArgsContainer().AESDecryptArgs; if (DecryptionArgs.Challenge.SequenceEqual(CResponse)) { OutPacket = new PacketStream((byte)PacketType.LOGIN_SUCCESS_CITY, 0); OutPacket.WriteByte(0x01); Client.SendEncrypted((byte)PacketType.LOGIN_SUCCESS_CITY, OutPacket.ToArray()); Logger.LogInfo("Sent LOGIN_SUCCESS_CITY!"); } else { //Authentication failed, so send this packet unencrypted. OutPacket = new PacketStream((byte)PacketType.LOGIN_FAILURE_CITY, 0); OutPacket.WriteHeader(); OutPacket.WriteUInt16((ushort)(PacketHeaders.UNENCRYPTED + 1)); OutPacket.WriteByte(0x03); //Bad challenge response. Client.Send(OutPacket.ToArray()); Logger.LogInfo("Sent LOGIN_FAILURE_CITY!"); } } else { //Authentication failed, so send this packet unencrypted. OutPacket = new PacketStream((byte)PacketType.LOGIN_FAILURE_CITY, 0); OutPacket.WriteHeader(); OutPacket.WriteUInt16((ushort)(PacketHeaders.UNENCRYPTED + 1)); OutPacket.WriteByte(0x03); //Bad challenge response. Client.Send(OutPacket.ToArray()); Debug.WriteLine("HandleChallengeResponse - decryption failed!"); Logger.LogInfo("Sent LOGIN_FAILURE_CITY!"); } }
public static void Handle(NetworkClient Client, ProcessedPacket stream) { byte ID = (byte)stream.ReadByte(); if (m_Handlers.ContainsKey(ID)) { m_Handlers[ID].Handler(Client, stream); } }
/// <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!"); }
/// <summary> /// Received CharacterCreation packet from CityServer. /// </summary> /// <returns>The result of the character creation.</returns> public static CharacterCreationStatus OnCharacterCreationStatus(NetworkClient Client, ProcessedPacket Packet) { LogThis.Log.LogThis("Received OnCharacterCreationStatus!", LogThis.eloglevel.info); CharacterCreationStatus CCStatus = (CharacterCreationStatus)Packet.ReadByte(); ushort NumHouses = Packet.ReadUInt16(); LotTileEntry[] TileEntries = new LotTileEntry[NumHouses]; if (NumHouses > 0) { for (int i = 0; i < NumHouses; i++) { TileEntries[i] = new LotTileEntry(Packet.ReadInt32(), Packet.ReadString(), (short)Packet.ReadUInt16(), (short)Packet.ReadUInt16(), (byte)Packet.ReadByte(), Packet.ReadInt32()); } } lock(GameFacade.CDataRetriever.LotTileData) GameFacade.CDataRetriever.LotTileData = TileEntries; return CCStatus; }
/// <summary> /// Received CharacterCreation packet from LoginServer. /// </summary> /// <returns>The result of the character creation.</returns> public static CharacterCreationStatus OnCharacterCreationProgress(NetworkClient Client, ProcessedPacket Packet) { CharacterCreationStatus CCStatus = (CharacterCreationStatus)Packet.ReadByte(); if (CCStatus == CharacterCreationStatus.Success) { Guid CharacterGUID = Guid.NewGuid(); CharacterGUID = new Guid(Packet.ReadString()); PlayerAccount.CityToken = Packet.ReadString(); PlayerAccount.CurrentlyActiveSim.AssignGUID(CharacterGUID.ToString()); //This previously happened when clicking the accept button in CAS, causing //all chars to be cached even if the new char wasn't successfully created. lock(NetworkFacade.Avatars) Cache.CacheSims(NetworkFacade.Avatars); } return CCStatus; }
public static void OnLotPurchaseFailed(NetworkClient Client, ProcessedPacket Packet) { EventObject Event; switch(Packet.ReadByte()) { case 0x00: Event = new EventObject(EventCodes.TRANSACTION_RESULT); EventSink.RegisterEvent(Event); break; } }
public static LotTileEntry OnLotCostResponse(NetworkClient Client, ProcessedPacket Packet) { ushort X = Packet.ReadUInt16(); ushort Y = Packet.ReadUInt16(); int LotID = Packet.ReadInt32(); string LotName = Packet.ReadString(); //bit 0 = online, bit 1 = spotlight, bit 2 = locked, bit 3 = occupied, other bits free for whatever use byte Flags = (byte)Packet.ReadByte(); int Cost = Packet.ReadInt32(); return new LotTileEntry(LotID, LotName, (short)X, (short)Y, Flags, Cost); }
/// <summary> /// Occurs when the client was not authenticated by the loginserver. /// Called by UILoginDialog.cs. /// </summary> /// <param name="Client">The client that received the packet.</param> /// <param name="Packet">The packet that was received.</param> public static void OnLoginFailResponse(ref NetworkClient Client, ProcessedPacket Packet) { EventObject Event; switch (Packet.ReadByte()) { case 0x01: Event = new EventObject(EventCodes.BAD_USERNAME); EventSink.RegisterEvent(Event); break; case 0x02: Event = new EventObject(EventCodes.BAD_PASSWORD); EventSink.RegisterEvent(Event); break; case 0x03: Event = new EventObject(EventCodes.AUTHENTICATION_FAILURE); EventSink.RegisterEvent(Event); break; } Client.Disconnect(); }
/// <summary> /// Received from the CityServer in response to a CITY_TOKEN packet. /// </summary> public static CityTransferStatus OnCityTokenResponse(NetworkClient Client, ProcessedPacket Packet) { LogThis.Log.LogThis("Received OnCityTokenResponse", LogThis.eloglevel.info); CityTransferStatus Status = (CityTransferStatus)Packet.ReadByte(); ushort NumHouses = Packet.ReadUInt16(); LotTileEntry[] TileEntries = new LotTileEntry[NumHouses]; if (NumHouses > 0) { for(int i = 0; i < NumHouses; i++) { TileEntries[i] = new LotTileEntry(Packet.ReadInt32(), Packet.ReadString(), (short)Packet.ReadUInt16(), (short)Packet.ReadUInt16(), (byte)Packet.ReadByte(), Packet.ReadInt32()); } } PlayerAccount.Money = Packet.ReadInt32(); lock(GameFacade.CDataRetriever.LotTileData) GameFacade.CDataRetriever.LotTileData = TileEntries; return Status; }
public static void OnCityInfoResponse(ProcessedPacket Packet) { byte NumCities = (byte)Packet.ReadByte(); if (Packet.DecryptedLength > 1) { lock (NetworkFacade.Cities) { for (int i = 0; i < NumCities; i++) { string Name = Packet.ReadString(); string Description = Packet.ReadString(); string IP = Packet.ReadString(); int Port = Packet.ReadInt32(); byte StatusByte = (byte)Packet.ReadByte(); CityInfoStatus Status = (CityInfoStatus)StatusByte; ulong Thumbnail = Packet.ReadUInt64(); string UUID = Packet.ReadString(); ulong Map = Packet.ReadUInt64(); CityInfo Info = new CityInfo(false); Info.Name = Name; Info.Description = Description; Info.Thumbnail = Thumbnail; Info.UUID = UUID; Info.Map = Map; Info.IP = IP; Info.Port = Port; Info.Online = true; Info.Status = Status; NetworkFacade.Cities.Add(Info); } } } }
public static void HandleCityToken(NetworkClient Client, ProcessedPacket P) { try { bool ClientAuthenticated = false; using (var db = DataAccess.Get()) { byte HashLength = (byte)P.ReadByte(); byte[] HashBuf = new byte[HashLength]; P.Read(HashBuf, 0, HashLength); byte KeyLength = (byte)P.ReadByte(); byte[] EncKey = new byte[KeyLength]; P.Read(EncKey, 0, KeyLength); Client.ClientEncryptor = new ARC4Encryptor(Convert.ToBase64String(HashBuf), EncKey); string Token = P.ReadString(); foreach (ClientToken Tok in NetworkFacade.TransferringClients.GetList()) { if (Tok.Token == Token) { ClientAuthenticated = true; PacketStream SuccessPacket = new PacketStream((byte)PacketType.CITY_TOKEN, 0); SuccessPacket.WriteByte((byte)CityTransferStatus.Success); Client.SendEncrypted((byte)PacketType.CITY_TOKEN, SuccessPacket.ToArray()); } } if (!ClientAuthenticated) { PacketStream ErrorPacket = new PacketStream((byte)PacketType.CITY_TOKEN, 0); ErrorPacket.WriteByte((byte)CityTransferStatus.GeneralError); Client.SendEncrypted((byte)PacketType.CITY_TOKEN, ErrorPacket.ToArray()); } } } catch (Exception E) { Logger.LogDebug("Exception in HandleCityToken: " + E.ToString()); } }
/// <summary> /// Received from the CityServer in response to a CITY_TOKEN packet. /// </summary> public static CityTransferStatus OnCityTokenResponse(NetworkClient Client, ProcessedPacket Packet) { Debug.WriteLine("Received OnCityTokenResponse"); CityTransferStatus Status = (CityTransferStatus)Packet.ReadByte(); return Status; }
public static void InitialClientConnect(NetworkClient Client, ProcessedPacket P) { Logger.LogInfo("Received InitialClientConnect!"); PacketStream EncryptedPacket = new PacketStream((byte)PacketType.LOGIN_NOTIFY_CITY, 0); EncryptedPacket.WriteHeader(); AESEncryptor Enc = (AESEncryptor)Client.ClientEncryptor; Enc.PublicKey = P.ReadBytes((P.ReadByte())); Enc.NOnce = P.ReadBytes((P.ReadByte())); Enc.PrivateKey = NetworkFacade.ServerPrivateKey; Client.ClientEncryptor = Enc; MemoryStream StreamToEncrypt = new MemoryStream(); BinaryWriter Writer = new BinaryWriter(StreamToEncrypt); Writer.Write(Enc.Challenge, 0, Enc.Challenge.Length); Writer.Flush(); byte[] EncryptedData = StaticStaticDiffieHellman.Encrypt(NetworkFacade.ServerPrivateKey, System.Security.Cryptography.ECDiffieHellmanCngPublicKey.FromByteArray(Enc.PublicKey, System.Security.Cryptography.CngKeyBlobFormat.EccPublicBlob), Enc.NOnce, StreamToEncrypt.ToArray()); EncryptedPacket.WriteUInt16((ushort)(PacketHeaders.UNENCRYPTED + (1 + NetworkFacade.ServerPublicKey.Length) + (1 + EncryptedData.Length))); EncryptedPacket.WriteByte((byte)NetworkFacade.ServerPublicKey.Length); EncryptedPacket.WriteBytes(NetworkFacade.ServerPublicKey); EncryptedPacket.WriteByte((byte)EncryptedData.Length); EncryptedPacket.WriteBytes(EncryptedData); Client.Send(EncryptedPacket.ToArray()); }
public static void HandleCharacterCreate(NetworkClient Client, ProcessedPacket P) { Logger.LogDebug("Received CharacterCreate!"); bool ClientAuthenticated = false; byte AccountStrLength = (byte)P.ReadByte(); byte[] AccountNameBuf = new byte[AccountStrLength]; P.Read(AccountNameBuf, 0, AccountStrLength); string AccountName = Encoding.ASCII.GetString(AccountNameBuf); using (var db = DataAccess.Get()) { var account = db.Accounts.GetByUsername(AccountName); byte KeyLength = (byte)P.ReadByte(); byte[] EncKey = new byte[KeyLength]; P.Read(EncKey, 0, KeyLength); Client.ClientEncryptor = new ARC4Encryptor(account.Password, EncKey); Client.ClientEncryptor.Username = AccountName; string Token = P.ReadString(); string GUID = ""; foreach (ClientToken CToken in NetworkFacade.TransferringClients.GetList()) { if (CToken.ClientIP == Client.RemoteIP) { if (CToken.Token == Token) { PacketStream SuccessPacket = new PacketStream(0x64, (int)(PacketHeaders.ENCRYPTED + 1)); SuccessPacket.WriteByte((byte)TSODataModel.Entities.CharacterCreationStatus.Success); Client.SendEncrypted(0x64, SuccessPacket.ToArray()); ClientAuthenticated = true; GUID = CToken.CharacterGUID; } break; } } SimBase Char = new SimBase(new Guid(GUID)); Char.Timestamp = P.ReadPascalString(); Char.Name = P.ReadPascalString(); Char.Sex = P.ReadPascalString(); Char.Description = P.ReadPascalString(); Char.HeadOutfitID = P.ReadUInt64(); Char.BodyOutfitID = P.ReadUInt64(); Char.Appearance = (AppearanceType)P.ReadByte(); Char.CityID = new Guid(P.ReadString()); Char.CreatedThisSession = true; var characterModel = new Character(); characterModel.Name = Char.Name; characterModel.Sex = Char.Sex; characterModel.Description = Char.Description; characterModel.LastCached = Char.Timestamp; characterModel.GUID = Char.GUID; characterModel.HeadOutfitID = (long)Char.HeadOutfitID; characterModel.BodyOutfitID = (long)Char.BodyOutfitID; characterModel.AccountID = account.AccountID; characterModel.AppearanceType = (int)Char.Appearance; characterModel.City = Char.CityID.ToString(); var status = db.Characters.CreateCharacter(characterModel); } //Invalid token, should never occur... if (!ClientAuthenticated) { PacketStream SuccessPacket = new PacketStream(0x65, (int)(PacketHeaders.ENCRYPTED + 1)); SuccessPacket.WriteByte((byte)TSODataModel.Entities.CharacterCreationStatus.GeneralError); Client.SendEncrypted(0x64, SuccessPacket.ToArray()); Client.Disconnect(); } }
/// <summary> /// Received initial packet from CityServer. /// </summary> public static void OnLoginNotifyCity(NetworkClient Client, ProcessedPacket Packet) { LogThis.Log.LogThis("Received OnLoginNotifyCity!", LogThis.eloglevel.info); //Should this be stored for permanent access? byte[] ServerPublicKey = Packet.ReadBytes(Packet.ReadByte()); byte[] EncryptedData = Packet.ReadBytes(Packet.ReadByte()); // lock (Client.ClientEncryptor) // { // AESEncryptor Enc = (AESEncryptor)Client.ClientEncryptor; // Enc.PublicKey = ServerPublicKey; // Client.ClientEncryptor = Enc; // lock (NetworkFacade.Client) // NetworkFacade.Client.ClientEncryptor = Enc; // } // ECDiffieHellmanCng PrivateKey = Client.ClientEncryptor.GetDecryptionArgsContainer().AESDecryptArgs.PrivateKey; // byte[] NOnce = Client.ClientEncryptor.GetDecryptionArgsContainer().AESDecryptArgs.NOnce; // byte[] ChallengeResponse = StaticStaticDiffieHellman.Decrypt(PrivateKey, // ECDiffieHellmanCngPublicKey.FromByteArray(ServerPublicKey, CngKeyBlobFormat.EccPublicBlob), // NOnce, EncryptedData); MemoryStream StreamToEncrypt = new MemoryStream(); BinaryWriter Writer = new BinaryWriter(StreamToEncrypt); // Writer.Write((byte)ChallengeResponse.Length); // Writer.Write(ChallengeResponse, 0, ChallengeResponse.Length); Writer.Flush(); //Encrypt data using key and IV from server, hoping that it'll be decrypted correctly at the other end... Client.SendEncrypted((byte)PacketType.CHALLENGE_RESPONSE, StreamToEncrypt.ToArray()); }
public static void HandleChallengeResponse(NetworkClient Client, ProcessedPacket Packet) { Console.WriteLine("Server receives challenge response - test 3"); byte[] CResponse = Packet.ReadBytes(Packet.ReadByte()); if (CResponse.SequenceEqual(ChallengeResponse)) Console.WriteLine("Received correct challenge response, client was authenticated!"); string Username = Packet.ReadString(); Console.WriteLine("Username: "******"Test 3: passed!"); }
/// <summary> /// New city server came online! /// </summary> public static void OnNewCityServer(NetworkClient Client, ProcessedPacket Packet) { lock (NetworkFacade.Cities) { CityInfo Info = new CityInfo(false); Info.Name = Packet.ReadString(); Info.Description = Packet.ReadString(); Info.IP = Packet.ReadString(); Info.Port = Packet.ReadInt32(); Info.Status = (CityInfoStatus)Packet.ReadByte(); Info.Thumbnail = Packet.ReadUInt64(); Info.UUID = Packet.ReadString(); Info.Map = Packet.ReadUInt64(); NetworkFacade.Cities.Add(Info); } }
/// <summary> /// A player joined a session (game) in progress. /// </summary> public static LotTileEntry OnPlayerJoinedSession(NetworkClient Client, ProcessedPacket Packet) { LotTileEntry TileEntry = new LotTileEntry(0, "", 0, 0, 0, 0); UISim Avatar = new UISim(Packet.ReadString()); Avatar.Name = Packet.ReadString(); Avatar.Sex = Packet.ReadString(); Avatar.Description = Packet.ReadString(); Avatar.HeadOutfitID = Packet.ReadUInt64(); Avatar.BodyOutfitID = Packet.ReadUInt64(); Avatar.Avatar.Appearance = (AppearanceType)Packet.ReadInt32(); byte HasHouse = (byte)Packet.ReadByte(); if (HasHouse != 0) { TileEntry = new LotTileEntry(Packet.ReadInt32(), Packet.ReadString(), (short)Packet.ReadUInt16(), (short)Packet.ReadUInt16(), (byte)Packet.ReadByte(), Packet.ReadInt32()); Avatar.LotID = TileEntry.lotid; Avatar.HouseX = TileEntry.x; Avatar.HouseY = TileEntry.y; LotTileEntry[] TileEntries = new LotTileEntry[GameFacade.CDataRetriever.LotTileData.Length + 1]; TileEntries[0] = TileEntry; GameFacade.CDataRetriever.LotTileData.CopyTo(TileEntries, 1); } lock (NetworkFacade.AvatarsInSession) { NetworkFacade.AvatarsInSession.Add(Avatar); } return TileEntry; }
/// <summary> /// A client wanted to transfer to this server, so a token was generated by the login server. /// </summary> public static void HandleClientToken(NetworkClient Client, ProcessedPacket P) { try { ClientToken Token = new ClientToken(); byte CharacterCreate = (byte)P.ReadByte(); Token.AccountID = P.ReadInt32(); Token.ClientIP = P.ReadString(); int ClientPort = P.ReadInt32(); Token.CharacterGUID = P.ReadString(); Token.Token = P.ReadString(); PacketStream PlayerOnlinePacket = new PacketStream(0x67, 0); PlayerOnlinePacket.WriteHeader(); PlayerOnlinePacket.WriteUInt16((ushort)(PacketHeaders.UNENCRYPTED + 1 + Token.Token.Length + 1 + Token.ClientIP.Length + 1 + 4)); if (CharacterCreate == 0) { if (NetworkFacade.CurrentSession.GetPlayer(Token.CharacterGUID) == null) { NetworkClient WaitingClient = NetworkFacade.NetworkListener.GetClient(Token.ClientIP, ClientPort); //Uh-oh, someone's waiting for their token! if(WaitingClient != null) { PacketStream SuccessPacket = new PacketStream((byte)PacketType.CITY_TOKEN, 0); SuccessPacket.WriteByte((byte)CityTransferStatus.Success); WaitingClient.SendEncrypted((byte)PacketType.CITY_TOKEN, SuccessPacket.ToArray()); } PlayerOnlinePacket.WriteByte(0x01); PlayerOnlinePacket.WriteString(Token.Token); PlayerOnlinePacket.WriteString(Token.ClientIP); PlayerOnlinePacket.WriteInt32(ClientPort); lock (NetworkFacade.TransferringClients) { if (!NetworkFacade.TransferringClients.Contains(Token)) NetworkFacade.TransferringClients.Add(Token); } Client.Send(PlayerOnlinePacket.ToArray()); } else { PlayerOnlinePacket.WriteByte(0x02); PlayerOnlinePacket.WriteString(Token.Token); PlayerOnlinePacket.WriteString(Token.ClientIP); PlayerOnlinePacket.WriteInt32(ClientPort); Client.Send(PlayerOnlinePacket.ToArray()); } } else { NetworkClient WaitingClient = NetworkFacade.NetworkListener.GetClient(Token.ClientIP, ClientPort); //Uh-oh, someone's waiting for their token! if (WaitingClient != null) { PacketStream SuccessPacket = new PacketStream((byte)PacketType.CITY_TOKEN, 0); SuccessPacket.WriteByte((byte)CityTransferStatus.Success); WaitingClient.SendEncrypted((byte)PacketType.CITY_TOKEN, SuccessPacket.ToArray()); } if (!NetworkFacade.TransferringClients.Contains(Token)) NetworkFacade.TransferringClients.Add(Token); } } catch (Exception E) { Logger.LogDebug("Exception in HandleClientToken: " + E.ToString()); } }
/// <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()); }
/// <summary> /// Client wanted to create a new character. /// </summary> public static void HandleCharacterCreate(NetworkClient Client, ProcessedPacket P) { try { Logger.LogInfo("Received CharacterCreate!"); bool ClientAuthenticated = false; byte AccountStrLength = (byte)P.ReadByte(); byte[] AccountNameBuf = new byte[AccountStrLength]; if (P.BufferLength >= AccountStrLength) { P.Read(AccountNameBuf, 0, AccountStrLength); string AccountName = Encoding.ASCII.GetString(AccountNameBuf); } else return; using (DataAccess db = DataAccess.Get()) { //No need to check for empty string here, because all it will do is have ClientAuthenticated be false string Token = P.ReadString(); string GUID = ""; int AccountID = 0; ClientToken TokenToRemove = NetworkFacade.GetClientToken(Client.RemoteIP); //Just in case... if (TokenToRemove != null) { if (TokenToRemove.Token.Equals(Token, StringComparison.CurrentCultureIgnoreCase)) { PacketStream SuccessPacket = new PacketStream((byte)PacketType.CHARACTER_CREATE_CITY, 0); SuccessPacket.WriteByte((byte)CityDataModel.Entities.CharacterCreationStatus.Success); House[] Houses = NetworkFacade.CurrentSession.GetHousesInSession(); SuccessPacket.WriteUInt16((ushort)Houses.Length); //Ho, ho, ho... foreach (House Ho in Houses) { SuccessPacket.WriteInt32(Ho.HouseID); SuccessPacket.WriteString(Ho.Name); SuccessPacket.WriteUInt16((ushort)Ho.X); SuccessPacket.WriteUInt16((ushort)Ho.Y); SuccessPacket.WriteByte((byte)Ho.Flags); //Might have to save this as unsigned in DB? SuccessPacket.WriteInt32(Ho.Cost); } Client.SendEncrypted((byte)PacketType.CHARACTER_CREATE_CITY, SuccessPacket.ToArray()); ClientAuthenticated = true; GUID = TokenToRemove.CharacterGUID; AccountID = TokenToRemove.AccountID; Sim Char = new Sim(new Guid(GUID)); Char.Timestamp = P.ReadString(); Char.Name = P.ReadString(); Char.Sex = P.ReadString(); Char.Description = P.ReadString(); Char.HeadOutfitID = P.ReadUInt64(); Char.BodyOutfitID = P.ReadUInt64(); Char.Appearance = (AppearanceType)P.ReadByte(); Char.CreatedThisSession = true; //These are going into DB, so be nazi. Sieg heil! if (Char.Timestamp == string.Empty || Char.Name == string.Empty || Char.Sex == string.Empty || Char.Description == string.Empty) { //TODO: Tell loginserver to clean up DB? ClientAuthenticated = false; } var characterModel = new Character(); characterModel.Name = Char.Name; characterModel.Sex = Char.Sex; characterModel.Description = Char.Description; characterModel.LastCached = ProtoHelpers.ParseDateTime(Char.Timestamp); characterModel.GUID = Char.GUID; characterModel.HeadOutfitID = (long)Char.HeadOutfitID; characterModel.BodyOutfitID = (long)Char.BodyOutfitID; characterModel.AccountID = AccountID; characterModel.AppearanceType = (int)Char.Appearance; characterModel.Money = NetworkFacade.INITIAL_MONEY; NetworkFacade.CurrentSession.AddPlayer(Client, characterModel); var status = db.Characters.CreateCharacter(characterModel); } } NetworkFacade.TransferringClients.TryRemove(out TokenToRemove); } //Invalid token, should never occur... if (!ClientAuthenticated) { NetworkFacade.CurrentSession.RemovePlayer(Client); PacketStream FailPacket = new PacketStream((byte)PacketType.CHARACTER_CREATE_CITY_FAILED, (int)(PacketHeaders.ENCRYPTED + 1)); FailPacket.WriteByte((byte)CityDataModel.Entities.CharacterCreationStatus.GeneralError); Client.SendEncrypted((byte)PacketType.CHARACTER_CREATE_CITY_FAILED, FailPacket.ToArray()); } } catch (Exception E) { Debug.WriteLine("Exception in HandleCharacterCreate: " + E.ToString()); Logger.LogDebug("Exception in HandleCharacterCreate: " + E.ToString()); PacketStream FailPacket = new PacketStream((byte)PacketType.CHARACTER_CREATE_CITY_FAILED, (int)(PacketHeaders.ENCRYPTED + 1)); FailPacket.WriteByte((byte)CityDataModel.Entities.CharacterCreationStatus.GeneralError); Client.SendEncrypted((byte)PacketType.CHARACTER_CREATE_CITY_FAILED, FailPacket.ToArray()); } }