public async Task Message(IMessage message) { var response = new UnstructuredOutgoingPacket(PacketSendOperations.Message); response.Write(message); await Dispatch(response); }
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)); }
public override IPacket GetLeaveFieldPacket() { var packet = new UnstructuredOutgoingPacket(PacketSendOperations.NpcLeaveField); packet.WriteInt(ID); return(packet); }
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 }); } }
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 }); }
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 }); }
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); }
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); }
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) ); }
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); }
protected override IPacket GetChangeControllerPacket(bool setAsController) { var packet = new UnstructuredOutgoingPacket(PacketSendOperations.NpcChangeController); packet.WriteBool(setAsController); packet.WriteInt(ID); if (setAsController) { WriteData(packet); } return(packet); }
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); }
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); }
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; } }
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); }
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); }
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); }
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); }
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))); }
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); }
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); }
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); }
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); }
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); }
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); } }
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); }
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); }
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))); }
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(); } }