Пример #1
0
        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);
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Occurs when the client has been sucessfully 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 OnLoginNotify(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;
            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.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());
        }
Пример #3
0
        /// <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!");
        }
Пример #4
0
        /// <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 HandlePlayerOnlineResponse(NetworkClient Client, ProcessedPacket P)
        {
            byte Result = (byte)P.ReadByte();
            string Token = P.ReadString();
            //NOTE: Might have to find another way to identify a client, since two people
            //		can be on the same account from the same IP.
            string RemoteIP = P.ReadString();
            int RemotePort = P.ReadInt32();

            PacketStream Packet;
            NetworkClient FoundClient;

            switch(Result)
            {
                case 0x01:
                    Packet = new PacketStream((byte)PacketType.REQUEST_CITY_TOKEN, 0);
                    Packet.WriteString(Token);
                    FoundClient = NetworkFacade.ClientListener.GetClient(RemoteIP, RemotePort);

                    if(FoundClient != null)
                        FoundClient.SendEncrypted((byte)PacketType.REQUEST_CITY_TOKEN, Packet.ToArray());

                    break;
                case 0x02: //Write player was already online packet!
                    Packet = new PacketStream((byte)PacketType.PLAYER_ALREADY_ONLINE, 0);
                    Packet.WriteByte(0x00); //Dummy
                    FoundClient = NetworkFacade.ClientListener.GetClient(RemoteIP, RemotePort);

                    if (FoundClient != null)
                        FoundClient.SendEncrypted((byte)PacketType.PLAYER_ALREADY_ONLINE, Packet.ToArray());

                    break;
            }
        }
        public static void OnCharacterCreationStatus(NetworkClient Client, ProcessedPacket Packet)
        {
            CharacterCreationStatus CCStatus = (CharacterCreationStatus)Packet.ReadByte();

            switch (CCStatus)
            {
                case CharacterCreationStatus.Success:
                    Guid CharacterGUID = new Guid();

                    //CityToken didn't exist, so transition to CityServer hasn't happened yet.
                    if (PlayerAccount.CityToken == "")
                    {
                        CharacterGUID = new Guid(Packet.ReadPascalString());
                        PlayerAccount.CityToken = Packet.ReadPascalString();
                    }

                    NetworkFacade.Controller._OnCharacterCreationStatus(CCStatus);

                    if(PlayerAccount.CityToken == "")
                        PlayerAccount.CurrentlyActiveSim.AssignGUID(CharacterGUID.ToString());

                    break;
                case CharacterCreationStatus.ExceededCharacterLimit:
                    NetworkFacade.Controller._OnCharacterCreationStatus(CCStatus);
                    break;
                case CharacterCreationStatus.NameAlreadyExisted:
                    NetworkFacade.Controller._OnCharacterCreationStatus(CCStatus);
                    break;
                case CharacterCreationStatus.GeneralError:
                    NetworkFacade.Controller._OnCharacterCreationStatus(CCStatus);
                    break;
                default:
                    break;
            }
        }
Пример #7
0
        /// <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);
        }
Пример #8
0
        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!");
        }
Пример #9
0
        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());
            }
        }
Пример #10
0
        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));
        }
Пример #11
0
        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;
            }
        }
Пример #12
0
        /// <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!");
        }
Пример #13
0
        /// <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);
        }
        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());
        }
Пример #15
0
        /// <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 = new Guid();

                CharacterGUID = new Guid(Packet.ReadPascalString());
                PlayerAccount.CityToken = Packet.ReadPascalString();
                PlayerAccount.CurrentlyActiveSim.AssignGUID(CharacterGUID.ToString());
            }

            return CCStatus;
        }
Пример #16
0
 /// <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 cityserver logged in!
        /// </summary>
        public static void HandleCityServerLogin(NetworkClient Client, ProcessedPacket P)
        {
            Logger.LogInfo("CityServer logged in!\r\n");

            string Name = P.ReadString();
            string Description = P.ReadString();
            string IP = P.ReadString();
            int Port = P.ReadInt32();
            CityInfoStatus Status = (CityInfoStatus)P.ReadByte();
            ulong Thumbnail = P.ReadUInt64();
            string UUID = P.ReadString();
            ulong Map = P.ReadUInt64();

            CityInfo Info = new CityInfo(true);
            Info.Name = Name;
            Info.Description = Description;
            Info.IP = IP;
            Info.Port = Port;
            Info.Status = Status;
            Info.Thumbnail = Thumbnail;
            Info.UUID = UUID;
            Info.Map = Map;
            Info.Client = Client;
            Info.Online = true;

            NetworkFacade.CServerListener.CityServers.Add(Info);
            NetworkFacade.CServerListener.PotentialLogins.TryTake(out Client);

            NetworkClient[] Clients = new NetworkClient[NetworkFacade.ClientListener.Clients.Count];
            NetworkFacade.ClientListener.Clients.CopyTo(Clients, 0);

            PacketStream ClientPacket = new PacketStream((byte)PacketType.NEW_CITY_SERVER, 0);
            ClientPacket.WriteString(Name);
            ClientPacket.WriteString(Description);
            ClientPacket.WriteString(IP);
            ClientPacket.WriteInt32(Port);
            ClientPacket.WriteByte((byte)Status);
            ClientPacket.WriteUInt64(Thumbnail);
            ClientPacket.WriteString(UUID);
            ClientPacket.WriteUInt64(Map);

            foreach(NetworkClient Receiver in Clients)
                Receiver.SendEncrypted((byte)PacketType.NEW_CITY_SERVER, ClientPacket.ToArray());
        }
Пример #18
0
        /// <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");

            byte[] PacketBuf = new byte[Packet.ReadByte()];
            Packet.Read(PacketBuf, 0, (int)PacketBuf.Length);

            ECDiffieHellmanPublicKey ServerPub = StaticStaticDiffieHellman.ImportKey("ServerPublic.dat");

            MemoryStream DecryptedStream = new MemoryStream(StaticStaticDiffieHellman.Decrypt(ClientKey, ServerPub,
                                                                                              ClientNOnce.ToByteArray(), PacketBuf));
            BinaryReader Reader = new BinaryReader(DecryptedStream);

            Guid ChallengeResponse = new Guid(Reader.ReadBytes(Reader.ReadByte()));

            SessionKey = Reader.ReadBytes(Reader.ReadByte());
            IV         = Reader.ReadBytes(Reader.ReadByte());

            //Yay, we have key and IV, we can now start encryption with AES!
            AES AesEncryptor = new AES(SessionKey, IV);

            PacketStream EncryptedPacket = new PacketStream(0x03, 0);

            EncryptedPacket.WriteHeader();

            MemoryStream StreamToEncrypt = new MemoryStream();
            BinaryWriter Writer          = new BinaryWriter(StreamToEncrypt);

            Writer.Write((byte)ChallengeResponse.ToByteArray().Length);
            Writer.Write(ChallengeResponse.ToByteArray(), 0, ChallengeResponse.ToByteArray().Length);

            //Encrypt data using key and IV from server, hoping that it'll be decrypted correctly at the other end...
            byte[] EncryptedData = AesEncryptor.Encrypt(StreamToEncrypt.ToArray());

            EncryptedPacket.WriteUInt16((ushort)(PacketHeaders.UNENCRYPTED + EncryptedData.Length + 1));
            EncryptedPacket.WriteByte((byte)EncryptedData.Length);
            EncryptedPacket.Write(EncryptedData, 0, EncryptedData.Length);

            Client.Send(EncryptedPacket.ToArray());

            Console.WriteLine("Test 2: passed!");
        }
        /// <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;
        }
Пример #20
0
        /// <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);
        }
Пример #21
0
        public static void HandleChallengeResponse(NetworkClient Client, ProcessedPacket Packet)
        {
            Console.WriteLine("Server receives challenge response - test 3");

            byte[] PacketBuf = new byte[Packet.ReadByte()];
            Packet.Read(PacketBuf, 0, (int)PacketBuf.Length);

            AES          AesEncryptor    = new AES(SessionKey, IV);
            MemoryStream DecryptedStream = new MemoryStream(AesEncryptor.Decrypt(PacketBuf));
            BinaryReader Reader          = new BinaryReader(DecryptedStream);

            byte[] CResponseBuf = Reader.ReadBytes(Reader.ReadByte());
            Guid   CResponse    = new Guid(CResponseBuf);

            if (CResponse.CompareTo(ChallengeResponse) == 0)
            {
                Console.WriteLine("Received correct challenge response, client was authenticated!");
            }

            Console.WriteLine("Test 3: passed!");
        }
        /// <summary>
        /// A cityserver logged in!
        /// </summary>
        public static void HandleCityServerLogin(NetworkClient Client, ProcessedPacket P)
        {
            CityServerClient CityClient = (CityServerClient)Client;

            Logger.LogInfo("CityServer logged in!\r\n");

            string Name = P.ReadString();
            string Description = P.ReadString();
            string IP = P.ReadString();
            int Port = P.ReadInt32();
            CityInfoStatus Status = (CityInfoStatus)P.ReadByte();
            ulong Thumbnail = P.ReadUInt64();
            string UUID = P.ReadString();
            ulong Map = P.ReadUInt64();

            CityInfo Info = new CityInfo(Name, Description, Thumbnail, UUID, Map, IP, Port);
            Info.Status = Status;
            CityClient.ServerInfo = Info;

            //Client instance changed, so update it...
            NetworkFacade.CServerListener.UpdateClient(CityClient);
        }
        /// <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(TSOClient.Code.GameFacade.CDataRetriever.LotTileData)
                TSOClient.Code.GameFacade.CDataRetriever.LotTileData = TileEntries;

            return CCStatus;
        }
Пример #24
0
        /// <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);
        }
Пример #25
0
        /// <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();
        }
        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);
        }
Пример #27
0
        /// <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>
 /// 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);
     }
 }
        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 void OnCityTokenResponse(NetworkClient Client, ProcessedPacket Packet)
        {
            CityTransferStatus Status = (CityTransferStatus)Packet.ReadByte();

            switch (Status)
            {
                case CityTransferStatus.Success:
                    NetworkFacade.Controller._OnCityTokenResponse(Status);
                    break;
                case CityTransferStatus.GeneralError:
                    NetworkFacade.Controller._OnCityTokenResponse(Status);
                    break;
            }
        }
        public static void HandleCharacterCreate(NetworkClient Client, ProcessedPacket P)
        {
            Logger.LogInfo("Received CharacterCreate!");

            string AccountName = SanitizeAccount(P.ReadPascalString());

            using (var db = DataAccess.Get())
            {
                Account Acc = db.Accounts.GetByUsername(AccountName);

                //TODO: Send GUID to client...
                SimBase Char = new SimBase(Guid.NewGuid());
                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.ResidingCity = new CityInfo(P.ReadPascalString(), "", P.ReadUInt64(), P.ReadPascalString(),
                    P.ReadUInt64(), P.ReadPascalString(), P.ReadInt32());
                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 = Acc.AccountID;
                characterModel.AppearanceType = (int)Char.Appearance;
                characterModel.City = Char.ResidingCity.UUID;
                characterModel.CityName = Char.ResidingCity.Name;
                characterModel.CityThumb = (long)Char.ResidingCity.Thumbnail;
                characterModel.CityMap = (long)Char.ResidingCity.Map;
                characterModel.CityIp = Char.ResidingCity.IP;
                characterModel.CityPort = Char.ResidingCity.Port;

                var status = db.Characters.CreateCharacter(characterModel);
                //Need to be variable length, because the success packet contains a token.
                PacketStream CCStatusPacket = new PacketStream((byte)PacketType.CHARACTER_CREATION_STATUS, 0);

                switch (status)
                {
                    case LoginDataModel.Entities.CharacterCreationStatus.NameAlreadyExisted:
                        CCStatusPacket.WriteByte((int)LoginDataModel.Entities.CharacterCreationStatus.NameAlreadyExisted);
                        Client.SendEncrypted(CCStatusPacket.PacketID, CCStatusPacket.ToArray());
                        break;
                    case LoginDataModel.Entities.CharacterCreationStatus.ExceededCharacterLimit:
                        CCStatusPacket.WriteByte((int)LoginDataModel.Entities.CharacterCreationStatus.ExceededCharacterLimit);
                        Client.SendEncrypted(CCStatusPacket.PacketID, CCStatusPacket.ToArray());
                        break;
                    case LoginDataModel.Entities.CharacterCreationStatus.Success:
                        CCStatusPacket.WriteByte((int)LoginDataModel.Entities.CharacterCreationStatus.Success);
                        CCStatusPacket.WritePascalString(Char.GUID.ToString());
                        Guid Token = Guid.NewGuid();
                        CCStatusPacket.WritePascalString(Token.ToString());
                        Client.SendEncrypted(CCStatusPacket.PacketID, CCStatusPacket.ToArray());

                        foreach (CityServerClient CServer in NetworkFacade.CServerListener.CityServers)
                        {
                            if (CServer.ServerInfo.UUID == Char.ResidingCity.UUID)
                            {
                                PacketStream CServerPacket = new PacketStream(0x01, 0);
                                CServerPacket.WriteHeader();

                                ushort PacketLength = (ushort)(PacketHeaders.UNENCRYPTED + 4 + (Client.RemoteIP.Length + 1)
                                    + (Char.GUID.ToString().Length + 1) + (Token.ToString().Length + 1));
                                CServerPacket.WriteUInt16(PacketLength);

                                CServerPacket.WriteInt32(Acc.AccountID);
                                CServerPacket.WritePascalString(Client.RemoteIP);
                                CServerPacket.WritePascalString(Char.GUID.ToString());
                                CServerPacket.WritePascalString(Token.ToString());
                                CServer.Send(CServerPacket.ToArray());

                                break;
                            }
                        }

                        break;
                }
            }

            //Client was modified, so update it.
            NetworkFacade.ClientListener.UpdateClient(Client);
        }
        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);
                    }
                }
            }
        }
Пример #33
0
        /// <summary>
        /// Received CharacterCreation packet from CityServer.
        /// </summary>
        /// <returns>The result of the character creation.</returns>
        public static CharacterCreationStatus OnCharacterCreationStatus(NetworkClient Client, ProcessedPacket Packet)
        {
            CharacterCreationStatus CCStatus = (CharacterCreationStatus)Packet.ReadByte();

            return CCStatus;
        }
        public static void OnCityInfoResponse(ProcessedPacket Packet)
        {
            byte NumCities = (byte)Packet.ReadByte();

            if (Packet.DecryptedLength > 1)
            {
                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(Name, Description, Thumbnail, UUID, Map, IP, Port);
                    Info.Online = true;
                    Info.Status = Status;
                    NetworkFacade.Cities.Add(Info);
                }
            }
        }
        /// <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());
        }
        /// <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());
            }
        }
        /// <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)
        {
            //If the decrypted length == 1, it means that there were 0
            //characters that needed to be updated, or that the user
            //hasn't created any characters on his/her account yet.
            //Since the Packet.Length property is equal to the length
            //of the encrypted data, it cannot be used to get the length
            //of the decrypted data.
            if (Packet.DecryptedLength > 1)
            {
                byte NumCharacters = (byte)Packet.ReadByte();
                List<Sim> FreshSims = new List<Sim>();

                for (int i = 0; i < NumCharacters; i++)
                {
                    int CharacterID = Packet.ReadInt32();

                    Sim FreshSim = new Sim(Packet.ReadString());
                    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.AppearanceType = (SimsLib.ThreeD.AppearanceType)Packet.ReadByte();
                    FreshSim.ResidingCity = new CityInfo(Packet.ReadString(), "", Packet.ReadUInt64(), Packet.ReadString(),
                        Packet.ReadUInt64(), Packet.ReadString(), Packet.ReadInt32());

                    FreshSims.Add(FreshSim);
                }

                NetworkFacade.Avatars = FreshSims;
                Cache.CacheSims(FreshSims);
            }

            PacketStream CityInfoRequest = new PacketStream(0x06, 0);
            CityInfoRequest.WriteByte(0x00); //Dummy

            Client.SendEncrypted((byte)PacketType.CITY_LIST, CityInfoRequest.ToArray());
        }
        /**
        * Actual packet handlers
        */
        public static void HandleLoginRequest(NetworkClient Client, ProcessedPacket P)
        {
            Logger.LogInfo("Received LoginRequest!\r\n");

            byte AccountStrLength = (byte)P.ReadByte();
            byte[] AccountNameBuf = new byte[AccountStrLength];
            P.Read(AccountNameBuf, 0, AccountStrLength);
            string AccountName = SanitizeAccount(Encoding.ASCII.GetString(AccountNameBuf));
            Logger.LogInfo("Accountname: " + AccountName + "\r\n");

            byte HashLength = (byte)P.ReadByte();
            byte[] HashBuf = new byte[HashLength];
            P.Read(HashBuf, 0, HashLength);

            if (AccountName == "")
            {
                PacketStream OutPacket = new PacketStream((byte)PacketType.LOGIN_FAILURE, 2);
                OutPacket.WriteHeader();
                OutPacket.WriteByte(0x01);
                Client.Send(OutPacket.ToArray());

                Logger.LogInfo("Bad accountname - sent SLoginFailResponse!\r\n");
                Client.Disconnect();
                return;
            }

            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);

                //TODO: Do something with this...
                byte Version1 = (byte)P.ReadByte();
                byte Version2 = (byte)P.ReadByte();
                byte Version3 = (byte)P.ReadByte();
                byte Version4 = (byte)P.ReadByte();

                string ClientVersion = Version1.ToString() + "." + Version2.ToString() + "." + Version3.ToString() +
                    "." + Version4.ToString();

                if (ClientVersion != GlobalSettings.Default.ClientVersion)
                {
                    PacketStream OutPacket = new PacketStream((byte)PacketType.INVALID_VERSION, 2);
                    OutPacket.WriteHeader();
                    OutPacket.WriteByte(0x01);
                    Client.Send(OutPacket.ToArray());

                    Logger.LogInfo("Bad version - sent SInvalidVersion!\r\n");
                    Client.Disconnect();
                    return;
                }

                if (!GlobalSettings.Default.CreateAccountsOnLogin)
                {
                    Logger.LogInfo("Done reading LoginRequest, checking account...\r\n");

                    if (account == null)
                    {
                        PacketStream OutPacket = new PacketStream((byte)PacketType.LOGIN_FAILURE, 2);
                        OutPacket.WriteHeader();
                        OutPacket.WriteByte(0x01);
                        Client.Send(OutPacket.ToArray());

                        Logger.LogInfo("Bad accountname - sent SLoginFailResponse!\r\n");
                        Client.Disconnect();
                        return;
                    }
                    else
                        Client.ClientEncryptor = new ARC4Encryptor(account.Password, EncKey);
                }
                else
                {
                    if (account == null)
                    {
                        try
                        {
                            db.Accounts.Create(new Account
                            {
                                AccountName = AccountName.ToLower(),
                                Password = Convert.ToBase64String(HashBuf)
                            });
                        }
                        catch (Exception)
                        {
                            PacketStream OutPacket = new PacketStream((byte)PacketType.LOGIN_FAILURE, 2);
                            OutPacket.WriteHeader();
                            OutPacket.WriteByte(0x01);
                            Client.Send(OutPacket.ToArray());

                            Logger.LogInfo("Bad accountname - sent SLoginFailResponse!\r\n");
                            Client.Disconnect();
                            return;
                        }

                        account = db.Accounts.GetByUsername(AccountName);
                    }

                    Client.ClientEncryptor = new ARC4Encryptor(account.Password, EncKey);
                }

                if (account.IsCorrectPassword(AccountName, HashBuf))
                {
                    //0x01 = InitLoginNotify
                    PacketStream OutPacket = new PacketStream((byte)PacketType.LOGIN_NOTIFY, 1);
                    OutPacket.WriteHeader();
                    OutPacket.WriteByte(0x01);
                    Client.ClientEncryptor.Username = AccountName;
                    Client.Send(OutPacket.ToArray());

                    Logger.LogInfo("Sent InitLoginNotify!\r\n");
                }
                else
                {
                    PacketStream OutPacket = new PacketStream((byte)PacketType.LOGIN_FAILURE, 2);
                    OutPacket.WriteHeader();
                    OutPacket.WriteByte(0x02);
                    Client.Send(OutPacket.ToArray());

                    Logger.LogInfo("Bad password - sent SLoginFailResponse!\r\n");
                    Client.Disconnect();
                    return;
                }
            }

            //Client was modified, update it.
            NetworkFacade.ClientListener.UpdateClient(Client);
        }
Пример #40
0
        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];
                P.Read(AccountNameBuf, 0, AccountStrLength);
                string AccountName = Encoding.ASCII.GetString(AccountNameBuf);

                byte   HashLength = (byte)P.ReadByte();
                byte[] HashBuf    = new byte[HashLength];
                P.Read(HashBuf, 0, HashLength);

                using (DataAccess db = DataAccess.Get())
                {
                    Client.ClientEncryptor          = new ARC4Encryptor(Convert.ToBase64String(HashBuf));
                    Client.ClientEncryptor.Username = AccountName;

                    string Token     = P.ReadString();
                    string GUID      = "";
                    int    AccountID = 0;

                    foreach (ClientToken CToken in NetworkFacade.TransferringClients.GetList())
                    {
                        if (CToken.ClientIP == Client.RemoteIP)
                        {
                            if (CToken.Token == Token)
                            {
                                PacketStream SuccessPacket = new PacketStream((byte)PacketType.CHARACTER_CREATE_CITY, (int)(PacketHeaders.ENCRYPTED + 1));
                                SuccessPacket.WriteByte((byte)CityDataModel.Entities.CharacterCreationStatus.Success);
                                Client.SendEncrypted((byte)PacketType.CHARACTER_CREATE_CITY, SuccessPacket.ToArray());
                                ClientAuthenticated = true;

                                GUID      = CToken.CharacterGUID;
                                AccountID = CToken.AccountID;
                            }

                            break;
                        }
                    }

                    Sim Char = new Sim(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.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      = AccountID;
                    characterModel.AppearanceType = (int)Char.Appearance;

                    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)CityDataModel.Entities.CharacterCreationStatus.GeneralError);
                    Client.SendEncrypted(0x64, SuccessPacket.ToArray());
                    Client.Disconnect();
                }
            }
            catch (Exception E)
            {
                Logger.LogDebug("Exception in HandleCharacterCreate: " + E.ToString());
            }
        }
        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!");
            }
        }
        /// <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>
        /// <param name="Screen">A UIScreen instance on which to display a messagebox to inform the player of the
        ///                      failure state.</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;
            }

            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(TSOClient.Code.GameFacade.CDataRetriever.LotTileData)
                TSOClient.Code.GameFacade.CDataRetriever.LotTileData = TileEntries;

            return Status;
        }
        /// <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[TSOClient.Code.GameFacade.CDataRetriever.LotTileData.Length + 1];
                TileEntries[0] = TileEntry;
                TSOClient.Code.GameFacade.CDataRetriever.LotTileData.CopyTo(TileEntries, 1);
            }

            lock (NetworkFacade.AvatarsInSession)
            {
                NetworkFacade.AvatarsInSession.Add(Avatar);
            }

            return TileEntry;
        }
        /// <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());
        }
Пример #46
0
        /// <summary>
        /// Client created a character!
        /// </summary>
        public static void HandleCharacterCreate(NetworkClient Client, ProcessedPacket P)
        {
            Logger.LogInfo("Received CharacterCreate!");

            string AccountName = SanitizeAccount(P.ReadString());
            //Need to be variable length, because the success packet contains a token.
            PacketStream CCStatusPacket = new PacketStream((byte)PacketType.CHARACTER_CREATION_STATUS, 0);

            using (var db = DataAccess.Get())
            {
                Account Acc = db.Accounts.GetByUsername(AccountName);

                if (Acc.NumCharacters >= 3)
                {
                    CCStatusPacket.WriteByte((int)LoginDataModel.Entities.CharacterCreationStatus.ExceededCharacterLimit);
                    Client.SendEncrypted(CCStatusPacket.PacketID, CCStatusPacket.ToArray());

                    return;
                }

                //TODO: Send GUID to client...
                var Char = new Character();
                string LastCached = P.ReadString();
                if (LastCached == string.Empty)
                {
                    //TODO: Proper error...
                    CCStatusPacket.WriteByte((int)LoginDataModel.Entities.CharacterCreationStatus.NameAlreadyExisted);
                    Client.SendEncrypted(CCStatusPacket.PacketID, CCStatusPacket.ToArray());
                    return;
                }

                Char.LastCached = ProtoHelpers.ParseDateTime(LastCached);
                Char.Name = P.ReadString();
                Char.Sex = P.ReadString();
                Char.Description = P.ReadString();
                Char.GUID = Guid.NewGuid();
                Char.HeadOutfitID = (long)P.ReadUInt64();
                Char.BodyOutfitID = (long)P.ReadUInt64();
                Char.AccountID = Acc.AccountID;
                Char.AppearanceType = P.ReadByte();
                Char.CityName = P.ReadString();
                Char.CityThumb = (long)P.ReadUInt64();
                Char.City = P.ReadString();
                Char.CityMap = (long)P.ReadUInt64();
                Char.CityIp = P.ReadString();
                Char.CityPort = P.ReadInt32();
                Char.Money = NetworkFacade.INITIAL_MONEY;

                //These are going into DB, so be nazi. Sieg heil!
                if (Char.Name == string.Empty || Char.Sex == string.Empty ||
                    Char.Description == string.Empty)
                {
                    CCStatusPacket.WriteByte((int)LoginDataModel.Entities.CharacterCreationStatus.NameAlreadyExisted);
                    Client.SendEncrypted(CCStatusPacket.PacketID, CCStatusPacket.ToArray());
                    return;
                }

                var status = db.Characters.CreateCharacter(Char);

                switch (status)
                {
                    case LoginDataModel.Entities.CharacterCreationStatus.NameAlreadyExisted:
                        CCStatusPacket.WriteByte((int)LoginDataModel.Entities.CharacterCreationStatus.NameAlreadyExisted);
                        Client.SendEncrypted(CCStatusPacket.PacketID, CCStatusPacket.ToArray());
                        break;
                    case LoginDataModel.Entities.CharacterCreationStatus.NameTooLong:
                        CCStatusPacket.WriteByte((int)LoginDataModel.Entities.CharacterCreationStatus.NameTooLong);
                        Client.SendEncrypted(CCStatusPacket.PacketID, CCStatusPacket.ToArray());
                        break;
                    case LoginDataModel.Entities.CharacterCreationStatus.Success:
                        Guid Token = Guid.NewGuid();

                        //This actually updates the record, not sure how.
                        Acc.NumCharacters++;

                        //THIS NEEDS TO HAPPEN FIRST FOR CITY SERVER AUTHENTICATION TO WORK!
                        CityInfo CServer = NetworkFacade.CServerListener.GetCityServer(Char.City);

                        //Just in case...
                        if (CServer != null)
                        {
                            PacketStream CServerPacket = new PacketStream(0x01, 0);
                            CServerPacket.WriteHeader();

                            ushort PacketLength = (ushort)(PacketHeaders.UNENCRYPTED + 1 + 4 + (Client.RemoteIP.Length + 1)
                                + 4 + (Char.GUID.ToString().Length + 1) + (Token.ToString().Length + 1));
                            CServerPacket.WriteUInt16(PacketLength);

                            CServerPacket.WriteByte(1); //CharacterCreate = true
                            CServerPacket.WriteInt32(Acc.AccountID);
                            CServerPacket.WriteString(Client.RemoteIP);
                            CServerPacket.WriteInt32(Client.RemotePort);
                            CServerPacket.WriteString(Char.GUID.ToString());
                            CServerPacket.WriteString(Token.ToString(""));
                            CServer.Client.Send(CServerPacket.ToArray());
                        }

                        CCStatusPacket.WriteByte((int)LoginDataModel.Entities.CharacterCreationStatus.Success);
                        CCStatusPacket.WriteString(Char.GUID.ToString());
                        CCStatusPacket.WriteString(Token.ToString());
                        Client.SendEncrypted(CCStatusPacket.PacketID, CCStatusPacket.ToArray());

                        break;
                }
            }
        }
Пример #47
0
 /// <summary>
 /// Received from the CityServer in response to a CITY_TOKEN packet.
 /// </summary>
 public static CityTransferStatus OnCityTokenResponse(NetworkClient Client, ProcessedPacket Packet)
 {
     CityTransferStatus Status = (CityTransferStatus)Packet.ReadByte();
     return Status;
 }
Пример #48
0
        /// <summary>
        /// Client sent a response to our challenge, as well as account name and password.
        /// </summary>
        public static void HandleChallengeResponse(NetworkClient Client, ProcessedPacket P)
        {
            PacketStream OutPacket;

            if (P.BufferLength <= 1)
            {
                OutPacket = new PacketStream((byte)PacketType.LOGIN_FAILURE, 0);
                OutPacket.WriteByte(0x03); //Bad challenge response.
                Client.Send(OutPacket.ToArray());

                Logger.LogInfo("Bad challenge response - sent SLoginFailResponse!\r\n");
                return; //How does this even happen?!
            }

            int Length = P.ReadByte();
            byte[] CResponse;

            if (P.BufferLength >= Length)
                CResponse = P.ReadBytes(Length);
            else
                return;

            AESDecryptionArgs DecryptionArgs = Client.ClientEncryptor.GetDecryptionArgsContainer().AESDecryptArgs;

            if (DecryptionArgs.Challenge.SequenceEqual(CResponse))
            {
                string AccountName = SanitizeAccount(P.ReadString());

                Length = P.ReadByte();
                byte[] PasswordHash;

                if (P.BufferLength >= Length)
                    PasswordHash = P.ReadBytes(Length);
                else
                    return;

                // Check whether the accountname is empty or is/contains "username"
                if (AccountName == string.Empty || AccountName.ToLower().Equals("username") || AccountName.ToLower().Contains("username"))
                {
                    OutPacket = new PacketStream((byte)PacketType.LOGIN_FAILURE, 0);
                    OutPacket.WriteHeader();
                    OutPacket.WriteUInt16((ushort)(PacketHeaders.UNENCRYPTED + 1));
                    OutPacket.WriteByte(0x01);
                    Client.Send(OutPacket.ToArray());

                    Logger.LogInfo(@"Bad accountname (""" + AccountName + @""") - sent SLoginFailResponse!\r\n");
                    Client.Disconnect();
                    return;
                }

                using (var db = DataAccess.Get())
                {
                    var account = db.Accounts.GetByUsername(AccountName);

                    if (!GlobalSettings.Default.CreateAccountsOnLogin)
                    {
                        Logger.LogInfo("Done reading LoginRequest, checking account...\r\n");

                        if (account == null)
                        {
                            OutPacket = new PacketStream((byte)PacketType.LOGIN_FAILURE, 0);
                            OutPacket.WriteHeader();
                            OutPacket.WriteUInt16((ushort)(PacketHeaders.UNENCRYPTED + 1));
                            OutPacket.WriteByte(0x01);
                            Client.Send(OutPacket.ToArray());

                            Logger.LogInfo(@"Bad accountname (""" + AccountName + @""") - sent SLoginFailResponse!\r\n");
                            Client.Disconnect();
                            return;
                        }
                    }
                    else
                    {
                        if (account == null)
                        {
                            try
                            {
                                if (!AccountName.ToLower().Equals("username") || !AccountName.ToLower().Contains("username"))
                                db.Accounts.Create(new Account
                                {
                                    AccountName = AccountName.ToLower(),
                                    Password = Convert.ToBase64String(PasswordHash)
                                });
                            }
                            catch (Exception)
                            {
                                OutPacket = new PacketStream((byte)PacketType.LOGIN_FAILURE, 0);
                                OutPacket.WriteHeader();
                                OutPacket.WriteUInt16((ushort)(PacketHeaders.UNENCRYPTED + 1));
                                OutPacket.WriteByte(0x01);
                                Client.Send(OutPacket.ToArray());

                                Logger.LogInfo(@"Bad accountname (""" + AccountName + @""") - sent SLoginFailResponse!\r\n");
                                Client.Disconnect();
                                return;
                            }

                            account = db.Accounts.GetByUsername(AccountName);
                        }
                    }

                    if (account.IsCorrectPassword(AccountName, PasswordHash))
                    {
                        OutPacket = new PacketStream((byte)PacketType.LOGIN_SUCCESS, 0);
                        OutPacket.WriteByte(0x01);
                        Client.ClientEncryptor.Username = AccountName;
                        Client.SendEncrypted((byte)PacketType.LOGIN_SUCCESS, OutPacket.ToArray());

                        Logger.LogInfo("Sent SLoginSuccessResponse!\r\n");
                        return;
                    }
                    else
                    {
                        OutPacket = new PacketStream((byte)PacketType.LOGIN_FAILURE, 0);
                        OutPacket.WriteHeader();
                        OutPacket.WriteUInt16((ushort)(PacketHeaders.UNENCRYPTED + 1));
                        OutPacket.WriteByte(0x02);
                        Client.Send(OutPacket.ToArray());

                        Logger.LogInfo("Bad password - sent SLoginFailResponse!\r\n");
                        Client.Disconnect();
                        return;
                    }
                }
            }

            OutPacket = new PacketStream((byte)PacketType.LOGIN_FAILURE, 0);
            OutPacket.WriteHeader();
            OutPacket.WriteUInt16((ushort)(PacketHeaders.UNENCRYPTED + 1));
            OutPacket.WriteByte(0x03); //Bad challenge response.
            Client.Send(OutPacket.ToArray());

            Logger.LogInfo("Bad challenge response - sent SLoginFailResponse!\r\n");
            return;
        }
        /**
        * Actual packet handlers
        */
        public static void HandleLoginRequest(NetworkClient Client, ProcessedPacket P)
        {
            Logger.LogInfo("Received LoginRequest!\r\n");

            byte AccountStrLength = (byte)P.ReadByte();
            byte[] AccountNameBuf = new byte[AccountStrLength];
            P.Read(AccountNameBuf, 0, AccountStrLength);
            string AccountName = Encoding.ASCII.GetString(AccountNameBuf);
            Logger.LogInfo("Accountname: " + AccountName + "\r\n");

            byte HashLength = (byte)P.ReadByte();
            byte[] HashBuf = new byte[HashLength];
            P.Read(HashBuf, 0, HashLength);

            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);

                //TODO: Do something with this...
                byte Version1 = (byte)P.ReadByte();
                byte Version2 = (byte)P.ReadByte();
                byte Version3 = (byte)P.ReadByte();
                byte Version4 = (byte)P.ReadByte();

                Logger.LogInfo("Done reading LoginRequest, checking account...\r\n");

                if (account == null)
                {
                    PacketStream OutPacket = new PacketStream(0x02, 2);
                    OutPacket.WriteHeader();
                    OutPacket.WriteByte(0x01);
                    Client.Send(OutPacket.ToArray());

                    Logger.LogInfo("Bad accountname - sent SLoginFailResponse!\r\n");
                    Client.Disconnect();
                    return;
                }

                if (account.IsCorrectPassword(AccountName, HashBuf))
                {
                    //0x01 = InitLoginNotify
                    PacketStream OutPacket = new PacketStream(0x01, 1);
                    OutPacket.WriteHeader();
                    OutPacket.WriteByte(0x01);
                    Client.ClientEncryptor.Username = AccountName;
                    //This is neccessary to encrypt packets.
                    //TODO: Put something else here
                    //Client.Password = Account.GetPassword(AccountName);
                    Client.Send(OutPacket.ToArray());

                    Logger.LogInfo("Sent InitLoginNotify!\r\n");
                }
            }

            //Client was modified, update it.
            NetworkFacade.ClientListener.UpdateClient(Client);
        }
Пример #50
0
        /// <summary>
        /// Client wanted to log in!
        /// </summary>
        public static void HandleLoginRequest(NetworkClient Client, ProcessedPacket P)
        {
            try
            {
                Logger.LogInfo("Received LoginRequest!\r\n");

                byte Version1 = (byte)P.ReadByte();
                byte Version2 = (byte)P.ReadByte();
                byte Version3 = (byte)P.ReadByte();
                byte Version4 = (byte)P.ReadByte();

                string ClientVersion = Version1.ToString() + "." + Version2.ToString() + "." + Version3.ToString() +
                    "." + Version4.ToString();

                if (ClientVersion != GlobalSettings.Default.ClientVersion)
                {
                    PacketStream OutPacket = new PacketStream((byte)PacketType.INVALID_VERSION, 2);
                    OutPacket.WriteHeader();
                    OutPacket.WriteByte(0x01);
                    Client.Send(OutPacket.ToArray());

                    Logger.LogInfo("Bad version - sent SInvalidVersion!\r\n");
                    Client.Disconnect();
                    return;
                }

                PacketStream EncryptedPacket = new PacketStream((byte)PacketType.LOGIN_NOTIFY, 0);
                EncryptedPacket.WriteHeader();

                AESEncryptor Enc = (AESEncryptor)Client.ClientEncryptor;

                if (Enc == null)
                    Enc = new AESEncryptor("");

                Enc.PublicKey = P.ReadBytes((P.ReadByte()));
                Enc.NOnce = P.ReadBytes((P.ReadByte()));
                Enc.PrivateKey = NetworkFacade.ServerKey;
                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.ServerKey,
                    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());
            }
            //This should HOPEFULLY wade off clients sending unreadable (I.E old protocol) packets...
            catch (Exception E)
            {
                Logger.LogDebug("Error while handling login request, disconnecting client: " +
                    E.ToString());
                Client.Disconnect();
                return;
            }
        }