public static void HandleCharacterCreate(NetworkClient Client, ProcessedPacket P) { Logger.LogDebug("Received CharacterCreate!"); bool ClientAuthenticated = false; byte AccountStrLength = (byte)P.ReadByte(); byte[] AccountNameBuf = new byte[AccountStrLength]; P.Read(AccountNameBuf, 0, AccountStrLength); string AccountName = Encoding.ASCII.GetString(AccountNameBuf); using (var db = DataAccess.Get()) { var account = db.Accounts.GetByUsername(AccountName); byte KeyLength = (byte)P.ReadByte(); byte[] EncKey = new byte[KeyLength]; P.Read(EncKey, 0, KeyLength); Client.ClientEncryptor = new ARC4Encryptor(account.Password, EncKey); Client.ClientEncryptor.Username = AccountName; string Token = P.ReadString(); string GUID = ""; foreach (ClientToken CToken in NetworkFacade.TransferringClients.GetList()) { if (CToken.ClientIP == Client.RemoteIP) { if (CToken.Token == Token) { PacketStream SuccessPacket = new PacketStream(0x64, (int)(PacketHeaders.ENCRYPTED + 1)); SuccessPacket.WriteByte((byte)TSODataModel.Entities.CharacterCreationStatus.Success); Client.SendEncrypted(0x64, SuccessPacket.ToArray()); ClientAuthenticated = true; GUID = CToken.CharacterGUID; } break; } } SimBase Char = new SimBase(new Guid(GUID)); Char.Timestamp = P.ReadPascalString(); Char.Name = P.ReadPascalString(); Char.Sex = P.ReadPascalString(); Char.Description = P.ReadPascalString(); Char.HeadOutfitID = P.ReadUInt64(); Char.BodyOutfitID = P.ReadUInt64(); Char.Appearance = (AppearanceType)P.ReadByte(); Char.CityID = new Guid(P.ReadString()); Char.CreatedThisSession = true; var characterModel = new Character(); characterModel.Name = Char.Name; characterModel.Sex = Char.Sex; characterModel.Description = Char.Description; characterModel.LastCached = Char.Timestamp; characterModel.GUID = Char.GUID; characterModel.HeadOutfitID = (long)Char.HeadOutfitID; characterModel.BodyOutfitID = (long)Char.BodyOutfitID; characterModel.AccountID = account.AccountID; characterModel.AppearanceType = (int)Char.Appearance; characterModel.City = Char.CityID.ToString(); var status = db.Characters.CreateCharacter(characterModel); } //Invalid token, should never occur... if (!ClientAuthenticated) { PacketStream SuccessPacket = new PacketStream(0x65, (int)(PacketHeaders.ENCRYPTED + 1)); SuccessPacket.WriteByte((byte)TSODataModel.Entities.CharacterCreationStatus.GeneralError); Client.SendEncrypted(0x64, SuccessPacket.ToArray()); Client.Disconnect(); } }
public static void HandleCharacterCreate(NetworkClient Client, ProcessedPacket P) { Logger.LogInfo("Received CharacterCreate!"); string AccountName = SanitizeAccount(P.ReadPascalString()); using (var db = DataAccess.Get()) { Account Acc = db.Accounts.GetByUsername(AccountName); //TODO: Send GUID to client... SimBase Char = new SimBase(Guid.NewGuid()); Char.Timestamp = P.ReadPascalString(); Char.Name = P.ReadPascalString(); Char.Sex = P.ReadPascalString(); Char.Description = P.ReadPascalString(); Char.HeadOutfitID = P.ReadUInt64(); Char.BodyOutfitID = P.ReadUInt64(); Char.Appearance = (AppearanceType)P.ReadByte(); Char.ResidingCity = new CityInfo(P.ReadPascalString(), "", P.ReadUInt64(), P.ReadPascalString(), P.ReadUInt64(), P.ReadPascalString(), P.ReadInt32()); Char.CreatedThisSession = true; var characterModel = new Character(); characterModel.Name = Char.Name; characterModel.Sex = Char.Sex; characterModel.Description = Char.Description; characterModel.LastCached = Char.Timestamp; characterModel.GUID = Char.GUID; characterModel.HeadOutfitID = (long)Char.HeadOutfitID; characterModel.BodyOutfitID = (long)Char.BodyOutfitID; characterModel.AccountID = Acc.AccountID; characterModel.AppearanceType = (int)Char.Appearance; characterModel.City = Char.ResidingCity.UUID; characterModel.CityName = Char.ResidingCity.Name; characterModel.CityThumb = (long)Char.ResidingCity.Thumbnail; characterModel.CityMap = (long)Char.ResidingCity.Map; characterModel.CityIp = Char.ResidingCity.IP; characterModel.CityPort = Char.ResidingCity.Port; var status = db.Characters.CreateCharacter(characterModel); //Need to be variable length, because the success packet contains a token. PacketStream CCStatusPacket = new PacketStream((byte)PacketType.CHARACTER_CREATION_STATUS, 0); switch (status) { case LoginDataModel.Entities.CharacterCreationStatus.NameAlreadyExisted: CCStatusPacket.WriteByte((int)LoginDataModel.Entities.CharacterCreationStatus.NameAlreadyExisted); Client.SendEncrypted(CCStatusPacket.PacketID, CCStatusPacket.ToArray()); break; case LoginDataModel.Entities.CharacterCreationStatus.ExceededCharacterLimit: CCStatusPacket.WriteByte((int)LoginDataModel.Entities.CharacterCreationStatus.ExceededCharacterLimit); Client.SendEncrypted(CCStatusPacket.PacketID, CCStatusPacket.ToArray()); break; case LoginDataModel.Entities.CharacterCreationStatus.Success: CCStatusPacket.WriteByte((int)LoginDataModel.Entities.CharacterCreationStatus.Success); CCStatusPacket.WritePascalString(Char.GUID.ToString()); Guid Token = Guid.NewGuid(); CCStatusPacket.WritePascalString(Token.ToString()); Client.SendEncrypted(CCStatusPacket.PacketID, CCStatusPacket.ToArray()); foreach (CityServerClient CServer in NetworkFacade.CServerListener.CityServers) { if (CServer.ServerInfo.UUID == Char.ResidingCity.UUID) { PacketStream CServerPacket = new PacketStream(0x01, 0); CServerPacket.WriteHeader(); ushort PacketLength = (ushort)(PacketHeaders.UNENCRYPTED + 4 + (Client.RemoteIP.Length + 1) + (Char.GUID.ToString().Length + 1) + (Token.ToString().Length + 1)); CServerPacket.WriteUInt16(PacketLength); CServerPacket.WriteInt32(Acc.AccountID); CServerPacket.WritePascalString(Client.RemoteIP); CServerPacket.WritePascalString(Char.GUID.ToString()); CServerPacket.WritePascalString(Token.ToString()); CServer.Send(CServerPacket.ToArray()); break; } } break; } } //Client was modified, so update it. NetworkFacade.ClientListener.UpdateClient(Client); }