Files
ft/Client/Assets/Scripts/Services/KvUserService.cs

982 lines
36 KiB
C#

using Core.KV;
using game.KV;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using asap.core;
using GameCore;
using tysdk;
using UnityEngine;
using Newtonsoft.Json;
using YiDun.Protector;
#if UNITY_ANDROID
using TapjoyUnity.Internal;
#endif
namespace game
{
// Failed login attempts may retry; explicit logout ends this service lifetime.
public class KvUserService : IUserService
{
[Inject]
public IConfig config
{
get;
set;
}
[Inject]
public ICustomServerMgr customServerMgr
{
get;
set;
}
[Inject]
public IPlayerSaveStore SaveStore
{
get;
set;
}
//
private readonly KvRuntimeSelection selection;
private readonly CancellationTokenSource lifetime = new();
private readonly Dictionary<string, PlayInfo> profiles = new();
private readonly Dictionary<string, int> levels = new();
private KvGameLoadCoordinator coordinator;
private KvSessionOwner handle;
private bool loading, closing, published;
private KvSessionOwner failedHandle;
private int mmTestValue;
private Task closeTask;
private long epoch;
private string playerId;
private uint internalId;
public string CustomId
{
get;
set;
}
public string UserId => KVHandoffReady ? playerId : null;
public string ApiPlayerId => UserId;
public uint InternalId => KVHandoffReady ? internalId : 0;
public bool IsLogin => KVHandoffReady && playerId != null;
public bool IsAuthorized => published && InternalId != 0 && KVHandoffReady;
public CancellationToken LoginLifetime => lifetime.Token;
public DateTime LastLoginTime
{
get;
private set;
}
public DateTime LoginTime
{
get;
private set;
}
public DateTime CreateTime
{
get;
private set;
}
public string DisplayName
{
get;
private set;
}
public string AvatarUrl
{
get;
private set;
}
public string Language
{
get;
private set;
}
public string ContinentCode
{
get;
private set;
}
public Dictionary<string, string> EAccoutUrl
{
get;
protected set;
} = new Dictionary<string, string>();
internal bool KVHandoffReady => !closing && handle != null && coordinator != null &&
coordinator.TryGetCurrentGameHandle(epoch, out var current) && ReferenceEquals(current, handle);
public KvUserService()
{
selection = SubBoostrap.RuntimeSelection;
Application.quitting += OnApplicationQuitting;
}
protected virtual string NewPlayerName => $"Angler#{CustomId}";
protected virtual string NewPlayerAvatar => string.Empty;
protected virtual void InitData(IDictionary<string, string> data)
{
}
public virtual async Task<ELoginStep> Login(Action<int> progress, bool tyrLoginByToken = true)
{
if (loading || closing)
{
return ELoginStep.Api;
}
if (IsLogin)
{
progress?.Invoke(2);
return ELoginStep.Done;
}
if (selection == null || !selection.IsKV || !selection.TryAdmitPlayer(CustomId, out var canonicalId))
{
return ELoginStep.Api;
}
loading = true;
var requestedId = CustomId;
bool successEventStarted = false;
IChatService chat = null;
try
{
CustomServerMgr server;
KvSaveStore store;
KvGameLoadResult result;
KvSessionOwner original;
try
{
if (!await ReleaseFailedLoginAsync() || closing)
{
return ELoginStep.Api;
}
server = customServerMgr as CustomServerMgr;
if (server == null || server.ApiBaseUri.AbsoluteUri != selection.Api.AbsoluteUri)
{
throw new InvalidOperationException("Formal KV transport required.");
}
coordinator = new KvGameLoadCoordinator(
() => loading && !closing && !published && handle == null,
server.BindKVForGame, server.ClearKVForGame);
server.KVUnauthorized += OnUnauthorized;
var api = selection.Api;
var cacheRoot = Application.persistentDataPath;
if (api == null || !api.IsAbsoluteUri || (api.Scheme != "http" && api.Scheme != "https") ||
!string.IsNullOrEmpty(api.UserInfo) || !string.IsNullOrEmpty(api.Query) || !string.IsNullOrEmpty(api.Fragment))
{
throw new ArgumentException("Formal KV endpoint mismatch.", nameof(api));
}
if (string.IsNullOrEmpty(cacheRoot))
{
throw new ArgumentException("Controlled load configuration invalid.");
}
api = new Uri(api.AbsoluteUri.TrimEnd('/') + "/");
result = await coordinator.LoadForGameAsync(canonicalId, api, cacheRoot, LoginLifetime,
() => !closing && CustomId == requestedId);
if (result.Error != KVGameLoadError.None ||
closing || CustomId != requestedId || result.Account == null ||
result.Account.PlayerId != canonicalId || result.Account.Epoch != result.Epoch ||
!coordinator.TryGetCurrentGameHandle(result.Epoch, out original))
{
await FailLoginAsync();
return ELoginStep.Api;
}
epoch = result.Epoch;
handle = original;
store = SaveStore as KvSaveStore;
if (store == null)
{
throw new InvalidOperationException("KV save store required.");
}
store.Bind(original, LoginLifetime);
}
catch (Exception ex)
{
Debug.LogError("KV preparation failed: " + ex.GetType().Name);
await FailLoginAsync();
return ELoginStep.Api;
}
await PrepareProfileAsync(result.Account);
if (!KVHandoffReady || CustomId != requestedId)
{
await FailLoginAsync();
return ELoginStep.Api;
}
playerId = result.Account.PlayerId;
internalId = result.Account.InternalId;
ZZTimeHelper.AdjustTime(LoginTime);
ZZTimeHelper.WathForcusChange();
if (!original.CompareDatas(ZZTimeHelper.UtcNow().Ticks).Success)
{
await FailLoginAsync();
return ELoginStep.Api;
}
var merged = original.ReadLocalSnapshot();
if (!merged.Success)
{
await FailLoginAsync();
return ELoginStep.Api;
}
KvMgr.Bind(store);
InitializePlayerData(merged.Data.ToDictionary(pair => pair.Key, pair => pair.Value, StringComparer.Ordinal));
if (!KVHandoffReady || CustomId != requestedId)
{
await FailLoginAsync();
return ELoginStep.Api;
}
SetMMTestValue();
try
{
BindPromptServices(original);
}
catch (Exception ex)
{
Debug.LogError("KV prompt binding failed: " + ex.GetType().Name);
await FailLoginAsync();
return ELoginStep.Api;
}
chat = GContext.container.Resolve<IChatService>();
chat.WaitingForLogin();
OnYinDunLogin();
if (!KVHandoffReady || CustomId != requestedId)
{
await FailLoginAsync();
return ELoginStep.Api;
}
server.EnableKVBusiness(epoch);
published = true;
successEventStarted = true;
try
{
GContext.Publish(new EvtAPISvrLoginSuccess { playerId = playerId, internalId = internalId });
}
catch (Exception ex)
{
// Original LoginApiServer catches subscriber errors and removes API authorization.
Debug.LogError(ex);
internalId = 0;
published = false;
server.DisableKVBusiness();
}
if (closing)
{
return ELoginStep.Api;
}
InitTapJoy();
progress?.Invoke(2);
return ELoginStep.Done;
}
catch (Exception ex)
{
if (successEventStarted)
{
throw;
}
Debug.LogError("KV login failed: " + ex.GetType().Name);
try
{
(chat as IDisposable)?.Dispose();
}
catch (Exception cleanupError)
{
Debug.LogError("KV chat cleanup failed: " + cleanupError);
}
try
{
await FailLoginAsync();
}
catch (Exception cleanupError)
{
Debug.LogError("KV login cleanup failed: " + cleanupError);
}
throw;
}
finally
{
loading = false;
}
}
private void InitializePlayerData(Dictionary<string, string> data)
{
mmTestValue = 0;
if (!data.ContainsKey("MMTest"))
{
if (config.Get<bool>("NewlyCreated", false))
{
mmTestValue = -1;
}
else
{
SaveStore.Write("MMTest", "MMFailParam#0").RequireAccepted();
}
}
else
{
var parts = data["MMTest"].Split('#');
if (parts.Length > 1 && parts[0] == "MMFailParam")
{
int.TryParse(parts[1], out var value);
mmTestValue = value;
}
else
{
mmTestValue = 0;
SaveStore.Write("MMTest", "MMFailParam#0").RequireAccepted();
}
}
GContext.container.Resolve<PlayerData>().LoadPlayerData(data);
InitData(data);
}
private async Task PrepareProfileAsync(KvAccountDescriptor account)
{
if (account.InternalId == 0 || account.CreateTimeUtc == DateTime.MinValue || account.ServerTimeUtc == DateTime.MinValue)
{
throw new InvalidOperationException("Authenticated account metadata required.");
}
CreateTime = account.CreateTimeUtc;
LoginTime = account.ServerTimeUtc;
config.Set("NewlyCreated", account.NewlyCreated);
var previous = Read("LastLoginTimeUtc");
LastLoginTime = ParseLastLoginTime(previous.Value, previous.Found.Value);
DisplayName = Read("DisplayName").Value;
AvatarUrl = Read("AvatarUrl").Value ?? string.Empty;
Language = Read("Language").Value;
var continent = Read("ContinentCode").Value;
ContinentCode = new[] { "AF", "AN", "AS", "EU", "NA", "OC", "SA" }.Contains(continent) ? continent : null;
if (string.IsNullOrEmpty(DisplayName))
{
var name = await ChangeDisplayName(NewPlayerName);
LoginLifetime.ThrowIfCancellationRequested();
if (!KVHandoffReady)
{
throw new InvalidOperationException("Stale KV profile.");
}
DisplayName = name;
}
if (string.IsNullOrEmpty(AvatarUrl))
{
await UpdateAvatarUrl(NewPlayerAvatar);
}
await UpdateLanguage(GContext.container.Resolve<ISettingService>().Lang);
LoginLifetime.ThrowIfCancellationRequested();
}
private async Task FailLoginAsync()
{
if (closing)
{
return;
}
if (closeTask != null)
{
await ReleaseFailedLoginAsync();
return;
}
failedHandle = handle;
handle = null;
playerId = null;
internalId = 0;
published = false;
DisplayName = AvatarUrl = Language = ContinentCode = null;
ClearPlayInfos();
if (customServerMgr is CustomServerMgr server)
{
server.KVUnauthorized -= OnUnauthorized;
server.DisableKVBusiness();
}
closeTask = coordinator?.Revoke() ?? Task.CompletedTask;
await ReleaseFailedLoginAsync();
}
private async Task<bool> ReleaseFailedLoginAsync()
{
if (closeTask == null)
{
return true;
}
var status = await (coordinator?.ObserveQuitAsync() ?? Task.FromResult(KVShutdownStatus.Ready));
if (closing || status != KVShutdownStatus.Ready || closeTask.Status != TaskStatus.RanToCompletion)
{
return false;
}
if (failedHandle != null)
{
KvMgr.Unbind(SaveStore as KvSaveStore);
(SaveStore as KvSaveStore)?.ReleaseFailedBinding(failedHandle);
(GContext.container.Resolve<ISettingService>() as DefaultSettingService)?.ReleaseFailedPromptOwner(failedHandle);
GContext.container.Resolve<ClubService>().ReleaseFailedPromptOwner(failedHandle);
}
failedHandle = null;
closeTask = null;
coordinator = null;
epoch = 0;
return true;
}
internal static DateTime ParseLastLoginTime(string value, bool found)
{
if (!found)
{
return DateTime.MinValue;
}
if (!DateTime.TryParseExact(value, "O", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var time) ||
time == DateTime.MinValue || time.Kind == DateTimeKind.Unspecified)
{
throw new FormatException("Invalid LastLoginTimeUtc.");
}
return time.ToUniversalTime();
}
private PlayerSaveReadResult Read(string key)
{
var result = SaveStore.Read(key);
if (!result.Success)
{
throw new InvalidOperationException("KV profile read failed: " + result.Error);
}
return result;
}
private void BindPromptServices(KvSessionOwner original)
{
if (!KVHandoffReady)
{
throw new InvalidOperationException("Prompt binding is stale.");
}
var settings = GContext.container.Resolve<ISettingService>() as DefaultSettingService;
var notifications = GContext.container.Resolve<ILocalNotificationService>() as LocalNotificationService;
var club = GContext.container.Resolve<ClubService>();
if (settings == null || notifications == null || club == null)
{
throw new InvalidOperationException("Formal prompt services required.");
}
settings.PreflightFormalPromptOwner(original);
club.PreflightFormalPromptOwner(original);
notifications.PreflightFormalPromptSettings(settings);
settings.BindFormalPromptOwner(original);
club.BindFormalPromptOwner(original);
notifications.BindFormalPromptSettings(settings);
if (!KVHandoffReady)
{
throw new InvalidOperationException("Formal prompt binding changed.");
}
}
private void OnUnauthorized(int version)
{
if (version == customServerMgr.SessionVersion)
{
Logout();
}
}
private void OnApplicationQuitting()
{
var original = SaveStore as KvSaveStore;
try
{
KvMgr.Stop(original);
if (original != null && original.IsCurrent)
{
_ = original.SyncDataAsync();
}
}
catch (Exception ex)
{
Debug.LogError("KV quit save failed: " + ex.GetType().Name);
}
finally
{
Logout();
}
}
public virtual void Logout()
{
ObserveClose(CloseKVForValidationAsync());
}
private async void ObserveClose(Task task)
{
try
{
await task;
}
catch (Exception ex)
{
Debug.LogError("KV close failed: " + ex.GetType().Name);
}
}
internal Task CloseKVForValidationAsync()
{
if (closing)
{
return closeTask ?? Task.CompletedTask;
}
closing = true;
published = false;
KvMgr.Unbind(SaveStore as KvSaveStore);
(SaveStore as KvSaveStore)?.Dispose();
playerId = null;
internalId = 0;
handle = null;
epoch = 0;
DisplayName = AvatarUrl = Language = ContinentCode = null;
ClearPlayInfos();
Application.quitting -= OnApplicationQuitting;
if (customServerMgr is CustomServerMgr server)
{
server.KVUnauthorized -= OnUnauthorized;
server.DisableKVBusiness();
}
// Revoke first; a synchronous cancellation callback must already see invalid identity.
closeTask = coordinator?.Revoke() ?? Task.CompletedTask;
lifetime.Cancel();
return closeTask;
}
internal Task<KVShutdownStatus> ObserveKVQuitAsync() =>
coordinator?.ObserveQuitAsync() ?? Task.FromResult(KVShutdownStatus.Ready);
private async Task<bool> SaveProfile(string key, string value)
{
var original = handle;
var store = SaveStore;
if ((!IsLogin && !loading) || !KVHandoffReady || store == null)
{
return false;
}
try
{
var result = await store.SyncDataImmidiate(key, value);
return ReferenceEquals(original, handle) && KVHandoffReady &&
ReferenceEquals(store, SaveStore) && store.IsCurrent && result;
}
catch (OperationCanceledException)
{
return false;
}
}
public async Task<string> ChangeDisplayName(string newName)
{
var originName = string.IsNullOrEmpty(DisplayName) ? NewPlayerName : DisplayName;
if (!await SaveProfile("DisplayName", newName))
{
return originName;
}
DisplayName = newName;
GContext.Publish(new ChangeAvatarEvent());
UpdateProfileName();
return newName;
}
public async Task<string> UpdateAvatarUrl(string url)
{
var originUrl = AvatarUrl;
Debug.Log("UpdateAvatarUrlAsync originUrl:" + originUrl + " url " + url);
if (string.IsNullOrEmpty(url))
{
return originUrl;
}
if (url == originUrl)
{
return originUrl;
}
if (!await SaveProfile("AvatarUrl", url))
{
return originUrl;
}
AvatarUrl = url;
GContext.Publish(new ChangeAvatarEvent());
UpdateProfileAvatar();
return url;
}
public async Task<string> UpdateLanguage(string code)
{
if (Language == code)
{
return Language;
}
if (await SaveProfile("Language", code.Replace('_', '-')))
{
Language = code;
}
return Language;
}
public void GMMMT(int value)
{
mmTestValue = value;
SaveStore.Write("MMTest", $"MMFailParam#{mmTestValue}").RequireAccepted();
SetMMTestValue();
}
private void SetMMTestValue()
{
string ab = GContext.container.Resolve<MMTService>().Init(mmTestValue);
GEvent.SetUserProp("MMTestValue", ab, true);
Debug.Log($"UserId:{UserId} MMTestValue :0b{Convert.ToString(mmTestValue, 2)} MMTestValueString:{ab}");
}
protected void AvatarToKV(TYSdkFacade.AccountInfo accountInfo)
{
if (accountInfo != null &&
(accountInfo.channel == EAccoutType.hwFacebook || accountInfo.channel == EAccoutType.hwGoogle) &&
!string.IsNullOrEmpty(accountInfo.avatar))
{
if (EAccoutUrl == null)
{
EAccoutUrl = new Dictionary<string, string>();
}
EAccoutUrl[accountInfo.channel.ToString()] = accountInfo.avatar;
SaveStore.Write("EAccoutUrl", JsonConvert.SerializeObject(EAccoutUrl)).RequireAccepted();
}
}
private void InitTapJoy()
{
#if UNITY_ANDROID
var lastBalanceStr = Read("TapJoy_Diamond").Value ?? "";
Debug.Log($"InitTapJoy -> {lastBalanceStr}");
var lastBalance = int.TryParse(lastBalanceStr, out var temp) ? temp : 0;
var tapjoyObject = GameObject.FindObjectOfType<TapjoyComponent>();
if (tapjoyObject && tapjoyObject.gameObject && !tapjoyObject.GetComponent<TapjoyHelper>())
{
var tapjoyHelper = tapjoyObject.gameObject.AddComponent<TapjoyHelper>();
GameObject.DontDestroyOnLoad(tapjoyHelper);
tapjoyHelper.Init(lastBalance, OnEarnCurrencyName, OnBalance);
}
return;
void OnEarnCurrencyName(string currencyName, int amount)
{
Debug.Log($"OnEarnCurrencyName -> {currencyName} {amount}");
// var amount = (balance - lastBalance);
var diamonds = new ItemData { id = 1005, count = amount };
diamonds.curCount = (ulong)GContext.container.Resolve<PlayerItemData>().GetItemCount(diamonds.id);
GContext.container.Resolve<PlayerItemData>().AddItem(diamonds, null);
GContext.Publish(new ShowData(new List<ItemData> { diamonds }, RewardType.NormalOne));
GContext.Publish(new ShowData());
#if AGG
using (var e = GEvent.GameEvent("tapjoy"))
{
e.AddContent("item_id", diamonds.id)
.AddContent("item_count", diamonds.count);
}
#endif
}
void OnBalance(string currencyName, int balance)
{
Debug.Log($"OnBalance -> {currencyName} {balance}");
// const string tapjoyKey = "TapJoy_Diamond";
// var lastBalanceStr = PlayFabMgr.Instance.GetLocalData(tapjoyKey) ?? "";
// var lastBalance = int.TryParse(lastBalanceStr, out var temp) ? temp : 0;
{
// PlayFabMgr.Instance.UpdateUserDataValue(tapjoyKey, balance.ToString());
// if (balance > lastBalance)
// {
// var amount = (balance - lastBalance);
// var diamonds = new ItemData { id = 1005, count = amount };
// diamonds.curCount = (ulong)GContext.container.Resolve<PlayerItemData>().GetItemCount(diamonds.id);
// GContext.container.Resolve<PlayerItemData>().AddItem(diamonds);
// GContext.Publish(new ShowData(new List<ItemData> { diamonds }, RewardType.NormalOne));
// // GContext.Publish(new ShowData(diamonds));
// GContext.Publish(new ShowData());
// }
}
}
#endif
}
private async void OnYinDunLogin()
{
// 开发模式下,先不启用了
if (config != null && (config.Get("DEBUG", "0") == "1" || config.Get("GM", "0") == "1"))
{
return;
}
var userService = GContext.container.Resolve<IUserService>();
var yiDunManager = GContext.container.Resolve<YiDunManager>();
var roleName = userService.DisplayName;
var roleId = userService.UserId;
var roleAccount = userService.CustomId;
var versionData = new
{
GameVersion = Application.version,
AssetVersion = config.Get(GConstant.K_AssetVersion, string.Empty),
#if UNITY_ANDROID
Channel = GConstant.Yidun_GooglePlayChannel
#elif UNITY_IOS
Channel = GConstant.Yidun_IOSChannel
#endif
};
Debug.Log($"JsonUtility.ToJson(versionData) => {JsonConvert.SerializeObject(versionData)}");
#if (UNITY_ANDROID || UNITY_IOS || UNITY_IPHONE) && !UNITY_EDITOR
var businessId = GConstant.Yidun_AndroidBusinessId;
#if UNITY_IOS
businessId = GConstant.Yidun_IOSBusinessId;
#endif
yiDunManager.SetRoleInfo(businessId, roleId, roleName, roleAccount, null, -1, JsonConvert.SerializeObject(versionData));
yiDunManager.PostRiskCheck();
#endif
}
public double CreateTotalSeconds() => (ZZTimeHelper.UtcNow() - CreateTime).TotalSeconds;
private sealed class BindConflictPreviewResponse
{
public int Code
{
get;
set;
}
public bool Exists
{
get;
set;
}
public bool HasArchive
{
get;
set;
}
public string DisplayName
{
get;
set;
}
public string AvatarUrl
{
get;
set;
}
public int Level
{
get;
set;
}
}
public async Task<PlayFabTools.PFPlayerInfo> GetBindConflictPreview(int sdkId)
{
try
{
string json = null;
for (var attempt = 0; attempt < 4; attempt++)
{
json = await customServerMgr.AccountRequest("GetBindConflictPreview",
new { targetUserId = sdkId.ToString() });
if (json != null)
{
break;
}
if (attempt < 3)
{
await Task.Delay(TimeSpan.FromSeconds(1 << attempt));
}
}
if (string.IsNullOrEmpty(json))
{
return PlayFabTools.PFPlayerInfo.Empty(sdkId);
}
var response = JsonConvert.DeserializeObject<BindConflictPreviewResponse>(json);
if (response == null || response.Code <= 0 || !response.Exists)
{
return PlayFabTools.PFPlayerInfo.Empty(sdkId);
}
if (!response.HasArchive)
{
return new PlayFabTools.PFPlayerInfo
{
SdkId = sdkId,
PlayFabId = sdkId.ToString()
};
}
return new PlayFabTools.PFPlayerInfo
{
SdkId = sdkId,
PlayFabId = sdkId.ToString(),
DisplayName = response.DisplayName,
Avatar = response.AvatarUrl,
Level = response.Level
};
}
catch (Exception e)
{
Debug.LogWarning(e.Message);
return PlayFabTools.PFPlayerInfo.Empty(sdkId);
}
}
// The non-AGG channel has no account-link operation; never manufacture a successful binding.
public virtual async Task<(int code, int userid)> LinkAccount(EAccoutType type)
{
await Awaiters.NextFrame;
return (1, 0);
}
public virtual async Task<bool> GetLinkState(EAccoutType type)
{
await Awaiters.NextFrame;
return false;
}
public string GetDefaultName(string id) => "Angler#" + (string.IsNullOrEmpty(id) ? string.Empty : id.Substring(0, Math.Min(5, id.Length)));
public void SetPlayerLv(string id, int level) => levels[id] = id == UserId ? GContext.container.Resolve<PlayerData>().lv : level;
public int GetPlayerLv(string id) => levels.TryGetValue(id, out var level) ? level : 1;
public async Task<(string, int)> GetPlayLv(string id)
{
var level = id == UserId && IsAuthorized ? (int)GContext.container.Resolve<PlayerData>().lv :
id != null && levels.TryGetValue(id, out var cachedLevel) ? cachedLevel : -1;
if (level >= 0)
{
return (id, level);
}
if (id != UserId && !string.IsNullOrEmpty(id) && !levels.ContainsKey(id))
{
var json = await customServerMgr.FriendRequest("SearchFriend", new SearchFriendReq { PlayFabId = id });
if (!string.IsNullOrEmpty(json))
{
SearchFriendResp response = null;
try
{
response = Newtonsoft.Json.JsonConvert.DeserializeObject<SearchFriendResp>(json);
}
catch (Newtonsoft.Json.JsonException ex)
{
Debug.LogError("KV player level response failed: " + ex.GetType().Name);
}
if (response != null && response.Code > 0 && response.KvProfile != null)
{
level = response.KvProfile.Level ?? 1;
if (level >= 0)
{
levels[id] = level;
return (id, level);
}
}
}
}
throw new InvalidOperationException("Public player level has not been loaded.");
}
public PlayInfo GetPlayInfo(string id)
{
if (string.IsNullOrEmpty(id))
{
return null;
}
if (!profiles.TryGetValue(id, out var profile))
{
profile = new PlayInfo { name = GetDefaultName(id) };
profiles.Add(id, profile);
SetPlayInfo(id, profile);
}
return profile;
}
private async void SetPlayInfo(string id, PlayInfo profile)
{
if (id == UserId)
{
profile.name = DisplayName;
profile.avatarUrl = AvatarUrl;
GContext.Publish(new GetClubPlayInfoEvent { id = id, name = profile.name, avatarUrl = profile.avatarUrl });
return;
}
var json = await customServerMgr.FriendRequest("SearchFriend", new SearchFriendReq { PlayFabId = id });
if (string.IsNullOrEmpty(json))
{
return;
}
SearchFriendResp result;
try
{
result = Newtonsoft.Json.JsonConvert.DeserializeObject<SearchFriendResp>(json);
}
catch (Newtonsoft.Json.JsonException ex)
{
Debug.LogError("KV player profile response failed: " + ex.GetType().Name);
return;
}
if (result != null && result.Code > 0 && result.KvProfile != null)
{
if (!string.IsNullOrEmpty(result.KvProfile.DisplayName))
{
profile.name = result.KvProfile.DisplayName;
}
profile.avatarUrl = result.KvProfile.AvatarUrl;
GContext.Publish(new GetClubPlayInfoEvent { id = id, name = profile.name, avatarUrl = profile.avatarUrl });
}
}
public void SetPlayInfo(string id, string name, string avatarUrl)
{
profiles[id] = new PlayInfo
{
name = string.IsNullOrEmpty(name) ? GetDefaultName(id) : name,
avatarUrl = avatarUrl
};
}
public void ClearPlayInfos()
{
profiles.Clear();
levels.Clear();
}
private void UpdateProfileName()
{
if (!IsAuthorized)
{
return;
}
PlayerProfile playerProfile = new PlayerProfile();
playerProfile.DisplayName = DisplayName;
LoginRequest loginRequest = new LoginRequest() { playerId = ApiPlayerId, playerProfile = playerProfile };
customServerMgr.AccountRequest("UpdateProfile", loginRequest);
}
private void UpdateProfileAvatar()
{
if (!IsAuthorized)
{
return;
}
PlayerProfile playerProfile = new PlayerProfile();
playerProfile.Avatar = AvatarUrl;
LoginRequest loginRequest = new LoginRequest() { playerId = ApiPlayerId, playerProfile = playerProfile };
customServerMgr.AccountRequest("UpdateProfile", loginRequest);
}
public void UpdateProfile()
{
if (IsAuthorized)
{
customServerMgr.AccountRequest("UpdateProfile", new LoginRequest
{
playerId = ApiPlayerId,
playerProfile = new PlayerProfile { Level = GContext.container.Resolve<PlayerData>().lv, Avatar = AvatarUrl, DisplayName = DisplayName }
});
}
}
public void UpdateProfileLv()
{
if (IsAuthorized)
{
customServerMgr.AccountRequest("UpdateProfile", new LoginRequest
{
playerId = ApiPlayerId,
playerProfile = new PlayerProfile { Level = GContext.container.Resolve<PlayerData>().lv }
});
}
}
}
}