Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Assets/Talo Game Services/Talo/Runtime/APIs/BaseAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace TaloGameServices
public class BaseAPI
{
// automatically updated with a pre-commit hook
private const string ClientVersion = "0.54.0";
private const string ClientVersion = "0.55.0";

protected string baseUrl;

Expand Down
14 changes: 14 additions & 0 deletions Assets/Talo Game Services/Talo/Runtime/APIs/PlayerAuthAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,5 +167,19 @@ public async Task DeleteAccount(string currentPassword)

await _sessionManager.ClearSession();
}

public async Task MigrateAccount(string currentPassword, string service, string identifier)
{
var uri = new Uri($"{baseUrl}/migrate");
string content = JsonUtility.ToJson(new PlayerAuthMigrateAccountRequest {
currentPassword = currentPassword,
service = service,
identifier = identifier
});
var json = await Call(uri, "POST", content);

var res = JsonUtility.FromJson<PlayerAuthMigrateAccountResponse>(json);
await _sessionManager.HandleAccountMigrated(res);
}
}
}
126 changes: 119 additions & 7 deletions Assets/Talo Game Services/Talo/Runtime/Entities/EntityWithProps.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace TaloGameServices
Expand All @@ -19,24 +20,135 @@ public void SetProp(string key, string value)
{
props = props.Select((prop) =>
{
if (prop.key == key) prop.value = value;
if (prop.key == key)
{
prop.value = value;
}

return prop;
}).ToArray();
}
else
{
var propList = props.ToList();
propList.Add(new Prop((key, value)));
props = propList.ToArray();
props = props.Append(new Prop((key, value))).ToArray();
}
}

public void DeleteProp(string key)
{
Prop prop = props.FirstOrDefault((prop) => prop.key == key);
if (prop == null) throw new Exception($"Prop with key {key} does not exist");
var prop = props.FirstOrDefault((prop) => prop.key == key) ??
throw new Exception($"Prop with key {key} does not exist");

prop.value = null;
}

private string ToArrayKey(string key)
{
if (key.EndsWith("[]"))
{
return key;
}

return $"{key}[]";
}

public IReadOnlyList<string> GetPropArray(string key)
{
var items = props
.Where((prop) => prop.key == ToArrayKey(key) && prop.value != null)
.Select((prop) => prop.value);

return items.ToList().AsReadOnly();
}

private void EnsurePropArraySentinelRemoved(string key)
{
var arrayKey = ToArrayKey(key);

var hasSentinel = props.Any((prop) => prop.key == arrayKey && prop.value == null);
if (hasSentinel)
{
props = props.Where((prop) => prop.key != arrayKey).ToArray();
}
}

public void SetPropArray(string key, IEnumerable<string> values)
{
var validValues = values.Where((value) => !string.IsNullOrEmpty(value)).Distinct().ToList();

if (validValues.Count == 0)
{
throw new Exception($"Values for prop array {key} must contain at least one non-empty value");
}

var arrayKey = ToArrayKey(key);
props = props.Where((prop) => prop.key != arrayKey).ToArray();

props = props.Concat(validValues.Select((value) => new Prop((arrayKey, value)))).ToArray();
}

public void DeletePropArray(string key)
{
var arrayKey = ToArrayKey(key);

if (!props.Any((prop) => prop.key == arrayKey))
{
throw new Exception($"Prop array with key {key} does not exist");
}

props = props
.Where((prop) => prop.key != arrayKey)
// set a single value to null - this ensures the array is cleared
.Append(new Prop((arrayKey, null)))
.ToArray();
}

public void InsertIntoPropArray(string key, string value)
{
if (string.IsNullOrEmpty(value))
{
throw new Exception($"Value for prop array {key} cannot be null or empty");
}

var arrayKey = ToArrayKey(key);

var hasDupe = props.Any((prop) => prop.key == arrayKey && prop.value == value);
if (!hasDupe)
{
EnsurePropArraySentinelRemoved(key);
props = props.Append(new Prop((arrayKey, value))).ToArray();
}
}

private void EnsurePropArrayHasSentinel(string key)
{
var hasItems = props
.Where((prop) => prop.key == ToArrayKey(key))
.Any();

if (!hasItems)
{
props = props.Append(new Prop((ToArrayKey(key), null))).ToArray();
}
}

public void RemoveFromPropArray(string key, string value)
{
var arrayKey = ToArrayKey(key);
EnsurePropArraySentinelRemoved(key);

if (!props.Any((prop) => prop.key == arrayKey && prop.value == value))
{
EnsurePropArrayHasSentinel(key);
throw new Exception($"Value {value} does not exist in prop array {key}");
}

props = props.Where((prop) => {
var isMatchingValue = prop.key == arrayKey && prop.value == value;
return !isMatchingValue;
}).ToArray();

EnsurePropArrayHasSentinel(key);
}
}
}
}
41 changes: 41 additions & 0 deletions Assets/Talo Game Services/Talo/Runtime/Entities/Player.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using UnityEngine;
using System.Linq;
using System;
using System.Collections.Generic;

namespace TaloGameServices
{
Expand Down Expand Up @@ -37,6 +38,46 @@ public void DeleteProp(string key, bool update = true)
}
}

public void SetPropArray(string key, IEnumerable<string> values, bool update = true)
{
base.SetPropArray(key, values);

if (update)
{
Talo.Players.DebounceUpdate();
}
}

public void DeletePropArray(string key, bool update = true)
{
base.DeletePropArray(key);

if (update)
{
Talo.Players.DebounceUpdate();
}
}

public void InsertIntoPropArray(string key, string value, bool update = true)
{
base.InsertIntoPropArray(key, value);

if (update)
{
Talo.Players.DebounceUpdate();
}
}

public void RemoveFromPropArray(string key, string value, bool update = true)
{
base.RemoveFromPropArray(key, value);

if (update)
{
Talo.Players.DebounceUpdate();
}
}

public bool IsInGroupID(string groupId)
{
return groups.Any((group) => group.id == groupId);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace TaloGameServices
{
[System.Serializable]
public class PlayerAuthMigrateAccountRequest
{
public string currentPassword;
public string service;
public string identifier;
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace TaloGameServices
{
[System.Serializable]
public class PlayerAuthMigrateAccountResponse
{
public PlayerAlias alias;
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Assets/Talo Game Services/Talo/Runtime/Talo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ public static bool IsOffline()

internal static bool CheckTestMode()
{
#if UNITY_EDITOR || DEBUG
#if UNITY_EDITOR
var assembly = AppDomain.CurrentDomain.GetAssemblies()
.FirstOrDefault((assembly) => assembly.FullName.ToLowerInvariant().StartsWith("nunit.framework"));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ public enum PlayerAuthErrorCode {
PASSWORD_RESET_CODE_INVALID,
VERIFICATION_EMAIL_REQUIRED,
INVALID_EMAIL,
NEW_IDENTIFIER_MATCHES_CURRENT_IDENTIFIER
NEW_IDENTIFIER_MATCHES_CURRENT_IDENTIFIER,
INVALID_MIGRATION_TARGET
}

public class PlayerAuthException : Exception
Expand Down
23 changes: 19 additions & 4 deletions Assets/Talo Game Services/Talo/Runtime/Utils/SessionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,14 @@ private void SaveSession(string sessionToken)
SetIdentifierPlayerPref();
}

public async Task ClearSession()
public async Task ClearSession(bool resetSocket = true)
{
Talo.CurrentAlias = null;
PlayerPrefs.DeleteKey("TaloSessionToken");
await Talo.Socket.ResetConnection();
if (resetSocket)
{
await Talo.Socket.ResetConnection();
}
}

public string GetSessionToken()
Expand All @@ -48,11 +51,23 @@ public bool CheckForSession()
return !string.IsNullOrEmpty(GetSessionToken());
}

private void SetNewAlias(PlayerAlias alias)
{
Talo.CurrentAlias = alias;
alias.WriteOfflineAlias();
}

public void HandleIdentifierUpdated(PlayerAuthChangeIdentifierResponse res)
{
Talo.CurrentAlias = res.alias;
Talo.CurrentAlias.WriteOfflineAlias();
SetNewAlias(res.alias);
SetIdentifierPlayerPref();
}

public async Task HandleAccountMigrated(PlayerAuthMigrateAccountResponse res)
{
await ClearSession(false);
SetNewAlias(res.alias);
Talo.Players.InvokeIdentifiedEvent();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public enum SocketErrorCode {

public class SocketException : Exception
{
private SocketError errorData;
private readonly SocketError errorData;

public string Req => errorData?.req ?? "unknown";
public SocketErrorCode ErrorCode => GetErrorCode();
Expand Down
8 changes: 8 additions & 0 deletions Assets/Talo Game Services/Talo/Tests/EntityWithProps.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading