SendEncrypted() 공개 메소드

Sends an encrypted packet to the server. Automatically appends the length of the packet after the ID, as the encrypted data can be smaller or longer than that of the unencrypted data.
public SendEncrypted ( byte PacketID, byte Data ) : void
PacketID byte The ID of the packet (will remain unencrypted).
Data byte The data that will be encrypted.
리턴 void
예제 #1
0
        public static void HandleLoginNotify(NetworkClient Client, ProcessedPacket Packet)
        {
            //Should this be stored for permanent access?
            byte[] ServerPublicKey = Packet.ReadBytes(Packet.ReadByte());
            byte[] EncryptedData = Packet.ReadBytes(Packet.ReadByte());

            AESEncryptor Enc = (AESEncryptor)Client.ClientEncryptor;
            Enc.PublicKey = ServerPublicKey;
            Client.ClientEncryptor = Enc;
            NetworkFacade.Client.ClientEncryptor = Enc;

            ECDiffieHellmanCng PrivateKey = Client.ClientEncryptor.GetDecryptionArgsContainer().AESDecryptArgs.PrivateKey;
            byte[] NOnce = Client.ClientEncryptor.GetDecryptionArgsContainer().AESDecryptArgs.NOnce;

            byte[] ChallengeResponse = StaticStaticDiffieHellman.Decrypt(PrivateKey,
                ECDiffieHellmanCngPublicKey.FromByteArray(ServerPublicKey, CngKeyBlobFormat.EccPublicBlob),
                NOnce, EncryptedData);

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

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

            Writer.Write(Client.ClientEncryptor.Username);
            Writer.Write((byte)PlayerAccount.Hash.Length);
            Writer.Write(PlayerAccount.Hash);
            Writer.Flush();

            //Encrypt data using key and IV from server, hoping that it'll be decrypted correctly at the other end...
            Client.SendEncrypted((byte)PacketType.CHALLENGE_RESPONSE, StreamToEncrypt.ToArray());
        }
예제 #2
0
        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!");
            }
        }
예제 #3
0
 /// <summary>
 /// Requests a token from the LoginServer, that can be used to log into a CityServer.
 /// </summary>
 /// <param name="Client">A NetworkClient instance.</param>
 public static void RequestCityToken(NetworkClient Client, UISim SelectedCharacter)
 {
     PacketStream Packet = new PacketStream((byte)PacketType.REQUEST_CITY_TOKEN, 0);
     Packet.WriteString(Client.ClientEncryptor.Username);
     Packet.WriteString(SelectedCharacter.ResidingCity.UUID);
     Packet.WriteString(SelectedCharacter.GUID.ToString());
     Client.SendEncrypted((byte)PacketType.REQUEST_CITY_TOKEN, Packet.ToArray());
 }
        public static void HandleCharacterInfoRequest(NetworkClient Client, ProcessedPacket P)
        {
            Logger.LogInfo("Received CharacterInfoRequest!");

            DateTime Timestamp = DateTime.Parse(P.ReadPascalString());

            //Database.CheckCharacterTimestamp(Client.Username, Client, TimeStamp);

            Character[] Characters = new Character[] { };

            using (var db = DataAccess.Get())
            {
                var account = db.Accounts.GetByUsername(Client.ClientEncryptor.Username);
                Characters = db.Characters.GetForAccount((int)account.AccountID).ToArray();
            }

            if (Characters != null)
            {
                PacketStream Packet = new PacketStream((byte)PacketType.CHARACTER_LIST, 0);
                MemoryStream PacketData = new MemoryStream();
                BinaryWriter PacketWriter = new BinaryWriter(PacketData);

                /**
                 * Whats the point of checking a timestamp here? It saves a few bytes on a packet
                 * sent once per user session. Premature optimization.
                 */
                PacketWriter.Write((byte)Characters.Length);
                foreach (Character avatar in Characters)
                {
                    PacketWriter.Write((int)avatar.CharacterID);
                    PacketWriter.Write(avatar.GUID.ToString());
                    PacketWriter.Write(avatar.LastCached);
                    PacketWriter.Write(avatar.Name);
                    PacketWriter.Write(avatar.Sex);
                    PacketWriter.Write(avatar.Description);
                    PacketWriter.Write((ulong)avatar.HeadOutfitID);
                    PacketWriter.Write((ulong)avatar.BodyOutfitID);
                    PacketWriter.Write((byte)avatar.AppearanceType);
                    PacketWriter.Write((string)avatar.CityName);
                    PacketWriter.Write((ulong)avatar.CityThumb);
                    PacketWriter.Write((string)avatar.City);
                    PacketWriter.Write((ulong)avatar.CityMap);
                    PacketWriter.Write((string)avatar.CityIp);
                    PacketWriter.Write((int)avatar.CityPort);
                }

                Packet.Write(PacketData.ToArray(), 0, (int)PacketData.Length);
                PacketWriter.Close();
                Client.SendEncrypted(0x05, Packet.ToArray());
            }
            else //No characters existed for the account.
            {
                PacketStream Packet = new PacketStream(0x05, 0);
                Packet.WriteByte(0x00); //0 characters.

                Client.SendEncrypted((byte)PacketType.CHARACTER_LIST, Packet.ToArray());
            }
        }
예제 #5
0
        /// <summary>
        /// Received client token.
        /// </summary>
        public static void HandleCityToken(NetworkClient Client, ProcessedPacket P)
        {
            try
            {
                //bool ClientAuthenticated = false;
                ClientToken TokenToRemove = new ClientToken();

                using (DataAccess db = DataAccess.Get())
                {
                    string Token = P.ReadString();
                    ClientToken Tok;

                    if (Token == string.Empty)
                        return;

                    Tok = NetworkFacade.GetClientToken(new Guid(Token));

                    if (Tok != null)
                    {
                        //ClientAuthenticated = true;
                        TokenToRemove = Tok;

                        Character Char = db.Characters.GetForCharacterGUID(new Guid(Tok.CharacterGUID));
                        if (Char != null)
                        {
                            NetworkFacade.CurrentSession.AddPlayer(Client, Char);

                            PacketStream SuccessPacket = new PacketStream((byte)PacketType.CITY_TOKEN, 0);
                            SuccessPacket.WriteByte((byte)CityTransferStatus.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);
                            }

                            SuccessPacket.WriteInt32(Char.Money);

                            Client.SendEncrypted((byte)PacketType.CITY_TOKEN, SuccessPacket.ToArray());
                        }
                        /*else
                        {
                            ClientAuthenticated = false;
                            break;
                        }*/
                    }

                    NetworkFacade.TransferringClients.TryRemove(out TokenToRemove);

                    //This is not really valid anymore, because if the token doesn't exist yet,
                    //the client will now receive it when it arrives - see LoginPacketHandlers.cs
                    // - HandleClientToken()
                    /*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());
                Debug.WriteLine("Exception in HandleCityToken: " + E.ToString());

                PacketStream ErrorPacket = new PacketStream((byte)PacketType.CITY_TOKEN, 0);
                ErrorPacket.WriteByte((byte)CityTransferStatus.GeneralError);
                Client.SendEncrypted((byte)PacketType.CITY_TOKEN, ErrorPacket.ToArray());
            }
        }
예제 #6
0
        /// <summary>
        /// Client requested information about a city.
        /// </summary>
        public static void HandleCityInfoRequest(NetworkClient Client, ProcessedPacket P)
        {
            //This packet only contains a dummy byte, don't bother reading it.
            PacketStream Packet = new PacketStream((byte)PacketType.CITY_LIST, 0);
            Packet.WriteByte((byte)NetworkFacade.CServerListener.CityServers.Count);

            if (NetworkFacade.CServerListener.CityServers.Count > 0)
            {
                lock (NetworkFacade.CServerListener.CityServers)
                {
                    foreach (CityInfo CInfo in NetworkFacade.CServerListener.CityServers)
                    {
                        Packet.WriteString(CInfo.Name);
                        Packet.WriteString(CInfo.Description);
                        Packet.WriteString(CInfo.IP);
                        Packet.WriteInt32(CInfo.Port);

                        //Hack (?) to ensure status is written correctly.
                        switch (CInfo.Status)
                        {
                            case CityInfoStatus.Ok:
                                Packet.WriteByte(1);
                                break;
                            case CityInfoStatus.Busy:
                                Packet.WriteByte(2);
                                break;
                            case CityInfoStatus.Full:
                                Packet.WriteByte(3);
                                break;
                            case CityInfoStatus.Reserved:
                                Packet.WriteByte(4);
                                break;
                        }

                        Packet.WriteUInt64(CInfo.Thumbnail);
                        Packet.WriteString(CInfo.UUID);
                        Packet.WriteUInt64(CInfo.Map);
                    }
                }
            }

            Client.SendEncrypted((byte)PacketType.CITY_LIST, Packet.ToArray());
        }
예제 #7
0
        /// <summary>
        /// Client requested information about its characters.
        /// </summary>
        public static void HandleCharacterInfoRequest(NetworkClient Client, ProcessedPacket P)
        {
            Logger.LogInfo("Received CharacterInfoRequest!");

            string DateTimeStr = P.ReadString();
            DateTime Timestamp;

            if (DateTimeStr != string.Empty)
                Timestamp = DateTime.Parse(DateTimeStr);
            else
            {
                //Unix epoch
                Timestamp = new DateTime(1970, 1, 1, 0, 0, 1);
            }

            Character[] Characters = new Character[] { };

            using (var db = DataAccess.Get())
            {
                var account = db.Accounts.GetByUsername(Client.ClientEncryptor.Username);
                Characters = db.Characters.GetForAccount((int)account.AccountID).ToArray();
            }

            int NumChars = 0, NewChars = 0;

            if (Characters != null)
            {
                PacketStream Packet = new PacketStream((byte)PacketType.CHARACTER_LIST, 0);
                MemoryStream PacketData = new MemoryStream();
                BinaryWriter PacketWriter = new BinaryWriter(PacketData);

                NumChars = Characters.Length;

                foreach (Character avatar in Characters)
                {
                    //Zero means same, less than zero means T1 is earlier than T2, more than zero means T1 is later.
                    if (DateTime.Compare(Timestamp, avatar.LastCached) < 0)
                    {
                        NewChars++;

                        PacketWriter.Write((int)avatar.CharacterID);
                        PacketWriter.Write(avatar.GUID.ToString());
                        PacketWriter.Write(avatar.LastCached.ToString("yyyy.MM.dd hh:mm:ss",
                            CultureInfo.InvariantCulture));
                        PacketWriter.Write(avatar.Name);
                        PacketWriter.Write(avatar.Sex);
                        PacketWriter.Write(avatar.Description);
                        PacketWriter.Write((ulong)avatar.HeadOutfitID);
                        PacketWriter.Write((ulong)avatar.BodyOutfitID);
                        PacketWriter.Write((byte)avatar.AppearanceType);
                        PacketWriter.Write((string)avatar.CityName);
                        PacketWriter.Write((ulong)avatar.CityThumb);
                        PacketWriter.Write((string)avatar.City);
                        PacketWriter.Write((ulong)avatar.CityMap);
                        PacketWriter.Write((string)avatar.CityIp);
                        PacketWriter.Write((int)avatar.CityPort);
                        PacketWriter.Write((int)avatar.Money);
                    }
                }

                //NOTE: If Characters != null, but no chars were new, NumChars will be however many characters,
                //      and NewChars will be 0.

                Packet.WriteByte((byte)NumChars);
                Packet.WriteByte((byte)NewChars);
                Packet.Write(PacketData.ToArray(), 0, (int)PacketData.Length);
                PacketWriter.Close();
                Client.SendEncrypted((byte)PacketType.CHARACTER_LIST, Packet.ToArray());
            }
            else //No characters existed for the account.
            {
                PacketStream Packet = new PacketStream(0x05, 0);
                Packet.WriteByte((byte)NumChars); //0 characters.
                Packet.WriteByte((byte)NewChars); //0 new characters.

                Client.SendEncrypted((byte)PacketType.CHARACTER_LIST, Packet.ToArray());
            }
        }
예제 #8
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;
                }
            }
        }
        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);
        }
예제 #10
0
 /// <summary>
 /// Sends a request to purchase a lot.
 /// </summary>
 /// <param name="Client">NetworkClient instance connected to city server.</param>
 /// <param name="X">X-coordinate of lot.</param>
 /// <param name="Y">Y-coordinate of lot.</param>
 public static void SendLotPurchaseRequest(NetworkClient Client, short X, short Y)
 {
     PacketStream Packet = new PacketStream((byte)PacketType.LOT_PURCHASE_REQUEST, 0);
     Packet.WriteUInt16((ushort)X);
     Packet.WriteUInt16((ushort)Y);
     Client.SendEncrypted((byte)PacketType.LOT_PURCHASE_REQUEST, Packet.ToArray());
 }
예제 #11
0
 public static void SendLetter(NetworkClient Client, string Msg, string Subject, string GUID)
 {
     PacketStream Packet = new PacketStream((byte)PacketType.PLAYER_SENT_LETTER, 0);
     Packet.WriteString(GUID);
     Packet.WriteString(Subject);
     Packet.WriteString(Msg);
     Client.SendEncrypted((byte)PacketType.PLAYER_SENT_LETTER, Packet.ToArray());
 }
예제 #12
0
        /// <summary>
        /// Sends a token to a CityServer, as received by a LoginServer.
        /// </summary>
        /// <param name="Client">A NetworkClient instance.</param>
        public static void SendCityToken(NetworkClient Client)
        {
            PacketStream Packet = new PacketStream((byte)PacketType.CITY_TOKEN, 0);

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

            Writer.Write(PlayerAccount.CityToken);

            Packet.WriteBytes(PacketData.ToArray());
            Writer.Close();

            Client.SendEncrypted((byte)PacketType.CITY_TOKEN, Packet.ToArray());
        }
예제 #13
0
        /// <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());
        }
예제 #14
0
        /// <summary>
        /// A player sent a lot purchase request!
        /// </summary>
        public static void HandleLotPurchaseRequest(NetworkClient Client, ProcessedPacket Packet)
        {
            int X = Packet.ReadUInt16();
            int Y = Packet.ReadUInt16();

            if (!NetworkFacade.CurrentSession.IsLotOccupied(X, Y))
            {
                using (DataAccess db = DataAccess.Get())
                {
                    //TODO: Enable this later??
                    //if (db.Houses.GetForPosition(X, Y).HouseID != 0)
                    //{
                        if (NetworkFacade.CurrentTerrain.IsLandBuildable(X, Y))
                        {
                            Guid CharGuid = NetworkFacade.CurrentSession.GetPlayer(Client).GUID;
                            Character Char = db.Characters.GetForCharacterGUID(CharGuid);

                            if (Char.Money >= NetworkFacade.LOT_COST)
                            {
                                Char.HouseHouse = new House();
                                Char.HouseHouse.Name = "Yolo"; //TODO: Fixme
                                Char.HouseHouse.X = X;
                                Char.HouseHouse.Y = Y;

                                switch(db.Houses.CreateHouse(Char.HouseHouse))
                                {
                                    case CityDataModel.Entities.HouseCreationStatus.GeneralError:
                                        PacketStream UnbuildablePacket = new PacketStream((byte)PacketType.LOT_UNBUILDABLE, 0);
                                        UnbuildablePacket.WriteByte(0x00);
                                        Client.SendEncrypted((byte)PacketType.LOT_UNBUILDABLE, UnbuildablePacket.ToArray());
                                        return;
                                    case CityDataModel.Entities.HouseCreationStatus.NameTooLong:
                                        PacketStream NameTooLongPacket = new PacketStream((byte)PacketType.LOT_NAME_TOO_LONG, 0);
                                        NameTooLongPacket.WriteByte(0x00);
                                        Client.SendEncrypted((byte)PacketType.LOT_NAME_TOO_LONG, NameTooLongPacket.ToArray());
                                        return;
                                    default:
                                        break;
                                }

                                Char.Money -= NetworkFacade.LOT_COST;

                                PacketStream SuccessPacket = new PacketStream((byte)PacketType.LOT_PURCHASE_SUCCESSFUL, 0);
                                SuccessPacket.WriteInt32(Char.Money);
                                Client.SendEncrypted((byte)PacketType.LOT_PURCHASE_SUCCESSFUL, SuccessPacket.ToArray());
                            }
                            else
                            {
                                PacketStream OutOfMoneyPacket = new PacketStream((byte)PacketType.LOT_PURCHASE_FAILED, 0);
                                OutOfMoneyPacket.WriteByte(0x00); //Out of money
                                Client.SendEncrypted((byte)PacketType.LOT_PURCHASE_FAILED, OutOfMoneyPacket.ToArray());
                            }
                        }
                        else
                        {
                            PacketStream UnbuildablePacket = new PacketStream((byte)PacketType.LOT_UNBUILDABLE, 0);
                            UnbuildablePacket.WriteByte(0x00);
                            Client.SendEncrypted((byte)PacketType.LOT_UNBUILDABLE, UnbuildablePacket.ToArray());
                        }
                    }
                //}
            }
            else
            {
                PacketStream OccupiedPacket = new PacketStream((byte)PacketType.LOT_PURCHASE_OCCUPIED, 0);
                OccupiedPacket.WriteByte(0x00);
                Client.SendEncrypted((byte)PacketType.LOT_PURCHASE_OCCUPIED, OccupiedPacket.ToArray());
            }
        }
예제 #15
0
        /// <summary>
        /// Player requested the cost of a lot.
        /// </summary>
        public static void HandleLotCostRequest(NetworkClient Client, ProcessedPacket Packet)
        {
            ushort X = Packet.ReadUInt16();
            ushort Y = Packet.ReadUInt16();
            int LotID;
            string LotName;

            using (DataAccess db = DataAccess.Get())
            {
                LotID = db.Houses.GetForPosition(X, Y).HouseID;
                LotName = db.Houses.GetForPosition(X, Y).Name;
            }

            PacketStream LotCostPacket = new PacketStream((byte)PacketType.LOT_PURCHASE_OCCUPIED, 0);
            LotCostPacket.WriteUInt16(X);
            LotCostPacket.WriteUInt16(Y);
            LotCostPacket.WriteInt32(LotID);
            LotCostPacket.WriteString(LotName);

            byte Flags = 0;

            using (DataAccess db = DataAccess.Get())
            {
                if (db.Houses.GetForPosition(X, Y).HouseID == 0)
                {
                    if (!NetworkFacade.CurrentSession.IsLotOccupied(X, Y))
                    {
                        ProtoHelpers.SetBit(ref Flags, 0, false); //Online.
                        ProtoHelpers.SetBit(ref Flags, 1, false); //Spotlight, this will have to be checked against DB.
                        ProtoHelpers.SetBit(ref Flags, 2, false); //Locked - is the house locked for public access?
                        ProtoHelpers.SetBit(ref Flags, 3, false); //Occupied.
                        LotCostPacket.WriteByte(Flags);
                        LotCostPacket.WriteInt32(NetworkFacade.LOT_COST); //TODO: Figure out a way to deal with this...
                    }
                }
                else
                {
                    if (NetworkFacade.CurrentSession.IsLotOccupied(X, Y))
                    {
                        ProtoHelpers.SetBit(ref Flags, 0, true);  //Online.
                        ProtoHelpers.SetBit(ref Flags, 1, false); //Spotlight, this will have to be checked against DB.
                        ProtoHelpers.SetBit(ref Flags, 2, false); //Locked - is the house locked for public access?
                        ProtoHelpers.SetBit(ref Flags, 3, true);  //Occupied.
                        LotCostPacket.WriteByte(Flags);
                        LotCostPacket.WriteInt32(0);
                    }
                    else if (!NetworkFacade.CurrentSession.IsLotOccupied(X, Y))
                    {
                        ProtoHelpers.SetBit(ref Flags, 0, false); //Online.
                        ProtoHelpers.SetBit(ref Flags, 1, false); //Spotlight, this will have to be checked against DB.
                        ProtoHelpers.SetBit(ref Flags, 2, false); //Locked - is the house locked for public access?
                        ProtoHelpers.SetBit(ref Flags, 3, true);  //Occupied.
                        LotCostPacket.WriteByte(Flags);
                        LotCostPacket.WriteInt32(0);
                    }
                }
            }

            Client.SendEncrypted((byte)PacketType.LOT_COST, LotCostPacket.ToArray());
        }
        public static void HandleCityInfoRequest(NetworkClient Client, ProcessedPacket P)
        {
            //This packet only contains a dummy byte, don't bother reading it.
            PacketStream Packet = new PacketStream((byte)PacketType.CITY_LIST, 0);
            MemoryStream PacketData = new MemoryStream();
            BinaryWriter PacketWriter = new BinaryWriter(PacketData);
            PacketWriter.Write((byte)NetworkFacade.CServerListener.CityServers.Count);

            foreach (CityServerClient City in NetworkFacade.CServerListener.CityServers)
            {
                PacketWriter.Write((string)City.ServerInfo.Name);
                PacketWriter.Write((string)City.ServerInfo.Description);
                PacketWriter.Write((string)City.ServerInfo.IP);
                PacketWriter.Write((int)City.ServerInfo.Port);

                //Hack (?) to ensure status is written correctly.
                switch (City.ServerInfo.Status)
                {
                    case CityInfoStatus.Ok:
                        PacketWriter.Write((byte)1);
                        break;
                    case CityInfoStatus.Busy:
                        PacketWriter.Write((byte)2);
                        break;
                    case CityInfoStatus.Full:
                        PacketWriter.Write((byte)3);
                        break;
                    case CityInfoStatus.Reserved:
                        PacketWriter.Write((byte)4);
                        break;
                }

                PacketWriter.Write((ulong)City.ServerInfo.Thumbnail);
                PacketWriter.Write((string)City.ServerInfo.UUID);
                PacketWriter.Write((ulong)City.ServerInfo.Map);

                PacketWriter.Flush();
            }

            Packet.Write(PacketData.ToArray(), 0, PacketData.ToArray().Length);
            PacketWriter.Close();

            Client.SendEncrypted((byte)PacketType.CITY_LIST, Packet.ToArray());
        }
        public static void HandleCityTokenRequest(NetworkClient Client, ProcessedPacket P)
        {
            string AccountName = P.ReadPascalString();
            string CityGUID = P.ReadPascalString();
            string CharGUID = P.ReadPascalString();
            string Token = new Guid().ToString();

            foreach (CityServerClient CServer in NetworkFacade.CServerListener.CityServers)
            {
                if (CityGUID == CServer.ServerInfo.UUID)
                {
                    using (var db = DataAccess.Get())
                    {
                        Account Acc = db.Accounts.GetByUsername(AccountName);

                        PacketStream CServerPacket = new PacketStream(0x01, 0);
                        CServerPacket.WriteHeader();

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

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

                        break;
                    }
                }
            }

            PacketStream Packet = new PacketStream((byte)PacketType.REQUEST_CITY_TOKEN, 0);
            Packet.WritePascalString(Token);
            Client.SendEncrypted((byte)PacketType.REQUEST_CITY_TOKEN, Packet.ToArray());
        }
예제 #18
0
        /// <summary>
        /// Sends a CharacterCreate packet to a CityServer.
        /// </summary>
        /// <param name="LoginArgs">Arguments used to log onto the CityServer.</param>
        /// <param name="Character">The character to create on the CityServer.</param>
        public static void SendCharacterCreateCity(NetworkClient Client, UISim Character)
        {
            PacketStream Packet = new PacketStream((byte)PacketType.CHARACTER_CREATE_CITY, 0);

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

            Writer.Write((byte)Client.ClientEncryptor.Username.Length);
            Writer.Write(Encoding.ASCII.GetBytes(Client.ClientEncryptor.Username), 0,
                Encoding.ASCII.GetBytes(Client.ClientEncryptor.Username).Length);

            Writer.Write(PlayerAccount.CityToken);
            Writer.Write(Character.Timestamp);
            Writer.Write(Character.Name);
            Writer.Write(Character.Sex);
            Writer.Write(Character.Description);
            Writer.Write((ulong)Character.HeadOutfitID);
            Writer.Write((ulong)Character.BodyOutfitID);
            Writer.Write((byte)Character.Avatar.Appearance);

            Packet.WriteBytes(PacketData.ToArray());
            Writer.Close();

            Client.SendEncrypted((byte)PacketType.CHARACTER_CREATE_CITY, Packet.ToArray());
        }
        public static void HandleCharacterCreate(NetworkClient Client, ProcessedPacket P)
        {
            Logger.LogDebug("Received CharacterCreate!");

            bool ClientAuthenticated = false;

            byte AccountStrLength = (byte)P.ReadByte();
            byte[] AccountNameBuf = new byte[AccountStrLength];
            P.Read(AccountNameBuf, 0, AccountStrLength);
            string AccountName = Encoding.ASCII.GetString(AccountNameBuf);

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

                byte KeyLength = (byte)P.ReadByte();
                byte[] EncKey = new byte[KeyLength];
                P.Read(EncKey, 0, KeyLength);
                Client.ClientEncryptor = new ARC4Encryptor(account.Password, EncKey);
                Client.ClientEncryptor.Username = AccountName;

                string Token = P.ReadString();
                string GUID = "";

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

                            GUID = CToken.CharacterGUID;
                        }

                        break;
                    }
                }

                SimBase Char = new SimBase(new Guid(GUID));
                Char.Timestamp = P.ReadPascalString();
                Char.Name = P.ReadPascalString();
                Char.Sex = P.ReadPascalString();
                Char.Description = P.ReadPascalString();
                Char.HeadOutfitID = P.ReadUInt64();
                Char.BodyOutfitID = P.ReadUInt64();
                Char.Appearance = (AppearanceType)P.ReadByte();
                Char.CityID = new Guid(P.ReadString());
                Char.CreatedThisSession = true;

                var characterModel = new Character();
                characterModel.Name = Char.Name;
                characterModel.Sex = Char.Sex;
                characterModel.Description = Char.Description;
                characterModel.LastCached = Char.Timestamp;
                characterModel.GUID = Char.GUID;
                characterModel.HeadOutfitID = (long)Char.HeadOutfitID;
                characterModel.BodyOutfitID = (long)Char.BodyOutfitID;
                characterModel.AccountID = account.AccountID;
                characterModel.AppearanceType = (int)Char.Appearance;
                characterModel.City = Char.CityID.ToString();

                var status = db.Characters.CreateCharacter(characterModel);
            }

            //Invalid token, should never occur...
            if (!ClientAuthenticated)
            {
                PacketStream SuccessPacket = new PacketStream(0x65, (int)(PacketHeaders.ENCRYPTED + 1));
                SuccessPacket.WriteByte((byte)TSODataModel.Entities.CharacterCreationStatus.GeneralError);
                Client.SendEncrypted(0x64, SuccessPacket.ToArray());
                Client.Disconnect();
            }
        }
        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());
            }
        }
예제 #21
0
        public static void OnLoginSuccess(NetworkClient Client, ProcessedPacket Packet)
        {
            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(0x04, StreamToEncrypt.ToArray());
        }
예제 #22
0
		/// <summary>
		/// A new player joined the current session!
		/// </summary>
		/// <param name="Client">Client to inform about new player.</param>
		public void SendPlayerJoinSession(NetworkClient Client, Character Player)
		{
			PacketStream JoinPacket = new PacketStream((byte)PacketType.PLAYER_JOINED_SESSION, 0);
			JoinPacket.WriteString(Player.GUID.ToString());
			JoinPacket.WriteString(Player.Name);
			JoinPacket.WriteString(Player.Sex);
			JoinPacket.WriteString(Player.Description);
			JoinPacket.WriteInt64(Player.HeadOutfitID);
			JoinPacket.WriteInt64(Player.BodyOutfitID);
			JoinPacket.WriteInt32(Player.AppearanceType);

			if (Player.House == 1)
			{
				JoinPacket.WriteByte(1);
				JoinPacket.WriteInt32(Player.HouseHouse.HouseID);
				JoinPacket.WriteUInt16((ushort)Player.HouseHouse.X);
				JoinPacket.WriteUInt16((ushort)Player.HouseHouse.Y);
				JoinPacket.WriteByte((byte)Player.HouseHouse.Flags); //Might have to save this as unsigned in DB?
			}
			else
				JoinPacket.WriteByte(0);

			Client.SendEncrypted((byte)PacketType.PLAYER_JOINED_SESSION, JoinPacket.ToArray());
		}
예제 #23
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;
        }
예제 #24
0
		/// <summary>
		/// A new player left the current session!
		/// </summary>
		/// <param name="Client">Client to inform about player leaving.</param>
		public void SendPlayerLeftSession(NetworkClient Client, Character Player)
		{
			PacketStream JoinPacket = new PacketStream((byte)PacketType.PLAYER_LEFT_SESSION, 0);
			JoinPacket.WriteString(Player.GUID.ToString());

			Client.SendEncrypted((byte)PacketType.PLAYER_LEFT_SESSION, JoinPacket.ToArray());
		}
예제 #25
0
        /// <summary>
        /// Client wanted to retire a character.
        /// </summary>
        public static void HandleCharacterRetirement(NetworkClient Client, ProcessedPacket P)
        {
            PacketStream Packet;

            string AccountName = P.ReadString();
            string GUID = P.ReadString();

            if (AccountName == string.Empty || GUID == string.Empty)
                return;

            using (var db = DataAccess.Get())
            {
                Account Acc = db.Accounts.GetByUsername(AccountName);
                IQueryable<Character> Query = db.Characters.GetForAccount(Acc.AccountID);

                //F**K, I hate LINQ.
                Guid CharGUID = new Guid(GUID);
                Character Char = Query.Where(x => x.GUID == CharGUID).SingleOrDefault();

                if (Char != null)
                    db.Characters.RetireCharacter(Char);
                else
                    return;

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

                if (Char != null)
                {
                    CityInfo CInfo = NetworkFacade.CServerListener.GetCityServer(Char.City);

                    //Just in case...
                    if (CInfo != null)
                    {
                        Packet = new PacketStream(0x02, 0);
                        Packet.WriteHeader();

                        ushort PacketLength = (ushort)(PacketHeaders.UNENCRYPTED + 4 + GUID.Length + 1);

                        Packet.WriteUInt16(PacketLength);
                        Packet.WriteInt32(Acc.AccountID);
                        Packet.WriteString(GUID);
                        CInfo.Client.Send(Packet.ToArray());
                    }
                }
            }

            Packet = new PacketStream((byte)PacketType.RETIRE_CHARACTER_STATUS, 0);
            Packet.WriteString(GUID);
            Client.SendEncrypted((byte)PacketType.RETIRE_CHARACTER_STATUS, Packet.ToArray());
        }
예제 #26
0
		/// <summary>
		/// Player received a letter from another player.
		/// </summary>
		/// <param name="Client">Client of receiving player.</param>
		/// <param name="Subject">Letter's subject.</param>
		/// <param name="Msg">Letter's body.</param>
		/// <param name="LetterFrom">Name of player sending the letter.</param>
		public void SendPlayerReceivedLetter(NetworkClient Client, string Subject, string Msg, string LetterFrom)
		{
			PacketStream Packet = new PacketStream((byte)PacketType.PLAYER_RECV_LETTER, 0);
			Packet.WriteString(LetterFrom);
			Packet.WriteString(Subject);
			Packet.WriteString(Msg);

			Client.SendEncrypted((byte)PacketType.PLAYER_RECV_LETTER, Packet.ToArray());
		}
예제 #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());
        }
예제 #28
0
        /// <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());
            }
        }