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 }); }
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 <DispatchToCharactersResponse> DispatchToCharacters(DispatchToCharactersRequest request) { var @event = new DispatchEvent { Data = request.Data.ToArray() }; foreach (var character in request.Characters) { @event.TargetCharacters.Add(character); } await _messenger.PublishAsync(@event); return(new DispatchToCharactersResponse { Result = DispatchServiceResult.Ok }); }
protected override async Task Handle(GameStageUser stageUser, IFieldObjUser user, IPacketReader packet) { var stage = stageUser.Stage; var flag = (WhisperFlags)packet.ReadByte(); switch (flag) { case WhisperFlags.Whisper | WhisperFlags.Request: { _ = packet.ReadInt(); var name = packet.ReadString(); var text = packet.ReadString(); if (name.Equals(user.Character.Name, StringComparison.CurrentCultureIgnoreCase)) { return; } var allowed = false; var target = await stage.CharacterRepository.RetrieveByName(name); var response = new UnstructuredOutgoingPacket(PacketSendOperations.Whisper); if (target != null) { var sessionRequest = new DescribeSessionByCharacterRequest { Character = target.ID }; var sessionResponse = await stage.SessionRegistry.DescribeByCharacter(sessionRequest); if (sessionResponse.Session.State == SessionState.LoggedIn) { allowed = true; } } response.WriteByte((byte)(WhisperFlags.Whisper | WhisperFlags.Result)); response.WriteString(allowed ? target.Name : name); response.WriteBool(allowed); if (allowed) { var whisper = new UnstructuredOutgoingPacket(PacketSendOperations.Whisper) .WriteByte((byte)(WhisperFlags.Whisper | WhisperFlags.Receive)) .WriteString(user.Character.Name) .WriteByte((byte)stage.ChannelID) .WriteBool(false) // bFromAdmin .WriteString(text); var whisperRequest = new DispatchToCharactersRequest { Data = ByteString.CopyFrom(whisper.Buffer) }; whisperRequest.Characters.Add(target.ID); await stage.DispatchService.DispatchToCharacters(whisperRequest); } await user.Dispatch(response); break; } default: stage.Logger.LogWarning($"Unhandled whisper flag: {flag}"); break; } }
protected override async Task Handle(GameStageUser stageUser, IFieldObjUser user, IPacketReader packet) { var stage = stageUser.Stage; var service = stage.PartyService; var type = (PartyResultCode)packet.ReadByte(); switch (type) { case PartyResultCode.InviteParty_Sent: case PartyResultCode.InviteParty_AlreadyInvited: case PartyResultCode.InviteParty_AlreadyInvitedByInviter: break; // Do nothing case PartyResultCode.InviteParty_Accepted: { var serviceRequest = new InviteClaimRequest { Type = InviteType.Party, Invited = user.ID }; var serviceResponse = await stage.InviteService.Claim(serviceRequest); if (serviceResponse.Result == InviteServiceResult.Ok) { var result = PartyResultCode.JoinParty_Done; var response = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult); var party = stage.GetUser(serviceResponse.Invite.Inviter)?.FieldUser?.Party?.ID; if (party == null) { result = PartyResultCode.JoinParty_UnknownUser; } else { var joinRequest = new PartyJoinRequest { Party = party.Value, Member = new PartyMemberContract { Id = user.ID, Name = user.Character.Name, Job = user.Character.Job, Level = user.Character.Level, Channel = stage.ChannelID, Field = user.Field.ID } }; var joinResponse = await service.Join(joinRequest); if (joinResponse.Result == PartyServiceResult.Ok) { return; } if (joinResponse.Result == PartyServiceResult.FailedAlreadyInParty) { result = PartyResultCode.JoinParty_AlreadyJoined; } if (joinResponse.Result == PartyServiceResult.FailedFullParty) { result = PartyResultCode.JoinParty_AlreadyFull; } } response.WriteByte((byte)result); await user.Dispatch(response); } break; } case PartyResultCode.InviteParty_Rejected: { if (user.Party != null) { return; } var serviceRequest = new InviteClaimRequest { Type = InviteType.Party, Invited = user.ID }; var serviceResponse = await stage.InviteService.Claim(serviceRequest); if (serviceResponse.Result == InviteServiceResult.Ok) { var inviter = serviceResponse.Invite.Inviter; var dispatch = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult) .WriteByte((byte)PartyResultCode.ServerMsg) .WriteBool(true) .WriteString($"'{user.Character.Name}' rejected the party invitation request."); var dispatchRequest = new DispatchToCharactersRequest { Data = ByteString.CopyFrom(dispatch.Buffer) }; dispatchRequest.Characters.Add(inviter); await stage.DispatchService.DispatchToCharacters(dispatchRequest); } break; } default: stage.Logger.LogWarning($"Unhandled party result type: {type}"); break; } }
protected override async Task Handle(GameStageUser stageUser, IFieldObjUser user, IPacketReader packet) { var stage = stageUser.Stage; var service = stage.PartyService; var type = (PartyRequestCode)packet.ReadByte(); switch (type) { case PartyRequestCode.CreateNewParty: { if (user.Party != null) { return; } var result = PartyResultCode.CreateNewParty_Done; var response = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult); var contract = new PartyCreateRequest { Member = new PartyMemberContract { Id = user.ID, Name = user.Character.Name, Job = user.Character.Job, Level = user.Character.Level, Channel = stage.ChannelID, Field = user.Field.ID } }; var serviceResponse = await service.Create(contract); var serviceResult = serviceResponse.Result; if (serviceResult == PartyServiceResult.FailedAlreadyInParty) { result = PartyResultCode.CreateNewParty_AlreadyJoined; } else if (serviceResult != PartyServiceResult.Ok) { result = PartyResultCode.CreateNewParty_Unknown; } response.WriteByte((byte)result); if (result == PartyResultCode.CreateNewParty_Done) { response.WriteInt(serviceResponse.Party.Id); response.WriteInt(0); // TownPortal-TownID response.WriteInt(0); // TownPortal-FieldID response.WriteInt(0); // TownPortal-SkillID response.WritePoint2D(new Point2D(0, 0)); //TownPortal-Position } await user.Dispatch(response); break; } case PartyRequestCode.WithdrawParty: { if (user.Party == null) { return; } var result = PartyResultCode.WithdrawParty_Done; var response = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult); var contract = new PartyWithdrawRequest { Character = user.ID, IsKick = false }; var serviceResponse = await service.Withdraw(contract); var serviceResult = serviceResponse.Result; if (serviceResult == PartyServiceResult.FailedNotInParty) { result = PartyResultCode.WithdrawParty_NotJoined; } else if (serviceResult != PartyServiceResult.Ok) { result = PartyResultCode.WithdrawParty_Unknown; } response.WriteByte((byte)result); if (result == PartyResultCode.WithdrawParty_Done) { return; } await user.Dispatch(response); break; } case PartyRequestCode.InviteParty: { if (user.Party == null) { var contract = new PartyCreateRequest { Member = new PartyMemberContract { Id = user.ID, Name = user.Character.Name, Job = user.Character.Job, Level = user.Character.Level, Channel = stage.ChannelID, Field = user.Field.ID } }; var serviceResponse = await service.Create(contract); var serviceResult = serviceResponse.Result; if (serviceResult != PartyServiceResult.Ok) { return; } var createResponse = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult); createResponse.WriteByte((byte)PartyResultCode.CreateNewParty_Done); createResponse.WriteInt(serviceResponse.Party.Id); createResponse.WriteInt(0); // TownPortal-TownID createResponse.WriteInt(0); // TownPortal-FieldID createResponse.WriteInt(0); // TownPortal-SkillID createResponse.WritePoint2D(new Point2D(0, 0)); //TownPortal-Position await user.Dispatch(createResponse); } if (user?.Party?.Boss != user.ID) { return; } var name = packet.ReadString(); var result = PartyResultCode.InviteParty_Sent; var response = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult); var character = await stage.CharacterRepository.RetrieveByName(name); if (character == null || user.Character.ID == character.ID) { result = PartyResultCode.InviteParty_BlockedUser; } if ((await service.LoadByCharacter(new PartyLoadByCharacterRequest { Character = character.ID })).Party != null) { result = PartyResultCode.JoinParty_AlreadyJoined; } else { var serviceResponse = await stage.InviteService.Register(new InviteRegisterRequest { Invite = new InviteContract { Type = InviteType.Party, Invited = character.ID, Inviter = user.ID } }); if (serviceResponse.Result != InviteServiceResult.Ok) { result = PartyResultCode.InviteParty_AlreadyInvited; } } response.WriteByte((byte)result); if (result == PartyResultCode.InviteParty_Sent) { var invitation = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult); var invitationRequest = new DispatchToCharactersRequest(); invitation.WriteByte((byte)PartyRequestCode.InviteParty); invitation.WriteInt(user.Character.ID); invitation.WriteString(user.Character.Name); invitation.WriteInt(user.Character.Level); invitation.WriteInt(user.Character.Job); invitation.WriteByte(0); // PartyOpt invitationRequest.Data = ByteString.CopyFrom(invitation.Buffer); invitationRequest.Characters.Add(character.ID); await stage.DispatchService.DispatchToCharacters(invitationRequest); response.WriteString(character.Name); } await user.Dispatch(response); break; } case PartyRequestCode.KickParty: { if (user.Party == null) { return; } if (user.Party.Boss != user.ID) { return; } var id = packet.ReadInt(); if (!user.Party.Members.Any(m => m.ID == id)) { return; } if (id == user.ID) { return; } var result = PartyResultCode.WithdrawParty_Done; var response = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult); var contract = new PartyWithdrawRequest { Character = id, IsKick = true }; var serviceResponse = await service.Withdraw(contract); var serviceResult = serviceResponse.Result; if (serviceResult == PartyServiceResult.FailedNotInParty) { result = PartyResultCode.WithdrawParty_NotJoined; } else if (serviceResult != PartyServiceResult.Ok) { result = PartyResultCode.WithdrawParty_Unknown; } response.WriteByte((byte)result); if (result == PartyResultCode.WithdrawParty_Done) { return; } await user.Dispatch(response); break; } case PartyRequestCode.ChangePartyBoss: { if (user.Party == null || user.Party.Boss != user.ID) { return; } var id = packet.ReadInt(); if (!user.Party.Members.Any(m => m.ID == id)) { return; } if (id == user.ID) { return; } var result = PartyResultCode.ChangePartyBoss_Done; var response = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult); var contract = new PartyChangeBossRequest { Character = id }; var serviceResponse = await service.ChangeBoss(contract); var serviceResult = serviceResponse.Result; if (serviceResult != PartyServiceResult.Ok) { result = PartyResultCode.WithdrawParty_Unknown; } response.WriteByte((byte)result); if (result == PartyResultCode.ChangePartyBoss_Done) { return; } await user.Dispatch(response); break; } default: stage.Logger.LogWarning($"Unhandled party request type: {type}"); break; } }
public async Task <PartyJoinResponse> Join(PartyJoinRequest 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.Retrieve(request.Party); if (await _repository.RetrieveByMember(request.Member.Id) != null) { result = PartyServiceResult.FailedAlreadyInParty; } if (party == null) { result = PartyServiceResult.FailedNonExistentParty; } else if (party.Members.Any(m => m.ID == request.Member.Id)) { result = PartyServiceResult.FailedAlreadyInParty; } else if (party.Members.Count >= 6) { result = PartyServiceResult.FailedFullParty; } if (result == PartyServiceResult.Ok) { party.Members.Add(new PartyMemberRecord(request.Member)); await _repository.Update(party); await Task.WhenAll(party.Members.Select(async m => { var packet = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult); packet.WriteByte((byte)PartyResultCode.JoinParty_Done); packet.WriteInt(party.ID); packet.WriteString(request.Member.Name); 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 PartyJoinResponse { Result = result, Party = party?.ToContract() }); } return(new PartyJoinResponse { Result = PartyServiceResult.FailedTimeout }); }
public async Task <PartyWithdrawResponse> Withdraw(PartyWithdrawRequest 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) { var targets = party.Members.ToList(); var isDisband = request.Character == party.Boss; if (isDisband) { party.Members.Clear(); await _repository.Delete(party); } else { party.Members.Remove(member); await _repository.Update(party); } await Task.WhenAll(targets.Select(async m => { var packet = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult); packet.WriteByte((byte)PartyResultCode.WithdrawParty_Done); packet.WriteInt(party.ID); packet.WriteInt(request.Character); packet.WriteBool(!isDisband); if (!isDisband) { packet.WriteBool(request.IsKick); packet.WriteString(member.Name); 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 PartyWithdrawResponse { Result = result }); } return(new PartyWithdrawResponse { Result = PartyServiceResult.FailedTimeout }); }