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
29 changes: 21 additions & 8 deletions Assets/Talo Game Services/Talo/Runtime/APIs/ChannelsAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ public class ChannelsAPI : BaseAPI
public event Action<Channel, PlayerAlias> OnOwnershipTransferred;
public event Action<Channel> OnChannelDeleted;
public event Action<Channel, string[]> OnChannelUpdated;
public event Action<RejectedProp[]> OnChannelPropsRejected;
public event Action<Channel, RejectedProp[]> OnChannelStoragePropsFailedToSet;
public event Action<Channel, ChannelStorageProp[], ChannelStorageProp[]> OnChannelStoragePropsUpdated;

Expand Down Expand Up @@ -170,7 +169,7 @@ public async Task<Channel[]> GetSubscribedChannels(GetSubscribedChannelsOptions
return res.channels;
}

private async Task<Channel> SendCreateChannelRequest(CreateChannelOptions options)
private async Task<ChannelUpsertResult> SendCreateChannelRequest(CreateChannelOptions options)
{
Talo.IdentityCheck();

Expand All @@ -191,19 +190,19 @@ private async Task<Channel> SendCreateChannelRequest(CreateChannelOptions option
var json = await Call(uri, "POST", content);

var res = JsonUtility.FromJson<ChannelResponse>(json);
return res.channel;
return new ChannelUpsertResult(true, res.channel);
}
catch (RequestException ex)
{
if (ex.IsBadRequest())
{
RejectedProp.TryEmit(ex.responseBody, OnChannelPropsRejected);
return new ChannelUpsertResult(false, null, RejectedProp.FromJson(ex.responseBody));
}
throw;
}
}

public async Task<Channel> Create(CreateChannelOptions options)
public async Task<ChannelUpsertResult> Create(CreateChannelOptions options)
{
options ??= new CreateChannelOptions();
return await SendCreateChannelRequest(options);
Expand All @@ -228,7 +227,7 @@ public async Task Leave(int channelId)
await Call(uri, "POST");
}

public async Task<Channel> Update(int channelId, UpdateChannelOptions options = null)
public async Task<ChannelUpsertResult> Update(int channelId, UpdateChannelOptions options = null)
{
Talo.IdentityCheck();

Expand All @@ -252,13 +251,13 @@ public async Task<Channel> Update(int channelId, UpdateChannelOptions options =
var json = await Call(uri, "PUT", content);

var res = JsonUtility.FromJson<ChannelResponse>(json);
return res.channel;
return new ChannelUpsertResult(true, res.channel);
}
catch (RequestException ex)
{
if (ex.IsBadRequest())
{
RejectedProp.TryEmit(ex.responseBody, OnChannelPropsRejected);
return new ChannelUpsertResult(false, null, RejectedProp.FromJson(ex.responseBody));
}
throw;
}
Expand Down Expand Up @@ -400,5 +399,19 @@ public async Task<ChannelStorageProp[]> ListStorageProps(int channelId, string[]

return Array.Empty<ChannelStorageProp>();
}

public class ChannelUpsertResult
{
public bool Success { get; }
public Channel Channel { get; }
public RejectedProp[] RejectedProps { get; }

public ChannelUpsertResult(bool success, Channel channel, RejectedProp[] rejectedProps = null)
{
Success = success;
Channel = channel;
RejectedProps = rejectedProps ?? Array.Empty<RejectedProp>();
}
}
}
}
19 changes: 15 additions & 4 deletions Assets/Talo Game Services/Talo/Runtime/APIs/FeedbackAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ namespace TaloGameServices
{
public class FeedbackAPI : BaseAPI
{
public event Action<RejectedProp[]> OnPropsRejected;

public FeedbackAPI() : base("v1/game-feedback") { }

public async Task<FeedbackCategory[]> GetCategories()
Expand All @@ -20,7 +18,7 @@ public async Task<FeedbackCategory[]> GetCategories()
return res.feedbackCategories;
}

public async Task Send(string categoryInternalName, string comment, params (string, string)[] props)
public async Task<FeedbackSendResult> Send(string categoryInternalName, string comment, params (string, string)[] props)
{
Talo.IdentityCheck();

Expand All @@ -31,15 +29,28 @@ public async Task Send(string categoryInternalName, string comment, params (stri
try
{
await Call(uri, "POST", content);
return new FeedbackSendResult(true);
}
catch (RequestException ex)
{
if (ex.IsBadRequest())
{
RejectedProp.TryEmit(ex.responseBody, OnPropsRejected);
return new FeedbackSendResult(false, RejectedProp.FromJson(ex.responseBody));
}
throw;
}
}

public class FeedbackSendResult
{
public bool Success { get; }
public RejectedProp[] RejectedProps { get; }

public FeedbackSendResult(bool success, RejectedProp[] rejectedProps = null)
{
Success = success;
RejectedProps = rejectedProps ?? Array.Empty<RejectedProp>();
}
}
}
}
26 changes: 20 additions & 6 deletions Assets/Talo Game Services/Talo/Runtime/APIs/LeaderboardsAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ public class LeaderboardsAPI : BaseAPI
{
private readonly LeaderboardEntriesManager _entriesManager = new();

public event Action<RejectedProp[]> OnPropsRejected;

public LeaderboardsAPI() : base("v1/leaderboards") { }

public List<LeaderboardEntry> GetCachedEntries(string internalName, GetCachedEntriesOptions options = null)
Expand Down Expand Up @@ -77,7 +75,7 @@ public async Task<LeaderboardEntriesResponse> GetEntries(string internalName, Ge
return res;
}

public async Task<(LeaderboardEntry, bool)> AddEntry(string internalName, float score, params (string, string)[] propTuples)
public async Task<AddEntryResult> AddEntry(string internalName, float score, params (string, string)[] propTuples)
{
Talo.IdentityCheck();

Expand All @@ -93,16 +91,32 @@ public async Task<LeaderboardEntriesResponse> GetEntries(string internalName, Ge
var res = JsonUtility.FromJson<LeaderboardEntryResponse>(json);
_entriesManager.UpsertEntry(internalName, res.entry, true);

return (res.entry, res.updated);
return new AddEntryResult(true, res.entry, res.updated);
}
catch (RequestException ex)
{
if (ex.IsBadRequest())
{
RejectedProp.TryEmit(ex.responseBody, OnPropsRejected);
return new AddEntryResult(false, null, false, RejectedProp.FromJson(ex.responseBody));
}
throw;
}
}

public class AddEntryResult
{
public bool Success { get; }
public LeaderboardEntry Entry { get; }
public bool Updated { get; }
public RejectedProp[] RejectedProps { get; }

public AddEntryResult(bool success, LeaderboardEntry entry, bool updated, RejectedProp[] rejectedProps = null)
{
Success = success;
Entry = entry;
Updated = updated;
RejectedProps = rejectedProps ?? Array.Empty<RejectedProp>();
}
}
}
}
}
6 changes: 0 additions & 6 deletions Assets/Talo Game Services/Talo/Runtime/APIs/PlayersAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ public enum DebouncedOperation
public event Action OnIdentificationStarted;
public event Action<IdentifyException> OnIdentificationFailed;
public event Action OnIdentityCleared;
public event Action<RejectedProp[]> OnPropsRejected;
public event Action<bool> OnPlayerUpdated;

public PlayersAPI() : base("v1/players")
Expand Down Expand Up @@ -175,11 +174,6 @@ private async Task<RejectedProp[]> RunUpdate()
Talo.CurrentPlayer = res.player;
Talo.CurrentAlias.WriteOfflineAlias();

if (res.rejectedProps != null && res.rejectedProps.Length > 0)
{
OnPropsRejected?.Invoke(res.rejectedProps);
}

return res.rejectedProps ?? Array.Empty<RejectedProp>();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,6 @@ public static RejectedProp[] FromJson(string json)
return wrapper?.rejectedProps ?? Array.Empty<RejectedProp>();
}

public static void TryEmit(string json, Action<RejectedProp[]> onRejected)
{
var rejectedProps = FromJson(json);
if (rejectedProps.Length > 0)
{
onRejected?.Invoke(rejectedProps);
}
}
}

[Serializable]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,17 @@ private async Task SetupDemoChannel()
("channel-storage-demo", "true")
}
};
demoChannel = await Talo.Channels.Create(createOptions);
var createResult = await Talo.Channels.Create(createOptions);
if (createResult.Success)
{
demoChannel = createResult.Channel;
}
}

if (demoChannel == null)
{
Debug.LogError("Failed to create or find a channel for the Channel Storage Demo");
return;
}

await Talo.Channels.Join(demoChannel.id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,9 @@ private async void OnCreateChannelClick()
return;
}

var channel = await Talo.Channels.Create(new CreateChannelOptions() { name = channelName, autoCleanup = true });
var result = await Talo.Channels.Create(new CreateChannelOptions() { name = channelName, autoCleanup = true });

var channel = result.Channel;
AddChannelToList(channel);
channelNameField.value = "";
activeChannelId = channel.id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ private async void OnPostClick()
var team = UnityEngine.Random.Range(0, 2) == 0 ? "Blue" : "Red";

await Talo.Players.Identify("username", username);
(LeaderboardEntry entry, bool updated) = await Talo.Leaderboards.AddEntry(
var result = await Talo.Leaderboards.AddEntry(
leaderboardName,
score,
("team", team)
);

infoLabel.text = $"You scored {score} for the {team} team.";
if (updated) infoLabel.text += " Your highscore was updated!";
if (result.Updated) infoLabel.text += " Your highscore was updated!";

entriesList.Rebuild();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,15 @@ public async void OnButtonClick()

try
{
await Talo.Feedback.Send(categoryInternalName, feedbackComment);
ResponseMessage.SetText($"Feedback sent for {categoryInternalName}: {feedbackComment}");
var result = await Talo.Feedback.Send(categoryInternalName, feedbackComment);
if (result.Success)
{
ResponseMessage.SetText($"Feedback sent for {categoryInternalName}: {feedbackComment}");
}
else
{
ResponseMessage.SetText("Failed to send feedback");
}
}
catch (Exception ex)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,15 @@ private async Task PostEntry()
try
{
int score = UnityEngine.Random.Range(0, 10000);
(LeaderboardEntry entry, bool updated) = await Talo.Leaderboards.AddEntry(leaderboardInternalName, score);
var result = await Talo.Leaderboards.AddEntry(leaderboardInternalName, score);

ResponseMessage.SetText($"Entry with score {score} added, position is {entry.position}, it was {(updated ? "" : "not")} updated");
if (result.Entry == null)
{
ResponseMessage.SetText("Failed to add entry");
return;
}

ResponseMessage.SetText($"Entry with score {score} added, position is {result.Entry.position}, it was {(result.Updated ? "" : "not")} updated");
}
catch (Exception ex)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,9 @@ public IEnumerator LeadingAndTrailing_FireOnPlayerUpdatedTwice()
}

[UnityTest]
public IEnumerator PropRejection_BothOnPropsRejectedAndOnPlayerUpdatedFire()
public IEnumerator PropRejection_OnPlayerUpdatedFiresWithRejectedProps()
{
int rejectedCount = 0;
Talo.Players.OnPlayerUpdated += _mock.OnUpdated;
Talo.Players.OnPropsRejected += _ =>
{
rejectedCount++;
};

var uri = new Uri($"{Talo.Settings.apiUrl}/v1/players/uuid");
RequestMock.ReplyOnce(uri, "PATCH", JsonUtility.ToJson(new PlayersUpdateResponse
Expand All @@ -115,9 +110,10 @@ public IEnumerator PropRejection_BothOnPropsRejectedAndOnPlayerUpdatedFire()
rejectedProps = new[] { new RejectedProp { key = "k1", error = "PROP_VALUE_TOO_LONG", message = "too long" } }
}));

Talo.CurrentPlayer.SetProp("k1", "v1-updated");
var result = Talo.CurrentPlayer.SetProp("k1", "v1-updated").GetAwaiter().GetResult();

Assert.AreEqual(1, rejectedCount);
Assert.AreEqual(1, result.RejectedProps.Length);
Assert.AreEqual("k1", result.RejectedProps[0].key);
Assert.AreEqual(1, _mock.updatedCount);
Assert.IsTrue(_mock.lastSuccess);

Expand Down
Loading