초기커밋

This commit is contained in:
2025-05-01 07:20:41 +09:00
commit 98bb2e3c5c
2747 changed files with 646947 additions and 0 deletions

View 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);
}
}