diff --git a/Archipelago.MultiClient.Net.Tests/Archipelago.MultiClient.Net.Tests.csproj b/Archipelago.MultiClient.Net.Tests/Archipelago.MultiClient.Net.Tests.csproj index 1f1f85a..abc6286 100644 --- a/Archipelago.MultiClient.Net.Tests/Archipelago.MultiClient.Net.Tests.csproj +++ b/Archipelago.MultiClient.Net.Tests/Archipelago.MultiClient.Net.Tests.csproj @@ -22,15 +22,8 @@ ..\DLLs\net35\Newtonsoft.Json.dll - - - - ..\Archipelago.MultiClient.Net\bin\Debug\net35\Archipelago.MultiClient.Net.dll - - - - ..\Archipelago.MultiClient.Net\bin\Release\net35\Archipelago.MultiClient.Net.dll + ..\Archipelago.MultiClient.Net\bin\$(Configuration)\net35\Archipelago.MultiClient.Net.dll @@ -38,15 +31,8 @@ ..\DLLs\net40\Newtonsoft.Json.dll - - - - ..\Archipelago.MultiClient.Net\bin\Debug\net40\Archipelago.MultiClient.Net.dll - - - - ..\Archipelago.MultiClient.Net\bin\Release\net40\Archipelago.MultiClient.Net.dll + ..\Archipelago.MultiClient.Net\bin\$(Configuration)\net40\Archipelago.MultiClient.Net.dll @@ -54,15 +40,8 @@ ..\DLLs\net45\Newtonsoft.Json.dll - - - - ..\Archipelago.MultiClient.Net\bin\Debug\net45\Archipelago.MultiClient.Net.dll - - - - ..\Archipelago.MultiClient.Net\bin\Release\net45\Archipelago.MultiClient.Net.dll + ..\Archipelago.MultiClient.Net\bin\$(Configuration)\net45\Archipelago.MultiClient.Net.dll @@ -70,15 +49,8 @@ ..\DLLs\netstandard2.0\Newtonsoft.Json.dll - - - - ..\Archipelago.MultiClient.Net\bin\Debug\netstandard2.0\Archipelago.MultiClient.Net.dll - - - - ..\Archipelago.MultiClient.Net\bin\Release\netstandard2.0\Archipelago.MultiClient.Net.dll + ..\Archipelago.MultiClient.Net\bin\$(Configuration)\netstandard2.0\Archipelago.MultiClient.Net.dll diff --git a/Archipelago.MultiClient.Net.Tests/DataStorageWrapperFixture.cs b/Archipelago.MultiClient.Net.Tests/DataStorageWrapperFixture.cs index e8b743d..da50d06 100644 --- a/Archipelago.MultiClient.Net.Tests/DataStorageWrapperFixture.cs +++ b/Archipelago.MultiClient.Net.Tests/DataStorageWrapperFixture.cs @@ -2,6 +2,7 @@ using Archipelago.MultiClient.Net.Helpers; using Archipelago.MultiClient.Net.Models; using Archipelago.MultiClient.Net.Packets; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NSubstitute; using NUnit.Framework; @@ -321,6 +322,60 @@ public void GetSlotData_should_return_slot_data_for_current_player_slot() Assert.That(slotData["Two"], Is.EqualTo(2)); } + private class CustomSlotDataModel + { + public class Options + { + public bool IsXRandomized { get; set; } + public bool IsYRandomized { get; set; } + } + public int One { get; set; } + public long Two { get; set; } + public uint? Three { get; set; } + [JsonProperty("ListOfStuff")] + public List Strings { get; set; } + public Options SlotOptions { get; set; } + } + [Test] + public void GetSlotData_should_deserialize_custom_type_for_current_player_slot() + { + var socket = Substitute.For(); + var connectionInfo = Substitute.For(); + connectionInfo.Slot.Returns(4); + + CustomSlotDataModel slotData = null; + + var sut = new DataStorageHelper(socket, connectionInfo); + + var serverSlotData = new Dictionary + { + { "One", 1 }, + { "Two", 2 }, + { "ListOfStuff", new string[] { "A", "B", "C" } }, + { "SlotOptions", new CustomSlotDataModel.Options + { + IsXRandomized = true, + IsYRandomized = false + } } + }; + + ExecuteAsyncWithDelay( + () => { slotData = sut.GetSlotData(); }, + () => RaiseRetrieved(socket, "_read_slot_data_4", JObject.FromObject(serverSlotData))); + + socket.Received().SendPacketAsync(Arg.Is(p => p.Keys.FirstOrDefault() == "_read_slot_data_4")); + + Assert.IsNotNull(slotData); + + Assert.That(slotData.One, Is.EqualTo(1)); + Assert.That(slotData.Two, Is.EqualTo(2)); + Assert.That(slotData.Three, Is.Null); + Assert.That(slotData.Strings, Is.EquivalentTo(new List { "A", "B", "C" })); + Assert.That(slotData.SlotOptions.IsXRandomized, Is.True); + Assert.That(slotData.SlotOptions.IsYRandomized, Is.False); + + } + [Test] public void GetSlotData_should_return_null_for_non_existing_player_slot() { diff --git a/Archipelago.MultiClient.Net/Helpers/DataStorageWrappers.cs b/Archipelago.MultiClient.Net/Helpers/DataStorageWrappers.cs index edff89c..42547d8 100644 --- a/Archipelago.MultiClient.Net/Helpers/DataStorageWrappers.cs +++ b/Archipelago.MultiClient.Net/Helpers/DataStorageWrappers.cs @@ -58,6 +58,14 @@ void TrackHints(Action onHintsUpdated, /// the slot id of the player to request slot data for, defaults to the current player's slot if left empty /// An Dictionary with string keys, and custom defined values, the keys and values differ per game Dictionary GetSlotData(int? slot = null); + + /// + /// Retrieves the custom slot data for the specified slot + /// + /// The type to convert the slot data to + /// The slot ID of the player ot request slot data for, defaults to the current player's slot if left empty + /// The slot data, converted to a modeled object of the specified type + T GetSlotData(int? slot = null) where T : class; #if NET35 /// @@ -67,6 +75,14 @@ void TrackHints(Action onHintsUpdated, /// the slot id of the player to request slot data for, defaults to the current player's slot if left empty /// An Dictionary with string keys, and custom defined values, the keys and values differ per game void GetSlotDataAsync(Action> onSlotDataRetrieved, int? slot = null); + /// + /// Retrieves the custom slot data for the specified slot + /// + /// The type to convert the slot data to + /// the method to call with the retrieved slot data + /// the slot id of the player to request slot data for, defaults to the current player's slot if left empty + /// The slot data, converted to a modeled object of the specified type + void GetSlotDataAsync(Action onSlotDataRetrieved, int? slot = null) where T : class; #else /// /// Retrieves the custom slot data for the specified slot @@ -74,6 +90,13 @@ void TrackHints(Action onHintsUpdated, /// the slot id of the player to request slot data for, defaults to the current player's slot if left empty /// An Dictionary with string keys, and custom defined values, the keys and values differ per game Task> GetSlotDataAsync(int? slot = null); + /// + /// Retrieves the custom slot data for the specified slot + /// + /// The type to convert the slot data to + /// the slot id of the player to request slot data for, defaults to the current player's slot if left empty + /// The slot data, converted to a modeled object of the specified type + Task GetSlotDataAsync(int? slot = null) where T : class; #endif /// @@ -203,16 +226,25 @@ public void TrackHints(Action onHintsUpdated, } /// - public Dictionary GetSlotData(int? slot = null) => - GetSlotDataElement(slot).To>(); + public Dictionary GetSlotData(int? slot = null) => + GetSlotData>(slot); + /// + public T GetSlotData(int? slot = null) where T : class => + GetSlotDataElement(slot).To(); #if NET35 /// public void GetSlotDataAsync(Action> onSlotDataRetrieved, int? slot = null) => GetSlotDataElement(slot).GetAsync(t => onSlotDataRetrieved(t?.ToObject>())); + /// + public void GetSlotDataAsync(Action onSlotDataRetrieved, int? slot = null) where T : class => + GetSlotDataElement(slot).GetAsync(t => onSlotDataRetrieved(t?.ToObject())); #else /// public Task> GetSlotDataAsync(int? slot = null) => - GetSlotDataElement(slot).GetAsync>(); + GetSlotDataAsync>(slot); + /// + public Task GetSlotDataAsync(int? slot = null) where T : class => + GetSlotDataElement(slot).GetAsync(); #endif ///