示例#1
0
        public override async Task Handle(LoginStageUser user, IPacketReader packet)
        {
            _ = packet.ReadByte(); // Unknown1

            var worldID   = packet.ReadByte();
            var channelID = packet.ReadByte();

            var result   = LoginResultCode.Success;
            var response = new UnstructuredOutgoingPacket(PacketSendOperations.SelectWorldResult);

            var gameServerRequest = new DescribeServerByMetadataRequest();

            gameServerRequest.Metadata.Add("Type", Enum.GetName(ServerStageType.Game));
            gameServerRequest.Metadata.Add("WorldID", worldID.ToString());

            var gameServers = (await user.Stage.ServerRegistry.DescribeByMetadata(gameServerRequest)).Servers
                              .OrderBy(g => g.Metadata["ChannelID"])
                              .ToList();

            if (channelID > gameServers.Count)
            {
                result = LoginResultCode.NotConnectableWorld;
            }

            response.WriteByte((byte)result);

            if (result == LoginResultCode.Success)
            {
                var gameServer   = gameServers[channelID];
                var accountWorld = await user.Stage.AccountWorldRepository.RetrieveByAccountAndWorld(user.Account.ID, worldID);

                if (accountWorld == null)
                {
                    accountWorld = new AccountWorld
                    {
                        AccountID = user.Account.ID,
                        WorldID   = worldID
                    };

                    await user.Stage.AccountWorldRepository.Insert(accountWorld);
                }

                user.State             = LoginState.SelectCharacter;
                user.AccountWorld      = accountWorld;
                user.SelectedWorldID   = Convert.ToByte(gameServer.Metadata["WorldID"]);
                user.SelectedChannelID = Convert.ToByte(gameServer.Metadata["ChannelID"]);

                var characters = (await user.Stage.CharacterRepository.RetrieveAllByAccountWorld(accountWorld.ID)).ToList();

                response.WriteByte((byte)characters.Count);
                characters.ForEach(c =>
                {
                    response.WriteCharacterStats(c);
                    response.WriteCharacterLook(c);

                    response.WriteBool(false);
                    response.WriteBool(false);
                });

                response.WriteBool(!string.IsNullOrEmpty(user.Account.SPW)); // bLoginOpt TODO: proper bLoginOpt stuff
                response.WriteInt(accountWorld.SlotCount);
                response.WriteInt(0);
            }

            await user.Dispatch(response);
        }
        public override async Task Handle(LoginStageUser user, IPacketReader packet)
        {
            var name      = packet.ReadString();
            var race      = packet.ReadInt();
            var subJob    = packet.ReadShort();
            var face      = packet.ReadInt();
            var hair      = packet.ReadInt();
            var hairColor = packet.ReadInt();
            var skin      = packet.ReadInt();
            var coat      = packet.ReadInt();
            var pants     = packet.ReadInt();
            var shoes     = packet.ReadInt();
            var weapon    = packet.ReadInt();
            var gender    = packet.ReadByte();

            var result   = LoginResultCode.Success;
            var response = new UnstructuredOutgoingPacket(PacketSendOperations.CreateNewCharacterResult);

            var world = await user.Stage.WorldTemplates.Retrieve((int)user.SelectedWorldID);

            if (world.BlockCharCreation)
            {
                result = LoginResultCode.NotConnectableWorld;
            }

            var serverRequest = new DescribeServerByMetadataRequest();

            serverRequest.Metadata.Add("Type", Enum.GetName(ServerStageType.Game));
            serverRequest.Metadata.Add("WorldID", user.SelectedWorldID.ToString());
            serverRequest.Metadata.Add("ChannelID", user.SelectedChannelID.ToString());

            var server = (await user.Stage.ServerRegistry.DescribeByMetadata(serverRequest)).Servers.FirstOrDefault();

            if (server == null)
            {
                result = LoginResultCode.NotConnectableWorld;
            }

            response.WriteByte((byte)result);

            if (result == LoginResultCode.Success)
            {
                var character = new Character
                {
                    AccountWorldID = user.AccountWorld.ID,
                    Name           = name,
                    Job            = 0, // TODO: race -> job
                    Face           = face,
                    Hair           = hair + hairColor,
                    Skin           = (byte)skin,
                    Gender         = gender,
                    FieldID        = 310000000, // TODO: start maps
                    FieldPortal    = 0,
                    SubJob         = 0          // TODO: race -> subjob
                };
                var context = new ModifyMultiInventoryContext(character.Inventories, user.Stage.ItemTemplates);

                context.Set(BodyPart.Clothes, coat);
                context.Set(BodyPart.Shoes, shoes);
                context.Set(BodyPart.Weapon, weapon);
                if (pants > 0)
                {
                    context.Set(BodyPart.Pants, pants);
                }

                await user.Stage.CharacterRepository.Insert(character);

                user.Character = character;
                user.Stage.Logger.LogDebug($"Created new {race} character: {name} (ID: {character.ID})");

                response.WriteCharacterStats(character);
                response.WriteCharacterLook(character);
                response.WriteBool(false);
                response.WriteBool(false);
            }
            else
            {
                response.WriteInt(0);
            }

            await user.Dispatch(response);
        }