コード例 #1
0
        public override void RemoveClient(NetworkClient Client)
        {
            CityInfo Info = CityServers.FirstOrDefault(x => x.Client == Client);

            if (CityServers.TryTake(out Info))
            {
                lock (NetworkFacade.ClientListener.Clients)
                {
                    PacketStream ClientPacket = new PacketStream((byte)PacketType.CITY_SERVER_OFFLINE, 0);
                    ClientPacket.WriteString(Info.Name);
                    ClientPacket.WriteString(Info.Description);
                    ClientPacket.WriteString(Info.IP);
                    ClientPacket.WriteInt32(Info.Port);
                    ClientPacket.WriteByte((byte)Info.Status);
                    ClientPacket.WriteUInt64(Info.Thumbnail);
                    ClientPacket.WriteString(Info.UUID);
                    ClientPacket.WriteUInt64(Info.Map);

                    foreach (NetworkClient Receiver in NetworkFacade.ClientListener.Clients)
                    {
                        Receiver.SendEncrypted((byte)PacketType.CITY_SERVER_OFFLINE, ClientPacket.ToArray());
                    }
                }

                Debug.WriteLine("Removed CityServer!");
            }
        }
コード例 #2
0
        /// <summary>
        /// Client wanted to transfer to a city server.
        /// </summary>
        public static void HandleCityTokenRequest(NetworkClient Client, ProcessedPacket P)
        {
            string AccountName = P.ReadString();
            string CityGUID    = P.ReadString();
            string CharGUID    = P.ReadString();

            if (AccountName == string.Empty || CityGUID == string.Empty || CharGUID == string.Empty)
            {
                return;
            }

            Guid     Token   = Guid.NewGuid();
            CityInfo CServer = NetworkFacade.CServerListener.GetCityServer(CityGUID);

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

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

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

                CServerPacket.WriteByte(0);                 //CharacterCreate = false.
                CServerPacket.WriteInt32(Acc.AccountID);
                CServerPacket.WriteString(Client.RemoteIP);
                CServerPacket.WriteInt32(Client.RemotePort);
                CServerPacket.WriteString(CharGUID.ToString());
                CServerPacket.WriteString(Token.ToString(""));
                CServer.Client.Send(CServerPacket.ToArray());
            }
        }
コード例 #3
0
        /// <summary>
        /// A cityserver requested a decryptionkey for a client!
        /// </summary>
        public static void HandleKeyFetch(ref LoginListener Listener, PacketStream P, CityServerClient Client)
        {
            string AccountName = P.ReadString();

            byte[] EncKey = new byte[1];

            foreach (LoginClient Cl in Listener.Clients)
            {
                if (Cl.Username == AccountName)
                {
                    EncKey = Cl.EncKey;

                    if (Cl.CurrentlyActiveSim.CreatedThisSession)
                    {
                        //TODO: Update the DB to reflect the city that
                        //      this sim resides in.
                        Database.UpdateCityForCharacter(Cl.CurrentlyActiveSim.Name, Client.ServerInfo.Name);
                    }
                }
            }

            PacketStream OutPacket = new PacketStream(0x01, 0x00);
            OutPacket.WriteByte((byte)0x01);
            OutPacket.WriteByte((byte)(EncKey.Length + 2));
            OutPacket.WriteByte((byte)EncKey.Length);
            OutPacket.Write(EncKey, 0, EncKey.Length);
            Client.Send(OutPacket.ToArray());

            //For now, assume client has already disconnected and doesn't need to be disconnected manually.
            Listener.TransferringClients.Remove(Client);
        }
コード例 #4
0
        /// <summary>
        /// A cityserver requested a decryptionkey for a client!
        /// </summary>
        public static void HandleKeyFetch(NetworkClient Client, ProcessedPacket P)
        {
            string AccountName = P.ReadString();

            byte[] EncKey = new byte[1];

            foreach (NetworkClient Cl in NetworkFacade.CServerListener.Clients)
            {
                if (Cl.ClientEncryptor.Username == AccountName)
                {
                    EncKey = Cl.ClientEncryptor.GetDecryptionArgsContainer().ARC4DecryptArgs.EncryptionKey;

                    //TODO: Figure out what to do about CurrentlyActiveSim...
                    //if (Cl.CurrentlyActiveSim.CreatedThisSession)
                    {
                        //TODO: Update the DB to reflect the city that
                        //      this sim resides in.
                        //Database.UpdateCityForCharacter(Cl.CurrentlyActiveSim.Name, Client.ServerInfo.Name);
                    }
                }
            }

            PacketStream OutPacket = new PacketStream(0x01, 0x00);

            OutPacket.WriteByte((byte)0x01);
            OutPacket.WriteByte((byte)(EncKey.Length + 2));
            OutPacket.WriteByte((byte)EncKey.Length);
            OutPacket.Write(EncKey, 0, EncKey.Length);
            Client.Send(OutPacket.ToArray());

            //For now, assume client has already disconnected and doesn't need to be disconnected manually.
            NetworkFacade.CServerListener.TransferringClients.Remove(Client);
        }
コード例 #5
0
        /// <summary>
        /// A cityserver requested a decryptionkey for a client!
        /// </summary>
        public static void HandleKeyFetch(ref LoginListener Listener, PacketStream P, CityServerClient Client)
        {
            string AccountName = P.ReadString();

            byte[] EncKey = new byte[1];

            foreach (LoginClient Cl in Listener.Clients)
            {
                if (Cl.Username == AccountName)
                {
                    EncKey = Cl.EncKey;

                    if (Cl.CurrentlyActiveSim.CreatedThisSession)
                    {
                        //TODO: Update the DB to reflect the city that
                        //      this sim resides in.
                        Database.UpdateCityForCharacter(Cl.CurrentlyActiveSim.Name, Client.ServerInfo.Name);
                    }
                }
            }

            PacketStream OutPacket = new PacketStream(0x01, 0x00);

            OutPacket.WriteByte((byte)0x01);
            OutPacket.WriteByte((byte)(EncKey.Length + 2));
            OutPacket.WriteByte((byte)EncKey.Length);
            OutPacket.Write(EncKey, 0, EncKey.Length);
            Client.Send(OutPacket.ToArray());

            //For now, assume client has already disconnected and doesn't need to be disconnected manually.
            Listener.TransferringClients.Remove(Client);
        }
コード例 #6
0
        public static void HandleCityInfoRequest(PacketStream P, LoginClient Client)
        {
            byte PacketLength = (byte)P.ReadByte();
            //Length of the unencrypted data, excluding the header (ID, length, unencrypted length).
            byte UnencryptedLength = (byte)P.ReadByte();

            P.DecryptPacket(Client.EncKey, Client.CryptoService, UnencryptedLength);

            //This packet only contains a dummy byte, don't bother reading it.

            PacketStream Packet = new PacketStream(0x06, 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(City.ServerInfo.Name);
                PacketWriter.Write(City.ServerInfo.Description);
                PacketWriter.Write(City.ServerInfo.IP);
                PacketWriter.Write(City.ServerInfo.Port);
                PacketWriter.Write((byte)City.ServerInfo.Status);
                PacketWriter.Write(City.ServerInfo.Thumbnail);
                PacketWriter.Write(City.ServerInfo.UUID);

                PacketWriter.Flush();
            }

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

            Client.SendEncrypted(0x06, Packet.ToArray());
        }
コード例 #7
0
        public static void HandleLoginRequest(PacketStream P, ref LoginClient Client)
        {
            Logger.LogInfo("Received LoginRequest!\r\n");

            byte PacketLength = (byte)P.ReadByte();

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

            Client.Hash = HashBuf;

            byte KeyLength = (byte)P.ReadByte();

            Client.EncKey = new byte[KeyLength];
            P.Read(Client.EncKey, 0, KeyLength);

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

            //Database.CheckAccount(AccountName, Client, HashBuf);

            if (Account.DoesAccountExist(AccountName) && Account.IsCorrectPassword(AccountName, HashBuf))
            {
                //0x01 = InitLoginNotify
                PacketStream OutPacket = new PacketStream(0x01, 2);
                OutPacket.WriteByte(0x01);
                OutPacket.WriteByte(0x01);
                Client.Username = AccountName;
                //This is neccessary to encrypt packets.
                Client.Password = Account.GetPassword(AccountName);
                Client.Send(OutPacket.ToArray());

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

                Logger.LogInfo("Bad accountname - sent SLoginFailResponse!\r\n");
                Client.Disconnect();
            }
        }
コード例 #8
0
        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());
            }
        }
コード例 #9
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());
        }
コード例 #10
0
        public static void HandleCityInfoRequest(ref LoginClient Client, PacketStream P)
        {
            ushort PacketLength = (ushort)P.ReadUShort();
            //Length of the unencrypted data, excluding the header (ID, length, unencrypted length).
            ushort UnencryptedLength = (ushort)P.ReadUShort();

            P.DecryptPacket(Client.EncKey, Client.CryptoService, UnencryptedLength);

            //This packet only contains a dummy byte, don't bother reading it.
            PacketStream Packet       = new PacketStream(0x06, 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(0x06, Packet.ToArray());
        }
コード例 #11
0
        public static void HandleCharacterInfoRequest(ref LoginClient Client, PacketStream P)
        {
            ushort PacketLength = (ushort)P.ReadUShort();
            //Length of the unencrypted data, excluding the header (ID, length, unencrypted length).
            ushort UnencryptedLength = (ushort)P.ReadUShort();

            P.DecryptPacket(Client.EncKey, Client.CryptoService, UnencryptedLength);

            Logger.LogDebug("Received CharacterInfoRequest!");

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

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

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

            using (var db = DataAccess.Get())
            {
                Characters = db.Characters.GetForAccount(Client.AccountID).ToArray();
            }

            if (Characters != null)
            {
                PacketStream Packet       = new PacketStream(0x05, 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(avatar.CharacterID);
                    PacketWriter.Write(avatar.GUID.ToString());
                    PacketWriter.Write(avatar.LastCached);
                    PacketWriter.Write(avatar.Name);
                    PacketWriter.Write(avatar.Sex);
                }

                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(0x05, Packet.ToArray());
            }
        }
コード例 #12
0
        /// <summary>
        /// Client wanted to retire a character.
        /// </summary>
        public static void HandleCharacterRetirement(NetworkClient Client, ProcessedPacket P)
        {
            PacketStream Packet;

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

            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 this is the case, char likely didn't exist in DB, so proceed as normal, client will delete cache.
                if (Char != null)
                {
                    db.Characters.RetireCharacter(Char);
                }

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

                for (int i = 0; i < NetworkFacade.CServerListener.CityServers.Count; i++)
                {
                    if (Char != null) //Assume char didn't exist in city either.
                    {
                        if (NetworkFacade.CServerListener.CityServers[i].ServerInfo.Name == Char.CityName)
                        {
                            Packet = new PacketStream(0x02, 0);
                            Packet.WriteHeader();

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

                            Packet.WriteUInt16(PacketLength);
                            Packet.WriteInt32(Acc.AccountID);
                            Packet.WritePascalString(GUID);
                            NetworkFacade.CServerListener.CityServers[i].Send(Packet.ToArray());

                            break;
                        }
                    }
                }
            }

            Packet = new PacketStream((byte)PacketType.RETIRE_CHARACTER_STATUS, 0);
            Packet.WritePascalString(GUID);
            Client.SendEncrypted((byte)PacketType.RETIRE_CHARACTER_STATUS, Packet.ToArray());
        }
コード例 #13
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);
            MemoryStream PacketData   = new MemoryStream();
            BinaryWriter PacketWriter = new BinaryWriter(PacketData);

            PacketWriter.Write((byte)NetworkFacade.CServerListener.CityServers.Count);

            //foreach (CityServerClient City in NetworkFacade.CServerListener.CityServers)
            for (int i = 0; i < NetworkFacade.CServerListener.CityServers.Count; i++)
            {
                PacketWriter.Write((string)NetworkFacade.CServerListener.CityServers[i].ServerInfo.Name);
                PacketWriter.Write((string)NetworkFacade.CServerListener.CityServers[i].ServerInfo.Description);
                PacketWriter.Write((string)NetworkFacade.CServerListener.CityServers[i].ServerInfo.IP);
                PacketWriter.Write((int)NetworkFacade.CServerListener.CityServers[i].ServerInfo.Port);

                //Hack (?) to ensure status is written correctly.
                switch (NetworkFacade.CServerListener.CityServers[i].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)NetworkFacade.CServerListener.CityServers[i].ServerInfo.Thumbnail);
                PacketWriter.Write((string)NetworkFacade.CServerListener.CityServers[i].ServerInfo.UUID);
                PacketWriter.Write((ulong)NetworkFacade.CServerListener.CityServers[i].ServerInfo.Map);

                PacketWriter.Flush();
            }

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

            Client.SendEncrypted((byte)PacketType.CITY_LIST, Packet.ToArray());
        }
コード例 #14
0
        /// <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());
            }
        }
コード例 #15
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());
        }
コード例 #16
0
        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;
            }
        }
コード例 #17
0
        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
        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...
                Sim Char = new Sim(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);
        }
コード例 #19
0
        /**
         * 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);
        }
コード例 #20
0
        public static void HandleCharacterInfoRequest(PacketStream P, LoginClient Client)
        {
            byte PacketLength = (byte)P.ReadByte();
            //Length of the unencrypted data, excluding the header (ID, length, unencrypted length).
            byte UnencryptedLength = (byte)P.ReadByte();

            P.DecryptPacket(Client.EncKey, Client.CryptoService, UnencryptedLength);

            Logger.LogDebug("Received CharacterInfoRequest!");

            byte Length = (byte)P.ReadByte();
            byte[] StrBuf = new byte[Length];
            P.Read(StrBuf, 0, Length - 1);
            DateTime Timestamp = DateTime.Parse(Encoding.ASCII.GetString(StrBuf));

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

            Character[] Characters = Character.GetCharacters(Client.Username);

            if (Characters != null)
            {
                PacketStream Packet = new PacketStream(0x05, 0);

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

                //The timestamp for all characters should be equal, so just check the first character.
                if (Timestamp < DateTime.Parse(Characters[0].LastCached) ||
                    Timestamp > DateTime.Parse(Characters[0].LastCached))
                {
                    //Write the characterdata into a temporary buffer.
                    if (Characters.Length == 1)
                    {
                        PacketWriter.Write(Characters[0].CharacterID);
                        PacketWriter.Write(Characters[0].GUID);
                        PacketWriter.Write(Characters[0].LastCached);
                        PacketWriter.Write(Characters[0].Name);
                        PacketWriter.Write(Characters[0].Sex);

                        PacketWriter.Flush();
                    }
                    else if (Characters.Length == 2)
                    {
                        PacketWriter.Write(Characters[0].CharacterID);
                        PacketWriter.Write(Characters[0].GUID);
                        PacketWriter.Write(Characters[0].LastCached);
                        PacketWriter.Write(Characters[0].Name);
                        PacketWriter.Write(Characters[0].Sex);

                        PacketWriter.Write(Characters[1].CharacterID);
                        PacketWriter.Write(Characters[1].GUID);
                        PacketWriter.Write(Characters[1].LastCached);
                        PacketWriter.Write(Characters[1].Name);
                        PacketWriter.Write(Characters[1].Sex);

                        PacketWriter.Flush();
                    }
                    else if (Characters.Length == 3)
                    {
                        PacketWriter.Write(Characters[0].CharacterID);
                        PacketWriter.Write(Characters[0].GUID);
                        PacketWriter.Write(Characters[0].LastCached);
                        PacketWriter.Write(Characters[0].Name);
                        PacketWriter.Write(Characters[0].Sex);

                        PacketWriter.Write(Characters[1].CharacterID);
                        PacketWriter.Write(Characters[1].GUID);
                        PacketWriter.Write(Characters[1].LastCached);
                        PacketWriter.Write(Characters[1].Name);
                        PacketWriter.Write(Characters[1].Sex);

                        PacketWriter.Write(Characters[2].CharacterID);
                        PacketWriter.Write(Characters[2].GUID);
                        PacketWriter.Write(Characters[2].LastCached);
                        PacketWriter.Write(Characters[2].Name);
                        PacketWriter.Write(Characters[2].Sex);

                        PacketWriter.Flush();
                    }

                    Packet.WriteByte((byte)Characters.Length);      //Total number of characters.
                    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(0x05, Packet.ToArray());
            }
        }
コード例 #21
0
 public void Send(PacketStream stream)
 {
     this.Send(stream.ToArray());
 }
コード例 #22
0
        public void OnReceivedData(IAsyncResult AR)
        {
            //base.OnReceivedData(AR); //Not needed for this application!
            try
            {
                Socket Sock = (Socket)AR.AsyncState;
                int NumBytesRead = Sock.EndReceive(AR);

                if (NumBytesRead > 0)
                {

                    byte[] TmpBuf = new byte[NumBytesRead];
                    Buffer.BlockCopy(m_RecvBuffer, 0, TmpBuf, 0, NumBytesRead);

                    //The packet is given an ID of 0x00 because its ID is currently unknown.
                    PacketStream TempPacket = new PacketStream(0x00, NumBytesRead, TmpBuf);
                    byte ID = TempPacket.PeekByte(0);
                    int PacketLength = 0;

                    bool FoundMatchingID = false;

                    /*foreach (KeyValuePair<byte, int> Pair in m_PacketIDs)
                    {
                        if (ID == Pair.Key)
                        {
                            Console.WriteLine("Found matching Packet ID!");

                            FoundMatchingID = true;
                            PacketLength = Pair.Value;
                            break;
                        }
                    }*/

                    FoundMatchingID = FindMatchingPacketID(ID);

                    if (FoundMatchingID)
                    {
                        PacketLength = m_PacketIDs[ID];

                        Logger.LogInfo("Found matching PacketID!\r\n\r\n");

                        if (NumBytesRead == PacketLength)
                        {
                            Logger.LogInfo("Got packet - exact length!\r\n\r\n");
                            m_RecvBuffer = new byte[11024];
                            m_Listener.OnReceivedData(new PacketStream(ID, PacketLength, TempPacket.ToArray()), this);
                        }
                        else if (NumBytesRead < PacketLength)
                        {
                            m_TempPacket = new PacketStream(ID, PacketLength);
                            byte[] TmpBuffer = new byte[NumBytesRead];

                            //Store the number of bytes that were read in the temporary buffer.
                            Logger.LogInfo("Got data, but not a full packet - stored " +
                                NumBytesRead.ToString() + "bytes!\r\n\r\n");
                            Buffer.BlockCopy(m_RecvBuffer, 0, TmpBuffer, 0, NumBytesRead);
                            m_TempPacket.WriteBytes(TmpBuffer);

                            //And reset the buffers!
                            m_RecvBuffer = new byte[11024];
                            TmpBuffer = null;
                        }
                        else if (PacketLength == 0)
                        {
                            Logger.LogInfo("Received variable length packet!\r\n");

                            if (NumBytesRead > 2)
                            {
                                PacketLength = TempPacket.PeekByte(1);

                                if (NumBytesRead == PacketLength)
                                {
                                    Logger.LogInfo("Received exact number of bytes for packet!\r\n");

                                    m_RecvBuffer = new byte[11024];
                                    m_TempPacket = null;
                                    m_Listener.OnReceivedData(new PacketStream(ID, PacketLength,
                                        TempPacket.ToArray()), this);
                                }
                                else if (NumBytesRead < PacketLength)
                                {
                                    Logger.LogInfo("Didn't receive entire packet - stored: " + PacketLength + " bytes!\r\n");

                                    TempPacket.SetLength(PacketLength);
                                    m_TempPacket = TempPacket;
                                    m_RecvBuffer = new byte[11024];
                                }
                                else if (NumBytesRead > PacketLength)
                                {
                                    Logger.LogInfo("Received more bytes than needed for packet. Excess: " +
                                        (NumBytesRead - PacketLength) + "\r\n");

                                    byte[] TmpBuffer = new byte[NumBytesRead - PacketLength];
                                    Buffer.BlockCopy(TempPacket.ToArray(), 0, TmpBuffer, 0, TmpBuffer.Length);
                                    m_TempPacket = new PacketStream(TmpBuffer[0], NumBytesRead - PacketLength,
                                        TmpBuffer);

                                    byte[] PacketBuffer = new byte[PacketLength];
                                    Buffer.BlockCopy(TempPacket.ToArray(), 0, PacketBuffer, 0, PacketBuffer.Length);

                                    m_RecvBuffer = new byte[11024];
                                    m_Listener.OnReceivedData(new PacketStream(ID, PacketLength, PacketBuffer),
                                        this);
                                }
                            }
                        }
                    }
                    else
                    {
                        if (m_TempPacket != null)
                        {
                            if (m_TempPacket.Length < m_TempPacket.BufferLength)
                            {
                                //Received the exact number of bytes needed to complete the stored packet.
                                if ((m_TempPacket.BufferLength + NumBytesRead) == m_TempPacket.Length)
                                {
                                    byte[] TmpBuffer = new byte[NumBytesRead];
                                    Buffer.BlockCopy(m_RecvBuffer, 0, TmpBuffer, 0, NumBytesRead);

                                    m_RecvBuffer = new byte[11024];
                                    TmpBuffer = null;
                                }
                                //Received more than the number of bytes needed to complete the packet!
                                else if ((m_TempPacket.BufferLength + NumBytesRead) > m_TempPacket.Length)
                                {
                                    int Target = (int)((m_TempPacket.BufferLength + NumBytesRead) - m_TempPacket.Length);
                                    byte[] TmpBuffer = new byte[Target];

                                    Buffer.BlockCopy(m_RecvBuffer, 0, TmpBuffer, 0, Target);
                                    m_TempPacket.WriteBytes(TmpBuffer);

                                    //Now we have a full packet, so call the received event!
                                    m_Listener.OnReceivedData(new PacketStream(m_TempPacket.PacketID,
                                        (int)m_TempPacket.Length, m_TempPacket.ToArray()), this);

                                    //Copy the remaining bytes in the receiving buffer.
                                    TmpBuffer = new byte[NumBytesRead - Target];
                                    Buffer.BlockCopy(m_RecvBuffer, Target, TmpBuffer, 0, (NumBytesRead - Target));

                                    //Give the temporary packet an ID of 0x00 since we don't know its ID yet.
                                    TempPacket = new PacketStream(0x00, NumBytesRead - Target, TmpBuffer);
                                    ID = TempPacket.PeekByte(0);

                                    //This SHOULD be an existing ID, but let's sanity-check it...
                                    if (FindMatchingPacketID(ID))
                                    {
                                        m_TempPacket = new PacketStream(ID, m_PacketIDs[ID], TempPacket.ToArray());

                                        //Congratulations, you just received another packet!
                                        if (m_TempPacket.Length == m_TempPacket.BufferLength)
                                        {
                                            m_Listener.OnReceivedData(new PacketStream(m_TempPacket.PacketID,
                                                (int)m_TempPacket.Length, m_TempPacket.ToArray()), this);

                                            //No more data to store on this read, so reset everything...
                                            m_TempPacket = null;
                                            TmpBuffer = null;
                                            m_RecvBuffer = new byte[11024];
                                        }
                                    }
                                    else
                                    {
                                        //Houston, we have a problem (this should never occur)!
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    //Client disconnected!
                    //For now, assume that client initiated a transfer.
                    m_Listener.TransferClient(this);
                }

                m_Socket.BeginReceive(m_RecvBuffer, 0, m_RecvBuffer.Length, SocketFlags.None,
                    new AsyncCallback(OnReceivedData), m_Socket);
            }
            catch (SocketException)
            {
                Disconnect();
            }
        }
コード例 #23
0
        /// <summary>
        /// Callback-function for CheckAccount().
        /// </summary>
        private static void EndCheckAccount(IAsyncResult AR)
        {
            DatabaseAsyncObject AsyncObject = AR.AsyncState as DatabaseAsyncObject;
            bool FoundAccountName           = false;

            using (MySqlDataReader Reader = AsyncObject.MySQLCmd.EndExecuteReader(AR))
            {
                while (Reader.Read())
                {
                    if (((string)Reader[0]).ToUpper() == AsyncObject.AccountName.ToUpper())
                    {
                        FoundAccountName = true;

                        AsyncObject.Password = (string)Reader[1];
                    }
                }
            }

            if (FoundAccountName == true)
            {
                //0x01 = InitLoginNotify
                PacketStream P = new PacketStream(0x01, 2);

                SaltedHash SHash = new SaltedHash(new SHA512Managed(), AsyncObject.AccountName.Length);

                if (SHash.VerifyHash(Encoding.ASCII.GetBytes(AsyncObject.Password.ToUpper()), AsyncObject.Hash,
                                     Encoding.ASCII.GetBytes(AsyncObject.AccountName)))
                {
                    AsyncObject.Client.Username = AsyncObject.AccountName.ToUpper();
                    AsyncObject.Client.Password = AsyncObject.Password.ToUpper();
                    P.WriteByte(0x01);
                    P.WriteByte(0x01);
                }
                else //The client's password was wrong.
                {
                    PacketStream RejectPacket = new PacketStream(0x02, 2);
                    RejectPacket.WriteByte(0x02);
                    RejectPacket.WriteByte(0x02);
                    AsyncObject.Client.Send(RejectPacket.ToArray());

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

                    return;
                }

                AsyncObject.Client.Send(P.ToArray());

                Logger.LogInfo("Sent InitLoginNotify!\r\n");
            }
            else
            {
                PacketStream P = new PacketStream(0x02, 2);
                P.WriteByte(0x02);
                P.WriteByte(0x01);
                AsyncObject.Client.Send(P.ToArray());

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

            //If this setting is true, it means an account will be created
            //if it doesn't exist.
            if (GlobalSettings.Default.CreateAccountsOnLogin == true)
            {
                if (FoundAccountName == false)
                {
                    //No idea if this call is gonna succeed, given it's called from a callback function...
                    CreateAccount(AsyncObject.AccountName, AsyncObject.Password);
                }
            }
        }
コード例 #24
0
        /// <summary>
        /// Callback mehod for CheckCharacterTimestamp.
        /// This queries for the existence of a particular account
        /// in the DB and retrieves the character IDs associated with it.
        /// </summary>
        private static void EndCheckCharacterID(IAsyncResult AR)
        {
            DatabaseAsyncObject AsyncObject = AR.AsyncState as DatabaseAsyncObject;
            bool FoundAccountName           = false;

            int NumCharacters = 0;
            int CharacterID1  = 0;
            int CharacterID2  = 0;
            int CharacterID3  = 0;

            using (MySqlDataReader Reader = AsyncObject.MySQLCmd.EndExecuteReader(AR))
            {
                while (Reader.Read())
                {
                    if (((string)Reader[0]).ToUpper() == AsyncObject.AccountName.ToUpper())
                    {
                        FoundAccountName = true;

                        NumCharacters = (int)Reader[1];

                        if (NumCharacters == 0)
                        {
                            break;
                        }
                        else if (NumCharacters == 1)
                        {
                            CharacterID1 = (int)Reader[2];
                        }
                        else if (NumCharacters == 2)
                        {
                            CharacterID1 = (int)Reader[2];
                            CharacterID2 = (int)Reader[3];
                        }
                        else if (NumCharacters == 3)
                        {
                            CharacterID1 = (int)Reader[2];
                            CharacterID2 = (int)Reader[3];
                            CharacterID3 = (int)Reader[4];
                        }

                        if (FoundAccountName == true)
                        {
                            break;
                        }
                    }
                }
            }

            if (FoundAccountName)
            {
                if (NumCharacters > 0)
                {
                    MySqlCommand Command = new MySqlCommand("SELECT CharacterID, LastCached, Name, Sex FROM Character");

                    AsyncObject.NumCharacters = NumCharacters;
                    AsyncObject.CharacterID1  = CharacterID1;
                    AsyncObject.CharacterID2  = CharacterID2;
                    AsyncObject.CharacterID3  = CharacterID3;

                    Command.Connection = m_Connection;
                    EndCheckCharacterTimestamp(Command.BeginExecuteReader(System.Data.CommandBehavior.Default));
                }
                else
                {
                    PacketStream Packet = new PacketStream(0x05, 0);
                    Packet.WriteByte(0x00); //0 characters.

                    AsyncObject.Client.SendEncrypted(0x05, Packet.ToArray());
                }
            }
        }
コード例 #25
0
        public static void HandleCityInfoRequest(ref LoginClient Client, PacketStream P)
        {
            ushort PacketLength = (ushort)P.ReadUShort();
            //Length of the unencrypted data, excluding the header (ID, length, unencrypted length).
            ushort UnencryptedLength = (ushort)P.ReadUShort();
            P.DecryptPacket(Client.EncKey, Client.CryptoService, UnencryptedLength);

            //This packet only contains a dummy byte, don't bother reading it.
            PacketStream Packet = new PacketStream(0x06, 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(0x06, Packet.ToArray());
        }
コード例 #26
0
        /**
         * Actual packet handlers
         */
        public static void HandleLoginRequest(ref LoginClient Client, PacketStream P)
        {
            Logger.LogInfo("Received LoginRequest!\r\n");
            ushort PacketLength = (ushort)P.ReadUShort();

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

            Client.Hash = HashBuf;

            byte KeyLength = (byte)P.ReadByte();
            Client.EncKey = new byte[KeyLength];
            P.Read(Client.EncKey, 0, KeyLength);

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

            using (var db = DataAccess.Get())
            {
                var account = db.Accounts.GetByUsername(AccountName);
                if (account == null)
                {
                    PacketStream OutPacket = new PacketStream(0x02, 2);
                    OutPacket.WriteHeader();
                    OutPacket.WriteByte(0x01);
                    Client.Send(OutPacket);

                    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();
                    Client.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");
                }
            }
        }
コード例 #27
0
        /// <summary>
        /// Client requested information about its characters.
        /// </summary>
        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);

                int NumChars = 0;

                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, DateTime.Parse(avatar.LastCached)) < 0)
                    {
                        NumChars++;

                        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.WriteByte((byte)NumChars);
                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());
            }
        }
コード例 #28
0
        /// <summary>
        /// Callback mehod for CheckCharacterTimestamp.
        /// This queries for the existence of a particular account
        /// in the DB and retrieves the character IDs associated with it.
        /// </summary>
        private static void EndCheckCharacterID(IAsyncResult AR)
        {
            DatabaseAsyncObject AsyncObject = AR.AsyncState as DatabaseAsyncObject;
            bool FoundAccountName = false;

            int NumCharacters = 0;
            int CharacterID1 = 0;
            int CharacterID2 = 0;
            int CharacterID3 = 0;

            using (MySqlDataReader Reader = AsyncObject.MySQLCmd.EndExecuteReader(AR))
            {
                while (Reader.Read())
                {
                    if (((string)Reader[0]).ToUpper() == AsyncObject.AccountName.ToUpper())
                    {
                        FoundAccountName = true;

                        NumCharacters = (int)Reader[1];

                        if (NumCharacters == 0)
                            break;
                        else if (NumCharacters == 1)
                            CharacterID1 = (int)Reader[2];
                        else if (NumCharacters == 2)
                        {
                            CharacterID1 = (int)Reader[2];
                            CharacterID2 = (int)Reader[3];
                        }
                        else if (NumCharacters == 3)
                        {
                            CharacterID1 = (int)Reader[2];
                            CharacterID2 = (int)Reader[3];
                            CharacterID3 = (int)Reader[4];
                        }

                        if (FoundAccountName == true)
                            break;
                    }
                }
            }

            if (FoundAccountName)
            {
                if (NumCharacters > 0)
                {
                    MySqlCommand Command = new MySqlCommand("SELECT CharacterID, LastCached, Name, Sex FROM Character");

                    AsyncObject.NumCharacters = NumCharacters;
                    AsyncObject.CharacterID1 = CharacterID1;
                    AsyncObject.CharacterID2 = CharacterID2;
                    AsyncObject.CharacterID3 = CharacterID3;

                    Command.Connection = m_Connection;
                    EndCheckCharacterTimestamp(Command.BeginExecuteReader(System.Data.CommandBehavior.Default));
                }
                else
                {
                    PacketStream Packet = new PacketStream(0x05, 0);
                    Packet.WriteByte(0x00); //0 characters.

                    AsyncObject.Client.SendEncrypted(0x05, Packet.ToArray());
                }
            }
        }
コード例 #29
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());
            }
        }
コード例 #30
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;
            }
        }
コード例 #31
0
        public static void HandleCityInfoRequest(PacketStream P, LoginClient Client)
        {
            byte PacketLength = (byte)P.ReadByte();
            //Length of the unencrypted data, excluding the header (ID, length, unencrypted length).
            byte UnencryptedLength = (byte)P.ReadByte();

            P.DecryptPacket(Client.EncKey, Client.CryptoService, UnencryptedLength);

            //This packet only contains a dummy byte, don't bother reading it.

            PacketStream Packet = new PacketStream(0x06, 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(City.ServerInfo.Name);
                PacketWriter.Write(City.ServerInfo.Description);
                PacketWriter.Write(City.ServerInfo.IP);
                PacketWriter.Write(City.ServerInfo.Port);
                PacketWriter.Write((byte)City.ServerInfo.Status);
                PacketWriter.Write(City.ServerInfo.Thumbnail);
                PacketWriter.Write(City.ServerInfo.UUID);

                PacketWriter.Flush();
            }

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

            Client.SendEncrypted(0x06, Packet.ToArray());
        }
コード例 #32
0
        public void OnReceivedData(IAsyncResult AR)
        {
            try
            {
                int NumBytesRead = m_Socket.EndReceive(AR);

                Logger.LogInfo("Received: " + NumBytesRead.ToString() + " bytes!\r\n\r\n");

                //The packet is given an ID of 0x00 because its ID is currently unknown.
                PacketStream TempPacket   = new PacketStream(0x00, NumBytesRead, CreateABuffer(NumBytesRead, m_RecvBuffer));
                byte         ID           = TempPacket.PeekByte(0);
                int          PacketLength = 0;

                bool FoundMatchingID = false;

                FoundMatchingID = FindMatchingPacketID(ID);

                if (FoundMatchingID)
                {
                    PacketLength = m_PacketIDs[ID];

                    Logger.LogInfo("Found matching PacketID!\r\n\r\n");

                    if (NumBytesRead == PacketLength)
                    {
                        Logger.LogInfo("Got packet - exact length!\r\n\r\n");
                        m_Listener.OnReceivedData(new PacketStream(ID, PacketLength, TempPacket.ToArray()), this);
                        m_RecvBuffer = new byte[11024];
                    }
                    else if (NumBytesRead < PacketLength)
                    {
                        m_TempPacket = new PacketStream(ID, PacketLength);
                        byte[] TmpBuffer = new byte[NumBytesRead];

                        //Store the number of bytes that were read in the temporary buffer.
                        Logger.LogInfo("Got data, but not a full packet - stored " +
                                       NumBytesRead.ToString() + "bytes!\r\n\r\n");
                        Buffer.BlockCopy(m_RecvBuffer, 0, TmpBuffer, 0, NumBytesRead);
                        m_TempPacket.WriteBytes(TmpBuffer);

                        //And reset the buffers!
                        m_RecvBuffer = new byte[11024];
                        TmpBuffer    = null;
                    }
                    else if (PacketLength == 0)
                    {
                    }
                }
                else
                {
                    if (m_TempPacket != null)
                    {
                        if (m_TempPacket.Length < m_TempPacket.BufferLength)
                        {
                            //Received the exact number of bytes needed to complete the stored packet.
                            if ((m_TempPacket.BufferLength + NumBytesRead) == m_TempPacket.Length)
                            {
                                byte[] TmpBuffer = new byte[NumBytesRead];
                                Buffer.BlockCopy(m_RecvBuffer, 0, TmpBuffer, 0, NumBytesRead);

                                m_RecvBuffer = new byte[11024];
                                TmpBuffer    = null;
                            }
                            //Received more than the number of bytes needed to complete the packet!
                            else if ((m_TempPacket.BufferLength + NumBytesRead) > m_TempPacket.Length)
                            {
                                int    Target    = (int)((m_TempPacket.BufferLength + NumBytesRead) - m_TempPacket.Length);
                                byte[] TmpBuffer = new byte[Target];

                                Buffer.BlockCopy(m_RecvBuffer, 0, TmpBuffer, 0, Target);
                                m_TempPacket.WriteBytes(TmpBuffer);

                                //Now we have a full packet, so call the received event!
                                m_Listener.OnReceivedData(new PacketStream(m_TempPacket.PacketID,
                                                                           (int)m_TempPacket.Length, m_TempPacket.ToArray()), this);

                                //Copy the remaining bytes in the receiving buffer.
                                TmpBuffer = new byte[NumBytesRead - Target];
                                Buffer.BlockCopy(m_RecvBuffer, Target, TmpBuffer, 0, (NumBytesRead - Target));

                                //Give the temporary packet an ID of 0x00 since we don't know its ID yet.
                                TempPacket = new PacketStream(0x00, NumBytesRead - Target, TmpBuffer);
                                ID         = TempPacket.PeekByte(0);

                                //This SHOULD be an existing ID, but let's sanity-check it...
                                if (FindMatchingPacketID(ID))
                                {
                                    m_TempPacket = new PacketStream(ID, m_PacketIDs[ID], TempPacket.ToArray());

                                    //Congratulations, you just received another packet!
                                    if (m_TempPacket.Length == m_TempPacket.BufferLength)
                                    {
                                        m_Listener.OnReceivedData(new PacketStream(m_TempPacket.PacketID,
                                                                                   (int)m_TempPacket.Length, m_TempPacket.ToArray()), this);

                                        //No more data to store on this read, so reset everything...
                                        m_TempPacket = null;
                                        TmpBuffer    = null;
                                        m_RecvBuffer = new byte[11024];
                                    }
                                }
                                else
                                {
                                    //Houston, we have a problem (this should never occur)!
                                }
                            }
                        }
                    }
                }

                m_Socket.BeginReceive(m_RecvBuffer, 0, m_RecvBuffer.Length, SocketFlags.None,
                                      new AsyncCallback(OnReceivedData), m_Socket);
            }
            catch (SocketException)
            {
                Disconnect();
            }
        }
コード例 #33
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;
        }
コード例 #34
0
        /// <summary>
        /// Callback method for EndCheckCharacterID.
        /// This retrieves information about the characters
        /// corresponding to the IDs retrieved earlier.
        /// </summary>
        private static void EndCheckCharacterTimestamp(IAsyncResult AR)
        {
            DatabaseAsyncObject AsyncObject = AR.AsyncState as DatabaseAsyncObject;

            List <Sim> Sims = new List <Sim>();

            using (MySqlDataReader Reader = AsyncObject.MySQLCmd.EndExecuteReader(AR))
            {
                while (Reader.Read())
                {
                    if ((int)Reader[0] == AsyncObject.CharacterID1)
                    {
                        int CharacterID = AsyncObject.CharacterID1;

                        Sim Character = new Sim((string)Reader[1]);
                        Character.CharacterID = CharacterID;
                        Character.Timestamp   = (string)Reader[2];
                        Character.Name        = (string)Reader[3];
                        Character.Sex         = (string)Reader[4];

                        Sims.Add(Character);
                    }

                    if (AsyncObject.NumCharacters == 1)
                    {
                        break;
                    }

                    if (AsyncObject.NumCharacters > 1)
                    {
                        if ((int)Reader[1] == AsyncObject.CharacterID2)
                        {
                            int CharacterID = AsyncObject.CharacterID2;

                            Sim Character = new Sim((string)Reader[1]);
                            Character.CharacterID = CharacterID;
                            Character.Timestamp   = (string)Reader[2];
                            Character.Name        = (string)Reader[3];
                            Character.Sex         = (string)Reader[4];

                            Sims.Add(Character);
                        }
                    }

                    if (AsyncObject.NumCharacters == 2)
                    {
                        break;
                    }

                    if (AsyncObject.NumCharacters > 2)
                    {
                        if ((int)Reader[2] == AsyncObject.CharacterID3)
                        {
                            int CharacterID = AsyncObject.CharacterID3;

                            Sim Character = new Sim((string)Reader[1]);
                            Character.CharacterID = CharacterID;
                            Character.Timestamp   = (string)Reader[2];
                            Character.Name        = (string)Reader[3];
                            Character.Sex         = (string)Reader[4];

                            Sims.Add(Character);

                            //For now, assume that finding the third character means
                            //all characters have been found.
                            break;
                        }
                    }
                }
            }

            PacketStream Packet = new PacketStream(0x05, 0);

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

            //The timestamp for all characters should be equal, so just check the first character.
            if (AsyncObject.CharacterTimestamp < DateTime.Parse(Sims[0].Timestamp) ||
                AsyncObject.CharacterTimestamp > DateTime.Parse(Sims[0].Timestamp))
            {
                //Write the characterdata into a temporary buffer.
                if (AsyncObject.NumCharacters == 1)
                {
                    PacketWriter.Write(Sims[0].CharacterID);
                    PacketWriter.Write(Sims[0].GUID);
                    PacketWriter.Write(Sims[0].Timestamp);
                    PacketWriter.Write(Sims[0].Name);
                    PacketWriter.Write(Sims[0].Sex);

                    PacketWriter.Flush();
                }
                else if (AsyncObject.NumCharacters == 2)
                {
                    PacketWriter.Write(Sims[0].CharacterID);
                    PacketWriter.Write(Sims[0].GUID);
                    PacketWriter.Write(Sims[0].Timestamp);
                    PacketWriter.Write(Sims[0].Name);
                    PacketWriter.Write(Sims[0].Sex);

                    PacketWriter.Write(Sims[1].CharacterID);
                    PacketWriter.Write(Sims[1].GUID);
                    PacketWriter.Write(Sims[1].Timestamp);
                    PacketWriter.Write(Sims[1].Name);
                    PacketWriter.Write(Sims[1].Sex);

                    PacketWriter.Flush();
                }
                else if (AsyncObject.NumCharacters == 3)
                {
                    PacketWriter.Write(Sims[0].CharacterID);
                    PacketWriter.Write(Sims[0].GUID);
                    PacketWriter.Write(Sims[0].Timestamp);
                    PacketWriter.Write(Sims[0].Name);
                    PacketWriter.Write(Sims[0].Sex);

                    PacketWriter.Write(Sims[1].CharacterID);
                    PacketWriter.Write(Sims[1].GUID);
                    PacketWriter.Write(Sims[1].Timestamp);
                    PacketWriter.Write(Sims[1].Name);
                    PacketWriter.Write(Sims[1].Sex);

                    PacketWriter.Write(Sims[2].CharacterID);
                    PacketWriter.Write(Sims[2].GUID);
                    PacketWriter.Write(Sims[2].Timestamp);
                    PacketWriter.Write(Sims[2].Name);
                    PacketWriter.Write(Sims[2].Sex);

                    PacketWriter.Flush();
                }

                Packet.WriteByte((byte)AsyncObject.NumCharacters);      //Total number of characters.
                Packet.Write(PacketData.ToArray(), 0, (int)PacketData.Length);

                AsyncObject.Client.SendEncrypted(0x05, Packet.ToArray());
            }
            else if (AsyncObject.CharacterTimestamp == DateTime.Parse(Sims[0].Timestamp))
            {
                PacketWriter.Write((byte)0x00); //0 characters.

                AsyncObject.Client.SendEncrypted(0x05, Packet.ToArray());
            }

            PacketWriter.Close();
        }
コード例 #35
0
        public static void HandleCharacterInfoRequest(ref LoginClient Client, PacketStream P)
        {
            ushort PacketLength = (ushort)P.ReadUShort();
            //Length of the unencrypted data, excluding the header (ID, length, unencrypted length).
            ushort UnencryptedLength = (ushort)P.ReadUShort();

            P.DecryptPacket(Client.EncKey, Client.CryptoService, UnencryptedLength);

            Logger.LogDebug("Received CharacterInfoRequest!");

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

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

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

            using (var db = DataAccess.Get())
            {
                Characters = db.Characters.GetForAccount(Client.AccountID).ToArray();
            }

            if (Characters != null)
            {
                PacketStream Packet = new PacketStream(0x05, 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(avatar.CharacterID);
                    PacketWriter.Write(avatar.GUID.ToString());
                    PacketWriter.Write(avatar.LastCached);
                    PacketWriter.Write(avatar.Name);
                    PacketWriter.Write(avatar.Sex);
                }

                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(0x05, Packet.ToArray());
            }
        }
コード例 #36
0
        public void OnReceivedData(IAsyncResult AR)
        {
            //base.OnReceivedData(AR); //Not needed for this application!

            try
            {
                int NumBytesRead = m_Socket.EndReceive(AR);

                Logger.LogInfo("Received: " + NumBytesRead.ToString() + " bytes!\r\n\r\n");

                //The packet is given an ID of 0x00 because its ID is currently unknown.
                PacketStream TempPacket = new PacketStream(0x00, NumBytesRead, CreateABuffer(NumBytesRead, m_RecvBuffer));
                byte ID = TempPacket.PeekByte(0);
                int PacketLength = 0;

                bool FoundMatchingID = false;

                FoundMatchingID = FindMatchingPacketID(ID);

                if (FoundMatchingID)
                {
                    PacketLength = m_PacketIDs[ID];

                    Logger.LogInfo("Found matching PacketID!\r\n\r\n");

                    if (NumBytesRead == PacketLength)
                    {
                        Logger.LogInfo("Got packet - exact length!\r\n\r\n");
                        m_Listener.OnReceivedData(new PacketStream(ID, PacketLength, TempPacket.ToArray()), this);
                        m_RecvBuffer = new byte[11024];
                    }
                    else if (NumBytesRead < PacketLength)
                    {
                        m_TempPacket = new PacketStream(ID, PacketLength);
                        byte[] TmpBuffer = new byte[NumBytesRead];

                        //Store the number of bytes that were read in the temporary buffer.
                        Logger.LogInfo("Got data, but not a full packet - stored " +
                            NumBytesRead.ToString() + "bytes!\r\n\r\n");
                        Buffer.BlockCopy(m_RecvBuffer, 0, TmpBuffer, 0, NumBytesRead);
                        m_TempPacket.WriteBytes(TmpBuffer);

                        //And reset the buffers!
                        m_RecvBuffer = new byte[11024];
                        TmpBuffer = null;
                    }
                    else if (PacketLength == 0)
                    {

                    }
                }
                else
                {
                    if (m_TempPacket != null)
                    {
                        if (m_TempPacket.Length < m_TempPacket.BufferLength)
                        {
                            //Received the exact number of bytes needed to complete the stored packet.
                            if ((m_TempPacket.BufferLength + NumBytesRead) == m_TempPacket.Length)
                            {
                                byte[] TmpBuffer = new byte[NumBytesRead];
                                Buffer.BlockCopy(m_RecvBuffer, 0, TmpBuffer, 0, NumBytesRead);

                                m_RecvBuffer = new byte[11024];
                                TmpBuffer = null;
                            }
                            //Received more than the number of bytes needed to complete the packet!
                            else if ((m_TempPacket.BufferLength + NumBytesRead) > m_TempPacket.Length)
                            {
                                int Target = (int)((m_TempPacket.BufferLength + NumBytesRead) - m_TempPacket.Length);
                                byte[] TmpBuffer = new byte[Target];

                                Buffer.BlockCopy(m_RecvBuffer, 0, TmpBuffer, 0, Target);
                                m_TempPacket.WriteBytes(TmpBuffer);

                                //Now we have a full packet, so call the received event!
                                m_Listener.OnReceivedData(new PacketStream(m_TempPacket.PacketID,
                                    (int)m_TempPacket.Length, m_TempPacket.ToArray()), this);

                                //Copy the remaining bytes in the receiving buffer.
                                TmpBuffer = new byte[NumBytesRead - Target];
                                Buffer.BlockCopy(m_RecvBuffer, Target, TmpBuffer, 0, (NumBytesRead - Target));

                                //Give the temporary packet an ID of 0x00 since we don't know its ID yet.
                                TempPacket = new PacketStream(0x00, NumBytesRead - Target, TmpBuffer);
                                ID = TempPacket.PeekByte(0);

                                //This SHOULD be an existing ID, but let's sanity-check it...
                                if (FindMatchingPacketID(ID))
                                {
                                    m_TempPacket = new PacketStream(ID, m_PacketIDs[ID], TempPacket.ToArray());

                                    //Congratulations, you just received another packet!
                                    if (m_TempPacket.Length == m_TempPacket.BufferLength)
                                    {
                                        m_Listener.OnReceivedData(new PacketStream(m_TempPacket.PacketID,
                                            (int)m_TempPacket.Length, m_TempPacket.ToArray()), this);

                                        //No more data to store on this read, so reset everything...
                                        m_TempPacket = null;
                                        TmpBuffer = null;
                                        m_RecvBuffer = new byte[11024];
                                    }
                                }
                                else
                                {
                                    //Houston, we have a problem (this should never occur)!
                                }
                            }
                        }
                    }
                }

                m_Socket.BeginReceive(m_RecvBuffer, 0, m_RecvBuffer.Length, SocketFlags.None,
                    new AsyncCallback(OnReceivedData), m_Socket);
            }
            catch (SocketException)
            {
                Disconnect();
            }
        }
コード例 #37
0
 public void Send(PacketStream stream)
 {
     this.Send(stream.ToArray());
 }
コード例 #38
0
        public void OnReceivedData(IAsyncResult AR)
        {
            //base.OnReceivedData(AR); //Not needed for this application!
            try
            {
                Socket Sock         = (Socket)AR.AsyncState;
                int    NumBytesRead = Sock.EndReceive(AR);

                if (NumBytesRead > 0)
                {
                    byte[] TmpBuf = new byte[NumBytesRead];
                    Buffer.BlockCopy(m_RecvBuffer, 0, TmpBuf, 0, NumBytesRead);

                    //The packet is given an ID of 0x00 because its ID is currently unknown.
                    PacketStream TempPacket = new PacketStream(0x00, NumBytesRead, TmpBuf);

                    /** Get the packet type **/
                    byte ID      = TempPacket.PeekByte(0);
                    var  handler = FindPacketHandler(ID);

                    if (handler != null)
                    {
                        var PacketLength = handler.Length;
                        Logger.LogInfo("Found matching PacketID!\r\n\r\n");

                        if (NumBytesRead == PacketLength)
                        {
                            Logger.LogInfo("Got packet - exact length!\r\n\r\n");
                            m_RecvBuffer = new byte[11024];
                            m_Listener.OnReceivedData(new PacketStream(ID, PacketLength, TempPacket.ToArray()), this);
                        }
                        else if (NumBytesRead < PacketLength)
                        {
                            m_TempPacket = new PacketStream(ID, PacketLength);
                            byte[] TmpBuffer = new byte[NumBytesRead];

                            //Store the number of bytes that were read in the temporary buffer.
                            Logger.LogInfo("Got data, but not a full packet - stored " +
                                           NumBytesRead.ToString() + "bytes!\r\n\r\n");
                            Buffer.BlockCopy(m_RecvBuffer, 0, TmpBuffer, 0, NumBytesRead);
                            m_TempPacket.WriteBytes(TmpBuffer);

                            //And reset the buffers!
                            m_RecvBuffer = new byte[11024];
                            TmpBuffer    = null;
                        }
                        else if (PacketLength == 0)
                        {
                            Logger.LogInfo("Received variable length packet!\r\n");

                            if (NumBytesRead > (int)PacketHeaders.UNENCRYPTED) //Header is 3 bytes.
                            {
                                PacketLength = TempPacket.PeekUShort(1);

                                if (NumBytesRead == PacketLength)
                                {
                                    Logger.LogInfo("Received exact number of bytes for packet!\r\n");

                                    m_RecvBuffer = new byte[11024];
                                    m_TempPacket = null;
                                    m_Listener.OnReceivedData(new PacketStream(ID, PacketLength,
                                                                               TempPacket.ToArray()), this);
                                }
                                else if (NumBytesRead < PacketLength)
                                {
                                    Logger.LogInfo("Didn't receive entire packet - stored: " + PacketLength + " bytes!\r\n");

                                    TempPacket.SetLength(PacketLength);
                                    m_TempPacket = TempPacket;
                                    m_RecvBuffer = new byte[11024];
                                }
                                else if (NumBytesRead > PacketLength)
                                {
                                    Logger.LogInfo("Received more bytes than needed for packet. Excess: " +
                                                   (NumBytesRead - PacketLength) + "\r\n");

                                    byte[] TmpBuffer = new byte[NumBytesRead - PacketLength];
                                    Buffer.BlockCopy(TempPacket.ToArray(), 0, TmpBuffer, 0, TmpBuffer.Length);
                                    m_TempPacket = new PacketStream(TmpBuffer[0], NumBytesRead - PacketLength,
                                                                    TmpBuffer);

                                    byte[] PacketBuffer = new byte[PacketLength];
                                    Buffer.BlockCopy(TempPacket.ToArray(), 0, PacketBuffer, 0, PacketBuffer.Length);

                                    m_RecvBuffer = new byte[11024];
                                    m_Listener.OnReceivedData(new PacketStream(ID, PacketLength, PacketBuffer),
                                                              this);
                                }
                            }
                        }
                    }
                    else
                    {
                        if (m_TempPacket != null)
                        {
                            if (m_TempPacket.Length < m_TempPacket.BufferLength)
                            {
                                //Received the exact number of bytes needed to complete the stored packet.
                                if ((m_TempPacket.BufferLength + NumBytesRead) == m_TempPacket.Length)
                                {
                                    byte[] TmpBuffer = new byte[NumBytesRead];
                                    Buffer.BlockCopy(m_RecvBuffer, 0, TmpBuffer, 0, NumBytesRead);

                                    m_RecvBuffer = new byte[11024];
                                    TmpBuffer    = null;
                                }
                                //Received more than the number of bytes needed to complete the packet!
                                else if ((m_TempPacket.BufferLength + NumBytesRead) > m_TempPacket.Length)
                                {
                                    int    Target    = (int)((m_TempPacket.BufferLength + NumBytesRead) - m_TempPacket.Length);
                                    byte[] TmpBuffer = new byte[Target];

                                    Buffer.BlockCopy(m_RecvBuffer, 0, TmpBuffer, 0, Target);
                                    m_TempPacket.WriteBytes(TmpBuffer);

                                    //Now we have a full packet, so call the received event!
                                    m_Listener.OnReceivedData(new PacketStream(m_TempPacket.PacketID,
                                                                               (int)m_TempPacket.Length, m_TempPacket.ToArray()), this);

                                    //Copy the remaining bytes in the receiving buffer.
                                    TmpBuffer = new byte[NumBytesRead - Target];
                                    Buffer.BlockCopy(m_RecvBuffer, Target, TmpBuffer, 0, (NumBytesRead - Target));

                                    //Give the temporary packet an ID of 0x00 since we don't know its ID yet.
                                    TempPacket = new PacketStream(0x00, NumBytesRead - Target, TmpBuffer);
                                    ID         = TempPacket.PeekByte(0);
                                    handler    = FindPacketHandler(ID);

                                    //This SHOULD be an existing ID, but let's sanity-check it...
                                    if (handler != null)
                                    {
                                        m_TempPacket = new PacketStream(ID, handler.Length, TempPacket.ToArray());

                                        //Congratulations, you just received another packet!
                                        if (m_TempPacket.Length == m_TempPacket.BufferLength)
                                        {
                                            m_Listener.OnReceivedData(new PacketStream(m_TempPacket.PacketID,
                                                                                       (int)m_TempPacket.Length, m_TempPacket.ToArray()), this);

                                            //No more data to store on this read, so reset everything...
                                            m_TempPacket = null;
                                            TmpBuffer    = null;
                                            m_RecvBuffer = new byte[11024];
                                        }
                                    }
                                    else
                                    {
                                        //Houston, we have a problem (this should never occur)!
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    //Client disconnected!
                    //TODO: Figure out if this client was successfully authenticated before transferring.
                    m_Listener.TransferClient(this);
                }

                m_Socket.BeginReceive(m_RecvBuffer, 0, m_RecvBuffer.Length, SocketFlags.None,
                                      new AsyncCallback(OnReceivedData), m_Socket);
            }
            catch (SocketException)
            {
                Disconnect();
            }
        }
コード例 #39
0
        /**
         * Actual packet handlers
         */
        public static void HandleLoginRequest(ref LoginClient Client, PacketStream P)
        {
            Logger.LogInfo("Received LoginRequest!\r\n");
            ushort PacketLength = (ushort)P.ReadUShort();

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

            Client.Hash = HashBuf;

            byte KeyLength = (byte)P.ReadByte();

            Client.EncKey = new byte[KeyLength];
            P.Read(Client.EncKey, 0, KeyLength);

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

            using (var db = DataAccess.Get())
            {
                var account = db.Accounts.GetByUsername(AccountName);
                if (account == null)
                {
                    PacketStream OutPacket = new PacketStream(0x02, 2);
                    OutPacket.WriteHeader();
                    OutPacket.WriteByte(0x01);
                    Client.Send(OutPacket);

                    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();
                    Client.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");
                }
            }
        }
コード例 #40
0
        /// <summary>
        /// Callback-function for CheckAccount().
        /// </summary>
        private static void EndCheckAccount(IAsyncResult AR)
        {
            DatabaseAsyncObject AsyncObject = AR.AsyncState as DatabaseAsyncObject;
            bool FoundAccountName = false;

            using (MySqlDataReader Reader = AsyncObject.MySQLCmd.EndExecuteReader(AR))
            {
                while (Reader.Read())
                {
                    if (((string)Reader[0]).ToUpper() == AsyncObject.AccountName.ToUpper())
                    {
                        FoundAccountName = true;

                        AsyncObject.Password = (string)Reader[1];
                    }
                }
            }

            if (FoundAccountName == true)
            {
                //0x01 = InitLoginNotify
                PacketStream P = new PacketStream(0x01, 2);

                SaltedHash SHash = new SaltedHash(new SHA512Managed(), AsyncObject.AccountName.Length);

                if (SHash.VerifyHash(Encoding.ASCII.GetBytes(AsyncObject.Password.ToUpper()), AsyncObject.Hash,
                    Encoding.ASCII.GetBytes(AsyncObject.AccountName)))
                {
                    AsyncObject.Client.Username = AsyncObject.AccountName.ToUpper();
                    AsyncObject.Client.Password = AsyncObject.Password.ToUpper();
                    P.WriteByte(0x01);
                    P.WriteByte(0x01);
                }
                else //The client's password was wrong.
                {
                    PacketStream RejectPacket = new PacketStream(0x02, 2);
                    RejectPacket.WriteByte(0x02);
                    RejectPacket.WriteByte(0x02);
                    AsyncObject.Client.Send(RejectPacket.ToArray());

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

                    return;
                }

                AsyncObject.Client.Send(P.ToArray());

                Logger.LogInfo("Sent InitLoginNotify!\r\n");
            }
            else
            {
                PacketStream P = new PacketStream(0x02, 2);
                P.WriteByte(0x02);
                P.WriteByte(0x01);
                AsyncObject.Client.Send(P.ToArray());

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

            //If this setting is true, it means an account will be created
            //if it doesn't exist.
            if (GlobalSettings.Default.CreateAccountsOnLogin == true)
            {
                if (FoundAccountName == false)
                {
                    //No idea if this call is gonna succeed, given it's called from a callback function...
                    CreateAccount(AsyncObject.AccountName, AsyncObject.Password);
                }
            }
        }
コード例 #41
0
        public static void HandleLoginRequest(PacketStream P, ref LoginClient Client)
        {
            Logger.LogInfo("Received LoginRequest!\r\n");

            byte PacketLength = (byte)P.ReadByte();

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

            Client.Hash = HashBuf;

            byte KeyLength = (byte)P.ReadByte();
            Client.EncKey = new byte[KeyLength];
            P.Read(Client.EncKey, 0, KeyLength);

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

            //Database.CheckAccount(AccountName, Client, HashBuf);

            if (Account.DoesAccountExist(AccountName) && Account.IsCorrectPassword(AccountName, HashBuf))
            {
                //0x01 = InitLoginNotify
                PacketStream OutPacket = new PacketStream(0x01, 2);
                OutPacket.WriteByte(0x01);
                OutPacket.WriteByte(0x01);
                Client.Username = AccountName;
                //This is neccessary to encrypt packets.
                Client.Password = Account.GetPassword(AccountName);
                Client.Send(OutPacket.ToArray());

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

                Logger.LogInfo("Bad accountname - sent SLoginFailResponse!\r\n");
                Client.Disconnect();
            }
        }
コード例 #42
0
        /// <summary>
        /// Callback method for EndCheckCharacterID.
        /// This retrieves information about the characters 
        /// corresponding to the IDs retrieved earlier.
        /// </summary>
        private static void EndCheckCharacterTimestamp(IAsyncResult AR)
        {
            DatabaseAsyncObject AsyncObject = AR.AsyncState as DatabaseAsyncObject;

            List<Sim> Sims = new List<Sim>();

            using (MySqlDataReader Reader = AsyncObject.MySQLCmd.EndExecuteReader(AR))
            {
                while (Reader.Read())
                {
                    if ((int)Reader[0] == AsyncObject.CharacterID1)
                    {
                        int CharacterID = AsyncObject.CharacterID1;

                        Sim Character = new Sim((string)Reader[1]);
                        Character.CharacterID = CharacterID;
                        Character.Timestamp = (string)Reader[2];
                        Character.Name = (string)Reader[3];
                        Character.Sex = (string)Reader[4];

                        Sims.Add(Character);
                    }

                    if (AsyncObject.NumCharacters == 1)
                        break;

                    if (AsyncObject.NumCharacters > 1)
                    {
                        if ((int)Reader[1] == AsyncObject.CharacterID2)
                        {
                            int CharacterID = AsyncObject.CharacterID2;

                            Sim Character = new Sim((string)Reader[1]);
                            Character.CharacterID = CharacterID;
                            Character.Timestamp = (string)Reader[2];
                            Character.Name = (string)Reader[3];
                            Character.Sex = (string)Reader[4];

                            Sims.Add(Character);
                        }
                    }

                    if (AsyncObject.NumCharacters == 2)
                        break;

                    if (AsyncObject.NumCharacters > 2)
                    {
                        if ((int)Reader[2] == AsyncObject.CharacterID3)
                        {
                            int CharacterID = AsyncObject.CharacterID3;

                            Sim Character = new Sim((string)Reader[1]);
                            Character.CharacterID = CharacterID;
                            Character.Timestamp = (string)Reader[2];
                            Character.Name = (string)Reader[3];
                            Character.Sex = (string)Reader[4];

                            Sims.Add(Character);

                            //For now, assume that finding the third character means
                            //all characters have been found.
                            break;
                        }
                    }
                }
            }

            PacketStream Packet = new PacketStream(0x05, 0);

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

            //The timestamp for all characters should be equal, so just check the first character.
            if (AsyncObject.CharacterTimestamp < DateTime.Parse(Sims[0].Timestamp) ||
                AsyncObject.CharacterTimestamp > DateTime.Parse(Sims[0].Timestamp))
            {
                //Write the characterdata into a temporary buffer.
                if (AsyncObject.NumCharacters == 1)
                {
                    PacketWriter.Write(Sims[0].CharacterID);
                    PacketWriter.Write(Sims[0].GUID);
                    PacketWriter.Write(Sims[0].Timestamp);
                    PacketWriter.Write(Sims[0].Name);
                    PacketWriter.Write(Sims[0].Sex);

                    PacketWriter.Flush();
                }
                else if (AsyncObject.NumCharacters == 2)
                {
                    PacketWriter.Write(Sims[0].CharacterID);
                    PacketWriter.Write(Sims[0].GUID);
                    PacketWriter.Write(Sims[0].Timestamp);
                    PacketWriter.Write(Sims[0].Name);
                    PacketWriter.Write(Sims[0].Sex);

                    PacketWriter.Write(Sims[1].CharacterID);
                    PacketWriter.Write(Sims[1].GUID);
                    PacketWriter.Write(Sims[1].Timestamp);
                    PacketWriter.Write(Sims[1].Name);
                    PacketWriter.Write(Sims[1].Sex);

                    PacketWriter.Flush();
                }
                else if (AsyncObject.NumCharacters == 3)
                {
                    PacketWriter.Write(Sims[0].CharacterID);
                    PacketWriter.Write(Sims[0].GUID);
                    PacketWriter.Write(Sims[0].Timestamp);
                    PacketWriter.Write(Sims[0].Name);
                    PacketWriter.Write(Sims[0].Sex);

                    PacketWriter.Write(Sims[1].CharacterID);
                    PacketWriter.Write(Sims[1].GUID);
                    PacketWriter.Write(Sims[1].Timestamp);
                    PacketWriter.Write(Sims[1].Name);
                    PacketWriter.Write(Sims[1].Sex);

                    PacketWriter.Write(Sims[2].CharacterID);
                    PacketWriter.Write(Sims[2].GUID);
                    PacketWriter.Write(Sims[2].Timestamp);
                    PacketWriter.Write(Sims[2].Name);
                    PacketWriter.Write(Sims[2].Sex);

                    PacketWriter.Flush();
                }

                Packet.WriteByte((byte)AsyncObject.NumCharacters);      //Total number of characters.
                Packet.Write(PacketData.ToArray(), 0, (int)PacketData.Length);

                AsyncObject.Client.SendEncrypted(0x05, Packet.ToArray());
            }
            else if (AsyncObject.CharacterTimestamp == DateTime.Parse(Sims[0].Timestamp))
            {
                PacketWriter.Write((byte)0x00); //0 characters.

                AsyncObject.Client.SendEncrypted(0x05, Packet.ToArray());
            }

            PacketWriter.Close();
        }
コード例 #43
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;
                }
            }
        }