Files
LuaCsForBarotraumaEP/Libraries/BarotraumaLibs/EosInterfacePrivate/InterfaceImpl/Friends/FriendsPrivate.cs
2024-03-28 18:34:33 +02:00

250 lines
11 KiB
C#

#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading.Tasks;
using Barotrauma.Networking;
using Barotrauma;
using Barotrauma.Extensions;
namespace EosInterfacePrivate;
static class FriendsPrivate
{
internal static async Task<Result<Epic.OnlineServices.UserInfo.UserInfoData, EosInterface.Friends.GetFriendsError>> GetUserInfoData(
EpicAccountId selfEaid, EpicAccountId friendEaid)
{
if (CorePrivate.EgsUserInfoInterface is not { } egsUserInfoInterface) { return Result.Failure(EosInterface.Friends.GetFriendsError.EosNotInitialized); }
var selfEaidInternal = Epic.OnlineServices.EpicAccountId.FromString(selfEaid.EosStringRepresentation);
var friendEaidInternal = Epic.OnlineServices.EpicAccountId.FromString(friendEaid.EosStringRepresentation);
var queryUserInfoOptions = new Epic.OnlineServices.UserInfo.QueryUserInfoOptions
{
LocalUserId = selfEaidInternal,
TargetUserId = friendEaidInternal
};
var queryUserInfoWaiter = new CallbackWaiter<Epic.OnlineServices.UserInfo.QueryUserInfoCallbackInfo>();
egsUserInfoInterface.QueryUserInfo(options: ref queryUserInfoOptions, clientData: null, completionDelegate: queryUserInfoWaiter.OnCompletion);
var queryUserInfoResult = await queryUserInfoWaiter.Task;
if (!queryUserInfoResult.TryUnwrap(out var queryUserInfo))
{
return Result.Failure(EosInterface.Friends.GetFriendsError.UserInfoQueryTimedOut);
}
if (queryUserInfo.ResultCode != Epic.OnlineServices.Result.Success)
{
return Result.Failure(EosInterface.Friends.GetFriendsError.UserInfoQueryFailed);
}
var copyUserInfoOptions = new Epic.OnlineServices.UserInfo.CopyUserInfoOptions
{
LocalUserId = selfEaidInternal,
TargetUserId = friendEaidInternal
};
var copyUserInfoResult = egsUserInfoInterface.CopyUserInfo(ref copyUserInfoOptions, out var friendInfoNullable);
if (copyUserInfoResult != Epic.OnlineServices.Result.Success)
{
return Result.Failure(EosInterface.Friends.GetFriendsError.CopyUserInfoFailed);
}
if (friendInfoNullable is not { } friendInfo)
{
return Result.Failure(EosInterface.Friends.GetFriendsError.CopyUserInfoFailed);
}
string displayName = friendInfo.Nickname ?? friendInfo.DisplayName ?? "";
if (string.IsNullOrEmpty(displayName))
{
return Result.Failure(EosInterface.Friends.GetFriendsError.DisplayNameIsEmpty);
}
return Result.Success(friendInfo);
}
internal static async Task<Result<EosInterface.EgsFriend, EosInterface.Friends.GetFriendsError>> GetPresenceFromUserInfoData(
EpicAccountId selfEaid, EpicAccountId friendEaid, Epic.OnlineServices.UserInfo.UserInfoData friendInfo)
{
if (CorePrivate.EgsPresenceInterface is not { } egsPresenceInterface) { return Result.Failure(EosInterface.Friends.GetFriendsError.EosNotInitialized); }
var selfEaidInternal = Epic.OnlineServices.EpicAccountId.FromString(selfEaid.EosStringRepresentation);
var friendEaidInternal = friendInfo.UserId;
string displayName = friendInfo.Nickname ?? friendInfo.DisplayName ?? "";
var queryPresenceOptions = new Epic.OnlineServices.Presence.QueryPresenceOptions
{
LocalUserId = selfEaidInternal,
TargetUserId = friendEaidInternal
};
var queryPresenceWaiter = new CallbackWaiter<Epic.OnlineServices.Presence.QueryPresenceCallbackInfo>();
egsPresenceInterface.QueryPresence(options: ref queryPresenceOptions, clientData: null, completionDelegate: queryPresenceWaiter.OnCompletion);
var queryPresenceResult = await queryPresenceWaiter.Task;
if (!queryPresenceResult.TryUnwrap(out var queryPresence))
{
return Result.Failure(EosInterface.Friends.GetFriendsError.EgsPresenceQueryTimedOut);
}
if (queryPresence.ResultCode != Epic.OnlineServices.Result.Success)
{
return Result.Failure(EosInterface.Friends.GetFriendsError.EgsPresenceQueryFailed);
}
var copyPresenceOptions = new Epic.OnlineServices.Presence.CopyPresenceOptions
{
LocalUserId = selfEaidInternal,
TargetUserId = friendEaidInternal
};
var copyPresenceResult = egsPresenceInterface.CopyPresence(ref copyPresenceOptions, out var friendPresenceNullable);
if (copyPresenceResult != Epic.OnlineServices.Result.Success)
{
return Result.Failure(EosInterface.Friends.GetFriendsError.CopyPresenceFailed);
}
if (friendPresenceNullable is not { } friendPresence)
{
return Result.Failure(EosInterface.Friends.GetFriendsError.CopyPresenceFailed);
}
string productId = friendPresence.ProductId ?? "";
var friendStatus = friendPresence.Status switch
{
Epic.OnlineServices.Presence.Status.Offline
=> FriendStatus.Offline,
_
=> productId == PlatformInterfaceOptionsPrivate.BasePlatformInterfaceOptions.ProductId
? FriendStatus.PlayingBarotrauma
: !string.IsNullOrEmpty(productId)
? FriendStatus.PlayingAnotherGame
: FriendStatus.NotPlaying
};
var records = friendPresence.Records ?? Array.Empty<Epic.OnlineServices.Presence.DataRecord>();
string getRecordValue(string key)
=> records
.FirstOrNone(r => string.Equals(r.Key, key, StringComparison.OrdinalIgnoreCase))
.Select(r => r.Value)
.Fallback("");
var connectCommand = getRecordValue("connectcommand");
var serverName = getRecordValue("servername");
return Result.Success(new EosInterface.EgsFriend(
DisplayName: displayName,
EpicAccountId: friendEaid,
Status: friendStatus,
ConnectCommand: connectCommand,
ServerName: serverName));
}
public static async Task<Result<EosInterface.EgsFriend, EosInterface.Friends.GetFriendsError>> GetSelfUserInfo(EpicAccountId epicAccount)
{
var getUserInfoDataResult = await GetUserInfoData(epicAccount, epicAccount);
if (getUserInfoDataResult.TryUnwrapFailure(out var error))
{
return Result.Failure(error);
}
if (!getUserInfoDataResult.TryUnwrapSuccess(out var friendInfo))
{
throw new UnreachableCodeException();
}
string displayName = friendInfo.Nickname ?? friendInfo.DisplayName ?? "";
return Result.Success(new EosInterface.EgsFriend(
DisplayName: displayName,
EpicAccountId: epicAccount,
Status: FriendStatus.PlayingBarotrauma,
ConnectCommand: "",
ServerName: ""));
}
public static async Task<Result<EosInterface.EgsFriend, EosInterface.Friends.GetFriendsError>> GetFriend(EpicAccountId selfEaid, EpicAccountId friendEaid)
{
var getUserInfoDataResult = await GetUserInfoData(selfEaid, friendEaid);
if (getUserInfoDataResult.TryUnwrapFailure(out var error))
{
return Result.Failure(error);
}
if (!getUserInfoDataResult.TryUnwrapSuccess(out var friendInfo))
{
throw new UnreachableCodeException();
}
return await GetPresenceFromUserInfoData(selfEaid, friendEaid, friendInfo);
}
public static async Task<Result<ImmutableArray<EosInterface.EgsFriend>, EosInterface.Friends.GetFriendsError>> GetFriends(EpicAccountId epicAccount)
{
if (CorePrivate.EgsFriendsInterface is not { } egsFriendsInterface) { return Result.Failure(EosInterface.Friends.GetFriendsError.EosNotInitialized); }
var selfEaidInternal = Epic.OnlineServices.EpicAccountId.FromString(epicAccount.EosStringRepresentation);
var queryFriendsOptions = new Epic.OnlineServices.Friends.QueryFriendsOptions
{
LocalUserId = selfEaidInternal
};
var queryFriendsWaiter = new CallbackWaiter<Epic.OnlineServices.Friends.QueryFriendsCallbackInfo>();
egsFriendsInterface.QueryFriends(options: ref queryFriendsOptions, clientData: null, completionDelegate: queryFriendsWaiter.OnCompletion);
var queryFriendsInfoResult = await queryFriendsWaiter.Task;
if (!queryFriendsInfoResult.TryUnwrap(out var queryFriendsInfo))
{
return Result.Failure(EosInterface.Friends.GetFriendsError.EgsFriendsQueryTimedOut);
}
if (queryFriendsInfo.ResultCode != Epic.OnlineServices.Result.Success)
{
return Result.Failure(EosInterface.Friends.GetFriendsError.EgsFriendsQueryFailed);
}
var getFriendsCountOptions = new Epic.OnlineServices.Friends.GetFriendsCountOptions
{
LocalUserId = selfEaidInternal
};
var friendCount = egsFriendsInterface.GetFriendsCount(ref getFriendsCountOptions);
var friends = new List<EosInterface.EgsFriend>();
for (int i = 0; i < friendCount; i++)
{
var getFriendAtIndexOptions = new Epic.OnlineServices.Friends.GetFriendAtIndexOptions
{
LocalUserId = selfEaidInternal,
Index = i
};
var friendId = egsFriendsInterface.GetFriendAtIndex(ref getFriendAtIndexOptions);
if (friendId == null)
{
continue;
}
if (!EpicAccountId.Parse(friendId.ToString()).TryUnwrap(out var friendIdPublic))
{
continue;
}
var getUserInfoDataResult = await GetUserInfoData(epicAccount, friendIdPublic);
if (!getUserInfoDataResult.TryUnwrapSuccess(out var friendInfo))
{
continue;
}
var egsFriendPublicResult = await GetPresenceFromUserInfoData(epicAccount, friendIdPublic, friendInfo);
if (!egsFriendPublicResult.TryUnwrapSuccess(out var egsFriendPublic))
{
continue;
}
friends.Add(egsFriendPublic);
}
return Result.Success(friends.ToImmutableArray());
}
}
internal sealed partial class ImplementationPrivate : EosInterface.Implementation
{
public override Task<Result<EosInterface.EgsFriend, EosInterface.Friends.GetFriendsError>> GetFriend(EpicAccountId selfEaid, EpicAccountId friendEaid)
=> TaskScheduler.Schedule(() => FriendsPrivate.GetFriend(selfEaid, friendEaid));
public override Task<Result<ImmutableArray<EosInterface.EgsFriend>, EosInterface.Friends.GetFriendsError>> GetFriends(EpicAccountId epicAccountId)
=> TaskScheduler.Schedule(() => FriendsPrivate.GetFriends(epicAccountId));
public override Task<Result<EosInterface.EgsFriend, EosInterface.Friends.GetFriendsError>> GetSelfUserInfo(EpicAccountId epicAccountId)
=> TaskScheduler.Schedule(() => FriendsPrivate.GetSelfUserInfo(epicAccountId));
}