예제 #1
0
        public async Task Message(IMessage message)
        {
            var response = new UnstructuredOutgoingPacket(PacketSendOperations.Message);

            response.Write(message);
            await Dispatch(response);
        }
예제 #2
0
        public Task Enter(IFieldObjUser user)
        {
            var items = Info.Items.Values
                        .OrderBy(i => i.ID)
                        .ToList();
            var packet = new UnstructuredOutgoingPacket(PacketSendOperations.OpenShopDlg);

            packet.WriteInt(TemplateID);
            packet.WriteShort((short)items.Count);

            items.ForEach(i =>
            {
                packet.WriteInt(i.TemplateID);
                packet.WriteInt(i.Price);
                packet.WriteByte(i.DiscountRate);
                packet.WriteInt(i.TokenTemplateID);
                packet.WriteInt(i.TokenPrice);
                packet.WriteInt(i.ItemPeriod);
                packet.WriteInt(i.LevelLimited);

                if (GameConstants.IsRechargeableItem(i.TemplateID))
                {
                    packet.WriteDouble(i.UnitPrice);
                }
                else
                {
                    packet.WriteShort((short)i.Quantity);
                }

                packet.WriteShort(i.MaxPerSlot);
            });

            return(user.Dispatch(packet));
        }
예제 #3
0
        public override IPacket GetLeaveFieldPacket()
        {
            var packet = new UnstructuredOutgoingPacket(PacketSendOperations.NpcLeaveField);

            packet.WriteInt(ID);
            return(packet);
        }
예제 #4
0
        public async Task ModifyStats(Action <IModifyStatContext> action = null, bool exclRequest = false)
        {
            var context = new ModifyStatContext(Character);

            action?.Invoke(context);
            await UpdateStats();

            if (!IsInstantiated)
            {
                return;
            }

            var statPacket = new UnstructuredOutgoingPacket(PacketSendOperations.StatChanged);

            statPacket.WriteBool(exclRequest);
            statPacket.Write(context);
            statPacket.WriteBool(false);
            statPacket.WriteBool(false);

            await Dispatch(statPacket);

            if (Party != null && (context.Flag.HasFlag(ModifyStatType.Job) || context.Flag.HasFlag(ModifyStatType.Level)))
            {
                _ = GameStage.PartyService.UpdateChangeLevelOrJob(new PartyUpdateChangeLevelOrJobRequest
                {
                    Character = ID,
                    Level     = context.Level,
                    Job       = context.Job
                });
            }
        }
예제 #5
0
        public async Task <PartyUpdateUserMigrationResponse> UpdateUserMigration(PartyUpdateUserMigrationRequest request)
        {
            var source = new CancellationTokenSource();

            source.CancelAfter(PartyLockTimeoutDuration);

            var @lock = await _locker.AcquireAsync(PartyLockKey, cancellationToken : source.Token);

            if (@lock != null)
            {
                var result = PartyServiceResult.Ok;
                var party  = await _repository.RetrieveByMember(request.Character);

                var member = party?.Members?.FirstOrDefault(m => m.ID == request.Character);

                if (party == null || member == null)
                {
                    result = PartyServiceResult.FailedNotInParty;
                }

                if (result == PartyServiceResult.Ok)
                {
                    member.Channel = request.Channel;
                    member.Field   = request.Field;

                    await _repository.Update(party);

                    await Task.WhenAll(party.Members.Select(async m =>
                    {
                        var packet = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult);

                        packet.WriteByte((byte)PartyResultCode.UserMigration);
                        packet.WriteInt(party.ID);
                        packet.WritePartyData(party, m.Channel);

                        var dispatchRequest = new DispatchToCharactersRequest {
                            Data = ByteString.CopyFrom(packet.Buffer)
                        };

                        dispatchRequest.Characters.Add(m.ID);

                        await _dispatcher.DispatchToCharacters(dispatchRequest);
                    }));

                    await _messenger.PublishAsync(new PartyUpdateEvent { Party = party });
                }

                await @lock.ReleaseAsync();

                return(new PartyUpdateUserMigrationResponse {
                    Result = result
                });
            }

            return(new PartyUpdateUserMigrationResponse {
                Result = PartyServiceResult.FailedTimeout
            });
        }
예제 #6
0
        public async Task <PartyChangeBossResponse> ChangeBoss(PartyChangeBossRequest request)
        {
            var source = new CancellationTokenSource();

            source.CancelAfter(PartyLockTimeoutDuration);

            var @lock = await _locker.AcquireAsync(PartyLockKey, cancellationToken : source.Token);

            if (@lock != null)
            {
                var result = PartyServiceResult.Ok;
                var party  = await _repository.RetrieveByMember(request.Character);

                if (party == null)
                {
                    result = PartyServiceResult.FailedNotInParty;
                }
                else if (party.Boss == request.Character)
                {
                    result = PartyServiceResult.FailedAlreadyBoss;
                }

                if (result == PartyServiceResult.Ok)
                {
                    var targets = party.Members.Select(m => m.ID).ToImmutableList();
                    var packet  = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult);

                    party.Boss = request.Character;

                    await _repository.Update(party);

                    packet.WriteByte((byte)PartyResultCode.ChangePartyBoss_Done);
                    packet.WriteInt(request.Character);
                    packet.WriteBool(request.IsDisconnect);

                    var dispatchRequest = new DispatchToCharactersRequest {
                        Data = ByteString.CopyFrom(packet.Buffer)
                    };

                    dispatchRequest.Characters.Add(targets);

                    await _dispatcher.DispatchToCharacters(dispatchRequest);

                    await _messenger.PublishAsync(new PartyUpdateEvent { Party = party });
                }

                await @lock.ReleaseAsync();

                return(new PartyChangeBossResponse {
                    Result = result
                });
            }

            return(new PartyChangeBossResponse {
                Result = PartyServiceResult.FailedTimeout
            });
        }
예제 #7
0
        public override IPacket GetEnterFieldPacket()
        {
            var packet = new UnstructuredOutgoingPacket(PacketSendOperations.UserEnterField);

            packet.WriteInt(ID);

            packet.WriteByte(Character.Level);
            packet.WriteString(Character.Name);

            packet.WriteString(Guild?.Name ?? "");
            packet.WriteShort(Guild?.MarkBg ?? 0);
            packet.WriteByte(Guild?.MarkBgColor ?? 0);
            packet.WriteShort(Guild?.Mark ?? 0);
            packet.WriteByte(Guild?.MarkColor ?? 0);

            packet.WriteSecondaryStatsToRemote(SecondaryStats);

            packet.WriteShort(Character.Job);
            packet.WriteCharacterLook(Character);

            packet.WriteInt(0);
            packet.WriteInt(0);
            packet.WriteInt(0);
            packet.WriteInt(0);
            packet.WriteInt(0);
            packet.WriteInt(0);

            packet.WritePoint2D(Position);
            packet.WriteByte((byte)Action);
            packet.WriteShort((short)(Foothold?.ID ?? 0));
            packet.WriteByte(0);

            packet.WriteBool(false);
            packet.WriteBool(false);
            packet.WriteBool(false);

            packet.WriteBool(false);

            packet.WriteInt(0);
            packet.WriteInt(0);
            packet.WriteInt(0);

            packet.WriteByte(0);

            packet.WriteBool(false);

            packet.WriteBool(false);
            packet.WriteBool(false);
            packet.WriteBool(false);

            packet.WriteByte(0);

            packet.WriteByte(0);
            packet.WriteInt(0);

            return(packet);
        }
예제 #8
0
        public override async Task Handle(LoginStageUser user, IPacketReader packet)
        {
            var response = new UnstructuredOutgoingPacket(PacketSendOperations.CheckPinCodeResult);

            response.WriteByte((byte)LoginResultCode.Success);

            user.State = LoginState.SelectWorld;

            await user.Dispatch(response);
        }
예제 #9
0
        public override async Task Handle(LoginStageUser user, IPacketReader packet)
        {
            var worldTemplates = (await Task.WhenAll(user.Stage.Info.Worlds
                                                     .Select(w => user.Stage.WorldTemplates.Retrieve(w))))
                                 .Where(w => w != null)
                                 .OrderBy(w => w.ID)
                                 .ToList();

            foreach (var world in worldTemplates)
            {
                var response = new UnstructuredOutgoingPacket(PacketSendOperations.WorldInformation);

                response.WriteByte((byte)world.ID);
                response.WriteString(world.Name);
                response.WriteByte(world.State);
                response.WriteString(""); // WorldEventDesc
                response.WriteShort(0);   // WorldEventEXP_WSE, WorldSpecificEvent
                response.WriteShort(0);   // WorldEventDrop_WSE, WorldSpecificEvent
                response.WriteBool(world.BlockCharCreation);

                var channelServerRequest = new DescribeServerByMetadataRequest();

                channelServerRequest.Metadata.Add("Type", Enum.GetName(ServerStageType.Game));
                channelServerRequest.Metadata.Add("WorldID", world.ID.ToString());

                var channelServers = (await user.Stage.ServerRegistry.DescribeByMetadata(channelServerRequest)).Servers
                                     .OrderBy(c => c.Id)
                                     .ToList();

                response.WriteByte((byte)channelServers.Count);

                foreach (var channel in channelServers)
                {
                    response.WriteString(channel.Metadata["ID"]);
                    response.WriteInt(0); // TODO: UserNo
                    response.WriteByte(Convert.ToByte(channel.Metadata["WorldID"]));
                    response.WriteByte(Convert.ToByte(channel.Metadata["ChannelID"]));
                    response.WriteBool(false); // TODO: AdultChannel
                }

                response.WriteShort(0); // TODO: Balloon
                await user.Dispatch(response);
            }

            await user.Dispatch(
                new UnstructuredOutgoingPacket(PacketSendOperations.WorldInformation)
                .WriteByte(0xFF)
                );

            await user.Dispatch(
                new UnstructuredOutgoingPacket(PacketSendOperations.LatestConnectedWorld)
                .WriteInt(user.Account.LatestConnectedWorld ?? 0)
                );
        }
예제 #10
0
        public override async Task Handle(LoginStageUser user, IPacketReader packet)
        {
            _ = packet.ReadByte(); // WorldID
            _ = packet.ReadByte(); // Unknown1

            var response = new UnstructuredOutgoingPacket(PacketSendOperations.CheckUserLimitResult);

            response.WriteByte(0); // TODO: bWarningLevel
            response.WriteByte(0); // TODO: bPopulateLevel

            await user.Dispatch(response);
        }
예제 #11
0
        protected override IPacket GetChangeControllerPacket(bool setAsController)
        {
            var packet = new UnstructuredOutgoingPacket(PacketSendOperations.NpcChangeController);

            packet.WriteBool(setAsController);
            packet.WriteInt(ID);

            if (setAsController)
            {
                WriteData(packet);
            }
            return(packet);
        }
예제 #12
0
        protected virtual IPacket GetMigratePacket(byte[] address, short port)
        {
            var packet = new UnstructuredOutgoingPacket(PacketSendOperations.MigrateCommand);

            packet.WriteBool(true);

            foreach (var b in address)
            {
                packet.WriteByte(b);
            }
            packet.WriteShort(port);
            return(packet);
        }
        protected override async Task Handle(GameStageUser stageUser, IFieldObjUser user, IPacketReader packet)
        {
            _ = packet.ReadInt();
            var type     = (ItemInventoryType)packet.ReadByte();
            var response = new UnstructuredOutgoingPacket(PacketSendOperations.GatherItemResult);

            response.WriteBool(false);
            response.WriteByte((byte)type);

            await user.ModifyInventory(i => i[type].Gather(), true);

            await user.Dispatch(response);
        }
예제 #14
0
        public override async Task Handle(LoginStageUser user, IPacketReader packet)
        {
            var name = packet.ReadString();

            var result = await user.Stage.CharacterRepository.CheckExistsByName(name);

            var response = new UnstructuredOutgoingPacket(PacketSendOperations.CheckDuplicatedIDResult);

            response.WriteString(name);
            response.WriteBool(result);

            await user.Dispatch(response);
        }
예제 #15
0
        protected override async Task Handle(GameStageUser stageUser, IFieldObjUser user, IPacketReader packet)
        {
            _ = packet.ReadInt();

            var type = (GroupMessageType)packet.ReadByte();

            var recipientCount = packet.ReadByte();
            var recipients     = new int[recipientCount];

            for (var i = 0; i < recipientCount; i++)
            {
                recipients[i] = packet.ReadInt();
            }

            var text = packet.ReadString();

            switch (type)
            {
            case GroupMessageType.Party:
            {
                if (user.Party == null)
                {
                    return;
                }

                var partyChat = new UnstructuredOutgoingPacket(PacketSendOperations.GroupMessage);

                partyChat.WriteByte((byte)GroupMessageType.Party);
                partyChat.WriteString(user.Character.Name);
                partyChat.WriteString(text);

                var dispatchRequest = new DispatchToCharactersRequest {
                    Data = ByteString.CopyFrom(partyChat.Buffer)
                };

                dispatchRequest.Characters.Add(user.Party.Members
                                               .Select(m => m.ID)
                                               .Where(m => m != user.ID)
                                               );

                await stageUser.Stage.DispatchService.DispatchToCharacters(dispatchRequest);

                break;
            }

            default:
                stageUser.Stage.Logger.LogWarning($"Unhandled group message type: {type}");
                break;
            }
        }
예제 #16
0
        public async Task ModifySkills(Action <IModifySkillContext> action = null, bool exclRequest = false)
        {
            var context = new ModifySkillContext(Character);

            action?.Invoke(context);
            await UpdateStats();

            var skillPacket = new UnstructuredOutgoingPacket(PacketSendOperations.ChangeSkillRecordResult);

            skillPacket.WriteBool(exclRequest);
            skillPacket.Write(context);
            skillPacket.WriteBool(true);

            await Dispatch(skillPacket);
        }
예제 #17
0
        public async Task UpdateAvatar()
        {
            var avatarPacket = new UnstructuredOutgoingPacket(PacketSendOperations.UserAvatarModified);

            avatarPacket.WriteInt(ID);
            avatarPacket.WriteByte(0x1); // Flag
            avatarPacket.WriteCharacterLook(Character);

            avatarPacket.WriteBool(false);
            avatarPacket.WriteBool(false);
            avatarPacket.WriteBool(false);
            avatarPacket.WriteInt(0);

            await FieldSplit.Dispatch(this, avatarPacket);
        }
예제 #18
0
        public override async Task Enter(GameStageUser user)
        {
            await base.Enter(user);

            var field = await FieldRepository.Retrieve(user.Character.FieldID);

            var fieldUser = new FieldObjUser(user);

            var guildLoadResponse = await GuildService.LoadByCharacter(new GuildLoadByCharacterRequest { Character = user.Character.ID });

            var partyLoadResponse = await PartyService.LoadByCharacter(new PartyLoadByCharacterRequest { Character = user.Character.ID });

            if (guildLoadResponse.Guild != null)
            {
                fieldUser.Guild = new Guild(guildLoadResponse.Guild);
            }
            if (partyLoadResponse.Party != null)
            {
                fieldUser.Party = new Party(partyLoadResponse.Party);
            }

            user.FieldUser = fieldUser;

            await field.Enter(fieldUser);

            var functionKeyPacket  = new UnstructuredOutgoingPacket(PacketSendOperations.FuncKeyMappedInit);
            var quickSlotKeyPacket = new UnstructuredOutgoingPacket(PacketSendOperations.QuickslotMappedInit);

            functionKeyPacket.WriteBool(false);

            for (var i = 0; i < 90; i++)
            {
                var key = user.Character.FunctionKeys[i];

                functionKeyPacket.WriteByte(key?.Type ?? 0);
                functionKeyPacket.WriteInt(key?.Action ?? 0);
            }

            quickSlotKeyPacket.WriteBool(false);

            for (var i = 0; i < 8; i++)
            {
                quickSlotKeyPacket.WriteInt(user.Character.QuickSlotKeys[i].Key);
            }

            _ = user.Dispatch(functionKeyPacket);
            _ = user.Dispatch(quickSlotKeyPacket);
        }
예제 #19
0
        protected override async Task Handle(GameStageUser stageUser, IFieldObjUser user, IPacketReader packet)
        {
            var contimove = await stageUser.Stage.ContiMoveRepository.RetrieveByField(user.Field);

            if (contimove == null)
            {
                return;
            }

            var response = new UnstructuredOutgoingPacket(PacketSendOperations.CONTISTATE);

            response.WriteByte((byte)contimove.State);
            response.WriteBool(contimove.State == ContiMoveState.Event);

            await user.Dispatch(response);
        }
예제 #20
0
        private async Task OnDispatch(DispatchContract contract)
        {
            var targets = GetUsers();
            var packet  = new UnstructuredOutgoingPacket();

            packet.WriteBytes(contract.Data.ToArray());

            if (contract.TargetCharacters.Count > 0)
            {
                targets = targets
                          .Where(u => contract.TargetCharacters.Contains(u.ID))
                          .ToList();
            }

            await Task.WhenAll(targets.Select(t => t.Dispatch(packet)));
        }
예제 #21
0
        protected override async Task Handle(GameStageUser stageUser, IFieldObjUser user, IPacketReader packet)
        {
            _ = packet.ReadInt();
            var targetID = packet.ReadInt();
            var target   = user.Watching
                           .SelectMany(w => w.GetObjects <IFieldObjUser>())
                           .Where(o => o.ID == targetID)
                           .FirstOrDefault();

            if (target == null)
            {
                return;
            }

            var response = new UnstructuredOutgoingPacket(PacketSendOperations.CharacterInfo);

            response.WriteInt(target.ID);
            response.WriteByte(target.Character.Level);
            response.WriteShort(target.Character.Job);
            response.WriteShort(target.Character.POP);

            response.WriteByte(0);

            response.WriteString(target?.Guild?.Name ?? "");
            response.WriteString("");  // sAlliance

            response.WriteByte(0);     // Medal?

            response.WriteBool(false); // Pets

            response.WriteByte(0);     // TamingMobInfo
            response.WriteByte(0);     // Wishlist

            response.WriteInt(0);      // MedalAchievementInfo
            response.WriteShort(0);

            var chairs = target.Character.Inventories[ItemInventoryType.Install].Items
                         .Select(kv => kv.Value)
                         .Select(i => i.TemplateID)
                         .Where(i => i / 10000 == 301)
                         .ToList();

            response.WriteInt(chairs.Count);
            chairs.ForEach(i => response.WriteInt(i));

            await user.Dispatch(response);
        }
예제 #22
0
        protected override async Task Handle(GameStageUser stageUser, IFieldObjUser user, IPacketReader packet)
        {
            var emotion      = packet.ReadInt();
            var duration     = packet.ReadInt();
            var byItemOption = packet.ReadBool();

            // TODO item option check

            var response = new UnstructuredOutgoingPacket(PacketSendOperations.UserEmotion);

            response.WriteInt(user.ID);
            response.WriteInt(emotion);
            response.WriteInt(duration);
            response.WriteBool(byItemOption);

            await user.FieldSplit.Dispatch(user, response);
        }
예제 #23
0
        public async Task ModifyForcedStats(Action <IModifyForcedStatContext> action = null, bool exclRequest = false)
        {
            var context = new ModifyForcedStatContext(ForcedStats as ForcedStats);

            action?.Invoke(context);
            await UpdateStats();

            var statPacket = new UnstructuredOutgoingPacket(context.Flag > 0
                ? PacketSendOperations.ForcedStatSet
                : PacketSendOperations.ForcedStatReset);

            if (context.Flag > 0)
            {
                statPacket.Write(context);
            }

            await Dispatch(statPacket);
        }
예제 #24
0
        public override async Task Handle(LoginStageUser user, IPacketReader packet)
        {
            var spw         = packet.ReadString();
            var characterID = packet.ReadInt();

            var result    = LoginResultCode.Success;
            var response  = new UnstructuredOutgoingPacket(PacketSendOperations.DeleteCharacterResult);
            var character = await user.Stage.CharacterRepository.Retrieve(characterID);

            if (!BCrypt.Net.BCrypt.EnhancedVerify(spw, user.Account.SPW))
            {
                result = LoginResultCode.IncorrectSPW;
            }
            if (character == null || character.AccountWorldID != user.AccountWorld.ID)
            {
                result = LoginResultCode.DBFail;
            }

            var guild = (await user.Stage.GuildService.LoadByCharacter(new GuildLoadByCharacterRequest {
                Character = characterID
            })).Guild;
            var party = (await user.Stage.PartyService.LoadByCharacter(new PartyLoadByCharacterRequest {
                Character = characterID
            })).Party;

            if (result == LoginResultCode.Success)
            {
                // TODO: guild withdraw if not master

                if (party != null)
                {
                    _ = user.Stage.PartyService.Withdraw(new PartyWithdrawRequest {
                        Character = characterID
                    });
                }

                await user.Stage.CharacterRepository.Delete(characterID);
            }

            response.WriteInt(characterID);
            response.WriteByte((byte)result);

            await user.Dispatch(response);
        }
예제 #25
0
        protected override IPacket GetMigratePacket(byte[] address, short port)
        {
            var packet = new UnstructuredOutgoingPacket(PacketSendOperations.SelectCharacterResult);

            packet.WriteByte(0);
            packet.WriteByte(0);

            foreach (var b in address)
            {
                packet.WriteByte(b);
            }
            packet.WriteShort(port);

            packet.WriteInt(Character.ID);
            packet.WriteByte(0);
            packet.WriteInt(0);

            return(packet);
        }
예제 #26
0
        public async Task ModifySecondaryStats(Action <IModifySecondaryStatContext> action = null, bool exclRequest = false)
        {
            var context = new ModifySecondaryStatContext(SecondaryStats as SecondaryStats);

            action?.Invoke(context);
            await UpdateStats();

            if (context.ResetHistory.ToDictionary().Any())
            {
                var resetLocalPacket  = new UnstructuredOutgoingPacket(PacketSendOperations.TemporaryStatReset);
                var resetRemotePacket = new UnstructuredOutgoingPacket(PacketSendOperations.UserTemporaryStatReset);

                resetLocalPacket.WriteSecondaryStatsFlag(context.ResetHistory);
                resetLocalPacket.WriteBool(false); // IsMovementAffectingStat

                resetRemotePacket.WriteInt(ID);
                resetRemotePacket.WriteSecondaryStatsFlag(context.ResetHistory);

                await Dispatch(resetLocalPacket);

                await FieldSplit.Dispatch(resetRemotePacket);
            }

            if (context.SetHistory.ToDictionary().Any())
            {
                var setLocalPacket  = new UnstructuredOutgoingPacket(PacketSendOperations.TemporaryStatSet);
                var setRemotePacket = new UnstructuredOutgoingPacket(PacketSendOperations.UserTemporaryStatSet);

                setLocalPacket.WriteSecondaryStatsToLocal(context.SetHistory);
                setLocalPacket.WriteShort(0);    // tDelay
                setLocalPacket.WriteBool(false); // IsMovementAffectingStat

                setRemotePacket.WriteInt(ID);
                setRemotePacket.WriteSecondaryStatsToLocal(context.SetHistory);
                setRemotePacket.WriteShort(0); // tDelay

                await Dispatch(setLocalPacket);

                await FieldSplit.Dispatch(setRemotePacket);
            }
        }
예제 #27
0
        public override async Task Handle(LoginStageUser user, IPacketReader packet)
        {
            var cancel = !packet.ReadBool();

            if (cancel)
            {
                await user.Disconnect();

                return;
            }

            var gender   = (byte)(packet.ReadBool() ? 1 : 0);
            var response = new UnstructuredOutgoingPacket(PacketSendOperations.SetAccountResult);

            user.Account.Gender = gender;

            response.WriteByte(gender);
            response.WriteBool(!cancel);

            await user.Dispatch(response);
        }
예제 #28
0
        public IPacket GetSetFieldPacket()
        {
            var packet = new UnstructuredOutgoingPacket(PacketSendOperations.SetField);

            packet.WriteShort(0); // ClientOpt

            packet.WriteInt(GameStage.ChannelID);
            packet.WriteInt(GameStage.WorldID);

            packet.WriteBool(true); // sNotifierMessage._m_pStr
            packet.WriteBool(!IsInstantiated);
            packet.WriteShort(0);   // nNotifierCheck, loops

            if (!IsInstantiated)
            {
                packet.WriteUInt(Damage.InitSeed1);
                packet.WriteUInt(Damage.InitSeed2);
                packet.WriteUInt(Damage.InitSeed3);

                packet.WriteCharacterData(Character);

                packet.WriteInt(0);
                for (var i = 0; i < 3; i++)
                {
                    packet.WriteInt(0);
                }
            }
            else
            {
                packet.WriteByte(0);
                packet.WriteInt(Character.FieldID);
                packet.WriteByte(Character.FieldPortal);
                packet.WriteInt(Character.HP);
                packet.WriteBool(false);
            }

            packet.WriteDateTime(DateTime.Now);

            return(packet);
        }
예제 #29
0
        protected override async Task Handle(GameStageUser stageUser, IFieldObjUser user, IPacketReader packet)
        {
            _ = packet.ReadInt();
            var message     = packet.ReadString();
            var onlyBalloon = packet.ReadBool();

            if (message.StartsWith("!") || message.StartsWith("@")) // TODO: config?
            {
                await stageUser.Stage.CommandProcessor.Process(user, message.Substring(1));

                return;
            }

            var chatPacket1 = new UnstructuredOutgoingPacket(PacketSendOperations.UserChat);

            chatPacket1.WriteInt(user.ID);
            chatPacket1.WriteBool(user.Account.GradeCode > 0 || user.Account.SubGradeCode > 0); // TODO: proper gm chat checks
            chatPacket1.WriteString(message);
            chatPacket1.WriteBool(onlyBalloon);

            await user.FieldSplit.Dispatch(chatPacket1);

            if (onlyBalloon)
            {
                return;
            }

            var chatPacket2 = new UnstructuredOutgoingPacket(PacketSendOperations.UserChatNLCPQ);

            chatPacket2.WriteInt(user.ID);
            chatPacket2.WriteBool(user.Account.GradeCode > 0 || user.Account.SubGradeCode > 0); // TODO: proper gm chat checks
            chatPacket2.WriteString(message);
            chatPacket2.WriteBool(onlyBalloon);
            chatPacket2.WriteString(user.Character.Name);

            await Task.WhenAll(user.Field
                               .GetUsers()
                               .Except(user.FieldSplit.GetWatchers())
                               .Select(u => u.Dispatch(chatPacket2)));
        }
예제 #30
0
        public async Task ModifyInventory(Action <IModifyMultiInventoryContext> action = null, bool exclRequest = false)
        {
            var context = new ModifyMultiInventoryContext(Character.Inventories, GameStage.ItemTemplates);

            action?.Invoke(context);

            var inventoryPacket = new UnstructuredOutgoingPacket(PacketSendOperations.InventoryOperation);

            inventoryPacket.WriteBool(exclRequest);
            inventoryPacket.Write(context);
            inventoryPacket.WriteBool(false);

            await Dispatch(inventoryPacket);

            if (
                context.History.Any(o => o.Slot < 0) ||
                context.History.OfType <MoveModifyInventoryOperation>().Any(o => o.ToSlot < 0)
                )
            {
                await UpdateStats();
                await UpdateAvatar();
            }
        }