초기커밋
This commit is contained in:
61
GameServer/Contents/Party/Action/PartyAction.cs
Normal file
61
GameServer/Contents/Party/Action/PartyAction.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
using ServerCommon;
|
||||
|
||||
|
||||
using SESSION_ID = System.Int32;
|
||||
using WORLD_META_ID = System.UInt32;
|
||||
using META_ID = System.UInt32;
|
||||
using ENTITY_GUID = System.String;
|
||||
using ACCOUNT_ID = System.String;
|
||||
using OWNER_GUID = System.String;
|
||||
using USER_GUID = System.String;
|
||||
using CHARACTER_GUID = System.String;
|
||||
using ITEM_GUID = System.String;
|
||||
using PARTY_GUID = System.String;
|
||||
|
||||
|
||||
namespace GameServer
|
||||
{
|
||||
public class PartyAction : EntityActionBase
|
||||
{
|
||||
private PARTY_GUID m_party_guid = string.Empty;
|
||||
|
||||
|
||||
public PartyAction(Player owner)
|
||||
: base(owner)
|
||||
{
|
||||
}
|
||||
|
||||
public override async Task<Result> onInit()
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
|
||||
var result = new Result();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override void onClear()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public Task<Result> tryLoadParty()
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
|
||||
public PARTY_GUID getPartyGuid() => m_party_guid;
|
||||
public void setPartyGuid(PARTY_GUID partyGuid) => m_party_guid = partyGuid;
|
||||
}
|
||||
}
|
||||
245
GameServer/Contents/Party/Action/PartyInviteAction.cs
Normal file
245
GameServer/Contents/Party/Action/PartyInviteAction.cs
Normal file
@@ -0,0 +1,245 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
using PARTY_GUID = System.String;
|
||||
using USER_GUID = System.String;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class PartyInviteAction : EntityActionBase
|
||||
{
|
||||
public PartyInviteAction(PersonalParty owner) : base(owner)
|
||||
{
|
||||
}
|
||||
|
||||
public override async Task<Result> onInit()
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
|
||||
var result = new Result();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override void onClear()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public async Task<(Result result, Dictionary<USER_GUID, ServerErrorCode>? err_invites)> inviteParty(List<USER_GUID> invite_users)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
var personal_party = getOwner() as PersonalParty;
|
||||
NullReferenceCheckHelper.throwIfNull(personal_party, () => $"personal_party is null !!!");
|
||||
var owner = getOwner().getRootParent() as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
||||
|
||||
// 1. 파티 정보 획득
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party, () => $"global_party is null !!!");
|
||||
var global_party_action = global_party.getEntityAction<GlobalPartyAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party_action, () => $"global_party_action is null !!!");
|
||||
var party = global_party_action.getGlobalPartyDetail(personal_party.getPartyGuid());
|
||||
|
||||
// 2. 초대 조건 체크
|
||||
var check_invite_condition = await checkInviteConditions(party, invite_users);
|
||||
NullReferenceCheckHelper.throwIfNull(check_invite_condition.failed_invites, () => $"check_invite_condition.failed_invites is null !!!");
|
||||
var err_invites = inputInvitePartyErrorMembers(check_invite_condition.failed_invites);
|
||||
NullReferenceCheckHelper.throwIfNull(err_invites, () => $"err_invites is null !!!");
|
||||
|
||||
if (check_invite_condition.result.isFail() || check_invite_condition.failed_invites.Count == invite_users.Count)
|
||||
{
|
||||
return (check_invite_condition.result, err_invites);
|
||||
}
|
||||
|
||||
// 3. 파티 정보가 없으면 새로 생성
|
||||
if (null == party)
|
||||
{
|
||||
(result, party) = await createParty(owner, personal_party.getPartyGuid(), global_party_action);
|
||||
if (result.isFail()) return (result, err_invites);
|
||||
ArgumentNullException.ThrowIfNull(party);
|
||||
}
|
||||
|
||||
// 4. 초대하기
|
||||
var invite_party_send_action = party.getEntityAction<GlobalPartyInvitePartySendAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(invite_party_send_action, () => $"invite_party_send_action is null !!!");
|
||||
|
||||
result = await invite_party_send_action.sendInviteParty(check_invite_condition.success_invites);
|
||||
|
||||
return (result, err_invites);
|
||||
}
|
||||
|
||||
private async Task<(Result result, GlobalPartyDetail? detail)> createParty(Player owner, PARTY_GUID party_guid, GlobalPartyAction global_party_action)
|
||||
{
|
||||
// 1. LoginCache 갱신
|
||||
var user_login_cache_request = PartyHelper.getOwnUserLoginCacheRequest(owner);
|
||||
var user_login_cache = user_login_cache_request?.getLoginCache();
|
||||
NullReferenceCheckHelper.throwIfNull(user_login_cache_request, () => $"user_login_cache_request is null !!!");
|
||||
NullReferenceCheckHelper.throwIfNull(user_login_cache, () => $"user_login_cache is null !!!");
|
||||
|
||||
user_login_cache.PartyGuid = party_guid;
|
||||
|
||||
var result = await user_login_cache_request.upsertLogin();
|
||||
if (result.isFail())
|
||||
{
|
||||
var err_msg = $"Failed to set party guid to user attribute !!! : {nameof(inviteParty)}";
|
||||
result.setFail(ServerErrorCode.PartyCannotSetGuid, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
return (result, null);
|
||||
}
|
||||
|
||||
// 3. party 신규 생성
|
||||
result = await global_party_action.createParty(party_guid, owner.getUserGuid(), owner.getUserNickname());
|
||||
if (result.isFail()) return (result, null);
|
||||
|
||||
var detail = global_party_action.getGlobalPartyDetail(party_guid);
|
||||
ArgumentNullException.ThrowIfNull(detail);
|
||||
|
||||
return (result, detail);
|
||||
}
|
||||
|
||||
private async Task<(Result result, Dictionary<string, string>? success_invites, Dictionary<USER_GUID, ServerErrorCode>? failed_invites)> checkInviteConditions(GlobalPartyDetail? party, IReadOnlyList<USER_GUID> invite_users)
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
var owner = getOwner().getRootParent() as Player;
|
||||
ArgumentNullException.ThrowIfNull(owner);
|
||||
|
||||
// 1. 파티장 확인
|
||||
var party_attribute = party?.getEntityAttribute<PartyAttribute>();
|
||||
if (party != null && party_attribute != null && owner.getUserGuid() != party_attribute.PartyLeaderCharGuid)
|
||||
{
|
||||
err_msg = $"Failed to invite users !!! : not party leader - {owner.getUserGuid()}";
|
||||
result.setFail(ServerErrorCode.NotPartyLeader,err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return (result, null, null);
|
||||
}
|
||||
|
||||
// 2. 초대 인원수 확인
|
||||
var party_member_count = party?.getEntityAttribute<PartyMemberAttribute>()?.getPartyMemberCount() ?? 0;
|
||||
if (party != null && party_member_count >= MetaHelper.GameConfigMeta.MaxPartyMembers)
|
||||
{
|
||||
err_msg = $"Failed to invite user !!! : party is full - member count : {party_member_count}";
|
||||
result.set(ServerErrorCode.PartyIsFull, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return (result, null, null);
|
||||
}
|
||||
|
||||
// 3. 초대할 유저 상태 체크
|
||||
var check_invitee_condition = await checkInviteesCondition(party, invite_users);
|
||||
ArgumentNullException.ThrowIfNull(check_invitee_condition);
|
||||
|
||||
return (result, check_invitee_condition.success_invites, check_invitee_condition.failed_invites);
|
||||
}
|
||||
|
||||
private async Task<(Dictionary<string, string> success_invites, Dictionary<string, ServerErrorCode> failed_invites)> checkInviteesCondition(GlobalPartyDetail? party, IReadOnlyList<USER_GUID> invite_users)
|
||||
{
|
||||
var success_invites = new Dictionary<string, string>();
|
||||
var failed_invites = new Dictionary<USER_GUID, ServerErrorCode>();
|
||||
var owner = getOwner().getRootParent() as UserBase;
|
||||
ArgumentNullException.ThrowIfNull(owner);
|
||||
|
||||
foreach (var invitee in invite_users)
|
||||
{
|
||||
var check = await checkCondition(party, owner, invitee);
|
||||
if (! check.isSuccess)
|
||||
{
|
||||
failed_invites.Add(invitee, check.err_code);
|
||||
continue;
|
||||
}
|
||||
|
||||
success_invites.Add(invitee, check.current_server);
|
||||
}
|
||||
|
||||
return (success_invites, failed_invites);
|
||||
}
|
||||
|
||||
private async Task<(bool isSuccess, ServerErrorCode err_code, string current_server)> checkCondition(GlobalPartyDetail? party, UserBase? owner, USER_GUID invitee)
|
||||
{
|
||||
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
||||
var login_cache = await PartyHelper.getOtherUserLoginCache(owner, invitee);
|
||||
|
||||
// 3-1. login 체크
|
||||
if (null == login_cache)
|
||||
{
|
||||
return (false, ServerErrorCode.TargetUserNotLogIn, string.Empty);
|
||||
}
|
||||
|
||||
// 3-2. concert 체크
|
||||
var location_action = owner.getEntityAction<LocationAction>();
|
||||
ArgumentNullException.ThrowIfNull(location_action);
|
||||
if (location_action.isInConcert())
|
||||
{
|
||||
return (false, ServerErrorCode.InvalidInvitePlace, string.Empty);
|
||||
}
|
||||
|
||||
// 3-3. user block 체크 ( invitor -> invitee )
|
||||
var block_action = owner.getEntityAction<BlockUserAgentAction>();
|
||||
ArgumentNullException.ThrowIfNull(block_action);
|
||||
if (block_action.isBlockUser(invitee))
|
||||
{
|
||||
return (false, ServerErrorCode.BlockedByOther, string.Empty);
|
||||
}
|
||||
|
||||
// 3-4. user block 체크 ( invitee -> invitor )
|
||||
var is_block = await block_action.amIBockedFromOthers(invitee);
|
||||
if (is_block.reuslt.isFail() || is_block.isBlock)
|
||||
{
|
||||
return (false, ServerErrorCode.BlockedFromTarget, string.Empty);
|
||||
}
|
||||
|
||||
// 3-5. 이미 보낸 초대자 인지 체크
|
||||
var send_action = party?.getEntityAction<GlobalPartyInvitePartySendAction>();
|
||||
if (null != party)
|
||||
{
|
||||
var check_send = await (send_action?.isExistCheck(invitee) ?? Task.FromResult(false));
|
||||
if (check_send)
|
||||
{
|
||||
return (false, ServerErrorCode.AlreadyInviteParty, string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
// 3-6. 파티원인지 체크
|
||||
var check_party_member = await checkPartyMember(login_cache.PartyGuid);
|
||||
if (check_party_member)
|
||||
{
|
||||
return (false, ServerErrorCode.JoiningParty, string.Empty);
|
||||
}
|
||||
|
||||
return (true, ServerErrorCode.Success, login_cache.CurrentServer);
|
||||
}
|
||||
|
||||
private async Task<bool> checkPartyMember(PARTY_GUID party_guid)
|
||||
{
|
||||
if (string.IsNullOrEmpty(party_guid)) return false;
|
||||
|
||||
var party_member_cache_request =
|
||||
new PartyMemberCacheRequest(party_guid, GameServerApp.getServerLogic().getRedisConnector());
|
||||
|
||||
var result = await party_member_cache_request.fetchPartyMemberCache();
|
||||
if (result.isFail()) return false;
|
||||
|
||||
var cache = party_member_cache_request.getPartyMemberCache();
|
||||
ArgumentNullException.ThrowIfNull(cache);
|
||||
|
||||
return cache.PartyMembers.Count > 1;
|
||||
}
|
||||
|
||||
private Dictionary<USER_GUID, ServerErrorCode>? inputInvitePartyErrorMembers(Dictionary<USER_GUID, ServerErrorCode>? failed_invites)
|
||||
{
|
||||
return failed_invites?.ToDictionary(fail => fail.Key, fail => fail.Value);
|
||||
}
|
||||
}
|
||||
129
GameServer/Contents/Party/Action/PartyInvitePartyRecvAction.cs
Normal file
129
GameServer/Contents/Party/Action/PartyInvitePartyRecvAction.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
using PARTY_GUID = System.String;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class PartyInvitePartyRecvAction : EntityActionBase
|
||||
{
|
||||
private PartyInvitePartyRecvCacheRequest? m_party_invite_party_recv_cache_request { get; set; } = null;
|
||||
|
||||
public PartyInvitePartyRecvAction(Player owner)
|
||||
: base(owner)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public override async Task<Result> onInit()
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
|
||||
var result = new Result();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override void onClear()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public async Task<Result> loadInvitePartyRecv()
|
||||
{
|
||||
var player = getOwner() as Player;
|
||||
ArgumentNullException.ThrowIfNull(player);
|
||||
|
||||
var attribute = getOwner().getEntityAttribute<PartyInvitePartyRecvsAttribute>();
|
||||
ArgumentNullException.ThrowIfNull(attribute);
|
||||
|
||||
m_party_invite_party_recv_cache_request ??= new(player, GameServerApp.getServerLogic().getRedisConnector());
|
||||
ArgumentNullException.ThrowIfNull(m_party_invite_party_recv_cache_request);
|
||||
|
||||
var result = await m_party_invite_party_recv_cache_request.fetchInvitePartyRecvCache();
|
||||
if (result.isFail()) return result;
|
||||
|
||||
result = await ServerBase.DataCopyHelper.copyEntityAttributeFromCaches(attribute, new List<CacheBase> { m_party_invite_party_recv_cache_request.getPartyInvitePartyRecvCache()! });
|
||||
if (result.isFail())
|
||||
{
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<Dictionary<string, DateTime>> getPartyInvitePartyRecvs()
|
||||
{
|
||||
await organizeSendAttribute();
|
||||
|
||||
var attribute = getOwner().getEntityAttribute<PartyInvitePartyRecvsAttribute>();
|
||||
ArgumentNullException.ThrowIfNull(attribute);
|
||||
|
||||
var invites = attribute.getPartyInvitePartyRecvs().ToDictionary(invite => invite.Key, invite => invite.Value);
|
||||
return invites;
|
||||
}
|
||||
|
||||
public async Task<DateTime?> getPartyInvitePartyRecvTime(PARTY_GUID party_guid)
|
||||
{
|
||||
await organizeSendAttribute();
|
||||
|
||||
var attribute = getOwner().getEntityAttribute<PartyInvitePartyRecvsAttribute>();
|
||||
ArgumentNullException.ThrowIfNull(attribute);
|
||||
var invite_recv_time = attribute.getPartyInvitePartyRecvTime(party_guid);
|
||||
ArgumentNullException.ThrowIfNull(invite_recv_time);
|
||||
|
||||
return invite_recv_time;
|
||||
}
|
||||
|
||||
public async Task<Result> addInvitePartyRecv(PARTY_GUID party_guid)
|
||||
{
|
||||
var recv_time = DateTime.UtcNow;
|
||||
|
||||
// redis 저장
|
||||
NullReferenceCheckHelper.throwIfNull(m_party_invite_party_recv_cache_request, () => $"m_party_invite_party_recv_cache_request is null !!! - {party_guid}");
|
||||
var result = await m_party_invite_party_recv_cache_request.addInvitePartyRecvCache(party_guid, recv_time);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// attribute 저장
|
||||
var attribute = getOwner().getEntityAttribute<PartyInvitePartyRecvsAttribute>();
|
||||
ArgumentNullException.ThrowIfNull(attribute);
|
||||
attribute.addInvitePartyRecv(party_guid, recv_time);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<Result> deleteInvitePartyRecv(PARTY_GUID party_guid)
|
||||
{
|
||||
NullReferenceCheckHelper.throwIfNull(m_party_invite_party_recv_cache_request, () => $"m_party_invite_party_recv_cache_request is null !!! - {party_guid}");
|
||||
var result =
|
||||
await m_party_invite_party_recv_cache_request.deleteInvitePartyRecvCache(new List<PARTY_GUID> { party_guid });
|
||||
if (result.isFail()) return result;
|
||||
|
||||
var attribute = getOwner().getEntityAttribute<PartyInvitePartyRecvsAttribute>();
|
||||
ArgumentNullException.ThrowIfNull(attribute);
|
||||
|
||||
attribute.deleteInvitePartyRecvs(new List<PARTY_GUID> { party_guid });
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task organizeSendAttribute()
|
||||
{
|
||||
NullReferenceCheckHelper.throwIfNull(m_party_invite_party_recv_cache_request, () => $"m_party_invite_party_recv_cache_request is null !!!");
|
||||
var delete_recvs = await m_party_invite_party_recv_cache_request.organizeInvitePartyRecvCache();
|
||||
if (null == delete_recvs) return;
|
||||
|
||||
var attribute = getOwner().getEntityAttribute<PartyInvitePartyRecvsAttribute>();
|
||||
ArgumentNullException.ThrowIfNull(attribute);
|
||||
|
||||
attribute.deleteInvitePartyRecvs(delete_recvs);
|
||||
}
|
||||
}
|
||||
300
GameServer/Contents/Party/Action/PersonalPartyAction.cs
Normal file
300
GameServer/Contents/Party/Action/PersonalPartyAction.cs
Normal file
@@ -0,0 +1,300 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class PersonalPartyAction : EntityActionBase
|
||||
{
|
||||
private PersonalParty? m_party { get; set; }
|
||||
public PersonalPartyAction(Player owner)
|
||||
: base(owner)
|
||||
{
|
||||
}
|
||||
|
||||
public override async Task<Result> onInit()
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
|
||||
var result = new Result();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override void onClear()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public bool isParty() => m_party != null;
|
||||
|
||||
public async Task setPersonalParty(string party_guid)
|
||||
{
|
||||
var player = getOwner() as Player;
|
||||
ArgumentNullException.ThrowIfNull(player);
|
||||
|
||||
m_party = new PersonalParty(player, party_guid);
|
||||
await m_party.onInit();
|
||||
}
|
||||
|
||||
public async Task<Result> setPersonalPartyGuid(string party_guid)
|
||||
{
|
||||
var owner = getOwner() as Player;
|
||||
ArgumentNullException.ThrowIfNull(owner);
|
||||
|
||||
// 1. LoginCache 갱신
|
||||
var user_login_cache_request = PartyHelper.getOwnUserLoginCacheRequest(owner) ;
|
||||
ArgumentNullException.ThrowIfNull(user_login_cache_request);
|
||||
|
||||
var login_cache = user_login_cache_request.getLoginCache();
|
||||
NullReferenceCheckHelper.throwIfNull(login_cache, () => $"login cache is null !!! - {owner.toBasicString()}");
|
||||
|
||||
login_cache.PartyGuid = party_guid;
|
||||
var result = await user_login_cache_request.upsertLogin();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<Result> clearPersonalParty()
|
||||
{
|
||||
var result = await setPersonalPartyGuid(string.Empty);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
m_party?.Dispose();
|
||||
m_party = null;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<Result> sendPartyChat(string chat_message)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
var owner = getOwner() as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(owner, () => "player is null !!");
|
||||
|
||||
// 1. Party 확인
|
||||
if (null == m_party)
|
||||
{
|
||||
var err_msg = $"Failed to send party chat !!! : not party member - {owner.getUserGuid()}";
|
||||
result.setFail(ServerErrorCode.NotPartyMember, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party, () => "global party is null !!!");
|
||||
NullReferenceCheckHelper.throwIfNull(m_party, () => "personal party is null !!!");
|
||||
|
||||
var party = global_party.getParty(m_party.getPartyGuid());
|
||||
NullReferenceCheckHelper.throwIfNull(party, () => $"global party detail is null !!! - {m_party.getPartyGuid()} ");
|
||||
|
||||
// 2. 메시지 전송 ( to server )
|
||||
var server_message = new ServerMessage();
|
||||
server_message.NtfPartyChat = new();
|
||||
server_message.NtfPartyChat.PartyGuid = m_party.getPartyGuid();
|
||||
server_message.NtfPartyChat.PartySenderGuid = owner.getUserGuid();
|
||||
server_message.NtfPartyChat.PartySenderNickname = owner.getUserNickname();
|
||||
server_message.NtfPartyChat.PartySendMessage = chat_message;
|
||||
|
||||
PartyHelper.BroadcastToServers(party, server_message, true);
|
||||
|
||||
// 3. 메시지 전송 ( to client )
|
||||
var client_message = ChatNotifyHelper.makeChatMessage(ChatType.Party, owner.getUserNickname(), string.Empty,
|
||||
PlayerStateType.None, chat_message);
|
||||
|
||||
PartyHelper.BroadcastToClients(party, client_message, new List<string>() );
|
||||
|
||||
return await Task.FromResult(result);
|
||||
}
|
||||
|
||||
public PersonalParty? getPersonalParty() => m_party;
|
||||
|
||||
public async Task<Result> runPartyTick()
|
||||
{
|
||||
var result = new Result();
|
||||
var player = getOwner() as Player;
|
||||
ArgumentNullException.ThrowIfNull(player);
|
||||
|
||||
// 1. 파티 상태 체크
|
||||
var party_guid = m_party?.getPartyGuid();
|
||||
if (string.IsNullOrEmpty(party_guid)) return result;
|
||||
|
||||
// 2. 해당 파티 정보 얻기
|
||||
var party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>()?.getParty(party_guid);
|
||||
ArgumentNullException.ThrowIfNull(party);
|
||||
|
||||
var party_action = party.getEntityAction<GlobalPartyDetailAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_action);
|
||||
|
||||
// 3. 파티장 체크
|
||||
if (!party_action.isLeader(player.getUserGuid())) return result;
|
||||
|
||||
// 4. 파티 Keep 실행
|
||||
result = await party_action.keepParty();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<(bool in_party, string party_guid)> hasInParty()
|
||||
{
|
||||
var player = getOwner() as Player;
|
||||
ArgumentNullException.ThrowIfNull(player);
|
||||
|
||||
var login_cache_request = PartyHelper.getOwnUserLoginCacheRequest(player);
|
||||
if(login_cache_request == null)
|
||||
{
|
||||
return (false, string.Empty);
|
||||
}
|
||||
|
||||
var login_cache = login_cache_request.getLoginCache();
|
||||
NullReferenceCheckHelper.throwIfNull(login_cache, () => $"login cache is null !!! - {player.toBasicString()}");
|
||||
|
||||
return await Task.FromResult((true != login_cache.PartyGuid.isNullOrWhiteSpace(), login_cache.PartyGuid));
|
||||
}
|
||||
|
||||
public async Task<Result> tryLoadParty()
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
var player = getOwner() as Player;
|
||||
ArgumentNullException.ThrowIfNull(player);
|
||||
|
||||
// 1. user 의 Party invite recv 가져오기
|
||||
var party_invite_recv_action = player.getEntityAction<PartyInvitePartyRecvAction>();
|
||||
result = await party_invite_recv_action.loadInvitePartyRecv();
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 2. 파티에 가입중인가?
|
||||
var has_in_party = await hasInParty();
|
||||
if (false == has_in_party.in_party)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// 3. party join 시키기
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
var global_party_action = global_party?.getEntityAction<GlobalPartyAction>();
|
||||
if (null == global_party_action)
|
||||
{
|
||||
err_msg = $"Fail to get entity action !!! : {nameof(GlobalPartyAction)}";
|
||||
result.setFail(ServerErrorCode.EntityActionNotFound, err_msg );
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
var user = PartyHelper.makePartyMember(player.getUserGuid(), player.getUserNickname());
|
||||
result = await global_party_action.joinParty(has_in_party.party_guid, user);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 4. 파티 정보 설정
|
||||
await setPersonalParty(has_in_party.party_guid);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<Result> createDefaultParty()
|
||||
{
|
||||
var result = new Result();
|
||||
var owner = getOwner() as Player;
|
||||
ArgumentNullException.ThrowIfNull(owner);
|
||||
|
||||
// 1. 파티 존재 여부 체크
|
||||
if (null != m_party)
|
||||
{
|
||||
var err_msg = $"Failed to create party !!! : already party - {m_party.getPartyGuid()}";
|
||||
result.setFail(ServerErrorCode.AlreadyPartyMember, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 파티 생성
|
||||
var party_guid = Guid.NewGuid().ToString();
|
||||
await setPersonalParty(party_guid);
|
||||
|
||||
return await Task.FromResult(result);
|
||||
}
|
||||
|
||||
public async Task<Result> leaveParty()
|
||||
{
|
||||
var result = new Result();
|
||||
var log_invokers = new List<ILogInvoker>(3);
|
||||
|
||||
var owner = getOwner() as Player;
|
||||
ArgumentNullException.ThrowIfNull(owner);
|
||||
|
||||
// 1. 파티 상태 체크
|
||||
var party_guid = m_party?.getPartyGuid();
|
||||
if (string.IsNullOrEmpty(party_guid))
|
||||
{
|
||||
var err_msg = "Failed to get party !!! - not in party";
|
||||
result.setFail(ServerErrorCode.NotParty, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 해당 파티 정보 얻기
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
var global_party_action = global_party?.getEntityAction<GlobalPartyAction>();
|
||||
ArgumentNullException.ThrowIfNull(global_party_action);
|
||||
|
||||
var party = global_party_action.getGlobalPartyDetail(party_guid);
|
||||
if (null == party) return result;
|
||||
|
||||
var party_info = await global_party_action.getPartyLeaderGuidAndMemberCount(party_guid);
|
||||
|
||||
var party_log_data = PartyBusinessLogHelper.toPartyLogData(party_guid, false);
|
||||
party_log_data.PartyMemberCount -= 1;
|
||||
var party_business_log = new PartyBusinessLog(party_log_data);
|
||||
log_invokers.Add(party_business_log);
|
||||
|
||||
// 3. 파티장인 경우, 리더 전환
|
||||
if (party_info.leader_guid == owner.getUserGuid() && party_info.member_count > 2)
|
||||
{
|
||||
// 3-1. 소환 취소 요청
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_member_action);
|
||||
|
||||
var cancel_summon = await party_member_action.cancelAllSummonAsync();
|
||||
if (cancel_summon.result.isFail()) return cancel_summon.result;
|
||||
|
||||
// 3-2. 파티장 위임
|
||||
var party_action = party.getEntityAction<GlobalPartyDetailAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_action);
|
||||
|
||||
(result, var change_leader_guid) = await party_action.changePartyLeader();
|
||||
if (result.isFail()) return result;
|
||||
|
||||
var party_leader_member_log_data = PartyBusinessLogHelper.toPartyMemberLogData(party_guid, change_leader_guid, PartyMemberActionType.PartyLeader);
|
||||
var party_leader_member_business_log = new PartyMemberBusinessLog(party_leader_member_log_data);
|
||||
log_invokers.Add(party_leader_member_business_log);
|
||||
}
|
||||
|
||||
var party_member_log_data = PartyBusinessLogHelper.toPartyMemberLogData(party_guid, owner.getUserGuid(), PartyMemberActionType.LeaveParty);
|
||||
var party_member_business_log = new PartyMemberBusinessLog(party_member_log_data);
|
||||
log_invokers.Add(party_member_business_log);
|
||||
|
||||
// 4. 파티 탈퇴 처리
|
||||
result = await global_party_action.leaveParty(party_guid, owner.getUserGuid(), BoolType.False);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 5. 개인 파티 정리
|
||||
await clearPersonalParty();
|
||||
|
||||
// 6. Business Log 기록
|
||||
BusinessLogger.collectLogs(new LogActionEx(LogActionType.LeaveParty), owner, log_invokers);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
119
GameServer/Contents/Party/Helper/PartyBusinessLogHelper.cs
Normal file
119
GameServer/Contents/Party/Helper/PartyBusinessLogHelper.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public static class PartyBusinessLogHelper
|
||||
{
|
||||
public static PartyLogData toPartyLogData(string partyGuid, bool isCreate)
|
||||
{
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
ArgumentNullException.ThrowIfNull(global_party);
|
||||
var party = global_party.getParty(partyGuid);
|
||||
|
||||
if (null == party) return new PartyLogData { PartyGuid = partyGuid };
|
||||
|
||||
var party_attribute = party.getEntityAttribute<PartyAttribute>();
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_attribute);
|
||||
ArgumentNullException.ThrowIfNull(party_member_action);
|
||||
|
||||
var party_log_data = new PartyLogData();
|
||||
party_log_data.PartyGuid = party.PartyGuid;
|
||||
party_log_data.PartyName = party_attribute.PartyName;
|
||||
party_log_data.PartyLeaderCharGuid = party_attribute.PartyLeaderCharGuid;
|
||||
party_log_data.PartyMemberCount = (isCreate) ? 1 : party_member_action.getMemberCount();
|
||||
party_log_data.CreatePartyTime = party_attribute.CreatePartyTime;
|
||||
|
||||
return party_log_data;
|
||||
}
|
||||
|
||||
public static PartyMemberLogData toPartyMemberLogData(string partyGuid, string userGuid, PartyMemberActionType actionType)
|
||||
{
|
||||
var log_data = new PartyMemberLogData();
|
||||
log_data.PartyGuid = partyGuid;
|
||||
log_data.UserGuid = userGuid;
|
||||
log_data.PartyMemberActionType = actionType;
|
||||
log_data.PartyMemberActionTime = DateTimeHelper.Current;
|
||||
|
||||
return log_data;
|
||||
}
|
||||
|
||||
public static PartyVoteLogData toPartyVoteLogData(string partyGuid, bool isStart)
|
||||
{
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
ArgumentNullException.ThrowIfNull(global_party);
|
||||
var party = global_party.getParty(partyGuid);
|
||||
if (null == party) return new PartyVoteLogData { PartyGuid = partyGuid };
|
||||
|
||||
var party_detail_action = party.getEntityAction<GlobalPartyDetailInfoAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_detail_action);
|
||||
var party_vote = party_detail_action.getPartyVoteInfo();
|
||||
if(null == party_vote) return new PartyVoteLogData { PartyGuid = partyGuid };
|
||||
|
||||
var log_data = new PartyVoteLogData();
|
||||
log_data.PartyGuid = partyGuid;
|
||||
log_data.VoteTitle = party_vote.VoteTitle;
|
||||
log_data.StartVoteTime = party_vote.StartVoteTime.ToDateTime();
|
||||
|
||||
if (isStart) return log_data;
|
||||
|
||||
log_data.EndVoteTime = DateTimeHelper.Current;
|
||||
var vote_result = new VoteResult();
|
||||
foreach (var vote in party_vote.Votes)
|
||||
{
|
||||
switch (vote.Value)
|
||||
{
|
||||
case VoteType.Agreement:
|
||||
vote_result.Agree += 1;
|
||||
break;
|
||||
case VoteType.DisAgreement:
|
||||
vote_result.DisAgree += 1;
|
||||
break;
|
||||
default:
|
||||
vote_result.Abstain += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
log_data.VoteResult = vote_result;
|
||||
|
||||
return log_data;
|
||||
}
|
||||
|
||||
public static PartyInstanceLogData toPartyInstanceLogData(string partyGuid, bool isCreate)
|
||||
{
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
ArgumentNullException.ThrowIfNull(global_party);
|
||||
var party = global_party.getParty(partyGuid);
|
||||
|
||||
if (null == party) return new PartyInstanceLogData { PartyGuid = partyGuid };
|
||||
|
||||
var party_instance_attribute = party.getEntityAttribute<PartyInstanceAttribute>();
|
||||
ArgumentNullException.ThrowIfNull(party_instance_attribute);
|
||||
|
||||
var log_data = new PartyInstanceLogData();
|
||||
log_data.PartyGuid = partyGuid;
|
||||
log_data.InstanceId = party_instance_attribute.InstanceId;
|
||||
log_data.InstanceRoomId = party_instance_attribute.RoomId;
|
||||
log_data.JoinMemberCount = party_instance_attribute.JoinMemberCount;
|
||||
log_data.CreateTime = DateTimeHelper.Current;
|
||||
log_data.StartTime = party_instance_attribute.StartTime.ToDateTime();
|
||||
if (false == isCreate)
|
||||
{
|
||||
log_data.EndTime = party_instance_attribute.EndTime.ToDateTime();
|
||||
}
|
||||
|
||||
return log_data;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer.PacketHandler;
|
||||
|
||||
|
||||
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.BanPartyMemberReq), typeof(BanPartyMemberPacketHandler), typeof(GameLoginListener))]
|
||||
public class BanPartyMemberPacketHandler : PacketRecvHandler
|
||||
{
|
||||
private static void send_S2C_ACK_BAN_PARTY_MEMBER(Player? owner, Result result)
|
||||
{
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
||||
|
||||
var ack_packet = new ClientToGame
|
||||
{
|
||||
Response = new ClientToGameRes
|
||||
{
|
||||
ErrorCode = result.ErrorCode,
|
||||
BanPartyMemberRes = new()
|
||||
}
|
||||
};
|
||||
|
||||
GameServerApp.getServerLogic().onSendPacket(owner, ack_packet);
|
||||
}
|
||||
|
||||
public override async Task<Result> onProcessPacket(ISession entityWithSession, IMessage recvMessage)
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
var log_invokers = new List<ILogInvoker>(3);
|
||||
|
||||
var entity_player = entityWithSession as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(entity_player, () => $"entity_player is null !!!");
|
||||
|
||||
// 1. 기본 정보 체크
|
||||
var request = (recvMessage as ClientToGame)?.Request.BanPartyMemberReq;
|
||||
if (null == request)
|
||||
{
|
||||
err_msg = $"Failed to get request type !!! : {nameof(ClientToGame.Request.BanPartyMemberReq)}";
|
||||
result.setFail(ServerErrorCode.InvalidArgument, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
send_S2C_ACK_BAN_PARTY_MEMBER(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 소속 파티 Guid 조회
|
||||
var personal_party_action = entity_player.getEntityAction<PersonalPartyAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(personal_party_action, () => $"personal_party_action is null !!!");
|
||||
|
||||
var personal_party = personal_party_action.getPersonalParty();
|
||||
if (null == personal_party)
|
||||
{
|
||||
err_msg = $"Failed to get party info !!! - not party member - {entity_player.getUserGuid()}";
|
||||
result.setFail(ServerErrorCode.NotParty, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_BAN_PARTY_MEMBER(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party, () => $"global_party is null !!!");
|
||||
|
||||
var party = global_party.getParty(personal_party.getPartyGuid());
|
||||
NullReferenceCheckHelper.throwIfNull(party, () => $"party is null !!!");
|
||||
|
||||
var party_log_data = PartyBusinessLogHelper.toPartyLogData(party.PartyGuid, false);
|
||||
party_log_data.PartyMemberCount -= 1;
|
||||
var party_business_log = new PartyBusinessLog(party_log_data);
|
||||
log_invokers.Add(party_business_log);
|
||||
|
||||
// 3. 파티장 체크
|
||||
var party_action = party.getEntityAction<GlobalPartyDetailAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_action, () => $"party_action is null !!!");
|
||||
|
||||
var is_leader = party_action.isLeader(entity_player.getUserGuid());
|
||||
if (!is_leader)
|
||||
{
|
||||
err_msg = $"Failed to ban party member !!! : not party leader - {entity_player.getUserGuid()}";
|
||||
result.setFail(ServerErrorCode.NotPartyLeader, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_BAN_PARTY_MEMBER(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 4. 파티원 체크
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_member_action, () => $"party_member_action is null !!!");
|
||||
|
||||
var is_member = party_member_action.isPartyMember(request.PartyMemberUserGuid);
|
||||
if (false == is_member)
|
||||
{
|
||||
err_msg = $"Failed to ban party member !!! : not party member - {request.PartyMemberUserGuid}";
|
||||
result.setFail(ServerErrorCode.NotPartyMember, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_BAN_PARTY_MEMBER(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
var party_member_log_data = PartyBusinessLogHelper.toPartyMemberLogData(party.PartyGuid, request.PartyMemberUserGuid, PartyMemberActionType.BanParty);
|
||||
var party_member_business_log = new PartyMemberBusinessLog(party_member_log_data);
|
||||
log_invokers.Add(party_member_business_log);
|
||||
|
||||
// 5. 파티원 탈퇴 처리
|
||||
var global_party_action = global_party.getEntityAction<GlobalPartyAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party_action, () => $"server_logic is null !!!");
|
||||
|
||||
result = await global_party_action.leaveParty(party.PartyGuid, request.PartyMemberUserGuid, BoolType.True);
|
||||
if (result.isFail())
|
||||
{
|
||||
send_S2C_ACK_BAN_PARTY_MEMBER(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 6. 해당 파티원 ban 알림
|
||||
var message = new ServerMessage();
|
||||
message.BanPartyNoti = new();
|
||||
message.BanPartyNoti.PartyGuid = party.PartyGuid;
|
||||
message.BanPartyNoti.BanMemberGuid = request.PartyMemberUserGuid;
|
||||
|
||||
await PartyHelper.sendToServerByTargetClient(request.PartyMemberUserGuid, message);
|
||||
|
||||
// 7. Business Log 기록
|
||||
BusinessLogger.collectLogs(new LogActionEx(LogActionType.BanParty), entity_player, log_invokers);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
|
||||
namespace GameServer.PacketHandler;
|
||||
|
||||
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.CreatePartyInstanceReq), typeof(CreatePartyInstancePacketHandler), typeof(GameLoginListener))]
|
||||
public class CreatePartyInstancePacketHandler : PacketRecvHandler
|
||||
{
|
||||
private void send_S2C_ACK_CREATE_PARTY_INSTANCE(Player owner, Result result, string spendItemGuid)
|
||||
{
|
||||
var ack_packet = new ClientToGame
|
||||
{
|
||||
Response = new ClientToGameRes
|
||||
{
|
||||
ErrorCode = result.ErrorCode,
|
||||
CreatePartyInstanceRes = new()
|
||||
}
|
||||
};
|
||||
|
||||
if (result.isSuccess())
|
||||
{
|
||||
var spent = new ItemGuidCount();
|
||||
spent.ItemGuid = spendItemGuid;
|
||||
spent.ItemCount = 1;
|
||||
|
||||
ack_packet.Response.CreatePartyInstanceRes.Items.Add(spent);
|
||||
}
|
||||
GameServerApp.getServerLogic().onSendPacket(owner, ack_packet);
|
||||
}
|
||||
|
||||
public override async Task<Result> onProcessPacket(ISession entityWithSession, IMessage recvMessage)
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
var entity_player = entityWithSession as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(entity_player, () => $"entity_player is null !!!");
|
||||
|
||||
// 1. 기본 정보 체크
|
||||
var request = (recvMessage as ClientToGame)?.Request.CreatePartyInstanceReq;
|
||||
if (null == request)
|
||||
{
|
||||
err_msg = $"Failed to get request type !!! : {nameof(ClientToGame.Request.CreatePartyInstanceReq)}";
|
||||
result.setFail(ServerErrorCode.InvalidArgument, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
send_S2C_ACK_CREATE_PARTY_INSTANCE(entity_player, result, string.Empty);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 소속 파티 Guid 조회
|
||||
var personal_party_action = entity_player.getEntityAction<PersonalPartyAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(personal_party_action, () => $"personal_party_action is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
var personal_party = personal_party_action.getPersonalParty();
|
||||
if (null == personal_party)
|
||||
{
|
||||
err_msg = $"Failed to get party info !!! - not party member - {entity_player.getUserGuid()}";
|
||||
result.setFail(ServerErrorCode.NotParty, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_CREATE_PARTY_INSTANCE(entity_player, result, string.Empty);
|
||||
return result;
|
||||
}
|
||||
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party, () => $"global_party is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
var party = global_party.getParty(personal_party.getPartyGuid());
|
||||
NullReferenceCheckHelper.throwIfNull(party, () => $"party is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
// 3. 파티장 체크
|
||||
var party_action = party.getEntityAction<GlobalPartyDetailAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_action, () => $"party_action is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
var is_leader = party_action.isLeader(entity_player.getUserGuid());
|
||||
if (!is_leader)
|
||||
{
|
||||
err_msg = $"Failed to create party instance !!! : not party leader - {entity_player.getUserGuid()}";
|
||||
result.setFail(ServerErrorCode.NotPartyLeader, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_CREATE_PARTY_INSTANCE(entity_player, result, string.Empty);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 4. Party Instance 생성 처리
|
||||
result = await entity_player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "CreatePartyInstance", createPartyInstanceDelegate);
|
||||
if (result.isFail())
|
||||
{
|
||||
send_S2C_ACK_CREATE_PARTY_INSTANCE(entity_player, result, string.Empty);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
async Task<Result> createPartyInstanceDelegate() =>
|
||||
await createPartyInstanceAsync(entity_player, request, party);
|
||||
|
||||
}
|
||||
|
||||
private async Task<Result> createPartyInstanceAsync(Player owner, ClientToGameReq.Types.CreatePartyInstanceReq request, GlobalPartyDetail party)
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
// 1. party instance 정보 획득
|
||||
var instance_info = getPartyInstanceInfo(request);
|
||||
if (instance_info.result.isFail() || instance_info.concert_data == null) return instance_info.result;
|
||||
|
||||
// 2. Instance 생성
|
||||
var instance_room_id = await InstanceRoomHandler.CreatePartyInstance(party.PartyGuid, instance_info.instance_id);
|
||||
if (string.IsNullOrEmpty(instance_room_id))
|
||||
{
|
||||
err_msg = "Failed to create party instance !!!";
|
||||
result.setFail(ServerErrorCode.CreateRoomFail, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 3. 파티 채널 생성권 소모
|
||||
(result, var item) = await spendCreatePartyInstanceItem(owner);
|
||||
if(result.isFail()) return result;
|
||||
|
||||
// 4. 파티에 party instance 저장 ( PartyInstanceInfo )
|
||||
var party_info_action = party.getEntityAction<GlobalPartyDetailInstanceAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_info_action, () => $"party_info_action is null !!! - {owner.toBasicString()}");
|
||||
|
||||
var start_time = DateTime.UtcNow.AddSeconds(MetaHelper.GameConfigMeta.PartyConcertWaitingTimeSec).ToTimestamp();
|
||||
var end_time = start_time.ToDateTime().AddSeconds(instance_info.concert_data.ConcertLength).ToTimestamp();
|
||||
|
||||
result = await party_info_action.registerPartyInstance(instance_info.instance_id, instance_room_id, start_time, end_time, 0, true);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
var batch = new QueryBatchEx<QueryRunnerWithDocument>( owner, LogActionType.CreatePartyInstance, GameServerApp.getServerLogic().getDynamoDbClient());
|
||||
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
|
||||
batch.addQuery(new QueryFinal());
|
||||
|
||||
// 5. Business Log 기록
|
||||
writeBusinessLog(batch, party, item);
|
||||
|
||||
return await QueryHelper.sendQueryAndBusinessLog(batch);
|
||||
}
|
||||
|
||||
private (Result result, int instance_id, MetaAssets.InstanceConcertMetaData? concert_data) getPartyInstanceInfo(ClientToGameReq.Types.CreatePartyInstanceReq request)
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
// 1. Instance ID 획득
|
||||
(result, var room_map_tree, _) = MapHelper.tryGetRoomMapTree(request.LandId, request.Floor, request.BuildingId);
|
||||
if (result.isFail() || room_map_tree == null)
|
||||
{
|
||||
err_msg = $"Failed to tryGetRoomMapTree() !!! : {result.toBasicString()}";
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return (result, 0, null);
|
||||
}
|
||||
|
||||
var instance_id = room_map_tree.InstanceMetaId;
|
||||
|
||||
// 2. Indun data 획득
|
||||
if (!MetaData.Instance._IndunTable.TryGetValue(instance_id, out var indun_data))
|
||||
{
|
||||
err_msg = $"Failed to create party instance !!! : Not Found IndunData. instanceId:{instance_id}";
|
||||
result.setFail(ServerErrorCode.InstanceMetaDataNotFound, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return (result, 0, null);
|
||||
}
|
||||
|
||||
// 3. indun data 체크
|
||||
if (indun_data.placeType() != EPlaceType.Concert || indun_data.OverLimit == 0)
|
||||
{
|
||||
err_msg = $"Failed to create party instance !!! : invalid instance info. instanceId:{instance_id}";
|
||||
result.setFail(ServerErrorCode.NotUsablePlace, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return (result, 0, null);
|
||||
}
|
||||
|
||||
// 4. Concert 정보 획득
|
||||
if (MetaData.Instance._ConcertTable.TryGetValue(indun_data.MapId, out var concert_data) == false)
|
||||
{
|
||||
err_msg = $"Failed to create party instance !!! : not found Concert id:{indun_data.MapId}";
|
||||
result.setFail(ServerErrorCode.NotFoundTable, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return (result, 0, null);
|
||||
}
|
||||
|
||||
return (result, instance_id, concert_data);
|
||||
}
|
||||
|
||||
private async Task<(Result, Item?)> spendCreatePartyInstanceItem(Player owner)
|
||||
{
|
||||
var inventory_action = owner.getEntityAction<InventoryActionBase>();
|
||||
NullReferenceCheckHelper.throwIfNull(inventory_action, () => $"inventory_action is null !!! - {owner.toBasicString()}");
|
||||
|
||||
(var result, var delete_instance_items) = await inventory_action.tryDeleteItemByMetaId((uint)ServerCommon.Constant.PARTY_INSTANCE_CREATE_ITEM_ID, (ushort)MetaHelper.GameConfigMeta.ItemAmountPartyInstance);
|
||||
if (result.isFail()) return (result, null);
|
||||
|
||||
var item = delete_instance_items.FirstOrDefault();
|
||||
return (result, item);
|
||||
}
|
||||
|
||||
private void writeBusinessLog(QueryBatchBase queryBatchBase, GlobalPartyDetail party, Item? delItem)
|
||||
{
|
||||
// 1. 파티 정보
|
||||
var party_log_data = PartyBusinessLogHelper.toPartyLogData(party.PartyGuid, false);
|
||||
var party_business_log = new PartyBusinessLog(party_log_data);
|
||||
queryBatchBase.appendBusinessLog(party_business_log);
|
||||
|
||||
// 2. 파티 인스턴스 정보
|
||||
var party_instance_log_data = PartyBusinessLogHelper.toPartyInstanceLogData(party.PartyGuid, true);
|
||||
var party_instance_business_log = new PartyInstanceBusinessLog(party_instance_log_data);
|
||||
queryBatchBase.appendBusinessLog(party_instance_business_log);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer.PacketHandler;
|
||||
|
||||
|
||||
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.ExchangePartyMemberMarkReq), typeof(ExchangePartyMemberMarkPacketHandler), typeof(GameLoginListener))]
|
||||
public class ExchangePartyMemberMarkPacketHandler : PacketRecvHandler
|
||||
{
|
||||
private static void send_S2C_ACK_EXCHANGE_PARTY_MAKER(Player owner, Result result)
|
||||
{
|
||||
var ack_packet = new ClientToGame
|
||||
{
|
||||
Response = new ClientToGameRes
|
||||
{
|
||||
ErrorCode = result.ErrorCode,
|
||||
ExchangePartyMemberMarkRes = new()
|
||||
}
|
||||
};
|
||||
|
||||
GameServerApp.getServerLogic().onSendPacket(owner, ack_packet);
|
||||
}
|
||||
|
||||
public override async Task<Result> onProcessPacket(ISession entityWithSession, IMessage recvMessage)
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
var entity_player = entityWithSession as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(entity_player, () => $"entity_player is null !!!");
|
||||
|
||||
// 1. 기본 정보 체크
|
||||
var request = (recvMessage as ClientToGame)?.Request.ExchangePartyMemberMarkReq;
|
||||
if (null == request)
|
||||
{
|
||||
err_msg = $"Failed to get request type !!! : {nameof(ClientToGame.Request.ExchangePartyMemberMarkReq)}";
|
||||
result.setFail(ServerErrorCode.InvalidArgument, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
send_S2C_ACK_EXCHANGE_PARTY_MAKER(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 소속 파티 Guid 조회
|
||||
var personal_party_action = entity_player.getEntityAction<PersonalPartyAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(personal_party_action, () => $"personal_party_action is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
var personal_party = personal_party_action.getPersonalParty();
|
||||
if (null == personal_party)
|
||||
{
|
||||
err_msg = $"Failed to get party info !!! - not party member - {entity_player.getUserGuid()}";
|
||||
result.setFail(ServerErrorCode.NotParty, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_EXCHANGE_PARTY_MAKER(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party, () => $"global_party is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
var party = global_party.getParty(personal_party.getPartyGuid());
|
||||
NullReferenceCheckHelper.throwIfNull(party, () => $"party is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
// 3. 파티장 체크
|
||||
var party_action = party.getEntityAction<GlobalPartyDetailAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_action, () => $"party_action is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
var is_leader = party_action.isLeader(entity_player.getUserGuid());
|
||||
if (!is_leader)
|
||||
{
|
||||
err_msg = $"Failed to change party member maker !!! : not party leader - {entity_player.getUserGuid()}";
|
||||
result.setFail(ServerErrorCode.NotPartyLeader, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_EXCHANGE_PARTY_MAKER(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 4. Maker 변경
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_member_action, () => $"party_member_action is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
result = await party_member_action.changeMemberMaker(request.PartyMemberUserGuid, request.MarkId, true);
|
||||
if (result.isFail())
|
||||
{
|
||||
send_S2C_ACK_EXCHANGE_PARTY_MAKER(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 5. 변경사항 알림 ( to server )
|
||||
var server_message = new ServerMessage()
|
||||
{
|
||||
ExchangePartyMemberMarkNoti = new()
|
||||
{
|
||||
PartyGuid = party.PartyGuid,
|
||||
MemberUserGuid = request.PartyMemberUserGuid,
|
||||
MarkId = request.MarkId
|
||||
}
|
||||
};
|
||||
PartyHelper.BroadcastToServers(party, server_message, true);
|
||||
|
||||
// 6. 변경사항 알림 ( to client )
|
||||
var client_message = new ClientToGame()
|
||||
{
|
||||
Message = new()
|
||||
{
|
||||
ExchangePartyMemberMarkNoti = new()
|
||||
{
|
||||
MarkId = request.MarkId,
|
||||
MemberUserGuid = request.PartyMemberUserGuid
|
||||
}
|
||||
}
|
||||
};
|
||||
PartyHelper.BroadcastToClients(party, client_message, new List<string>());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
using USER_GUID = System.String;
|
||||
|
||||
|
||||
namespace GameServer.PacketHandler;
|
||||
|
||||
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.ExchangePartyNameReq), typeof(ExchangePartyNamePacketHandler), typeof(GameLoginListener))]
|
||||
public class ExchangePartyNamePacketHandler : PacketRecvHandler
|
||||
{
|
||||
private static void send_S2C_ACK_EXCHANGE_PARTY_NAME(Player owner, Result result)
|
||||
{
|
||||
var ack_packet = new ClientToGame
|
||||
{
|
||||
Response = new ClientToGameRes
|
||||
{
|
||||
ErrorCode = result.ErrorCode,
|
||||
ExchangePartyNameRes = new()
|
||||
}
|
||||
};
|
||||
|
||||
GameServerApp.getServerLogic().onSendPacket(owner, ack_packet);
|
||||
}
|
||||
|
||||
public override async Task<Result> onProcessPacket(ISession entityWithSession, IMessage recvMessage)
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var entity_player = entityWithSession as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(entity_player, () => $"entity_player is null !!!");
|
||||
|
||||
// 1. 기본 정보 체크
|
||||
var request = (recvMessage as ClientToGame)?.Request.ExchangePartyNameReq;
|
||||
if (null == request)
|
||||
{
|
||||
err_msg = $"Failed to get request type !!! : {nameof(ClientToGame.Request.ExchangePartyNameReq)}";
|
||||
result.setFail(ServerErrorCode.InvalidArgument, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
send_S2C_ACK_EXCHANGE_PARTY_NAME(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 소속 파티 Guid 조회
|
||||
var personal_party_action = entity_player.getEntityAction<PersonalPartyAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(personal_party_action, () => $"personal_party_action is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
var personal_party = personal_party_action.getPersonalParty();
|
||||
if (null == personal_party)
|
||||
{
|
||||
err_msg = $"Failed to get party info !!! - not party member - {entity_player.getUserGuid()}";
|
||||
result.setFail(ServerErrorCode.NotParty, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_EXCHANGE_PARTY_NAME(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 3. 조건 체크
|
||||
result = checkPartyNameConditions(request.NewPartyName);
|
||||
if (result.isFail())
|
||||
{
|
||||
send_S2C_ACK_EXCHANGE_PARTY_NAME(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 4. 파티 명칭 변경
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party, () => $"global_party is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
var party = global_party.getParty(personal_party.getPartyGuid());
|
||||
NullReferenceCheckHelper.throwIfNull(party, () => $"party is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
var party_info_action = party.getEntityAction<GlobalPartyDetailInfoAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_info_action, () => $"party_info_action is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
result = await party_info_action.changePartyName(request.NewPartyName, true);
|
||||
if (result.isFail())
|
||||
{
|
||||
send_S2C_ACK_EXCHANGE_PARTY_NAME(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 5. 파티명 변경 알림 ( to server )
|
||||
var server_message = new ServerMessage
|
||||
{
|
||||
ExchangePartyNameNoti = new()
|
||||
{
|
||||
PartyGuid = request.NewPartyName
|
||||
}
|
||||
};
|
||||
PartyHelper.BroadcastToServers(party, server_message, true);
|
||||
|
||||
// 6. 파티명 변경 알림 ( to client )
|
||||
var client_message = new ClientToGame()
|
||||
{
|
||||
Message = new ClientToGameMessage()
|
||||
{
|
||||
ExchangePartyNameNoti = new()
|
||||
{
|
||||
NewPartyName = request.NewPartyName
|
||||
}
|
||||
}
|
||||
};
|
||||
PartyHelper.BroadcastToClients(party, client_message, new List<USER_GUID>());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Result checkPartyNameConditions(string partyName)
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
// 1. 길이 체크
|
||||
if (partyName.Length > MetaHelper.GameConfigMeta.MaxPartyNameInput)
|
||||
{
|
||||
err_msg = $"fail to exchange party name !!! : invalid length - {partyName.Length}";
|
||||
result.setFail(ServerErrorCode.InvalidPartyStringLength, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 금칙어 체크
|
||||
if (StringRuleHelper.isBanWord(partyName, false))
|
||||
{
|
||||
err_msg = $"fail to exchange party name !!! : include ban word - {partyName}";
|
||||
result.setFail(ServerErrorCode.IncludeBanWordFromPartyName, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
using PARTY_GUID = System.String;
|
||||
|
||||
|
||||
namespace GameServer.PacketHandler;
|
||||
|
||||
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.InvitePartyListReq), typeof(InvitePartyListPacketHandler), typeof(GameLoginListener))]
|
||||
public class InvitePartyListPacketHandler : PacketRecvHandler
|
||||
{
|
||||
private static void send_S2C_ACK_INVITE_PARTY_LIST(Player owner, Result result, IReadOnlyList<InvitePartyState>? invites)
|
||||
{
|
||||
var ack_packet = new ClientToGame
|
||||
{
|
||||
Response = new ClientToGameRes
|
||||
{
|
||||
ErrorCode = result.ErrorCode,
|
||||
InvitePartyListRes = new()
|
||||
}
|
||||
};
|
||||
|
||||
if (result.isSuccess() && null != invites)
|
||||
{
|
||||
ack_packet.Response.InvitePartyListRes.InvitePartyList.AddRange(invites);
|
||||
}
|
||||
|
||||
GameServerApp.getServerLogic().onSendPacket(owner, ack_packet);
|
||||
}
|
||||
|
||||
public override async Task<Result> onProcessPacket(ISession entityWithSession, IMessage recvMessage)
|
||||
{
|
||||
var result = new Result();
|
||||
var entity_player = entityWithSession as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(entity_player, () => "player is null !!!");
|
||||
|
||||
// 1. 기본 정보 체크
|
||||
var request = (recvMessage as ClientToGame)?.Request.InvitePartyListReq;
|
||||
if (null == request)
|
||||
{
|
||||
var err_msg = $"Failed to get request type !!! : {nameof(ClientToGame.Request.InvitePartyListReq)}";
|
||||
result.setFail(ServerErrorCode.InvalidArgument, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
send_S2C_ACK_INVITE_PARTY_LIST(entity_player, result, null);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. invite recv list 획득
|
||||
var invite_party_recv_action = entity_player.getEntityAction<PartyInvitePartyRecvAction>();
|
||||
var list = await invite_party_recv_action.getPartyInvitePartyRecvs();
|
||||
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party, () => "global party is null !!!");
|
||||
|
||||
var global_party_action = global_party.getEntityAction<GlobalPartyAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party_action, () => $"global party action is null !!! - {entity_player.toBasicString()} / {global_party.toBasicString()}");
|
||||
|
||||
var invites = new List<InvitePartyState>();
|
||||
foreach (var recv in list)
|
||||
{
|
||||
// 2-1. party 정보 확인
|
||||
var party_info = await global_party_action.getPartyLeaderGuidAndMemberCount(recv.Key);
|
||||
if (PARTY_GUID.IsNullOrEmpty(party_info.leader_guid))
|
||||
{
|
||||
// recv 제거
|
||||
await invite_party_recv_action.deleteInvitePartyRecv(recv.Key);
|
||||
};
|
||||
|
||||
// 2-2. 데이터 채우기
|
||||
var invite_party_state = new InvitePartyState();
|
||||
invite_party_state.InvitePartyGuid = recv.Key;
|
||||
invite_party_state.InvitePartyLeaderNickname = party_info.leader_nickname;
|
||||
invite_party_state.InvitePartyLeaderGuid = party_info.leader_guid;
|
||||
invite_party_state.CurrentPartyMemberCount = party_info.member_count ?? 0;
|
||||
invite_party_state.EndTime = recv.Value.AddMilliseconds(ServerCommon.Constant.KEEP_INVITEPARTY_TIME).ToTimestamp();
|
||||
|
||||
invites.Add(invite_party_state);
|
||||
}
|
||||
|
||||
send_S2C_ACK_INVITE_PARTY_LIST(entity_player, result, invites);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
using USER_GUID = System.String;
|
||||
|
||||
|
||||
|
||||
namespace GameServer.PacketHandler;
|
||||
|
||||
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.InvitePartyReq), typeof(InvitePartyPacketHandler), typeof(GameLoginListener))]
|
||||
public class InvitePartyPacketHandler : PacketRecvHandler
|
||||
{
|
||||
private static void send_S2C_ACK_INVITE_PARTY(Player owner, Result result, Dictionary<(USER_GUID? userGuid, string? nickname), ServerErrorCode>? errInvites)
|
||||
{
|
||||
var ack_packet = new ClientToGame
|
||||
{
|
||||
Response = new ClientToGameRes
|
||||
{
|
||||
ErrorCode = result.ErrorCode,
|
||||
InvitePartyRes = new()
|
||||
}
|
||||
};
|
||||
|
||||
if (result.isSuccess())
|
||||
{
|
||||
foreach (var err_member in errInvites ?? new())
|
||||
{
|
||||
var invite_err = new InvitePartyErrorMember
|
||||
{
|
||||
ErrorCode = err_member.Value,
|
||||
InviteUserGuid = err_member.Key.userGuid ?? USER_GUID.Empty,
|
||||
InviteUserNickname = err_member.Key.nickname ?? string.Empty
|
||||
};
|
||||
|
||||
ack_packet.Response.InvitePartyRes.ErrorMemberList.Add(invite_err);
|
||||
}
|
||||
}
|
||||
|
||||
GameServerApp.getServerLogic().onSendPacket(owner, ack_packet);
|
||||
}
|
||||
|
||||
public override async Task<Result> onProcessPacket(ISession entityWithSession, IMessage recvMessage)
|
||||
{
|
||||
var player = entityWithSession as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
|
||||
|
||||
var recv_msg = recvMessage as ClientToGame;
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(recv_msg, () => $"recv_msg is null !!! - {player.toBasicString()}");
|
||||
var request = recv_msg.Request.InvitePartyReq;
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(request, () => $"request is null !!! - {player.toBasicString()}");
|
||||
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var player_action = player.getEntityAction<PlayerAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(player_action, () => $"player_action is null !!! - {player.toBasicString()}");
|
||||
|
||||
var selected_character = player_action.getSelectedCharacter();
|
||||
if (null == selected_character)
|
||||
{
|
||||
err_msg = $"Not selected Character !!! - {player.toBasicString()}";
|
||||
result.setFail(ServerErrorCode.CharacterNotSelected, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
send_S2C_ACK_INVITE_PARTY(player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
var character_action = selected_character.getEntityAction<CharacterAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(character_action, () => $"character_action is null !!! - {selected_character.toBasicString()}");
|
||||
if (character_action.isFarming())
|
||||
{
|
||||
err_msg = $"Character is Farming !!! - {selected_character.toBasicString()}, {player.toBasicString()}";
|
||||
result.setFail(ServerErrorCode.FarimgState, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
send_S2C_ACK_INVITE_PARTY(player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
var err_invites = new Dictionary<(USER_GUID? userGuid, string? nickname), ServerErrorCode>();
|
||||
|
||||
// 1. 초대하는 User 리스트 획득
|
||||
var request_invite_infos = await getInviteUserInfos(request);
|
||||
NullReferenceCheckHelper.throwIfNull(request_invite_infos, () => $"request_invite_infos is null !!! - {player.toBasicString()}");
|
||||
|
||||
var invite_users = new List<string>();
|
||||
foreach (var info in request_invite_infos)
|
||||
{
|
||||
if (info.Value == false)
|
||||
{
|
||||
var err = ServerErrorCode.Success;
|
||||
|
||||
if (info.Key.nickname == null) err = ServerErrorCode.NotFoundNickName;
|
||||
if (info.Key.userGuid == null) err = ServerErrorCode.NotFoundUser;
|
||||
|
||||
err_invites.Add((info.Key.userGuid, info.Key.nickname), err);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (null == info.Key.userGuid) continue;
|
||||
if (info.Key.userGuid == player.getUserGuid()) continue;
|
||||
|
||||
invite_users.Add(info.Key.userGuid);
|
||||
}
|
||||
|
||||
if (invite_users.Count <= 0)
|
||||
{
|
||||
err_msg = $"Failed to invite party !!! : invite user is zero!!";
|
||||
result.setFail(ServerErrorCode.InvitePartyInvalidUsers, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_INVITE_PARTY(player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 파티가 없으면 생성하기
|
||||
var personal_party_action = player.getEntityAction<PersonalPartyAction>();
|
||||
var party = personal_party_action.getPersonalParty();
|
||||
var is_create = false;
|
||||
if (null == party)
|
||||
{
|
||||
result = await personal_party_action.createDefaultParty();
|
||||
if (result.isFail())
|
||||
{
|
||||
send_S2C_ACK_INVITE_PARTY(player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
party = personal_party_action.getPersonalParty();
|
||||
is_create = true;
|
||||
}
|
||||
|
||||
NullReferenceCheckHelper.throwIfNull(party, () => $"party is null !!");
|
||||
|
||||
// 4. 파티 초대
|
||||
var party_invite_action = party.getEntityAction<PartyInviteAction>();
|
||||
if (null == party_invite_action)
|
||||
{
|
||||
err_msg = $"Failed to get entity action !!! : {nameof(PartyInviteAction)}";
|
||||
result.setFail(ServerErrorCode.EntityActionNotFound, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_INVITE_PARTY(player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
var invite_party = await party_invite_action.inviteParty(invite_users);
|
||||
|
||||
|
||||
// 5. 에러 유저 정리
|
||||
foreach (var invite_result in invite_party.err_invites ?? new())
|
||||
{
|
||||
var nickname = string.Empty;
|
||||
foreach (var user in request_invite_infos.Where(user => user.Key.userGuid == invite_result.Key))
|
||||
{
|
||||
nickname = user.Key.nickname;
|
||||
break;
|
||||
}
|
||||
|
||||
err_invites.Add((invite_result.Key, nickname), invite_result.Value);
|
||||
}
|
||||
|
||||
// 6. 데이터 정리
|
||||
if (is_create && (invite_party.result.isFail() || request.InviteUserGuids.Count + request.InviteUserNicknames.Count == err_invites.Count))
|
||||
{
|
||||
await personal_party_action.clearPersonalParty();
|
||||
}
|
||||
|
||||
// 7. 결과 전송
|
||||
send_S2C_ACK_INVITE_PARTY(player, invite_party.result, err_invites);
|
||||
|
||||
// 8. Business Log 기록
|
||||
if (invite_party.result.isSuccess())
|
||||
{
|
||||
writeBusinessLog(player, is_create, party.getPartyGuid(), invite_users);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Dictionary<(USER_GUID? userGuid, string? nickname), bool>> getInviteUserInfos(ClientToGameReq.Types.InvitePartyReq request)
|
||||
{
|
||||
var infos = new Dictionary<(USER_GUID?, string?), bool>();
|
||||
|
||||
// 1. nickname 으로 guid 획득
|
||||
foreach (var nickname in request.InviteUserNicknames)
|
||||
{
|
||||
var find = await NicknameHelper.findNickname(nickname);
|
||||
if (find.Item1.isFail() || null == find.Item2)
|
||||
{
|
||||
infos.Add((null, nickname), false);
|
||||
continue;
|
||||
}
|
||||
|
||||
infos.Add((find.Item2.UserGuid, nickname), true);
|
||||
}
|
||||
|
||||
// 2. guid 로 nickname 획득
|
||||
foreach (var guid in request.InviteUserGuids)
|
||||
{
|
||||
var nickname = await PartyHelper.getUserNicknameFromGuid(guid);
|
||||
if (null == nickname)
|
||||
{
|
||||
infos.Add((guid, null), false);
|
||||
continue;
|
||||
}
|
||||
|
||||
infos.Add((guid, nickname), true);
|
||||
}
|
||||
|
||||
return infos;
|
||||
}
|
||||
|
||||
private void writeBusinessLog(Player player, bool isCreate, string partyGuid, List<string> inviteUsers)
|
||||
{
|
||||
var party_log_data = PartyBusinessLogHelper.toPartyLogData(partyGuid, isCreate);
|
||||
|
||||
// 1. 파티 생성 기록
|
||||
PartyBusinessLog party_business_log;
|
||||
|
||||
if (isCreate)
|
||||
{
|
||||
party_business_log = new PartyBusinessLog(new LogActionEx(LogActionType.CreateParty), party_log_data);
|
||||
BusinessLogger.collectLog(player, party_business_log);
|
||||
}
|
||||
|
||||
// 2. 파티 초대 기록
|
||||
var invite_logs = new List<ILogInvoker>();
|
||||
foreach (var invite in inviteUsers)
|
||||
{
|
||||
var log_data = PartyBusinessLogHelper.toPartyMemberLogData(partyGuid, invite, PartyMemberActionType.Invite);
|
||||
var party_member_business_log = new PartyMemberBusinessLog(log_data);
|
||||
invite_logs.Add(party_member_business_log);
|
||||
}
|
||||
|
||||
party_business_log = new PartyBusinessLog(party_log_data);
|
||||
invite_logs.Add(party_business_log);
|
||||
|
||||
BusinessLogger.collectLogs(new LogActionEx(LogActionType.InviteParty), player, invite_logs);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
|
||||
namespace GameServer.PacketHandler;
|
||||
|
||||
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.InvitePartySendListReq), typeof(InvitePartySendListPacketHandler), typeof(GameLoginListener))]
|
||||
public class InvitePartySendListPacketHandler : PacketRecvHandler
|
||||
{
|
||||
private static void send_S2C_ACK_INVITE_PARTY_SEND_LIST(Player owner, Result result, IReadOnlyList<InvitePartySendState>? invites)
|
||||
{
|
||||
var ack_packet = new ClientToGame
|
||||
{
|
||||
Response = new ClientToGameRes
|
||||
{
|
||||
ErrorCode = result.ErrorCode,
|
||||
InvitePartySendListRes = new()
|
||||
}
|
||||
};
|
||||
|
||||
if (result.isSuccess() && null != invites)
|
||||
{
|
||||
ack_packet.Response.InvitePartySendListRes.InvitePartySendList.AddRange(invites);
|
||||
}
|
||||
|
||||
GameServerApp.getServerLogic().onSendPacket(owner, ack_packet);
|
||||
}
|
||||
|
||||
public override async Task<Result> onProcessPacket(ISession entityWithSession, IMessage recvMessage)
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
var entity_player = entityWithSession as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(entity_player, () => "player is null !!!");
|
||||
|
||||
// 1. 기본 정보 체크
|
||||
var request = (recvMessage as ClientToGame)?.Request.InvitePartySendListReq;
|
||||
if (null == request)
|
||||
{
|
||||
err_msg = $"Failed to get request type !!! : {nameof(ClientToGame.Request.InvitePartySendListReq)}";
|
||||
result.setFail(ServerErrorCode.InvalidArgument, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
send_S2C_ACK_INVITE_PARTY_SEND_LIST(entity_player, result, null);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 소속 파티 Guid 조회
|
||||
var personal_party_action = entity_player.getEntityAction<PersonalPartyAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(personal_party_action, () => $"personal party action is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
var personal_party = personal_party_action.getPersonalParty();
|
||||
if (null == personal_party)
|
||||
{
|
||||
err_msg = $"Failed to get party info !!! - not party member - {entity_player.getUserGuid()}";
|
||||
result.setFail(ServerErrorCode.NotParty, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_INVITE_PARTY_SEND_LIST(entity_player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party, () => "global party is null !!!");
|
||||
|
||||
var party = global_party.getParty(personal_party.getPartyGuid());
|
||||
NullReferenceCheckHelper.throwIfNull(party, () => "global party detail is null !!!");
|
||||
|
||||
// 3. 파티장 체크
|
||||
var party_action = party.getEntityAction<GlobalPartyDetailAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_action, () => $"party detail action is null !!! - {entity_player.toBasicString()} / {party.toBasicString()}");
|
||||
|
||||
var is_leader = party_action.isLeader(entity_player.getUserGuid());
|
||||
if (!is_leader)
|
||||
{
|
||||
err_msg = $"Failed to summon party member !!! : not party leader - {entity_player.getUserGuid()}";
|
||||
result.setFail(ServerErrorCode.NotPartyLeader, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_INVITE_PARTY_SEND_LIST(entity_player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 4. invite send list 획득
|
||||
var party_invite_send_action = party.getEntityAction<GlobalPartyInvitePartySendAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_invite_send_action, () => $"GlobalPartyInvitePartySendAction is null !!! - {entity_player.toBasicString()} / {party.toBasicString()}");
|
||||
|
||||
var sends = await party_invite_send_action.getPartyInvitePartySends();
|
||||
|
||||
var invites = new List<InvitePartySendState>();
|
||||
foreach (var send in sends)
|
||||
{
|
||||
var nickname = await PartyHelper.getUserNicknameFromGuid(send.Key);
|
||||
|
||||
var invite = new InvitePartySendState();
|
||||
invite.InviteUserNickname = nickname ?? string.Empty;
|
||||
invite.InviteUserGuid = send.Key;
|
||||
invite.EndTime = Timestamp.FromDateTime(send.Value);
|
||||
|
||||
invites.Add(invite);
|
||||
}
|
||||
|
||||
send_S2C_ACK_INVITE_PARTY_SEND_LIST(entity_player, result, invites);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,285 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
|
||||
namespace GameServer.PacketHandler;
|
||||
|
||||
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.JoinPartyInstanceReq), typeof(JoinPartyInstancePacketHandler), typeof(GameLoginListener))]
|
||||
public class JoinPartyInstancePacketHandler : PacketRecvHandler
|
||||
{
|
||||
private static void send_S2C_ACK_JOIN_PARTY_INSTANCE(Player owner, Result result, ClientToGameRes.Types.JoinPartyInstanceRes? response)
|
||||
{
|
||||
var ack_packet = new ClientToGame
|
||||
{
|
||||
Response = new ClientToGameRes
|
||||
{
|
||||
ErrorCode = result.ErrorCode,
|
||||
JoinPartyInstanceRes = new()
|
||||
}
|
||||
};
|
||||
|
||||
if (result.isSuccess())
|
||||
{
|
||||
ack_packet.Response.JoinPartyInstanceRes = response;
|
||||
}
|
||||
|
||||
GameServerApp.getServerLogic().onSendPacket(owner, ack_packet);
|
||||
}
|
||||
|
||||
public override async Task<Result> onProcessPacket(ISession entityWithSession, IMessage recvMessage)
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
var entity_player = entityWithSession as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(entity_player, () => "player is null !!!");
|
||||
|
||||
// 1. 기본 정보 체크
|
||||
var request = (recvMessage as ClientToGame)?.Request.JoinPartyInstanceReq;
|
||||
if (null == request)
|
||||
{
|
||||
err_msg = $"Failed to get request type !!! : {nameof(ClientToGame.Request.JoinPartyInstanceReq)}";
|
||||
result.setFail(ServerErrorCode.InvalidArgument, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
send_S2C_ACK_JOIN_PARTY_INSTANCE(entity_player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 소속 파티 Guid 조회
|
||||
var personal_party_action = entity_player.getEntityAction<PersonalPartyAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(personal_party_action, () => $"personal_party_action is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
var personal_party = personal_party_action.getPersonalParty();
|
||||
if (null == personal_party)
|
||||
{
|
||||
err_msg = $"Failed to get party info !!! - not party member - {entity_player.getUserGuid()}";
|
||||
result.setFail(ServerErrorCode.NotParty, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_JOIN_PARTY_INSTANCE(entity_player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party, () => "global_party is null !!!");
|
||||
|
||||
var party = global_party.getParty(personal_party.getPartyGuid());
|
||||
NullReferenceCheckHelper.throwIfNull(party, () => $"party is null !!! - party guid: {personal_party.getPartyGuid()}");
|
||||
|
||||
// 3. Party Instance 정보 조회
|
||||
var party_instance_attribute = party.getEntityAttribute<PartyInstanceAttribute>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_instance_attribute, () => $"party_instance_attribute is null !!! - {entity_player.toBasicString()} / {party.toBasicString()}");
|
||||
|
||||
if (party_instance_attribute.InstanceId <= 0)
|
||||
{
|
||||
err_msg = $"Failed to join party instance !!! - instance id is null - {party_instance_attribute.InstanceId}";
|
||||
result.setFail(ServerErrorCode.EmptyPartyInstanceId, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_JOIN_PARTY_INSTANCE(entity_player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 4. Party Instance 입장 요청
|
||||
result = await joinPartyInstance(entity_player, party_instance_attribute.InstanceId, party_instance_attribute.RoomId);
|
||||
if (result.isFail())
|
||||
{
|
||||
send_S2C_ACK_JOIN_PARTY_INSTANCE(entity_player, result, null);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Result> joinPartyInstance(Player player, int instanceId, string roomId)
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
var res = new ClientToGameRes.Types.JoinPartyInstanceRes();
|
||||
|
||||
// 1. instance 입장 티켓 확인
|
||||
result = player.checkInstanceAccess(instanceId);
|
||||
if (result.isFail())
|
||||
{
|
||||
err_msg = $"Failed to join party instance !!! : no exist entered ticket - instanceMetaId:{instanceId}";
|
||||
result.setFail(ServerErrorCode.NotExistInstanceTicket, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. join instance
|
||||
var instance_room_id = await InstanceRoomHandler.JoinPartyInstance(player.getUserGuid(), roomId);
|
||||
if (instance_room_id == string.Empty)
|
||||
{
|
||||
err_msg = $"Failed to join party instance !!! - {instanceId}";
|
||||
result.setFail(ServerErrorCode.JoinInstanceFail, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 3. room 정보 획득
|
||||
var instance_room_storage = new InstanceRoomStorage();
|
||||
instance_room_storage.Init(server_logic.getRedisDb(), "");
|
||||
|
||||
var instanceRoom = await instance_room_storage.GetInstanceRoomInfo(instance_room_id);
|
||||
if (instanceRoom == null)
|
||||
{
|
||||
err_msg = $"Not found InstanceRoomInfo. roomId:{instance_room_id}";
|
||||
result.setFail(ServerErrorCode.NotExistRoomInfoForEnter, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
var serverName = ServerType.Indun.toServerName(instanceRoom.InstanceAddress, (ushort)instanceRoom.InstancePort);
|
||||
|
||||
// 4. 이동 예약 요청
|
||||
var message = new ServerMessage.Types.GS2GS_REQ_RESERVATION_ENTER_TO_SERVER();
|
||||
message.MoveType = ServerMoveType.Force;
|
||||
message.RequestServerName = server_logic.getServerName();
|
||||
message.RequestUserGuid = player.getUserGuid();
|
||||
|
||||
var reserved = await server_logic.getReservationManager().registerReservationEnterToServer(message, serverName);
|
||||
|
||||
// 5. 예약 실패 체크
|
||||
if (null == reserved)
|
||||
{
|
||||
err_msg = $"Failed to reservation enter to game server!!! - {nameof(JoinInstancePacketHandler)}";
|
||||
Log.getLogger().error(err_msg);
|
||||
result.setFail(ServerErrorCode.FailedToReservationEnter, err_msg);
|
||||
|
||||
send_S2C_ACK_JOIN_PARTY_INSTANCE(player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 6. 이동 처리
|
||||
result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "JoinPartyInstance",
|
||||
joinPartyInstanceDelegate);
|
||||
if (result.isFail())
|
||||
{
|
||||
err_msg = $"Failed to transactionRunner !! : {result.ResultString}";
|
||||
Log.getLogger().error(err_msg);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
async Task<Result> joinPartyInstanceDelegate() => await joinPartyInstanceAsync(player, serverName, roomId, instanceRoom);
|
||||
}
|
||||
|
||||
public async Task<Result> joinPartyInstanceAsync(Player player, string destServerName, string roomId, InstanceRoomInfo instanceRoom)
|
||||
{
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
// 1. 위치 정보 수정
|
||||
var location_action = player.getEntityAction<LocationAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(location_action, () => $"location_action is null !!! - {player.toBasicString()}");
|
||||
|
||||
result = await location_action.tryMoveToIndun(instanceRoom);
|
||||
if (result.isFail())
|
||||
{
|
||||
err_msg = $"Fail to tryMoveToIndun";
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_JOIN_PARTY_INSTANCE(player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!MetaData.Instance._IndunTable.TryGetValue(instanceRoom.InstanceId, out var indun_meta_data))
|
||||
{
|
||||
err_msg = $"Failed to TryGetValue() !!! : instanceMetaId:{instanceRoom.InstanceId} : {this.getTypeName()}";
|
||||
result.setFail(ServerErrorCode.InstanceMetaDataNotFound, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
send_S2C_ACK_JOIN_PARTY_INSTANCE(player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
var buff_action = player.getEntityAction<BuffAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(buff_action, () => $"buff_action is null !!! - {player.toBasicString()}");
|
||||
|
||||
result = await buff_action.MoveServer(indun_meta_data.placeType());
|
||||
if (result.isFail())
|
||||
{
|
||||
send_S2C_ACK_JOIN_PARTY_INSTANCE(player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. otp 획득
|
||||
(result, var reserved_to_switch_server) = await ServerConnectionSwitchHelper.startServerSwitch(player, server_logic.getRedisConnector() , destServerName);
|
||||
if (result.isFail() || null == reserved_to_switch_server)
|
||||
{
|
||||
err_msg = $"Fail to startServerSwitch() !!! : {result.toBasicString()}";
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_JOIN_PARTY_INSTANCE(player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
var game_login_action = player.getEntityAction<GameLoginAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(game_login_action, () => $"game_login_action is null !!! - {player.toBasicString()}");
|
||||
|
||||
var login_cache = game_login_action.getLoginCacheRequest()?.getLoginCache();
|
||||
NullReferenceCheckHelper.throwIfNull(login_cache, () => $"Login Cache is null !!! - player: {player.toBasicString()}");
|
||||
|
||||
login_cache.ReservedToSwitchServer = reserved_to_switch_server;
|
||||
|
||||
var res = new ClientToGameRes.Types.JoinPartyInstanceRes();
|
||||
res.InstanceServerAddr = instanceRoom.InstanceAddress;
|
||||
res.InstanceServerPort = instanceRoom.InstancePort;
|
||||
res.Otp = reserved_to_switch_server.OneTimeKey;
|
||||
res.RoomId = roomId;
|
||||
|
||||
// 3. DB 갱신
|
||||
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.JoinPartyInstance, server_logic.getDynamoDbClient());
|
||||
{
|
||||
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
|
||||
batch.addQuery(new QueryFinal());
|
||||
}
|
||||
|
||||
writeBusinessLog(batch, player.getUserGuid(), roomId);
|
||||
|
||||
result = await QueryHelper.sendQueryAndBusinessLog(batch);
|
||||
if (result.isFail())
|
||||
{
|
||||
err_msg = $"Failed to write for reserve enter GameServer !!! - {player.toBasicString()}";
|
||||
result.setFail(ServerErrorCode.NoServerConnectable, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
send_S2C_ACK_JOIN_PARTY_INSTANCE(player, result, res);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void writeBusinessLog(QueryBatchBase queryBatchBase, string userGuid, string roomId)
|
||||
{
|
||||
var party_guid = PartyHelper.getPartyGuidFromPartyInstanceRoomId(roomId);
|
||||
if (string.IsNullOrEmpty(party_guid)) return;
|
||||
|
||||
// 1. 파티 인스턴스 정보
|
||||
var party_instance_log_data = PartyBusinessLogHelper.toPartyInstanceLogData(party_guid, false);
|
||||
var party_instance_business_log = new PartyInstanceBusinessLog(party_instance_log_data);
|
||||
queryBatchBase.appendBusinessLog(party_instance_business_log);
|
||||
|
||||
// 2. 파티 멤버 정보
|
||||
var party_member_log_data =
|
||||
PartyBusinessLogHelper.toPartyMemberLogData(party_guid, userGuid, PartyMemberActionType.PartyInstanceJoin);
|
||||
var party_member_business_log = new PartyMemberBusinessLog(party_member_log_data);
|
||||
queryBatchBase.appendBusinessLog(party_member_business_log);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
using PARTY_GUID = System.String;
|
||||
using USER_GUID = System.String;
|
||||
|
||||
|
||||
namespace GameServer.PacketHandler;
|
||||
|
||||
|
||||
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.LeavePartyReq), typeof(LeavePartyPacketHandler), typeof(GameLoginListener))]
|
||||
public class LeavePartyPacketHandler : PacketRecvHandler
|
||||
{
|
||||
private static void send_S2C_ACK_LEAVE_PARTY(Player owner, Result result)
|
||||
{
|
||||
var ack_packet = new ClientToGame
|
||||
{
|
||||
Response = new ClientToGameRes
|
||||
{
|
||||
ErrorCode = result.ErrorCode,
|
||||
LeavePartyRes = new()
|
||||
}
|
||||
};
|
||||
|
||||
GameServerApp.getServerLogic().onSendPacket(owner, ack_packet);
|
||||
}
|
||||
|
||||
public override async Task<Result> onProcessPacket(ISession entityWithSession, IMessage recvMessage)
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
var entity_player = entityWithSession as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(entity_player, () => "player is null !!!");
|
||||
|
||||
// 1. 기본 정보 체크
|
||||
var request = (recvMessage as ClientToGame)?.Request.LeavePartyReq;
|
||||
if (null == request)
|
||||
{
|
||||
err_msg = $"Failed to get request type !!! : {nameof(ClientToGame.Request.LeavePartyReq)}";
|
||||
result.setFail(ServerErrorCode.InvalidArgument, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
send_S2C_ACK_LEAVE_PARTY(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 파티 떠나기 처리
|
||||
var personal_party_action = entity_player.getEntityAction<PersonalPartyAction>();
|
||||
result = await personal_party_action.leaveParty();
|
||||
|
||||
send_S2C_ACK_LEAVE_PARTY(entity_player, result);
|
||||
await QuestManager.It.QuestCheck(entity_player, new QuestParty(EQuestEventTargetType.PARTY, EQuestEventNameType.EXITED));
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
using USER_GUID = System.String;
|
||||
|
||||
|
||||
namespace GameServer.PacketHandler;
|
||||
|
||||
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.PartyVoteReq), typeof(PartyVotePacketHandler), typeof(GameLoginListener))]
|
||||
public class PartyVotePacketHandler : PacketRecvHandler
|
||||
{
|
||||
private static void send_S2C_ACK_PARTY_VOTE(Player? owner, Result result)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(owner);
|
||||
var ack_packet = new ClientToGame
|
||||
{
|
||||
Response = new ClientToGameRes
|
||||
{
|
||||
ErrorCode = result.ErrorCode,
|
||||
PartyVoteRes = new()
|
||||
}
|
||||
};
|
||||
|
||||
GameServerApp.getServerLogic().onSendPacket(owner, ack_packet);
|
||||
}
|
||||
|
||||
public override async Task<Result> onProcessPacket(ISession entityWithSession, IMessage recvMessage)
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
var entity_player = entityWithSession as Player;
|
||||
ArgumentNullException.ThrowIfNull(entity_player);
|
||||
|
||||
// 1. 기본 정보 체크
|
||||
var request = (recvMessage as ClientToGame)?.Request.PartyVoteReq;
|
||||
if (null == request)
|
||||
{
|
||||
err_msg = $"Failed to get request type !!! : {nameof(ClientToGame.Request.PartyVoteReq)}";
|
||||
result.setFail(ServerErrorCode.InvalidArgument, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
send_S2C_ACK_PARTY_VOTE(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 소속 파티 Guid 조회
|
||||
var personal_party_action = entity_player.getEntityAction<PersonalPartyAction>();
|
||||
ArgumentNullException.ThrowIfNull(personal_party_action);
|
||||
|
||||
var personal_party = personal_party_action.getPersonalParty();
|
||||
if (null == personal_party)
|
||||
{
|
||||
err_msg = $"Failed to get party info !!! - not party member - {entity_player.getUserGuid()}";
|
||||
result.setFail(ServerErrorCode.NotParty, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_PARTY_VOTE(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
ArgumentNullException.ThrowIfNull(global_party);
|
||||
|
||||
var party = global_party.getParty(personal_party.getPartyGuid());
|
||||
ArgumentNullException.ThrowIfNull(party);
|
||||
|
||||
// 3. 파티장 체크
|
||||
var party_action = party.getEntityAction<GlobalPartyDetailAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_action);
|
||||
|
||||
var is_leader = party_action.isLeader(entity_player.getUserGuid());
|
||||
if (!is_leader)
|
||||
{
|
||||
err_msg = $"Failed to summon party member !!! : not party leader - {entity_player.getUserGuid()}";
|
||||
result.setFail(ServerErrorCode.NotPartyLeader, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_PARTY_VOTE(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 4. Vote 시작
|
||||
var party_info_action = party.getEntityAction<GlobalPartyDetailInfoAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_info_action);
|
||||
|
||||
var start_vote = await party_info_action.registerPartyVote(request.VoteInfo, DateTime.UtcNow.ToTimestamp(), true);
|
||||
if (start_vote.result.isFail())
|
||||
{
|
||||
send_S2C_ACK_PARTY_VOTE(entity_player, start_vote.result);
|
||||
return result;
|
||||
}
|
||||
NullReferenceCheckHelper.throwIfNull(start_vote.vote, () => $"start_vote.vote is null !!!");
|
||||
|
||||
// 4. vote 시작 알림 ( to server )
|
||||
var server_message = new ServerMessage();
|
||||
server_message.PartyVoteNoti = new();
|
||||
server_message.PartyVoteNoti.PartyGuid = party.PartyGuid;
|
||||
server_message.PartyVoteNoti.VoteTitle = start_vote.vote.VoteTitle;
|
||||
server_message.PartyVoteNoti.VoteStartTime = start_vote.vote.StartVoteTime;
|
||||
|
||||
PartyHelper.BroadcastToServers(party, server_message, true);
|
||||
|
||||
// 5. vote 시작 알림 ( to client )
|
||||
var client_message = new ClientToGame();
|
||||
client_message.Message = new();
|
||||
client_message.Message.PartyVoteNoti = new();
|
||||
client_message.Message.PartyVoteNoti.VoteTitle = start_vote.vote.VoteTitle;
|
||||
client_message.Message.PartyVoteNoti.VoteStartTime = start_vote.vote.StartVoteTime;
|
||||
|
||||
PartyHelper.BroadcastToClients(party, client_message, new List<USER_GUID>());
|
||||
|
||||
// 6. business log 기록
|
||||
writeBusinessLog(entity_player, party.PartyGuid);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void writeBusinessLog(Player owner, string partyGuid)
|
||||
{
|
||||
var log_invokers = new List<ILogInvoker>(2);
|
||||
|
||||
// 1. 파티 정보
|
||||
var party_log_data = PartyBusinessLogHelper.toPartyLogData(partyGuid, false);
|
||||
ArgumentNullException.ThrowIfNull(party_log_data);
|
||||
var party_business_log = new PartyBusinessLog(party_log_data);
|
||||
log_invokers.Add(party_business_log);
|
||||
|
||||
// 2. 파티 투표 정보
|
||||
var party_vote_log_data = PartyBusinessLogHelper.toPartyVoteLogData(partyGuid, true);
|
||||
ArgumentNullException.ThrowIfNull(party_vote_log_data);
|
||||
var party_vote_business_log = new PartyVoteBusinessLog(party_vote_log_data);
|
||||
log_invokers.Add(party_vote_business_log);
|
||||
|
||||
BusinessLogger.collectLogs(new LogActionEx(LogActionType.StartPartyVote), owner, log_invokers);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
using PARTY_GUID = System.String;
|
||||
using USER_GUID = System.String;
|
||||
|
||||
|
||||
namespace GameServer.PacketHandler;
|
||||
|
||||
|
||||
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.ReplyInvitePartyReq), typeof(ReplyInvitePartyPacketHandler), typeof(GameLoginListener))]
|
||||
public class ReplyInvitePartyPacketHandler : PacketRecvHandler
|
||||
{
|
||||
private static void send_S2C_ACK_REPLAY_INVITE_PARTY(Player owner, Result result)
|
||||
{
|
||||
var ack_packet = new ClientToGame
|
||||
{
|
||||
Response = new ClientToGameRes
|
||||
{
|
||||
ErrorCode = result.ErrorCode,
|
||||
ReplyInvitePartyRes = new()
|
||||
}
|
||||
};
|
||||
|
||||
GameServerApp.getServerLogic().onSendPacket(owner, ack_packet);
|
||||
}
|
||||
|
||||
public override async Task<Result> onProcessPacket(ISession entityWithSession, IMessage recvMessage)
|
||||
{
|
||||
Log.getLogger().info($"{nameof(ReplyInvitePartyPacketHandler)}.{nameof(onProcessPacket)}: - {recvMessage}");
|
||||
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
var entity_player = entityWithSession as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(entity_player, () => $"entity_player is null !!!");
|
||||
|
||||
// 1. 기본 정보 체크
|
||||
var request = (recvMessage as ClientToGame)?.Request.ReplyInvitePartyReq;
|
||||
if (null == request)
|
||||
{
|
||||
err_msg = $"Failed to get request type !!! : {nameof(ClientToGame.Request.ReplyInvitePartyReq)}";
|
||||
result.setFail(ServerErrorCode.InvalidArgument, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
send_S2C_ACK_REPLAY_INVITE_PARTY(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 조건 체크
|
||||
result = await checkReplayInvitePartyAsync(entity_player, request.InvitePartyGuid);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 3. 파티 초대 응답 로직 체크
|
||||
result = await replyInvitePartyAsync(entity_player, request.InvitePartyGuid, request.Result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Result> checkReplayInvitePartyAsync(Player entity_player, PARTY_GUID invite_party_guid)
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
// 1. 초대 수신 시간 체크
|
||||
var invite_recv_time = await entity_player.getEntityAction<PartyInvitePartyRecvAction>()
|
||||
.getPartyInvitePartyRecvTime(invite_party_guid);
|
||||
if (null == invite_recv_time)
|
||||
{
|
||||
err_msg = $"Failed to find invite party recv !!! : {invite_party_guid}";
|
||||
result.setFail(ServerErrorCode.NotFoundPartyInvite, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 파티 가입 여부 체크
|
||||
var login_cache_request = PartyHelper.getOwnUserLoginCacheRequest(entity_player);
|
||||
NullReferenceCheckHelper.throwIfNull(login_cache_request, () => $"login_cache_request is null !!! - party_guid : {invite_party_guid} - {entity_player.toBasicString()}");
|
||||
var loginCache = login_cache_request.getLoginCache();
|
||||
NullReferenceCheckHelper.throwIfNull(loginCache, () => $"loginCache is null !!! - party_guid : {invite_party_guid} -");
|
||||
if (string.IsNullOrEmpty(loginCache.PartyGuid)) return result;
|
||||
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party, () => $"global_party is null !!! - party_guid : {invite_party_guid} - {entity_player.toBasicString()}");
|
||||
|
||||
var party = global_party.getParty(loginCache.PartyGuid);
|
||||
NullReferenceCheckHelper.throwIfNull(party, () => $"party is null !!! - party_guid : {invite_party_guid} - {entity_player.toBasicString()}");
|
||||
|
||||
// 3. 파티원 수가 여러명인지 체크
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_member_action, () => $"party_member_action is null !!! - party_guid : {invite_party_guid} - {entity_player.toBasicString()}");
|
||||
|
||||
if (party_member_action.getMemberCount() > 1)
|
||||
{
|
||||
err_msg = $"Failed to reply invite party !!! : already party member - party_guid : {invite_party_guid} - {entity_player.getUserGuid()} ";
|
||||
result.setFail(ServerErrorCode.AlreadyPartyMember, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Result> replyInvitePartyAsync(Player entity_player, PARTY_GUID party_guid, BoolType reply_invite)
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
// 1. 파티 정보 조회
|
||||
var global_party_action = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>()
|
||||
?.getEntityAction<GlobalPartyAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party_action, () => $"global_party_action is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
var party_info = await global_party_action.getPartyLeaderGuidAndMemberCount(party_guid);
|
||||
if (PARTY_GUID.IsNullOrEmpty(party_info.leader_guid))
|
||||
{
|
||||
err_msg = $"Failed to find party info !!! : {party_guid}";
|
||||
result.setFail(ServerErrorCode.NotFoundParty, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. Invite 승인 로직 처리
|
||||
if (reply_invite == BoolType.True)
|
||||
{
|
||||
result = await acceptInvitePartyAsync(entity_player, party_guid);
|
||||
if (result.isFail())
|
||||
{
|
||||
send_S2C_ACK_REPLAY_INVITE_PARTY(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. leader 에게 통보
|
||||
result = await sendReplyInvitePartyResultAsync(entity_player, party_guid, party_info.leader_guid, reply_invite);
|
||||
|
||||
send_S2C_ACK_REPLAY_INVITE_PARTY(entity_player, result);
|
||||
|
||||
// 4. Business Log 기록
|
||||
writeBusinessLog(entity_player, party_guid, reply_invite);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Result> acceptInvitePartyAsync(Player entity_player, PARTY_GUID party_guid)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party, () => $"global_party is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
var global_party_action = global_party.getEntityAction<GlobalPartyAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party_action, () => $"global_party_action is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
// 0. 기존 요청 정보 정리
|
||||
result = await clearMyInvitePartySendAsync(entity_player);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 1. user 정보 수정
|
||||
result = await setInvitePartyToUserAsync(entity_player, party_guid);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 2. party join 처리
|
||||
var party_member = PartyHelper.makePartyMember(entity_player.getUserGuid(), entity_player.getUserNickname());
|
||||
result = await global_party_action.joinParty(party_guid, party_member);
|
||||
if (result.isFail())
|
||||
{
|
||||
// 2-1. user 정보 롤백
|
||||
result = await setInvitePartyToUserAsync(entity_player, string.Empty);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Result> clearMyInvitePartySendAsync(Player entity_player)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
// 1. 파티 정보 조회
|
||||
var personal_party_action = entity_player.getEntityAction<PersonalPartyAction>();
|
||||
var personal_party = personal_party_action.getPersonalParty();
|
||||
if (null == personal_party) return result;
|
||||
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party, () => $"global_party is null !!! - {entity_player.toBasicString()}");
|
||||
var party = global_party.getParty(personal_party.getPartyGuid());
|
||||
if (null == party) return result;
|
||||
|
||||
// 2. 파티 인원수 체크
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_member_action, () => $"party_member_action is null !!! - {entity_player.toBasicString()}");
|
||||
if (party_member_action.getMemberCount() > 1)
|
||||
{
|
||||
var err_msg = $"Failed to reply invite party !!! : already party member - {party.PartyGuid}";
|
||||
result.setFail(ServerErrorCode.AlreadyPartyMember, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 3. 파티 destroy
|
||||
var global_party_acton = global_party.getEntityAction<GlobalPartyAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party_acton, () => $"global_party_acton is null !!! - {entity_player.toBasicString()}");
|
||||
result = await global_party_acton.destroyParty(party.PartyGuid, false);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 4. user 정보 정리
|
||||
result = await personal_party_action.clearPersonalParty();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Result> setInvitePartyToUserAsync(Player entity_player, PARTY_GUID party_guid)
|
||||
{
|
||||
// 1. 파티 정보 설정
|
||||
var personal_party_action = entity_player.getEntityAction<PersonalPartyAction>();
|
||||
var result = await personal_party_action.setPersonalPartyGuid(party_guid);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 2. 파티 설정
|
||||
await personal_party_action.setPersonalParty(party_guid);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Result> sendReplyInvitePartyResultAsync(Player entity_player, PARTY_GUID party_guid, USER_GUID leader_guid, BoolType replay_invite)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
// 1. party leader 세션 체크
|
||||
var leader_login_cache = await PartyHelper.getOtherUserLoginCache(entity_player, leader_guid);
|
||||
if (null == leader_login_cache)
|
||||
{
|
||||
var err_msg = $"Failed to get party leader session !!! - {leader_guid}";
|
||||
result.setFail(ServerErrorCode.NotFoundParty, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. invite 응답 결과 전송
|
||||
var message_to_leader = new ServerMessage
|
||||
{
|
||||
ReplyInvitePartyNoti = new ServerMessage.Types.ReplyInvitePartyNoti()
|
||||
{
|
||||
InvitePartyGuid = party_guid,
|
||||
InviteUserGuid = entity_player.getUserGuid(),
|
||||
InviteUserNickname = entity_player.getUserNickname(),
|
||||
Result = replay_invite
|
||||
}
|
||||
};
|
||||
|
||||
var rabbit_mq = GameServerApp.getServerLogic().getRabbitMqConnector() as RabbitMqConnector;
|
||||
NullReferenceCheckHelper.throwIfNull(rabbit_mq, () => $"rabbit_mq is null !!!");
|
||||
rabbit_mq.SendMessage(leader_login_cache.CurrentServer, message_to_leader);
|
||||
|
||||
// 3. 파티 초대 Recv 메시지 삭제
|
||||
var party_recv_action = entity_player.getEntityAction<PartyInvitePartyRecvAction>();
|
||||
|
||||
result = await party_recv_action.deleteInvitePartyRecv(party_guid);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void writeBusinessLog(Player player, string partyGuid, BoolType isInviteAccept)
|
||||
{
|
||||
PartyMemberBusinessLog party_member_business_log;
|
||||
|
||||
// 1. 파티 초대 응답 기록
|
||||
var party_member_log =
|
||||
PartyBusinessLogHelper.toPartyMemberLogData(partyGuid, player.getUserGuid(), PartyMemberActionType.None);
|
||||
|
||||
if (BoolType.True != isInviteAccept)
|
||||
{
|
||||
party_member_log.PartyMemberActionType = PartyMemberActionType.InviteReject;
|
||||
party_member_business_log = new PartyMemberBusinessLog(party_member_log);
|
||||
|
||||
BusinessLogger.collectLog(player, party_member_business_log);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
party_member_log.PartyMemberActionType = PartyMemberActionType.InviteAccept;
|
||||
party_member_business_log = new PartyMemberBusinessLog(party_member_log);
|
||||
BusinessLogger.collectLog(player, party_member_business_log);
|
||||
|
||||
// 2. 파티 정보 기록
|
||||
var log_invokers = new List<ILogInvoker>(2);
|
||||
|
||||
var party_log_data = PartyBusinessLogHelper.toPartyLogData(partyGuid, false);
|
||||
var party_business_log = new PartyBusinessLog(party_log_data);
|
||||
log_invokers.Add(party_business_log);
|
||||
|
||||
// 3. 파티 가입 기록
|
||||
party_member_log.PartyMemberActionType = PartyMemberActionType.JoinParty;
|
||||
party_member_business_log = new PartyMemberBusinessLog(party_member_log);
|
||||
log_invokers.Add(party_member_business_log);
|
||||
|
||||
BusinessLogger.collectLogs(new LogActionEx(LogActionType.JoinParty), player, log_invokers);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
using USER_GUID = System.String;
|
||||
|
||||
|
||||
namespace GameServer.PacketHandler;
|
||||
|
||||
|
||||
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.ReplyPartyVoteReq), typeof(ReplyPartyVotePacketHandler), typeof(GameLoginListener))]
|
||||
public class ReplyPartyVotePacketHandler : PacketRecvHandler
|
||||
{
|
||||
private static void send_S2C_ACK_REPLY_PARTY_VOTE(Player owner, Result result)
|
||||
{
|
||||
var ack_packet = new ClientToGame
|
||||
{
|
||||
Response = new ClientToGameRes
|
||||
{
|
||||
ErrorCode = result.ErrorCode,
|
||||
ReplyPartyVoteRes = new()
|
||||
}
|
||||
};
|
||||
|
||||
GameServerApp.getServerLogic().onSendPacket(owner, ack_packet);
|
||||
}
|
||||
|
||||
public override async Task<Result> onProcessPacket(ISession entityWithSession, IMessage recvMessage)
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
var entity_player = entityWithSession as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(entity_player, () => $"entity_player is null !!!");
|
||||
|
||||
// 1. 기본 정보 체크
|
||||
var request = (recvMessage as ClientToGame)?.Request.ReplyPartyVoteReq;
|
||||
if (null == request)
|
||||
{
|
||||
err_msg = $"Failed to get request type !!! : {nameof(ClientToGame.Request.ReplyPartyVoteReq)}";
|
||||
result.setFail(ServerErrorCode.InvalidArgument, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
send_S2C_ACK_REPLY_PARTY_VOTE(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 소속 파티 Guid 조회
|
||||
var personal_party_action = entity_player.getEntityAction<PersonalPartyAction>();
|
||||
|
||||
var personal_party = personal_party_action.getPersonalParty();
|
||||
if (null == personal_party)
|
||||
{
|
||||
err_msg = $"Failed to get party info !!! - not party member - {entity_player.getUserGuid()}";
|
||||
result.setFail(ServerErrorCode.NotParty, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_REPLY_PARTY_VOTE(entity_player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party, () => $"global_party is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
var party = global_party.getParty(personal_party.getPartyGuid());
|
||||
NullReferenceCheckHelper.throwIfNull(party, () => $"party is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
// 3. Reply Vote 등록
|
||||
var party_info_action = party.getEntityAction<GlobalPartyDetailInfoAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_info_action, () => $"party_info_action is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
var vote = (request.Vote != VoteType.None) ? request.Vote : VoteType.Abstain;
|
||||
result = await party_info_action.VoteParty(vote, entity_player.getUserGuid());
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
using USER_GUID = System.String;
|
||||
using PARTY_GUID = System.String;
|
||||
|
||||
|
||||
namespace GameServer.PacketHandler;
|
||||
|
||||
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.ReplySummonPartyMemberReq), typeof(ReplySummonPartyMemberPacketHandler), typeof(GameLoginListener))]
|
||||
public class ReplySummonPartyMemberPacketHandler : PacketRecvHandler
|
||||
{
|
||||
private static void send_S2C_ACK_REPLY_SUMMON_PARTY_MEMBER(Player owner, Result result, ServerConnectInfo? server_connection_info)
|
||||
{
|
||||
var ack_packet = new ClientToGame
|
||||
{
|
||||
Response = new ClientToGameRes
|
||||
{
|
||||
ErrorCode = result.ErrorCode,
|
||||
ReplySummonPartyMemberRes = new()
|
||||
}
|
||||
};
|
||||
|
||||
if (result.isSuccess())
|
||||
{
|
||||
ack_packet.Response.ReplySummonPartyMemberRes.GameServerConnectInfo = server_connection_info;
|
||||
}
|
||||
|
||||
GameServerApp.getServerLogic().onSendPacket(owner, ack_packet);
|
||||
}
|
||||
|
||||
public override async Task<Result> onProcessPacket(ISession entityWithSession, IMessage recvMessage)
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
var entity_player = entityWithSession as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(entity_player, () => $"entity_player is null !!!");
|
||||
|
||||
// 1. 기본 정보 체크
|
||||
var request = (recvMessage as ClientToGame)?.Request.ReplySummonPartyMemberReq;
|
||||
if (null == request)
|
||||
{
|
||||
err_msg = $"Failed to get request type !!! : {nameof(ClientToGame.Request.ReplySummonPartyMemberReq)}";
|
||||
result.setFail(ServerErrorCode.InvalidArgument, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
send_S2C_ACK_REPLY_SUMMON_PARTY_MEMBER(entity_player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 소속 파티 Guid 조회
|
||||
var personal_party_action = entity_player.getEntityAction<PersonalPartyAction>();
|
||||
|
||||
var personal_party = personal_party_action.getPersonalParty();
|
||||
if (null == personal_party)
|
||||
{
|
||||
err_msg = $"Failed to get party info !!! - not party member - {entity_player.getUserGuid()}";
|
||||
result.setFail(ServerErrorCode.NotParty, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_REPLY_SUMMON_PARTY_MEMBER(entity_player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party, () => $"global_party is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
var party = global_party.getParty(personal_party.getPartyGuid());
|
||||
NullReferenceCheckHelper.throwIfNull(party, () => $"party is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
// 3. 소환 대상자 판단
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_member_action, () => $"party_member_action is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
var member = party_member_action.getMember(entity_player.getUserGuid());
|
||||
NullReferenceCheckHelper.throwIfNull(member, () => $"member is null !!! - {entity_player.toBasicString()}");
|
||||
if (false == member.Summon.IsAlreadySummon)
|
||||
{
|
||||
err_msg =
|
||||
$"Failed to reply summon party member !!! : invalid summon member - {entity_player.getUserGuid()}";
|
||||
result.setFail(ServerErrorCode.InvalidSummonMember, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_REPLY_SUMMON_PARTY_MEMBER(entity_player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
var summon_pos = member.Summon.SummonPos;
|
||||
NullReferenceCheckHelper.throwIfNull(summon_pos, () => $"summon_pos is null !!!");
|
||||
summon_pos.Z += 100;
|
||||
|
||||
var summon_server = member.Summon.SummonServer;
|
||||
NullReferenceCheckHelper.throwIfNull(summon_server, () => $"summon_server is null !!!");
|
||||
|
||||
// 4. reject 시 처리
|
||||
if (request.Result != SummonPartyMemberResultType.Accept)
|
||||
{
|
||||
sendReplySummonPartyMemberAsync(summon_server, party.PartyGuid, member.UserGuid, request.Result);
|
||||
send_S2C_ACK_REPLY_SUMMON_PARTY_MEMBER(entity_player, result, null);
|
||||
|
||||
writeBusinessLog(entity_player, party.PartyGuid, request.Result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 5. 동일 channel 서버일 경우
|
||||
if (GameServerApp.getServerLogic().getServerName() == summon_server)
|
||||
{
|
||||
sendReplySummonPartyMemberAsync(summon_server, party.PartyGuid, member.UserGuid, request.Result);
|
||||
send_S2C_ACK_REPLY_SUMMON_PARTY_MEMBER(entity_player, result, null);
|
||||
|
||||
result = moveLocation(entity_player, summon_pos);
|
||||
|
||||
writeBusinessLog(entity_player, party.PartyGuid, request.Result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 6. 다른 channel 서버일 경우
|
||||
result = await moveAnotherServer(entity_player, party.PartyGuid, summon_server, summon_pos);
|
||||
|
||||
writeBusinessLog(entity_player, party.PartyGuid, request.Result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Result moveLocation(Player player, Pos summonPos)
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
// 1. 위치 설정
|
||||
var game_zone_action = player.getEntityAction<GameZoneAction>();
|
||||
result = game_zone_action.tryMove(summonPos);
|
||||
if(result.isFail())
|
||||
{
|
||||
err_msg = $"Failed to tryMove at {this.getTypeName()} !!! : {result.toBasicString()} - {player.toBasicString()}";
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 3. 위치 전송
|
||||
player.send_S2C_NTF_SET_LOCATION();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Result> moveAnotherServer(Player entity_player, PARTY_GUID partyGuid, string summonServer, Pos summonPos)
|
||||
{
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
// 1. 이동 대상 서버 정보 체크
|
||||
var check = await checkServerStatus(summonServer);
|
||||
if (check.result != SummonPartyMemberResultType.Accept || null == check.server)
|
||||
{
|
||||
sendReplySummonPartyMemberAsync(summonServer, partyGuid, entity_player.getUserGuid(), check.result);
|
||||
result.setFail(ServerErrorCode.PartyLeaderServerIsFull, $"Failed to get summon server !!! : summon server is full - {summonServer}");
|
||||
|
||||
send_S2C_ACK_REPLY_SUMMON_PARTY_MEMBER(entity_player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 이동 대상 서버로 이동 예약
|
||||
var req_message = new ServerMessage.Types.GS2GS_REQ_RESERVATION_ENTER_TO_SERVER();
|
||||
req_message.RequestServerName = GameServerApp.getServerLogic().getServerName();
|
||||
req_message.RequestUserGuid = entity_player.getUserGuid();
|
||||
req_message.SummonPartyGuid = partyGuid;
|
||||
|
||||
var reserved = await server_logic.getReservationManager().registerReservationEnterToServer(req_message, summonServer);
|
||||
|
||||
// 3. 예약 실패 체크
|
||||
if (null == reserved)
|
||||
{
|
||||
err_msg = $"Failed to reservation enter to game server!!! - {nameof(ReplySummonPartyMemberPacketHandler)}";
|
||||
Log.getLogger().error(err_msg);
|
||||
result.setFail(ServerErrorCode.FailedToReservationEnter, err_msg);
|
||||
|
||||
sendReplySummonPartyMemberAsync(summonServer, partyGuid, entity_player.getUserGuid(), SummonPartyMemberResultType.SummonFail);
|
||||
send_S2C_ACK_REPLY_SUMMON_PARTY_MEMBER(entity_player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 4. 서버 이동 처리
|
||||
result = await entity_player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "SummonPartyMember", moveToLeaderDelegate);
|
||||
if (result.isFail())
|
||||
{
|
||||
sendReplySummonPartyMemberAsync(reserved.ReservationServerName, partyGuid, entity_player.getUserGuid(), SummonPartyMemberResultType.SummonFail);
|
||||
send_S2C_ACK_REPLY_SUMMON_PARTY_MEMBER(entity_player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 5. 이동 정보 체크
|
||||
var account_attribute = entity_player.getEntityAttribute<AccountAttribute>();
|
||||
NullReferenceCheckHelper.throwIfNull(account_attribute, () => $"account_attribute is null !!! - {entity_player.toBasicString()}");
|
||||
|
||||
var server_info = new ServerConnectInfo();
|
||||
server_info.ServerAddr = account_attribute.ToConnectGameServerAddress.IP;
|
||||
server_info.ServerPort = account_attribute.ToConnectGameServerAddress.Port;
|
||||
server_info.Otp = account_attribute.OtpForServerConnect;
|
||||
server_info.Pos = summonPos;
|
||||
|
||||
sendReplySummonPartyMemberAsync(reserved.ReservationServerName, req_message.SummonPartyGuid, entity_player.getUserGuid(), SummonPartyMemberResultType.Accept);
|
||||
send_S2C_ACK_REPLY_SUMMON_PARTY_MEMBER(entity_player, result, server_info);
|
||||
|
||||
return result;
|
||||
|
||||
async Task<Result> moveToLeaderDelegate() => await moveToLeaderAsync(entity_player, check.server, summonPos);
|
||||
}
|
||||
|
||||
private async Task<Result> moveToLeaderAsync(Player player, ServerInfo destServer, Pos summonPos)
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
// 0. 내가 Instance room 에 있으면, 나가기 처리
|
||||
if (GameServerApp.getServerLogic().getServerType().toServerType() == ServerType.Indun)
|
||||
{
|
||||
var location_attribute = player.getEntityAttribute<LocationAttribute>();
|
||||
NullReferenceCheckHelper.throwIfNull(location_attribute, () => $"location_attribute is null !!! - {player.toBasicString()}");
|
||||
|
||||
var instance_room_Id = location_attribute.CurrentIndunLocation.InstanceRoomId;
|
||||
if (!await InstanceRoomManager.Instance.LeaveRoom(player, instance_room_Id))
|
||||
{
|
||||
err_msg = $"Failed to LeaveRoom() !!! : instanceRoomId:{instance_room_Id}";
|
||||
result.setFail(ServerErrorCode.NotExistInstanceRoom, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// 1. 파티 리더 위치로 이동 ( to Channel )
|
||||
result = await GameZoneMoveHelper.moveToAnotherChannel(player, destServer, summonPos);
|
||||
if (result.isFail())
|
||||
{
|
||||
err_msg = $"Failed to moveToAnotherChannel() !!! : {result.toBasicString()}";
|
||||
result.setFail(ServerErrorCode.SummonPartyMemberFail, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. DB 갱신
|
||||
var batch = new QueryBatchEx<QueryRunnerWithDocument>( player, LogActionType.SummonParty
|
||||
, GameServerApp.getServerLogic().getDynamoDbClient(), true);
|
||||
{
|
||||
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
|
||||
batch.addQuery(new QueryFinal());
|
||||
}
|
||||
|
||||
return await QueryHelper.sendQueryAndBusinessLog(batch);
|
||||
}
|
||||
|
||||
private async Task<(SummonPartyMemberResultType result, ServerInfo? server)> checkServerStatus(string destServer)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
|
||||
(result, var server) = await server_logic.getServerInfoByServerName(destServer);
|
||||
NullReferenceCheckHelper.throwIfNull(server, () => $"server is null !!!");
|
||||
|
||||
// 1. world Id 체크
|
||||
if (server_logic.getWorldId() != server.WorldId) return (SummonPartyMemberResultType.SummonFail, null);
|
||||
|
||||
// 2. 대상 server 상황 체크
|
||||
var current_count = server.Sessions + server.Reservation + server.ReturnCount;
|
||||
|
||||
var result_type = server.Capacity <= current_count ? SummonPartyMemberResultType.ServerFull : SummonPartyMemberResultType.Accept;
|
||||
return (result_type, server);
|
||||
}
|
||||
|
||||
private void sendReplySummonPartyMemberAsync(string summon_server, string summon_party_guid, USER_GUID summon_user_guid, SummonPartyMemberResultType reply)
|
||||
{
|
||||
var server_message = new ServerMessage();
|
||||
server_message.ReplySummonPartyMemberNoti = new();
|
||||
server_message.ReplySummonPartyMemberNoti.SummonPartyGuid = summon_party_guid;
|
||||
server_message.ReplySummonPartyMemberNoti.SummonUserGuid = summon_user_guid;
|
||||
server_message.ReplySummonPartyMemberNoti.Result = reply;
|
||||
|
||||
PartyHelper.sendToServer(server_message, summon_server);
|
||||
}
|
||||
|
||||
private void writeBusinessLog(Player owner, string partyGuid, SummonPartyMemberResultType reply)
|
||||
{
|
||||
var log_invokers = new List<ILogInvoker>(2);
|
||||
|
||||
// 1. 파티 정보
|
||||
var party_log_data = PartyBusinessLogHelper.toPartyLogData(partyGuid, false);
|
||||
var party_business_log = new PartyBusinessLog(party_log_data);
|
||||
log_invokers.Add(party_business_log);
|
||||
|
||||
// 2. 파티 멤버 정보
|
||||
var actionType = reply == SummonPartyMemberResultType.Accept ? PartyMemberActionType.SummonAccept : PartyMemberActionType.SummonReject;
|
||||
var party_member_log_data = PartyBusinessLogHelper.toPartyMemberLogData(partyGuid, owner.getUserGuid(), actionType);
|
||||
var party_member_business_log = new PartyMemberBusinessLog(party_member_log_data);
|
||||
log_invokers.Add(party_member_business_log);
|
||||
|
||||
BusinessLogger.collectLogs(new LogActionEx(LogActionType.ReplySummonParty), owner, log_invokers);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
using USER_GUID = System.String;
|
||||
|
||||
|
||||
namespace GameServer.PacketHandler;
|
||||
|
||||
|
||||
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.SummonPartyMemberReq), typeof(SummonPartyMemberPacketHandler), typeof(GameLoginListener))]
|
||||
public class SummonPartyMemberPacketHandler : PacketRecvHandler
|
||||
{
|
||||
private static void send_S2C_ACK_SUMMON_PARTY_MEMBER(Player owner, Result result, Item? spentItem)
|
||||
{
|
||||
var ack_packet = new ClientToGame();
|
||||
ack_packet.Response = new();
|
||||
ack_packet.Response.ErrorCode = result.ErrorCode;
|
||||
ack_packet.Response.SummonPartyMemberRes = new();
|
||||
|
||||
if (result.isSuccess())
|
||||
{
|
||||
NullReferenceCheckHelper.throwIfNull(spentItem, () => $"spentItem is null !!! - {owner.toBasicString()}");
|
||||
|
||||
var delete = spentItem.toItemData4Client();
|
||||
|
||||
var item = new ItemGuidCount();
|
||||
item.ItemGuid = delete.ItemGuid;
|
||||
item.ItemCount = delete.Count;
|
||||
ack_packet.Response.SummonPartyMemberRes.Items.Add(item);
|
||||
}
|
||||
|
||||
GameServerApp.getServerLogic().onSendPacket(owner, ack_packet);
|
||||
}
|
||||
|
||||
public override async Task<Result> onProcessPacket(ISession entityWithSession, IMessage recvMessage)
|
||||
{
|
||||
var player = entityWithSession as Player;
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
|
||||
var game_msg = recvMessage as ClientToGame;
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(game_msg, () => $"game_msg is null !!! - {player.toBasicString()}");
|
||||
var request = game_msg.Request.SummonPartyMemberReq;
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(request, () => $"request is null !!! - {player.toBasicString()}");
|
||||
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
var player_action = player.getEntityAction<PlayerAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(player_action, () => $"player_action is null !!! - {player.toBasicString()}");
|
||||
|
||||
// 1. 캐릭터 선택 상태 체크
|
||||
var selected_character = player_action.getSelectedCharacter();
|
||||
if (null == selected_character)
|
||||
{
|
||||
err_msg = $"Not selected Character !!! - {player.toBasicString()}";
|
||||
result.setFail(ServerErrorCode.CharacterNotSelected, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
send_S2C_ACK_SUMMON_PARTY_MEMBER(player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 소속 파티 Guid 조회
|
||||
var personal_party_action = player.getEntityAction<PersonalPartyAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(personal_party_action, () => $"personal_party_action is null !!! - {player.toBasicString()}");
|
||||
|
||||
var personal_party = personal_party_action.getPersonalParty();
|
||||
if (null == personal_party)
|
||||
{
|
||||
err_msg = $"Failed to get party info !!! - not party member - {player.getUserGuid()}";
|
||||
result.setFail(ServerErrorCode.NotParty, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_SUMMON_PARTY_MEMBER(player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party, () => $"global_party is null !!! - {player.toBasicString()}");
|
||||
|
||||
var party = global_party.getParty(personal_party.getPartyGuid());
|
||||
NullReferenceCheckHelper.throwIfNull(party, () => $"party is null !!! - {player.toBasicString()}");
|
||||
|
||||
// 3. 파티장 체크
|
||||
var party_action = party.getEntityAction<GlobalPartyDetailAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_action, () => $"party_action is null !!! - {player.toBasicString()}");
|
||||
|
||||
var is_leader = party_action.isLeader(player.getUserGuid());
|
||||
if (false == is_leader)
|
||||
{
|
||||
err_msg = $"Failed to summon party member !!! : not party leader - {player.getUserGuid()}";
|
||||
result.setFail(ServerErrorCode.NotPartyLeader, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_SUMMON_PARTY_MEMBER(player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 4. 파티원 체크
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_member_action, () => $"party_member_action is null !!! - {player.toBasicString()}");
|
||||
|
||||
var is_member = party_member_action.isPartyMember(request.PartyMemberUserGuid);
|
||||
if (false == is_member)
|
||||
{
|
||||
err_msg = $"Failed to summon party member !!! : not party member - {request.PartyMemberUserGuid}";
|
||||
result.setFail(ServerErrorCode.NotPartyMember, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
send_S2C_ACK_SUMMON_PARTY_MEMBER(player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 5. 소환 조건 체크
|
||||
result = await checkSummonConditionAsync(player, request.PartyMemberUserGuid, party);
|
||||
if (result.isFail())
|
||||
{
|
||||
send_S2C_ACK_SUMMON_PARTY_MEMBER(player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 6. 소환 처리
|
||||
result = await player.runTransactionRunnerSafely( TransactionIdType.PrivateContents, "SummonPartyMember"
|
||||
, summonDelegate );
|
||||
if (result.isFail())
|
||||
{
|
||||
_ = await party_member_action.clearSummonMemberAsync(request.PartyMemberUserGuid, false);
|
||||
|
||||
send_S2C_ACK_SUMMON_PARTY_MEMBER(player, result, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
async Task<Result> summonDelegate() => await summonAsync(player, request.PartyMemberUserGuid, party);
|
||||
}
|
||||
|
||||
private async Task<Result> checkSummonConditionAsync(Player player, USER_GUID summonUserGuid, GlobalPartyDetail party)
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_member_action, () => $"party_member_action is null !!! - {player.toBasicString()}");
|
||||
|
||||
var summon_members = party_member_action.getSummonMembers();
|
||||
var proud_net_listener = server_logic.getProudNetListener();
|
||||
|
||||
// 1. base 체크
|
||||
var curr_user_count = proud_net_listener.getEntityWithSessions().Count +
|
||||
server_logic.getReservationManager().getReservedUserCount() +
|
||||
server_logic.getReturnManager().getReturnUserCount() +
|
||||
UgcNpcCountManager.Instance.calculateNpcCount();
|
||||
if (proud_net_listener.getMaxConnectionCount() <= curr_user_count)
|
||||
{
|
||||
err_msg = $"Failed to summon party member !!! : not channel server - {curr_user_count}";
|
||||
result.setFail(ServerErrorCode.PartyLeaderServerIsFull, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. leader condition 체크
|
||||
result = await checkLeaderConditions(player, summon_members.Count());
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 3. summon user condition 체크
|
||||
result = await checkSummonUserConditions(player, summon_members.ToList(), summonUserGuid);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Result> checkLeaderConditions(Player player, int summonMemberCount)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
// 1. leader 가 channel 인지 체크
|
||||
if (server_logic.getServerType().toServerType() != ServerType.Channel)
|
||||
{
|
||||
err_msg = $"Failed to summon party member !!! : not channel server - {GameServerApp.getServerLogic().getServerType().toServerType()}";
|
||||
result.setFail(ServerErrorCode.InvalidSummonServerType, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 소환 불가 위치 체크
|
||||
// todo (sangyeob.kim) : client 에서 체크 중 -> 서버체크는 필요시 추가 ( 현재는 notifyReply 로 한다. )
|
||||
|
||||
// 3. 소환석 아이템 수량 체크
|
||||
var inventory_action = player.getEntityAction<InventoryActionBase>();
|
||||
NullReferenceCheckHelper.throwIfNull(inventory_action, () => $"inventory_action is null !!! - {player.toBasicString()}");
|
||||
|
||||
var summon_item_count = inventory_action.getItemCountAllByMetaId((uint)MetaHelper.GameConfigMeta.SummonStoneItemMetaId);
|
||||
if (summon_item_count < summonMemberCount + 1)
|
||||
{
|
||||
err_msg = $"Failed to summon party member !!! : insufficient summon item - summon_item_count[{summon_item_count}] / summon_count[{summonMemberCount}]";
|
||||
result.setFail(ServerErrorCode.ItemCountNotEnough, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Result> checkSummonUserConditions(Player player, IReadOnlyList<USER_GUID> summonUsers, USER_GUID summonUserGuid)
|
||||
{
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
// 1. 소환 중인 유저 체크
|
||||
if (summonUsers.Contains(summonUserGuid))
|
||||
{
|
||||
err_msg = $"Failed to summon party member !!! : Already summon member - {summonUserGuid}";
|
||||
result.setFail(ServerErrorCode.AlreadySummon, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 소환 유저 로그인 체크
|
||||
var login_cache = await PartyHelper.getOtherUserLoginCache(summonUserGuid);
|
||||
if (null == login_cache)
|
||||
{
|
||||
err_msg = $"Failed to summon party member !!! : summon user logged out - {summonUserGuid}";
|
||||
result.setFail(ServerErrorCode.LogOffTarget, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 3. 동일 월드 체크
|
||||
(result, var summon_user_server_info) = await server_logic.getServerInfoByServerName(login_cache.CurrentServer);
|
||||
NullReferenceCheckHelper.throwIfNull(summon_user_server_info, () => $"summon_user_server_info is null !!! - {player.toBasicString()}");
|
||||
|
||||
if (summon_user_server_info.WorldId != server_logic.getWorldId())
|
||||
{
|
||||
err_msg = $"Failed to summon party member !!! : invalid world id - leader[{server_logic.getWorldId()}] summon[{summon_user_server_info.WorldId}]";
|
||||
result.setFail(ServerErrorCode.InvalidSummonWorldServer, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 4. 소환 파티원 위치 체크
|
||||
var player_manager = server_logic.getPlayerManager();
|
||||
if (player_manager.tryGetUserByPrimaryKey(summonUserGuid, out var summon_user))
|
||||
{
|
||||
if(null == summon_user)
|
||||
{
|
||||
err_msg = $"Failed to summon party member !!! : summon user logged out - {summonUserGuid}";
|
||||
result.setFail(ServerErrorCode.LogOffTarget, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
var leader_location_action = player.getEntityAction<LocationAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(leader_location_action, () => $"leader_location_action is null !!! - {player.toBasicString()}");
|
||||
|
||||
var leader_curr_pos = leader_location_action.getCurrentPos();
|
||||
|
||||
var summon_user_location_action = summon_user.getEntityAction<LocationAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(summon_user_location_action, () => $"summon_user_location_action is null !!! : {summon_user.toBasicString()} - {player.toBasicString()}");
|
||||
|
||||
var summon_user_location = summon_user_location_action.getCurrentPos();
|
||||
|
||||
var distance = PartyHelper.calculateDistance(leader_curr_pos, summon_user_location);
|
||||
if (distance <= ServerCommon.Constant.PARTY_SUMMON_LIMIT_DISTANCE)
|
||||
{
|
||||
err_msg = $"Failed to summon party member !!! : summon user is short distance - {distance}";
|
||||
result.setFail(ServerErrorCode.SummonUserLimitDistance, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Result> summonAsync(Player leader, string summon_user_guid, GlobalPartyDetail party)
|
||||
{
|
||||
var leader_location = leader.getEntityAction<LocationAction>()?.getCurrentPos();
|
||||
NullReferenceCheckHelper.throwIfNull(leader_location, () => $"leader_location is null !!! - {leader.toBasicString()}");
|
||||
|
||||
// 0. 소환 데이터 생성
|
||||
var summon = new SummonInfo();
|
||||
summon.IsAlreadySummon = true;
|
||||
summon.SummonServer = GameServerApp.getServerLogic().getServerName();
|
||||
summon.SummonPos = leader_location;
|
||||
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_member_action, () => $"party_member_action is null !!! - {leader.toBasicString()}");
|
||||
|
||||
// 1. 소환 처리
|
||||
var summon_result = await party_member_action.summonMemberAsync(summon_user_guid, summon);
|
||||
if (summon_result.result.isFail())
|
||||
{
|
||||
return summon_result.result;
|
||||
}
|
||||
|
||||
var batch = new QueryBatchEx<QueryRunnerWithDocument>( leader, LogActionType.SummonParty
|
||||
, GameServerApp.getServerLogic().getDynamoDbClient());
|
||||
{
|
||||
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
|
||||
batch.addQuery(new QueryFinal());
|
||||
}
|
||||
|
||||
// 2. Business Log 기록
|
||||
writeBusinessLog(batch, party.PartyGuid, summon_user_guid);
|
||||
|
||||
var result = await QueryHelper.sendQueryAndBusinessLog(batch);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
send_S2C_ACK_SUMMON_PARTY_MEMBER(leader, result, summon_result.delete_item);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void writeBusinessLog(QueryBatchBase queryBatch, string partyGuid, string userGuid)
|
||||
{
|
||||
// 1. 파티 정보
|
||||
var party_log_data = PartyBusinessLogHelper.toPartyLogData(partyGuid, false);
|
||||
var party_business_log = new PartyBusinessLog(party_log_data);
|
||||
queryBatch.appendBusinessLog(party_business_log);
|
||||
|
||||
// 2. 파티 멤버 정보
|
||||
var party_member_log_data =
|
||||
PartyBusinessLogHelper.toPartyMemberLogData(partyGuid, userGuid, PartyMemberActionType.Summon);
|
||||
var party_member_business_log = new PartyMemberBusinessLog(party_member_log_data);
|
||||
queryBatch.appendBusinessLog(party_member_business_log);
|
||||
}
|
||||
}
|
||||
53
GameServer/Contents/Party/PersonalParty.cs
Normal file
53
GameServer/Contents/Party/PersonalParty.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
|
||||
using PARTY_GUID = System.String;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class PersonalParty : EntityBase, IDisposable
|
||||
{
|
||||
private PARTY_GUID m_party_guid { get; set; }
|
||||
public PersonalParty(Player parent, string party_guid) : base(EntityType.PersonalParty, parent)
|
||||
{
|
||||
m_party_guid = party_guid;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public override async Task<Result> onInit()
|
||||
{
|
||||
// attribute
|
||||
|
||||
// action
|
||||
addEntityAction(new PartyInviteAction(this));
|
||||
|
||||
return await Task.FromResult(new Result());
|
||||
}
|
||||
|
||||
public override string toBasicString()
|
||||
{
|
||||
return $"{this.getTypeName()} - {getRootParent().toBasicString()}";
|
||||
}
|
||||
|
||||
public override string toSummaryString()
|
||||
{
|
||||
return $"{this.getTypeName()} - {getRootParent().toBasicString()}";
|
||||
}
|
||||
|
||||
public void setPartyGuid(string party_guid) => m_party_guid = party_guid;
|
||||
public string getPartyGuid() => m_party_guid;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyBanPartyMemberHandler
|
||||
{
|
||||
public async Task recvBanPartyMember(ServerMessage.Types.BanPartyNoti notify)
|
||||
{
|
||||
var player_manager = GameServerApp.getServerLogic().getPlayerManager();
|
||||
if (!player_manager.tryGetUserByPrimaryKey(notify.BanMemberGuid, out var player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var personal_party_action = player.getEntityAction<PersonalPartyAction>();
|
||||
ArgumentNullException.ThrowIfNull(personal_party_action);
|
||||
|
||||
// 1. 파티 정보 체크
|
||||
if (notify.PartyGuid != personal_party_action.getPersonalParty()?.getPartyGuid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 파티 정보 정리
|
||||
await personal_party_action.clearPersonalParty();
|
||||
|
||||
// 3. 밴 알림
|
||||
var message = new ClientToGame();
|
||||
message.Message = new();
|
||||
message.Message.NtfBanParty = new();
|
||||
|
||||
PartyHelper.sendToClient(message, player.getHostId());
|
||||
await QuestManager.It.QuestCheck(player, new QuestParty(EQuestEventTargetType.PARTY, EQuestEventNameType.EXITED));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyCancelSummonHandler
|
||||
{
|
||||
public async Task recvCancelSummonHandler(ServerMessage.Types.CancelSummonPartyMemberNoti notify)
|
||||
{
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party, () => $"global_party is null !!!");
|
||||
var global_party_action = global_party.getEntityAction<GlobalPartyAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party_action, () => $"global_party_action is null !!!");
|
||||
|
||||
// 1. 파티 정보 조회
|
||||
var party = global_party_action.getGlobalPartyDetail(notify.PartyGuid);
|
||||
if (null == party) return;
|
||||
|
||||
// 2. Member 정보 수정
|
||||
var party_member_attribute = party.getEntityAttribute<PartyMemberAttribute>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_member_attribute, () => $"party_member_attribute is null !!!");
|
||||
foreach (var cancel_member in notify.CancelSummonUserGuids)
|
||||
{
|
||||
if (!party_member_attribute.getPartyMembers().TryGetValue(cancel_member, out var member)) continue;
|
||||
member.Summon.clear();
|
||||
|
||||
// 2-2.cache 수정
|
||||
var member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(member_action, () => $"member_action is null !!!");
|
||||
_ = await member_action.changeMember(member);
|
||||
}
|
||||
|
||||
// 3. 해당 멤버 전송
|
||||
var client_message = new ClientToGame
|
||||
{
|
||||
Message = new ClientToGameMessage
|
||||
{
|
||||
NtfCancelSummonPartyMember = new()
|
||||
}
|
||||
};
|
||||
|
||||
var player_manger = GameServerApp.getServerLogic().getPlayerManager();
|
||||
ArgumentNullException.ThrowIfNull(player_manger);
|
||||
foreach (var notify_user in notify.CancelSummonUserGuids)
|
||||
{
|
||||
if (!player_manger.tryGetUserByPrimaryKey(notify_user, out var player)) continue;
|
||||
|
||||
PartyHelper.sendToClient(client_message, player.getHostId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
|
||||
using USER_GUID = System.String;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyChangePartyLeaderGuidHandler
|
||||
{
|
||||
public async Task recvChangePartyLeaderGuid(ServerMessage.Types.ChangePartyLeaderNoti notify)
|
||||
{
|
||||
// 1. party 정보 조회
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
ArgumentNullException.ThrowIfNull(global_party);
|
||||
|
||||
var party = global_party.getParty(notify.PartyGuid);
|
||||
if (null == party) return;
|
||||
|
||||
// 2. 파티 리더 정보 수정
|
||||
var party_detail_info_action = party.getEntityAction<GlobalPartyDetailInfoAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_detail_info_action);
|
||||
|
||||
var result = await party_detail_info_action.changePartyLeader(notify.NewPartyLeaderGuid, false);
|
||||
if (result.isFail()) return;
|
||||
|
||||
// 3. client 통보
|
||||
var message = new ClientToGame
|
||||
{
|
||||
Message = new()
|
||||
{
|
||||
ChangePartyLeaderNoti = new()
|
||||
{
|
||||
NewPartyLeaderGuid = notify.NewPartyLeaderGuid
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
PartyHelper.BroadcastToClients(party, message, new List<USER_GUID>());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyChangePartyMemberMarker
|
||||
{
|
||||
public async Task recvChangePartyMemberMarkerHandler(ServerMessage.Types.ExchangePartyMemberMarkNoti notify)
|
||||
{
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
ArgumentNullException.ThrowIfNull(global_party);
|
||||
|
||||
var party = global_party.getParty(notify.PartyGuid);
|
||||
ArgumentNullException.ThrowIfNull(party);
|
||||
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_member_action);
|
||||
|
||||
// 1. 파티원 마커 변경
|
||||
var result = await party_member_action.changeMemberMaker(notify.MemberUserGuid, notify.MarkId, false);
|
||||
if (result.isFail()) return;
|
||||
|
||||
// 2. 변경 알림
|
||||
var client_message = new ClientToGame()
|
||||
{
|
||||
Message = new()
|
||||
{
|
||||
ExchangePartyMemberMarkNoti = new()
|
||||
{
|
||||
MarkId = notify.MarkId,
|
||||
MemberUserGuid = notify.MemberUserGuid
|
||||
}
|
||||
}
|
||||
};
|
||||
PartyHelper.BroadcastToClients(party, client_message, new List<string>());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
using USER_GUID = System.String;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyChangePartyNameHandler
|
||||
{
|
||||
public async Task recvChangePartyNameHandler(ServerMessage.Types.ExchangePartyNameNoti notify)
|
||||
{
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
ArgumentNullException.ThrowIfNull(global_party);
|
||||
|
||||
var party = global_party.getParty(notify.PartyGuid);
|
||||
ArgumentNullException.ThrowIfNull(party);
|
||||
|
||||
var party_info_action = party.getEntityAction<GlobalPartyDetailInfoAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_info_action);
|
||||
|
||||
// 1. 파티명 변경
|
||||
var result = await party_info_action.changePartyName(notify.NewPartyName, false);
|
||||
if (result.isFail()) return;
|
||||
|
||||
// 2. 파티명 변경 알림
|
||||
var message = new ClientToGame()
|
||||
{
|
||||
Message = new()
|
||||
{
|
||||
ExchangePartyNameNoti = new()
|
||||
{
|
||||
NewPartyName = notify.NewPartyName
|
||||
}
|
||||
}
|
||||
};
|
||||
PartyHelper.BroadcastToClients(party, message, new List<USER_GUID>());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyChangePartyServerHandler
|
||||
{
|
||||
public async Task recvChangePartyServer(ServerMessage.Types.ChangePartyServerNameNoti notify)
|
||||
{
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
ArgumentNullException.ThrowIfNull(global_party);
|
||||
|
||||
var party = global_party.getParty(notify.PartyGuid);
|
||||
ArgumentNullException.ThrowIfNull(party);
|
||||
|
||||
var server_action = party.getEntityAction<GlobalPartyDetailServerAction>();
|
||||
ArgumentNullException.ThrowIfNull(server_action);
|
||||
|
||||
if (notify.IsAddition == BoolType.True)
|
||||
{
|
||||
await server_action.addPartyServer(notify.ServerName);
|
||||
}
|
||||
else
|
||||
{
|
||||
await server_action.deletePartyServer(notify.ServerName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyClearPartySummonHandler
|
||||
{
|
||||
public async Task recvClearPartySummon(ServerMessage.Types.GS2GS_NTF_CLEAR_PARTY_SUMMON notify)
|
||||
{
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
ArgumentNullException.ThrowIfNull(server_logic);
|
||||
|
||||
var global_party = server_logic.findGlobalEntity<GlobalParty>();
|
||||
ArgumentNullException.ThrowIfNull(global_party);
|
||||
|
||||
var party = global_party.getParty(notify.PartyGuid);
|
||||
if (null == party) return;
|
||||
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_member_action);
|
||||
|
||||
_ = await party_member_action.clearSummonMemberAsync(notify.MemberUserGuid, false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyDeletePartyInviteSendHandler
|
||||
{
|
||||
public async Task recvDeletePartyInviteSend(ServerMessage.Types.GS2GS_NTF_DELETE_PARTY_INVITE_SEND notify)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
// 1. party 체크
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
ArgumentNullException.ThrowIfNull(global_party);
|
||||
|
||||
var party = global_party.getParty(notify.PartyGuid);
|
||||
ArgumentNullException.ThrowIfNull(party);
|
||||
|
||||
// 2. send list 삭제
|
||||
var party_send_action = party.getEntityAction<GlobalPartyInvitePartySendAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_send_action);
|
||||
result = await party_send_action.deleteInvitePartySend(notify.InviteUserGuid);
|
||||
if (result.isFail())
|
||||
{
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyDestroyPartyHandler
|
||||
{
|
||||
public async Task recvDestroyParty(ServerMessage.Types.GS2C_NTF_DESTROY_PARTY notify)
|
||||
{
|
||||
// 1. 파티 조회
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
ArgumentNullException.ThrowIfNull(global_party);
|
||||
|
||||
var global_party_action = global_party.getEntityAction<GlobalPartyAction>();
|
||||
ArgumentNullException.ThrowIfNull(global_party_action);
|
||||
|
||||
// 2. 파티 제거
|
||||
await global_party_action.destroyParty(notify.DestroyPartyGuid, false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyInvitePartyRecvResultHandler
|
||||
{
|
||||
public async Task recvInvitePartyRecvResult(ServerMessage.Types.GS2C_NTF_PARTY_INVITE_RESULT notify)
|
||||
{
|
||||
// 0. client login 체크
|
||||
var player_manager = GameServerApp.getServerLogic().getPlayerManager();
|
||||
ArgumentNullException.ThrowIfNull(player_manager);
|
||||
|
||||
if (!player_manager.tryGetUserByPrimaryKey(notify.InviteHostGuid, out var player))
|
||||
{
|
||||
Log.getLogger().error($"Failed to get recv user !! - {notify.InviteUserGuid} / {nameof(recvInvitePartyRecvResult)}");
|
||||
return;
|
||||
}
|
||||
|
||||
ArgumentNullException.ThrowIfNull(player);
|
||||
|
||||
// 1. client 에 파티초대 결과 전송
|
||||
var message = new ClientToGame
|
||||
{
|
||||
Message = new()
|
||||
{
|
||||
InvitePartyResult = new()
|
||||
{
|
||||
ErrorCode = notify.ErrorCode,
|
||||
InviteUserGuid = notify.InviteUserGuid
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
GameServerApp.getServerLogic().onSendPacket(player, message);
|
||||
|
||||
if (notify.ErrorCode == ServerErrorCode.Success) return;
|
||||
|
||||
// 2. 실패시 send list 삭제
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
ArgumentNullException.ThrowIfNull(global_party);
|
||||
|
||||
var party = global_party.getParty(notify.InvitePartyGuid);
|
||||
ArgumentNullException.ThrowIfNull(party);
|
||||
|
||||
var party_send_action = party.getEntityAction<GlobalPartyInvitePartySendAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_send_action, () => $"party_send_action is null !!!");
|
||||
_ = await party_send_action.deleteInvitePartySend(notify.InviteUserGuid);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyInvitePartyReplyHandler
|
||||
{
|
||||
public async Task recvInvitePartyReply(ServerMessage.Types.ReplyInvitePartyNoti notify)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
// 1. party 체크
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
ArgumentNullException.ThrowIfNull(global_party);
|
||||
|
||||
var global_party_action = global_party.getEntityAction<GlobalPartyAction>();
|
||||
ArgumentNullException.ThrowIfNull(global_party_action);
|
||||
|
||||
var party_info = await global_party_action.getPartyLeaderGuidAndMemberCount(notify.InvitePartyGuid);
|
||||
if (string.IsNullOrEmpty(party_info.leader_guid)) return;
|
||||
|
||||
// 2. leader 체크
|
||||
var leader_login_cache = await PartyHelper.getOtherUserLoginCache(party_info.leader_guid);
|
||||
if (null == leader_login_cache) return;
|
||||
|
||||
// 3. 리더가 다른 서버로 이동했으면, 그쪽으로 전송
|
||||
var server_message = new ServerMessage();
|
||||
if (leader_login_cache.CurrentServer != GameServerApp.getServerLogic().getServerName())
|
||||
{
|
||||
server_message = new ServerMessage
|
||||
{
|
||||
ReplyInvitePartyNoti = new ServerMessage.Types.ReplyInvitePartyNoti
|
||||
{
|
||||
InvitePartyGuid = notify.InvitePartyGuid,
|
||||
InviteUserGuid = notify.InviteUserGuid,
|
||||
Result = notify.Result
|
||||
}
|
||||
};
|
||||
|
||||
PartyHelper.sendToServer(server_message, leader_login_cache.CurrentServer);
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. send list 삭제
|
||||
var party = global_party.getParty(notify.InvitePartyGuid);
|
||||
ArgumentNullException.ThrowIfNull(party);
|
||||
|
||||
server_message = new ServerMessage();
|
||||
server_message.NtfDeletePartyInviteSend = new();
|
||||
server_message.NtfDeletePartyInviteSend.PartyGuid = notify.InvitePartyGuid;
|
||||
server_message.NtfDeletePartyInviteSend.InviteUserGuid = notify.InviteUserGuid;
|
||||
|
||||
PartyHelper.BroadcastToServers(party, server_message, false);
|
||||
|
||||
// 5. 승락이면서, member 가 2명이면, leader 는 p2pGroup 에 join해야 한다.
|
||||
if (notify.Result == BoolType.True)
|
||||
{
|
||||
var party_action = party.getEntityAction<GlobalPartyDetailAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_action);
|
||||
|
||||
if (party_info.member_count == 2)
|
||||
{
|
||||
_ = await party_action.joinPartyP2PGroup(party_info.leader_guid);
|
||||
_ = await party_action.checkPartyP2PState(party_info.leader_guid, true, true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 6. client 에 전송
|
||||
var player_manager = GameServerApp.getServerLogic().getPlayerManager();
|
||||
ArgumentNullException.ThrowIfNull(player_manager);
|
||||
|
||||
if (!player_manager.tryGetUserByPrimaryKey(party_info.leader_guid, out var player))
|
||||
{
|
||||
Log.getLogger().error($"Failed to get recv user !! - leader[{party_info.leader_guid}] / invite[{notify.InviteUserGuid}] / {nameof(recvInvitePartyReply)}");
|
||||
return;
|
||||
}
|
||||
|
||||
var client_message = new ClientToGame
|
||||
{
|
||||
Message = new ClientToGameMessage
|
||||
{
|
||||
ReplyInvitePartyNoti = new ClientToGameMessage.Types.ReplyInvitePartyNoti
|
||||
{
|
||||
InviteUserGuid = notify.InviteUserGuid,
|
||||
InviteUserNickname = notify.InviteUserNickname,
|
||||
Result = notify.Result
|
||||
}
|
||||
}
|
||||
};
|
||||
PartyHelper.sendToClient(client_message, player.getHostId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyInvitePartySendHandler
|
||||
{
|
||||
public async Task recvInvitePartySend(ServerMessage.Types.InvitePartyNoti notify)
|
||||
{
|
||||
var player_manager = GameServerApp.getServerLogic().getPlayerManager();
|
||||
ArgumentNullException.ThrowIfNull(player_manager);
|
||||
|
||||
// 0. client login 체크
|
||||
if (!player_manager.tryGetUserByPrimaryKey(notify.InviteUserGuid, out var player))
|
||||
{
|
||||
|
||||
// 0-1. login_cache 가져오기
|
||||
var login_cache = await PartyHelper.getOtherUserLoginCache(notify.InviteUserGuid);
|
||||
if (null == login_cache)
|
||||
{
|
||||
await sendMessageToPartyLeader(notify, ServerErrorCode.UserNotLogin);
|
||||
return;
|
||||
}
|
||||
|
||||
// 0-2. 해당 서버로 mq 날리기
|
||||
var server_message = new ServerMessage
|
||||
{
|
||||
InvitePartyNoti = new()
|
||||
{
|
||||
InvitePartyLeaderGuid = notify.InvitePartyLeaderGuid,
|
||||
InvitePartyGuid = notify.InvitePartyGuid,
|
||||
InviteUserGuid = notify.InviteUserGuid
|
||||
}
|
||||
};
|
||||
|
||||
var rabbit_mq = GameServerApp.getServerLogic().getRabbitMqConnector() as RabbitMqConnector;
|
||||
NullReferenceCheckHelper.throwIfNull(rabbit_mq, () => $"rabbit_mq is null !!!");
|
||||
rabbit_mq.SendMessage(login_cache.CurrentServer, server_message);
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. client party 가입 체크
|
||||
var result = await checkJoinPartyCondition(player);
|
||||
if (result.isFail())
|
||||
{
|
||||
await sendMessageToPartyLeader(notify, result.ErrorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. recv 저장
|
||||
var party_recv_action = player.getEntityAction<PartyInvitePartyRecvAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_recv_action);
|
||||
|
||||
result = await party_recv_action.addInvitePartyRecv(notify.InvitePartyGuid);
|
||||
if (result.isFail())
|
||||
{
|
||||
await sendMessageToPartyLeader(notify, ServerErrorCode.FailToSendInviteMember);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. client 전달
|
||||
var client_message = new ClientToGame();
|
||||
client_message.Message = new();
|
||||
client_message.Message.InvitePartyNoti = new();
|
||||
client_message.Message.InvitePartyNoti.InviteHostUserGuid = notify.InvitePartyLeaderGuid;
|
||||
client_message.Message.InvitePartyNoti.InviteHostUserNickname =
|
||||
await PartyHelper.getUserNicknameFromGuid(notify.InvitePartyLeaderGuid);
|
||||
|
||||
PartyHelper.sendToClient(client_message, player.getHostId());
|
||||
}
|
||||
|
||||
private async Task sendMessageToPartyLeader(ServerMessage.Types.InvitePartyNoti notify, ServerErrorCode err_code)
|
||||
{
|
||||
var login_cache = await PartyHelper.getOtherUserLoginCache(notify.InvitePartyLeaderGuid);
|
||||
if (null == login_cache) return;
|
||||
|
||||
var message = new ServerMessage
|
||||
{
|
||||
NtfInvitePartyRecvResult = new ServerMessage.Types.GS2C_NTF_PARTY_INVITE_RESULT()
|
||||
{
|
||||
InvitePartyGuid = notify.InvitePartyGuid,
|
||||
InviteHostGuid = notify.InvitePartyLeaderGuid,
|
||||
InviteUserGuid = notify.InviteUserGuid,
|
||||
ErrorCode = err_code
|
||||
}
|
||||
};
|
||||
|
||||
var rabbit_mq = GameServerApp.getServerLogic().getRabbitMqConnector() as RabbitMqConnector;
|
||||
NullReferenceCheckHelper.throwIfNull(rabbit_mq, () => $"rabbit_mq is null !!!");
|
||||
rabbit_mq.SendMessage(login_cache.CurrentServer, message);
|
||||
}
|
||||
|
||||
private async Task<Result> checkJoinPartyCondition(Player player)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
var personal_party_action = player.getEntityAction<PersonalPartyAction>();
|
||||
ArgumentNullException.ThrowIfNull(personal_party_action);
|
||||
|
||||
var party_guid = personal_party_action.getPersonalParty()?.getPartyGuid();
|
||||
if (string.IsNullOrEmpty(party_guid)) return result;
|
||||
|
||||
// 1. party 정보 획득
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
ArgumentNullException.ThrowIfNull(global_party);
|
||||
var party = global_party.getParty(party_guid);
|
||||
if (null == party) return result;
|
||||
|
||||
// 2. 파티원 수 체크
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_member_action);
|
||||
|
||||
var member_count = party_member_action.getMemberCount();
|
||||
if (member_count < 2) return result;
|
||||
|
||||
result.setFail(ServerErrorCode.AlreadyPartyMember, $"Already Party Member !!! {player.getUserGuid()} / {party_guid}");
|
||||
|
||||
return await Task.FromResult(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyJoinPartyMemberHandler
|
||||
{
|
||||
public async Task recvJoinPartyMember(ServerMessage.Types.JoinPartyMemberNoti notify)
|
||||
{
|
||||
var join_info = JsonConvert.DeserializeObject<PartyMemberInfo>(notify.JoinPartyMemberInfo);
|
||||
if (null == join_info) return;
|
||||
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
ArgumentNullException.ThrowIfNull(global_party);
|
||||
|
||||
var party = global_party.getParty(notify.PartyGuid);
|
||||
ArgumentNullException.ThrowIfNull(party);
|
||||
|
||||
// 1. join member 등록
|
||||
var member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(member_action, () => $"member_action is null !!!");
|
||||
var change = await member_action.changeMember(join_info);
|
||||
if (change.result.isFail()) return;
|
||||
|
||||
// 2. 메시지 전송
|
||||
var client_message = new ClientToGame();
|
||||
client_message.Message = new();
|
||||
client_message.Message.JoinPartyMemberNoti = new();
|
||||
client_message.Message.JoinPartyMemberNoti.JoinPartyMemberGuid = join_info.UserGuid;
|
||||
client_message.Message.JoinPartyMemberNoti.JoinMemberInfo = new PartyMemberState();
|
||||
client_message.Message.JoinPartyMemberNoti.JoinMemberInfo.MarkId = join_info.MarkId;
|
||||
client_message.Message.JoinPartyMemberNoti.JoinMemberInfo.MemberGuid = join_info.UserGuid;
|
||||
client_message.Message.JoinPartyMemberNoti.JoinMemberInfo.MemberNickname = join_info.Nickname;
|
||||
client_message.Message.JoinPartyMemberNoti.JoinMemberInfo.LocationInfo = join_info.LocationInfo;
|
||||
|
||||
PartyHelper.BroadcastToClients(party, client_message, new List<string>());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
using USER_GUID = System.String;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyLeavePartyMemberHandler
|
||||
{
|
||||
public async Task recvLeavePartyMember(ServerMessage.Types.LeavePartyMemberNoti notify)
|
||||
{
|
||||
// 1. 파티 조회
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
ArgumentNullException.ThrowIfNull(global_party);
|
||||
|
||||
var party = global_party.getParty(notify.PartyGuid);
|
||||
ArgumentNullException.ThrowIfNull(party);
|
||||
|
||||
// 2. 파티원 제거
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_member_action);
|
||||
|
||||
var delete_member = await party_member_action.deleteJoinMember(notify.LeavePartyUserGuid, false);
|
||||
if (delete_member.result.isFail()) return;
|
||||
|
||||
// 2. Client 알림
|
||||
var message = new ClientToGame
|
||||
{
|
||||
Message = new()
|
||||
{
|
||||
LeavePartyMemberNoti = new()
|
||||
{
|
||||
LeavePartyUserGuid = notify.LeavePartyUserGuid,
|
||||
IsBan = notify.IsBan
|
||||
}
|
||||
}
|
||||
};
|
||||
PartyHelper.BroadcastToClients(party, message, new List<USER_GUID>());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
|
||||
using USER_GUID = System.String;
|
||||
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyPartyChatHandler
|
||||
{
|
||||
public Task recvPartyChat(ServerMessage.Types.GS2C_NTF_PARTY_CHAT notify)
|
||||
{
|
||||
// 1. 파티 정보 확인
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party, () => $"global_party is null !!!");
|
||||
var party = global_party.getParty(notify.PartyGuid);
|
||||
|
||||
ArgumentNullException.ThrowIfNull(party);
|
||||
|
||||
// 2. 메시지 전송 ( to Client )
|
||||
var client_message = ChatNotifyHelper.makeChatMessage(ChatType.Party, notify.PartySenderNickname, string.Empty,
|
||||
PlayerStateType.None, notify.PartySendMessage);
|
||||
ArgumentNullException.ThrowIfNull(client_message);
|
||||
|
||||
PartyHelper.BroadcastToClients(party, client_message, new List<USER_GUID>());
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyPartyInstanceHandler
|
||||
{
|
||||
public async Task recvPartyInstance(ServerMessage.Types.PartyInstanceInfoNoti notify)
|
||||
{
|
||||
// 1. party 정보
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party, () => $"global_party is null !!!");
|
||||
var party = global_party.getParty(notify.PartyGuid);
|
||||
ArgumentNullException.ThrowIfNull(party);
|
||||
|
||||
// 2. party instance 데이터 로딩
|
||||
var party_instance_action = party.getEntityAction<GlobalPartyDetailInstanceAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_instance_action);
|
||||
|
||||
var result = await party_instance_action.loadPartyInstance();
|
||||
if (result.isFail()) return;
|
||||
|
||||
// 3. party instance 조회
|
||||
var party_instance_attribute = party.getEntityAttribute<PartyInstanceAttribute>();
|
||||
ArgumentNullException.ThrowIfNull(party_instance_attribute);
|
||||
|
||||
// 4. 파티 인스턴스 정보 알림 ( to client )
|
||||
var client_message = new ClientToGame();
|
||||
client_message.Message = new();
|
||||
client_message.Message.PartyInstanceInfoNoti = new();
|
||||
client_message.Message.PartyInstanceInfoNoti.InstanceId = party_instance_attribute.InstanceId;
|
||||
client_message.Message.PartyInstanceInfoNoti.StartTime = party_instance_attribute.StartTime;
|
||||
client_message.Message.PartyInstanceInfoNoti.EndTime = party_instance_attribute.EndTime;
|
||||
client_message.Message.PartyInstanceInfoNoti.JoinMemberCount = party_instance_attribute.JoinMemberCount;
|
||||
client_message.Message.PartyInstanceInfoNoti.IsEnd = party_instance_attribute.InstanceId == 0 ? BoolType.True : BoolType.False;
|
||||
|
||||
PartyHelper.BroadcastToClients(party, client_message, new List<string>());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyPartyMemberLocationHandler
|
||||
{
|
||||
public async Task recvPartyMemberLocationHandler(ServerMessage.Types.PartyMemberLocationNoti notify)
|
||||
{
|
||||
var party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>()?.getParty(notify.PartyGuid);
|
||||
ArgumentNullException.ThrowIfNull(party);
|
||||
|
||||
// 1. party member 정보 reload
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_member_action);
|
||||
|
||||
var result = await party_member_action.loadPartyMember();
|
||||
if (result.isFail()) return;
|
||||
|
||||
// 2. 해당 멤버 정보 변경 전달 ( to Client )
|
||||
var member = party_member_action.getMember(notify.PartyMemberGuid);
|
||||
if (null == member) return;
|
||||
|
||||
var client_message = new ClientToGame();
|
||||
client_message.Message = new();
|
||||
client_message.Message.PartyMemberLocationNoti = new();
|
||||
client_message.Message.PartyMemberLocationNoti.MemberGuid = notify.PartyMemberGuid;
|
||||
client_message.Message.PartyMemberLocationNoti.LocationInfo = member.LocationInfo;
|
||||
|
||||
PartyHelper.BroadcastToClients(party, client_message, new List<string>());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyPartyVoteResultHandler
|
||||
{
|
||||
public async Task recvPartyVoteResult(ServerMessage.Types.PartyVoteResultNoti notify)
|
||||
{
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
NullReferenceCheckHelper.throwIfNull(global_party, () => $"global_party is null !!!");
|
||||
var party = global_party.getParty(notify.PartyGuid);
|
||||
ArgumentNullException.ThrowIfNull(party);
|
||||
|
||||
var party_attribute = party.getEntityAttribute<PartyAttribute>();
|
||||
ArgumentNullException.ThrowIfNull(party_attribute);
|
||||
|
||||
// 1. 결과 통보 ( to client )
|
||||
var client_message = new ClientToGame();
|
||||
client_message.Message = new();
|
||||
client_message.Message.PartyVoteResultNoti = new();
|
||||
client_message.Message.PartyVoteResultNoti.VoteTitle = notify.VoteTitle;
|
||||
client_message.Message.PartyVoteResultNoti.ResultTrue = notify.ResultTrue;
|
||||
client_message.Message.PartyVoteResultNoti.ResultFalse = notify.ResultFalse;
|
||||
client_message.Message.PartyVoteResultNoti.Abstain = notify.Abstain;
|
||||
|
||||
PartyHelper.BroadcastToClients(party, client_message, new List<string>());
|
||||
|
||||
// 6. 투표 데이터 삭제
|
||||
party_attribute.PartyVote = null;
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyReplyPartyVoteHandler
|
||||
{
|
||||
public async Task recvReplyPartyVote(ServerMessage.Types.ReplyPartyVoteNoti notify)
|
||||
{
|
||||
// 1. party 체크
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
ArgumentNullException.ThrowIfNull(global_party);
|
||||
|
||||
var party = global_party.getParty(notify.PartyGuid);
|
||||
ArgumentNullException.ThrowIfNull(party);
|
||||
|
||||
// 2. 파티원 체크
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_member_action);
|
||||
|
||||
var member = party_member_action.getMember(notify.PartyVoterGuid);
|
||||
if (null == member) return;
|
||||
|
||||
// 3. vote 저장
|
||||
var party_info_action = party.getEntityAction<GlobalPartyDetailInfoAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_info_action);
|
||||
|
||||
_ = await party_info_action.VoteParty(notify.Vote, notify.PartyVoterGuid);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
using USER_GUID = System.String;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyReplySummonPartyMemberHandler
|
||||
{
|
||||
public async Task recvReplySummonPartyMember(ServerMessage.Types.ReplySummonPartyMemberNoti notify)
|
||||
{
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
ArgumentNullException.ThrowIfNull(server_logic);
|
||||
|
||||
var global_party = server_logic.findGlobalEntity<GlobalParty>();
|
||||
ArgumentNullException.ThrowIfNull(global_party);
|
||||
|
||||
var party = global_party.getParty(notify.SummonPartyGuid);
|
||||
ArgumentNullException.ThrowIfNull(party);
|
||||
|
||||
// 1. Party Leader 조회
|
||||
var party_info = party.getEntityAction<GlobalPartyDetailAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_info, () => $"party_info is null !!!");
|
||||
var leader_guid = party_info.getLeaderGuid();
|
||||
ArgumentNullException.ThrowIfNull(party_info);
|
||||
ArgumentNullException.ThrowIfNull(leader_guid);
|
||||
|
||||
var player_manager = server_logic.getPlayerManager();
|
||||
if (!player_manager.tryGetUserByPrimaryKey(leader_guid, out var leader))
|
||||
{
|
||||
Log.getLogger().error($"Failed to get party leader session !!! : not found leader - {leader_guid}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. message 생성
|
||||
var message = new ClientToGame();
|
||||
message.Message = new();
|
||||
message.Message.ReplySummonPartyMemberNoti = new();
|
||||
message.Message.ReplySummonPartyMemberNoti.SummonMemberGuid = notify.SummonUserGuid;
|
||||
message.Message.ReplySummonPartyMemberNoti.Result = notify.Result;
|
||||
|
||||
// 3. 소환 상태 체크
|
||||
var is_summon = checkSummonStatus(party, notify.SummonUserGuid);
|
||||
|
||||
// 4. summon 정보 정리 및 알림
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(party_member_action, () => $"party_member_action is null !!!");
|
||||
_ = await party_member_action.clearSummonMemberAsync(notify.SummonUserGuid, true);
|
||||
ArgumentNullException.ThrowIfNull(party_member_action);
|
||||
|
||||
// 3. Client 통보
|
||||
PartyHelper.sendToClient(message, leader.getHostId());
|
||||
}
|
||||
|
||||
private bool checkSummonStatus(GlobalPartyDetail party, USER_GUID summon_user_guid)
|
||||
{
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_member_action);
|
||||
|
||||
var summon_members = party_member_action.getSummonMembers();
|
||||
return summon_members.Contains(summon_user_guid);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
|
||||
using USER_GUID = System.String;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifySendPartyInfoHandler
|
||||
{
|
||||
public async Task recvSendPartyInfo(ServerMessage.Types.GS2C_NTF_PARTY_INFO notify)
|
||||
{
|
||||
var party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>()?.getParty(notify.PartyGuid);
|
||||
ArgumentNullException.ThrowIfNull(party);
|
||||
|
||||
// 1. 파티 소속 인원 체크
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_member_action);
|
||||
|
||||
var sends = (from send in notify.PartyMemberGuids
|
||||
let is_member = party_member_action.isPartyMember(send)
|
||||
where is_member select send).ToList();
|
||||
ArgumentNullException.ThrowIfNull(sends);
|
||||
|
||||
// 2. 파티 정보 전달
|
||||
var party_action = party.getEntityAction<GlobalPartyDetailAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_action);
|
||||
|
||||
_ = await party_action.sendPartyInfo(sends, party_action.getLeaderGuid(), false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
using USER_GUID = System.String;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyStartPartyVoteHandler
|
||||
{
|
||||
public async Task recvStartPartyVote(ServerMessage.Types.PartyVoteNoti notify)
|
||||
{
|
||||
// 1. party 정보 체크
|
||||
var global_party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>();
|
||||
ArgumentNullException.ThrowIfNull(global_party);
|
||||
|
||||
var party = global_party.getParty(notify.PartyGuid);
|
||||
ArgumentNullException.ThrowIfNull(party);
|
||||
|
||||
// 2. party vote 등록
|
||||
var party_info_action = party.getEntityAction<GlobalPartyDetailInfoAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_info_action);
|
||||
|
||||
var register_vote = await party_info_action.registerPartyVote(notify.VoteTitle, notify.VoteStartTime, false);
|
||||
if (register_vote.result.isFail() || null == register_vote.vote) return;
|
||||
|
||||
// 3. 투표 시작 알림 ( to client )
|
||||
var client_message = new ClientToGame();
|
||||
client_message.Message = new();
|
||||
client_message.Message.PartyVoteNoti = new();
|
||||
client_message.Message.PartyVoteNoti.VoteTitle = register_vote.vote.VoteTitle;
|
||||
client_message.Message.PartyVoteNoti.VoteStartTime = register_vote.vote.StartVoteTime;
|
||||
|
||||
PartyHelper.BroadcastToClients(party, client_message, new List<USER_GUID>());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
using USER_GUID = System.String;
|
||||
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifySummonPartyMemberHandler
|
||||
{
|
||||
public async Task recvSummonPartyMember(ServerMessage.Types.SummonPartyMemberNoti notify)
|
||||
{
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
string err_msg;
|
||||
ArgumentNullException.ThrowIfNull(server_logic);
|
||||
|
||||
// 1. 파티 정보 체크
|
||||
var party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>()?.getParty(notify.SummonPartyGuid);
|
||||
if (null == party)
|
||||
{
|
||||
sendReplySummonPartyMemberAsync(notify.SummonPartyGuid, notify.SummonPartyGuid, notify.SummonUserGuid, SummonPartyMemberResultType.NotParty);
|
||||
return;
|
||||
}
|
||||
|
||||
// 1-1. 파티멤버 체크
|
||||
var party_member_action = party.getEntityAction<GlobalPartyDetailMemberAction>();
|
||||
ArgumentNullException.ThrowIfNull(party_member_action);
|
||||
|
||||
await party_member_action.loadPartyMember();
|
||||
|
||||
var member = party_member_action.getMember(notify.SummonUserGuid);
|
||||
if (null == member)
|
||||
{
|
||||
err_msg = $"Failed to summon party member !!! - user is not party member - {notify.SummonUserGuid}";
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
sendReplySummonPartyMemberAsync(notify.SummonServerName, notify.SummonPartyGuid, notify.SummonUserGuid, SummonPartyMemberResultType.NotPartyMember);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 유저 체크
|
||||
var player_manager = server_logic.getPlayerManager();
|
||||
ArgumentNullException.ThrowIfNull(player_manager);
|
||||
if (!player_manager.tryGetUserByPrimaryKey(notify.SummonUserGuid, out var summon_user))
|
||||
{
|
||||
// 2-1. summon user login cache 체크
|
||||
var login_cache_request = new LoginCacheOtherUserRequest(server_logic, server_logic.getRedisConnector(), notify.SummonUserGuid);
|
||||
var result = await login_cache_request.fetchLogin();
|
||||
if(result.isFail())
|
||||
{
|
||||
err_msg = $"Failed to fetchLogin() !!! : {result.toBasicString()}";
|
||||
Log.getLogger().error(err_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
var login_cache = login_cache_request.getLoginCache();
|
||||
if (null == login_cache)
|
||||
{
|
||||
err_msg = $"Failed to summon party member !!! - user not logged in - {notify.SummonUserGuid}";
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
sendReplySummonPartyMemberAsync(notify.SummonServerName, notify.SummonPartyGuid, notify.SummonUserGuid, SummonPartyMemberResultType.LogOut);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2-2. target 서버로 전송
|
||||
var server_message = new ServerMessage();
|
||||
server_message.SummonPartyMemberNoti = new();
|
||||
server_message.SummonPartyMemberNoti.SummonPartyGuid = notify.SummonPartyGuid;
|
||||
server_message.SummonPartyMemberNoti.SummonUserGuid = notify.SummonUserGuid;
|
||||
server_message.SummonPartyMemberNoti.SummonServerName = login_cache.CurrentServer;
|
||||
server_message.SummonPartyMemberNoti.SummonPos = notify.SummonPos;
|
||||
|
||||
PartyHelper.sendToServer(server_message, login_cache.CurrentServer);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Summon User 상태 체크
|
||||
var check_summon_user_condition = await checkSummonUserConditionAsync(party, summon_user);
|
||||
if (check_summon_user_condition != SummonPartyMemberResultType.Accept)
|
||||
{
|
||||
sendReplySummonPartyMemberAsync(notify.SummonServerName, notify.SummonPartyGuid, notify.SummonUserGuid, check_summon_user_condition);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Summon Message 전송
|
||||
var client_message = new ClientToGame();
|
||||
client_message.Message = new ClientToGameMessage();
|
||||
client_message.Message.SummonPartyMemberNoti = new();
|
||||
|
||||
PartyHelper.sendToClient(client_message, summon_user.getHostId());
|
||||
}
|
||||
|
||||
private async Task<SummonPartyMemberResultType> checkSummonUserConditionAsync(GlobalPartyDetail party, Player summon_user)
|
||||
{
|
||||
// 1. 파티원 체크
|
||||
var party_member_attribute = party.getEntityAttribute<PartyMemberAttribute>();
|
||||
if (null == party_member_attribute) return SummonPartyMemberResultType.NotParty;
|
||||
|
||||
var party_member = party_member_attribute.getPartyMember(summon_user.getUserGuid());
|
||||
if (null == party_member) return SummonPartyMemberResultType.NotParty;
|
||||
|
||||
// 2. 방해 금지 상태 체크
|
||||
var user_attribute = summon_user.getEntityAttribute<UserAttribute>();
|
||||
NullReferenceCheckHelper.throwIfNull(user_attribute, () => $"user_attribute is null !!!");
|
||||
if (user_attribute.PlayerState == PlayerStateType.DontDistrub) return SummonPartyMemberResultType.DoNotDisturb;
|
||||
|
||||
// 3. 소환 상태 체크
|
||||
if(false == party_member.Summon.IsAlreadySummon) return SummonPartyMemberResultType.NotSummon;
|
||||
|
||||
return await Task.FromResult(SummonPartyMemberResultType.Accept);
|
||||
}
|
||||
|
||||
private void sendReplySummonPartyMemberAsync(string summon_server, string summon_party_guid, USER_GUID summon_user_guid, SummonPartyMemberResultType reply)
|
||||
{
|
||||
var server_message = new ServerMessage();
|
||||
server_message.ReplySummonPartyMemberNoti = new();
|
||||
server_message.ReplySummonPartyMemberNoti.SummonPartyGuid = summon_party_guid;
|
||||
server_message.ReplySummonPartyMemberNoti.SummonUserGuid = summon_user_guid;
|
||||
server_message.ReplySummonPartyMemberNoti.Result = reply;
|
||||
|
||||
PartyHelper.sendToServer(server_message, summon_server);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user