From 6fa435065f59376f22291e22246cb036aa60dc4b Mon Sep 17 00:00:00 2001 From: Playfab Jenkins Bot <playfabjenkinsbot@github.com> Date: Mon, 7 Nov 2016 23:28:19 +0000 Subject: [PATCH] https://api.playfab.com/releaseNotes/#161107 --- PlayFabClientSDK/PlayFabSDK.csproj | 20 +- PlayFabClientSDK/source/Json/ISerializer.cs | 155 ++ .../source/Json/NewtonsoftWrapper.cs | 73 + PlayFabClientSDK/source/Json/SimpleJson.cs | 2078 ++++++++++++++++ PlayFabClientSDK/source/PlayFabClientAPI.cs | 2191 ++++++++--------- .../source/PlayFabClientModels.cs | 279 +-- PlayFabClientSDK/source/PlayFabErrors.cs | 25 +- PlayFabClientSDK/source/PlayFabFileUtil.cs | 71 + .../source/PlayFabHttp/IPlayFabHttp.cs | 9 + .../source/PlayFabHttp/PlayFabHttp.cs | 68 + .../source/PlayFabHttp/PlayFabSysHttp.cs | 107 + .../source/PlayFabHttp/PlayFabWinHttp.cs | 96 + PlayFabClientSDK/source/PlayFabSettings.cs | 8 +- PlayFabClientSDK/source/PlayFabUtil.cs | 51 +- .../source/Uunit/PlayFabApiTest.cs | 431 ++++ .../source/Uunit/UUnitAssertException.cs | 37 +- .../Uunit/UUnitIncrementalTestRunner.cs | 83 + .../source/Uunit/UUnitTestCase.cs | 114 +- .../source/Uunit/UUnitTestContext.cs | 254 ++ .../source/Uunit/UUnitTestReport.cs | 115 + .../source/Uunit/UUnitTestSuite.cs | 315 ++- .../source/WsaReflectionExtensions.cs | 89 + PlayFabSDK/PlayFabSDK.csproj | 20 +- PlayFabSDK/UnittestRunner/UUnitTestRunner.cs | 64 +- .../UnittestRunner/UnittestRunner.csproj | 5 +- PlayFabSDK/source/Json/ISerializer.cs | 155 ++ PlayFabSDK/source/Json/NewtonsoftWrapper.cs | 73 + PlayFabSDK/source/Json/SimpleJson.cs | 2078 ++++++++++++++++ PlayFabSDK/source/PlayFabAdminAPI.cs | 1674 +++++++------ PlayFabSDK/source/PlayFabAdminModels.cs | 1060 +++++++- PlayFabSDK/source/PlayFabClientAPI.cs | 2191 ++++++++--------- PlayFabSDK/source/PlayFabClientModels.cs | 279 +-- PlayFabSDK/source/PlayFabErrors.cs | 25 +- PlayFabSDK/source/PlayFabFileUtil.cs | 71 + PlayFabSDK/source/PlayFabHttp/IPlayFabHttp.cs | 9 + PlayFabSDK/source/PlayFabHttp/PlayFabHttp.cs | 68 + .../source/PlayFabHttp/PlayFabSysHttp.cs | 107 + .../source/PlayFabHttp/PlayFabWinHttp.cs | 96 + PlayFabSDK/source/PlayFabMatchmakerAPI.cs | 96 +- PlayFabSDK/source/PlayFabMatchmakerModels.cs | 18 +- PlayFabSDK/source/PlayFabServerAPI.cs | 1896 +++++++------- PlayFabSDK/source/PlayFabServerModels.cs | 608 ++++- PlayFabSDK/source/PlayFabSettings.cs | 8 +- PlayFabSDK/source/PlayFabUtil.cs | 51 +- PlayFabSDK/source/Uunit/PlayFabApiTest.cs | 431 ++++ .../source/Uunit/UUnitAssertException.cs | 37 +- .../Uunit/UUnitIncrementalTestRunner.cs | 83 + PlayFabSDK/source/Uunit/UUnitTestCase.cs | 114 +- PlayFabSDK/source/Uunit/UUnitTestContext.cs | 254 ++ PlayFabSDK/source/Uunit/UUnitTestReport.cs | 115 + PlayFabSDK/source/Uunit/UUnitTestSuite.cs | 315 ++- PlayFabSDK/source/WsaReflectionExtensions.cs | 89 + PlayFabServerSDK/PlayFabSDK.csproj | 20 +- PlayFabServerSDK/source/Json/ISerializer.cs | 155 ++ .../source/Json/NewtonsoftWrapper.cs | 73 + PlayFabServerSDK/source/Json/SimpleJson.cs | 2078 ++++++++++++++++ PlayFabServerSDK/source/PlayFabAdminAPI.cs | 1674 +++++++------ PlayFabServerSDK/source/PlayFabAdminModels.cs | 1060 +++++++- PlayFabServerSDK/source/PlayFabErrors.cs | 25 +- PlayFabServerSDK/source/PlayFabFileUtil.cs | 71 + .../source/PlayFabHttp/IPlayFabHttp.cs | 9 + .../source/PlayFabHttp/PlayFabHttp.cs | 68 + .../source/PlayFabHttp/PlayFabSysHttp.cs | 107 + .../source/PlayFabHttp/PlayFabWinHttp.cs | 96 + .../source/PlayFabMatchmakerAPI.cs | 96 +- .../source/PlayFabMatchmakerModels.cs | 18 +- PlayFabServerSDK/source/PlayFabServerAPI.cs | 1896 +++++++------- .../source/PlayFabServerModels.cs | 608 ++++- PlayFabServerSDK/source/PlayFabSettings.cs | 8 +- PlayFabServerSDK/source/PlayFabUtil.cs | 51 +- .../source/Uunit/PlayFabApiTest.cs | 431 ++++ .../source/Uunit/UUnitAssertException.cs | 37 +- .../Uunit/UUnitIncrementalTestRunner.cs | 83 + .../source/Uunit/UUnitTestCase.cs | 114 +- .../source/Uunit/UUnitTestContext.cs | 254 ++ .../source/Uunit/UUnitTestReport.cs | 115 + .../source/Uunit/UUnitTestSuite.cs | 315 ++- .../source/WsaReflectionExtensions.cs | 89 + 78 files changed, 20633 insertions(+), 7677 deletions(-) create mode 100644 PlayFabClientSDK/source/Json/ISerializer.cs create mode 100644 PlayFabClientSDK/source/Json/NewtonsoftWrapper.cs create mode 100644 PlayFabClientSDK/source/Json/SimpleJson.cs create mode 100644 PlayFabClientSDK/source/PlayFabFileUtil.cs create mode 100644 PlayFabClientSDK/source/PlayFabHttp/IPlayFabHttp.cs create mode 100644 PlayFabClientSDK/source/PlayFabHttp/PlayFabHttp.cs create mode 100644 PlayFabClientSDK/source/PlayFabHttp/PlayFabSysHttp.cs create mode 100644 PlayFabClientSDK/source/PlayFabHttp/PlayFabWinHttp.cs create mode 100644 PlayFabClientSDK/source/Uunit/PlayFabApiTest.cs create mode 100644 PlayFabClientSDK/source/Uunit/UUnitIncrementalTestRunner.cs create mode 100644 PlayFabClientSDK/source/Uunit/UUnitTestContext.cs create mode 100644 PlayFabClientSDK/source/Uunit/UUnitTestReport.cs create mode 100644 PlayFabClientSDK/source/WsaReflectionExtensions.cs create mode 100644 PlayFabSDK/source/Json/ISerializer.cs create mode 100644 PlayFabSDK/source/Json/NewtonsoftWrapper.cs create mode 100644 PlayFabSDK/source/Json/SimpleJson.cs create mode 100644 PlayFabSDK/source/PlayFabFileUtil.cs create mode 100644 PlayFabSDK/source/PlayFabHttp/IPlayFabHttp.cs create mode 100644 PlayFabSDK/source/PlayFabHttp/PlayFabHttp.cs create mode 100644 PlayFabSDK/source/PlayFabHttp/PlayFabSysHttp.cs create mode 100644 PlayFabSDK/source/PlayFabHttp/PlayFabWinHttp.cs create mode 100644 PlayFabSDK/source/Uunit/PlayFabApiTest.cs create mode 100644 PlayFabSDK/source/Uunit/UUnitIncrementalTestRunner.cs create mode 100644 PlayFabSDK/source/Uunit/UUnitTestContext.cs create mode 100644 PlayFabSDK/source/Uunit/UUnitTestReport.cs create mode 100644 PlayFabSDK/source/WsaReflectionExtensions.cs create mode 100644 PlayFabServerSDK/source/Json/ISerializer.cs create mode 100644 PlayFabServerSDK/source/Json/NewtonsoftWrapper.cs create mode 100644 PlayFabServerSDK/source/Json/SimpleJson.cs create mode 100644 PlayFabServerSDK/source/PlayFabFileUtil.cs create mode 100644 PlayFabServerSDK/source/PlayFabHttp/IPlayFabHttp.cs create mode 100644 PlayFabServerSDK/source/PlayFabHttp/PlayFabHttp.cs create mode 100644 PlayFabServerSDK/source/PlayFabHttp/PlayFabSysHttp.cs create mode 100644 PlayFabServerSDK/source/PlayFabHttp/PlayFabWinHttp.cs create mode 100644 PlayFabServerSDK/source/Uunit/PlayFabApiTest.cs create mode 100644 PlayFabServerSDK/source/Uunit/UUnitIncrementalTestRunner.cs create mode 100644 PlayFabServerSDK/source/Uunit/UUnitTestContext.cs create mode 100644 PlayFabServerSDK/source/Uunit/UUnitTestReport.cs create mode 100644 PlayFabServerSDK/source/WsaReflectionExtensions.cs diff --git a/PlayFabClientSDK/PlayFabSDK.csproj b/PlayFabClientSDK/PlayFabSDK.csproj index 5584f72b..ea6a6015 100644 --- a/PlayFabClientSDK/PlayFabSDK.csproj +++ b/PlayFabClientSDK/PlayFabSDK.csproj @@ -21,7 +21,7 @@ <DebugType>full</DebugType> <Optimize>false</Optimize> <OutputPath>bin\Debug\</OutputPath> - <DefineConstants>DEBUG;TRACE</DefineConstants> + <DefineConstants>TRACE;DEBUG;NETFX_CORE;SIMPLE_JSON_TYPEINFO</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> </PropertyGroup> @@ -29,23 +29,33 @@ <DebugType>pdbonly</DebugType> <Optimize>true</Optimize> <OutputPath>bin\Release\</OutputPath> - <DefineConstants>TRACE</DefineConstants> + <DefineConstants>TRACE;NETFX_CORE;SIMPLE_JSON_TYPEINFO</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> </PropertyGroup> <ItemGroup> + <Compile Include="source\Json\ISerializer.cs" /> + <Compile Include="source\Json\NewtonsoftWrapper.cs" /> + <Compile Include="source\Json\SimpleJson.cs" /> + <Compile Include="source\PlayFabHttp\IPlayFabHttp.cs" /> + <Compile Include="source\PlayFabHttp\PlayFabHttp.cs" /> + <Compile Include="source\PlayFabHttp\PlayFabSysHttp.cs" /> + <Compile Include="source\PlayFabHttp\PlayFabWinHttp.cs" /> <Compile Include="source\PlayFabClientAPI.cs" /> <Compile Include="source\PlayFabClientModels.cs" /> <Compile Include="source\PlayFabErrors.cs" /> - <Compile Include="source\PlayFabHTTP.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="source\PlayFabSettings.cs" /> + <Compile Include="source\PlayFabFileUtil.cs" /> <Compile Include="source\PlayFabUtil.cs" /> - <Compile Include="source\Uunit\UUnitAssert.cs" /> + <Compile Include="source\Uunit\PlayFabApiTest.cs" /> <Compile Include="source\Uunit\UUnitAssertException.cs" /> + <Compile Include="source\Uunit\UUnitIncrementalTestRunner.cs" /> <Compile Include="source\Uunit\UUnitTestCase.cs" /> - <Compile Include="source\Uunit\UUnitTestResult.cs" /> + <Compile Include="source\Uunit\UUnitTestContext.cs" /> + <Compile Include="source\Uunit\UUnitTestReport.cs" /> <Compile Include="source\Uunit\UUnitTestSuite.cs" /> + <Compile Include="source\WsaReflectionExtensions.cs" /> </ItemGroup> <ItemGroup> <Reference Include="Newtonsoft.Json"> diff --git a/PlayFabClientSDK/source/Json/ISerializer.cs b/PlayFabClientSDK/source/Json/ISerializer.cs new file mode 100644 index 00000000..012cd8ab --- /dev/null +++ b/PlayFabClientSDK/source/Json/ISerializer.cs @@ -0,0 +1,155 @@ + +using System; +using System.Globalization; +using System.Reflection; + +namespace PlayFab.Json +{ + public interface ISerializer + { + T DeserializeObject<T>(string json); + T DeserializeObject<T>(string json, object jsonSerializerStrategy); + object DeserializeObject(string json); + + string SerializeObject(object json); + string SerializeObject(object json, object jsonSerializerStrategy); + } + + + public static class JsonWrapper + { + private static ISerializer _instance = new SimpleJsonInstance(); + + /// <summary> + /// Use this property to override the Serialization for the SDK. + /// </summary> + public static ISerializer Instance + { + get { return _instance; } + set { _instance = value; } + } + + public static T DeserializeObject<T>(string json) + { + return _instance.DeserializeObject<T>(json); + } + + public static T DeserializeObject<T>(string json, object jsonSerializerStrategy) + { + return _instance.DeserializeObject<T>(json, jsonSerializerStrategy); + } + + public static object DeserializeObject(string json) + { + return _instance.DeserializeObject(json); + } + + public static string SerializeObject(object json) + { + return _instance.SerializeObject(json); + } + + public static string SerializeObject(object json, object jsonSerializerStrategy) + { + return _instance.SerializeObject(json, jsonSerializerStrategy); + } + } + + public class SimpleJsonInstance : ISerializer + { + public static PlayFabJsonSerializerStrategy ApiSerializerStrategy = new PlayFabJsonSerializerStrategy(); + private static DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind; + public class PlayFabJsonSerializerStrategy : PocoJsonSerializerStrategy + { + /// <summary> + /// Convert the json value into the destination field/property + /// </summary> + public override object DeserializeObject(object value, Type type) + { + var valueStr = value as string; + if (valueStr == null) // For all of our custom conversions, value is a string + return base.DeserializeObject(value, type); + + var underType = Nullable.GetUnderlyingType(type); + if (underType != null) + return DeserializeObject(value, underType); + else if (type.GetTypeInfo().IsEnum) + return Enum.Parse(type, (string)value, true); + else if (type == typeof(DateTime)) + { + DateTime output; + var result = DateTime.TryParseExact(valueStr, PlayFabUtil.DefaultDateTimeFormats, CultureInfo.CurrentCulture, _dateTimeStyles, out output); + if (result) + return output; + } + else if (type == typeof(DateTimeOffset)) + { + DateTimeOffset output; + var result = DateTimeOffset.TryParseExact(valueStr, PlayFabUtil.DefaultDateTimeFormats, CultureInfo.CurrentCulture, _dateTimeStyles, out output); + if (result) + return output; + } + else if (type == typeof(TimeSpan)) + { + double seconds; + if (double.TryParse(valueStr, out seconds)) + return TimeSpan.FromSeconds(seconds); + } + return base.DeserializeObject(value, type); + } + + /// <summary> + /// Set output to a string that represents the input object + /// </summary> + protected override bool TrySerializeKnownTypes(object input, out object output) + { + if (input.GetType().GetTypeInfo().IsEnum) + { + output = input.ToString(); + return true; + } + else if (input is DateTime) + { + output = ((DateTime)input).ToString(PlayFabUtil.DefaultDateTimeFormats[PlayFabUtil.DEFAULT_UTC_OUTPUT_INDEX], CultureInfo.CurrentCulture); + return true; + } + else if (input is DateTimeOffset) + { + output = ((DateTimeOffset)input).ToString(PlayFabUtil.DefaultDateTimeFormats[PlayFabUtil.DEFAULT_UTC_OUTPUT_INDEX], CultureInfo.CurrentCulture); + return true; + } + else if (input is TimeSpan) + { + output = ((TimeSpan)input).TotalSeconds; + return true; + } + return base.TrySerializeKnownTypes(input, out output); + } + } + + public T DeserializeObject<T>(string json) + { + return PlayFabSimpleJson.DeserializeObject<T>(json, ApiSerializerStrategy); + } + + public T DeserializeObject<T>(string json, object jsonSerializerStrategy) + { + return PlayFabSimpleJson.DeserializeObject<T>(json, (IJsonSerializerStrategy)jsonSerializerStrategy); + } + + public object DeserializeObject(string json) + { + return PlayFabSimpleJson.DeserializeObject(json, typeof(object), ApiSerializerStrategy); + } + + public string SerializeObject(object json) + { + return PlayFabSimpleJson.SerializeObject(json, ApiSerializerStrategy); + } + + public string SerializeObject(object json, object jsonSerializerStrategy) + { + return PlayFabSimpleJson.SerializeObject(json, (IJsonSerializerStrategy)jsonSerializerStrategy); + } + } +} diff --git a/PlayFabClientSDK/source/Json/NewtonsoftWrapper.cs b/PlayFabClientSDK/source/Json/NewtonsoftWrapper.cs new file mode 100644 index 00000000..9f1f7007 --- /dev/null +++ b/PlayFabClientSDK/source/Json/NewtonsoftWrapper.cs @@ -0,0 +1,73 @@ +#if USING_NEWTONSOFT +using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.IO; + +namespace PlayFab.Json +{ + public class NewtonsofJsonInstance : ISerializer + { + public static JsonSerializerSettings JsonSettings = new JsonSerializerSettings + { + NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore, + Converters = { new StringEnumConverter(), new TimeSpanFloatSeconds(), new IsoDateTimeConverter { DateTimeFormat = PlayFabUtil.DefaultDateTimeFormats[0] } }, + }; + private static Formatting JsonFormatting = Formatting.None; + + private readonly JsonSerializer _serializer = JsonSerializer.Create(JsonSettings); + + public T DeserializeObject<T>(string json) + { + return _serializer.Deserialize<T>(new JsonTextReader(new StringReader(json))); + } + + public T DeserializeObject<T>(string json, object jsonSerializerStrategy) + { + var customSerializer = JsonSerializer.Create((JsonSerializerSettings)jsonSerializerStrategy); + return customSerializer.Deserialize<T>(new JsonTextReader(new StringReader(json))); + } + + public object DeserializeObject(string json) + { + return _serializer.Deserialize(new JsonTextReader(new StringReader(json))); + } + + public string SerializeObject(object json) + { + var jsonString = new StringWriter(); + var writer = new JsonTextWriter(jsonString) { Formatting = JsonFormatting }; + _serializer.Serialize(writer, json); + return jsonString.ToString(); + } + + public string SerializeObject(object json, object jsonSerializerStrategy) + { + var customSerializer = JsonSerializer.Create((JsonSerializerSettings)jsonSerializerStrategy); + var jsonString = new StringWriter(); + var writer = new JsonTextWriter(jsonString) { Formatting = JsonFormatting }; + customSerializer.Serialize(writer, json); + return jsonString.ToString(); + } + } + + public class TimeSpanFloatSeconds : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var timeSpan = (TimeSpan)value; + serializer.Serialize(writer, timeSpan.TotalSeconds); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + return TimeSpan.FromSeconds(serializer.Deserialize<float>(reader)); + } + + public override bool CanConvert(Type objectType) + { + return objectType == typeof(TimeSpan); + } + } +} +#endif diff --git a/PlayFabClientSDK/source/Json/SimpleJson.cs b/PlayFabClientSDK/source/Json/SimpleJson.cs new file mode 100644 index 00000000..231b4f41 --- /dev/null +++ b/PlayFabClientSDK/source/Json/SimpleJson.cs @@ -0,0 +1,2078 @@ +//----------------------------------------------------------------------- +// <copyright file="SimpleJson.cs" company="The Outercurve Foundation"> +// Copyright (c) 2011, The Outercurve Foundation. +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.opensource.org/licenses/mit-license.php +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// </copyright> +// <author>Nathan Totten (ntotten.com), Jim Zimmerman (jimzimmerman.com) and Prabir Shrestha (prabir.me)</author> +// <website>https://github.com/facebook-csharp-sdk/simple-json</website> +//----------------------------------------------------------------------- + +// VERSION: + +// NOTE: uncomment the following line to make SimpleJson class internal. +//#define SIMPLE_JSON_INTERNAL + +// NOTE: uncomment the following line to make JsonArray and JsonObject class internal. +//#define SIMPLE_JSON_OBJARRAYINTERNAL + +// NOTE: uncomment the following line to enable dynamic support. +//#define SIMPLE_JSON_DYNAMIC + +// NOTE: uncomment the following line to enable DataContract support. +//#define SIMPLE_JSON_DATACONTRACT + +// NOTE: uncomment the following line to enable IReadOnlyCollection<T> and IReadOnlyList<T> support. +//#define SIMPLE_JSON_READONLY_COLLECTIONS + +// original json parsing code from http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html + +#if NETFX_CORE +#define SIMPLE_JSON_TYPEINFO +#endif + +using System; +using System.CodeDom.Compiler; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +#if SIMPLE_JSON_DYNAMIC +using System.Dynamic; +#endif +using System.Globalization; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.Serialization; +using System.Text; + +// ReSharper disable LoopCanBeConvertedToQuery +// ReSharper disable RedundantExplicitArrayCreation +// ReSharper disable SuggestUseVarKeywordEvident +namespace PlayFab.Json +{ + public enum NullValueHandling + { + Include, // Include null values when serializing and deserializing objects + Ignore // Ignore null values when serializing and deserializing objects + } + + /// <summary> + /// Customize the json output of a field or property + /// </summary> + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] + public class JsonProperty : Attribute + { + public string PropertyName = null; + public NullValueHandling NullValueHandling = NullValueHandling.Include; + } + + /// <summary> + /// Represents the json array. + /// </summary> + [GeneratedCode("simple-json", "1.0.0")] + [EditorBrowsable(EditorBrowsableState.Never)] + [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")] +#if SIMPLE_JSON_OBJARRAYINTERNAL + internal +#else + public +#endif + class JsonArray : List<object> + { + /// <summary> + /// Initializes a new instance of the <see cref="JsonArray"/> class. + /// </summary> + public JsonArray() { } + + /// <summary> + /// Initializes a new instance of the <see cref="JsonArray"/> class. + /// </summary> + /// <param name="capacity">The capacity of the json array.</param> + public JsonArray(int capacity) : base(capacity) { } + + /// <summary> + /// The json representation of the array. + /// </summary> + /// <returns>The json representation of the array.</returns> + public override string ToString() + { + return PlayFabSimpleJson.SerializeObject(this) ?? string.Empty; + } + } + + /// <summary> + /// Represents the json object. + /// </summary> + [GeneratedCode("simple-json", "1.0.0")] + [EditorBrowsable(EditorBrowsableState.Never)] + [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")] +#if SIMPLE_JSON_OBJARRAYINTERNAL + internal +#else + public +#endif + class JsonObject : +#if SIMPLE_JSON_DYNAMIC + DynamicObject, +#endif + IDictionary<string, object> + { + private const int DICTIONARY_DEFAULT_SIZE = 16; + /// <summary> + /// The internal member dictionary. + /// </summary> + private readonly Dictionary<string, object> _members; + + /// <summary> + /// Initializes a new instance of <see cref="JsonObject"/>. + /// </summary> + public JsonObject() + { + _members = new Dictionary<string, object>(DICTIONARY_DEFAULT_SIZE); + } + + /// <summary> + /// Initializes a new instance of <see cref="JsonObject"/>. + /// </summary> + /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer`1"/> implementation to use when comparing keys, or null to use the default <see cref="T:System.Collections.Generic.EqualityComparer`1"/> for the type of the key.</param> + public JsonObject(IEqualityComparer<string> comparer) + { + _members = new Dictionary<string, object>(comparer); + } + + /// <summary> + /// Gets the <see cref="System.Object"/> at the specified index. + /// </summary> + /// <value></value> + public object this[int index] + { + get { return GetAtIndex(_members, index); } + } + + internal static object GetAtIndex(IDictionary<string, object> obj, int index) + { + if (obj == null) + throw new ArgumentNullException("obj"); + if (index >= obj.Count) + throw new ArgumentOutOfRangeException("index"); + int i = 0; + foreach (KeyValuePair<string, object> o in obj) + if (i++ == index) return o.Value; + return null; + } + + /// <summary> + /// Adds the specified key. + /// </summary> + /// <param name="key">The key.</param> + /// <param name="value">The value.</param> + public void Add(string key, object value) + { + _members.Add(key, value); + } + + /// <summary> + /// Determines whether the specified key contains key. + /// </summary> + /// <param name="key">The key.</param> + /// <returns> + /// <c>true</c> if the specified key contains key; otherwise, <c>false</c>. + /// </returns> + public bool ContainsKey(string key) + { + return _members.ContainsKey(key); + } + + /// <summary> + /// Gets the keys. + /// </summary> + /// <value>The keys.</value> + public ICollection<string> Keys + { + get { return _members.Keys; } + } + + /// <summary> + /// Removes the specified key. + /// </summary> + /// <param name="key">The key.</param> + /// <returns></returns> + public bool Remove(string key) + { + return _members.Remove(key); + } + + /// <summary> + /// Tries the get value. + /// </summary> + /// <param name="key">The key.</param> + /// <param name="value">The value.</param> + /// <returns></returns> + public bool TryGetValue(string key, out object value) + { + return _members.TryGetValue(key, out value); + } + + /// <summary> + /// Gets the values. + /// </summary> + /// <value>The values.</value> + public ICollection<object> Values + { + get { return _members.Values; } + } + + /// <summary> + /// Gets or sets the <see cref="System.Object"/> with the specified key. + /// </summary> + /// <value></value> + public object this[string key] + { + get { return _members[key]; } + set { _members[key] = value; } + } + + /// <summary> + /// Adds the specified item. + /// </summary> + /// <param name="item">The item.</param> + public void Add(KeyValuePair<string, object> item) + { + _members.Add(item.Key, item.Value); + } + + /// <summary> + /// Clears this instance. + /// </summary> + public void Clear() + { + _members.Clear(); + } + + /// <summary> + /// Determines whether [contains] [the specified item]. + /// </summary> + /// <param name="item">The item.</param> + /// <returns> + /// <c>true</c> if [contains] [the specified item]; otherwise, <c>false</c>. + /// </returns> + public bool Contains(KeyValuePair<string, object> item) + { + return _members.ContainsKey(item.Key) && _members[item.Key] == item.Value; + } + + /// <summary> + /// Copies to. + /// </summary> + /// <param name="array">The array.</param> + /// <param name="arrayIndex">Index of the array.</param> + public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex) + { + if (array == null) throw new ArgumentNullException("array"); + int num = Count; + foreach (KeyValuePair<string, object> kvp in _members) + { + array[arrayIndex++] = kvp; + if (--num <= 0) + return; + } + } + + /// <summary> + /// Gets the count. + /// </summary> + /// <value>The count.</value> + public int Count + { + get { return _members.Count; } + } + + /// <summary> + /// Gets a value indicating whether this instance is read only. + /// </summary> + /// <value> + /// <c>true</c> if this instance is read only; otherwise, <c>false</c>. + /// </value> + public bool IsReadOnly + { + get { return false; } + } + + /// <summary> + /// Removes the specified item. + /// </summary> + /// <param name="item">The item.</param> + /// <returns></returns> + public bool Remove(KeyValuePair<string, object> item) + { + return _members.Remove(item.Key); + } + + /// <summary> + /// Gets the enumerator. + /// </summary> + /// <returns></returns> + public IEnumerator<KeyValuePair<string, object>> GetEnumerator() + { + return _members.GetEnumerator(); + } + + /// <summary> + /// Returns an enumerator that iterates through a collection. + /// </summary> + /// <returns> + /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection. + /// </returns> + IEnumerator IEnumerable.GetEnumerator() + { + return _members.GetEnumerator(); + } + + /// <summary> + /// Returns a json <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>. + /// </summary> + /// <returns> + /// A json <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>. + /// </returns> + public override string ToString() + { + return PlayFabSimpleJson.SerializeObject(_members); + } + +#if SIMPLE_JSON_DYNAMIC + /// <summary> + /// Provides implementation for type conversion operations. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for operations that convert an object from one type to another. + /// </summary> + /// <param name="binder">Provides information about the conversion operation. The binder.Type property provides the type to which the object must be converted. For example, for the statement (String)sampleObject in C# (CType(sampleObject, Type) in Visual Basic), where sampleObject is an instance of the class derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, binder.Type returns the <see cref="T:System.String"/> type. The binder.Explicit property provides information about the kind of conversion that occurs. It returns true for explicit conversion and false for implicit conversion.</param> + /// <param name="result">The result of the type conversion operation.</param> + /// <returns> + /// Alwasy returns true. + /// </returns> + public override bool TryConvert(ConvertBinder binder, out object result) + { + // <pex> + if (binder == null) + throw new ArgumentNullException("binder"); + // </pex> + Type targetType = binder.Type; + + if ((targetType == typeof(IEnumerable)) || + (targetType == typeof(IEnumerable<KeyValuePair<string, object>>)) || + (targetType == typeof(IDictionary<string, object>)) || + (targetType == typeof(IDictionary))) + { + result = this; + return true; + } + + return base.TryConvert(binder, out result); + } + + /// <summary> + /// Provides the implementation for operations that delete an object member. This method is not intended for use in C# or Visual Basic. + /// </summary> + /// <param name="binder">Provides information about the deletion.</param> + /// <returns> + /// Alwasy returns true. + /// </returns> + public override bool TryDeleteMember(DeleteMemberBinder binder) + { + // <pex> + if (binder == null) + throw new ArgumentNullException("binder"); + // </pex> + return _members.Remove(binder.Name); + } + + /// <summary> + /// Provides the implementation for operations that get a value by index. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for indexing operations. + /// </summary> + /// <param name="binder">Provides information about the operation.</param> + /// <param name="indexes">The indexes that are used in the operation. For example, for the sampleObject[3] operation in C# (sampleObject(3) in Visual Basic), where sampleObject is derived from the DynamicObject class, <paramref name="indexes"/> is equal to 3.</param> + /// <param name="result">The result of the index operation.</param> + /// <returns> + /// Alwasy returns true. + /// </returns> + public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) + { + if (indexes == null) throw new ArgumentNullException("indexes"); + if (indexes.Length == 1) + { + result = ((IDictionary<string, object>)this)[(string)indexes[0]]; + return true; + } + result = null; + return true; + } + + /// <summary> + /// Provides the implementation for operations that get member values. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for operations such as getting a value for a property. + /// </summary> + /// <param name="binder">Provides information about the object that called the dynamic operation. The binder.Name property provides the name of the member on which the dynamic operation is performed. For example, for the Console.WriteLine(sampleObject.SampleProperty) statement, where sampleObject is an instance of the class derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, binder.Name returns "SampleProperty". The binder.IgnoreCase property specifies whether the member name is case-sensitive.</param> + /// <param name="result">The result of the get operation. For example, if the method is called for a property, you can assign the property value to <paramref name="result"/>.</param> + /// <returns> + /// Alwasy returns true. + /// </returns> + public override bool TryGetMember(GetMemberBinder binder, out object result) + { + object value; + if (_members.TryGetValue(binder.Name, out value)) + { + result = value; + return true; + } + result = null; + return true; + } + + /// <summary> + /// Provides the implementation for operations that set a value by index. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for operations that access objects by a specified index. + /// </summary> + /// <param name="binder">Provides information about the operation.</param> + /// <param name="indexes">The indexes that are used in the operation. For example, for the sampleObject[3] = 10 operation in C# (sampleObject(3) = 10 in Visual Basic), where sampleObject is derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, <paramref name="indexes"/> is equal to 3.</param> + /// <param name="value">The value to set to the object that has the specified index. For example, for the sampleObject[3] = 10 operation in C# (sampleObject(3) = 10 in Visual Basic), where sampleObject is derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, <paramref name="value"/> is equal to 10.</param> + /// <returns> + /// true if the operation is successful; otherwise, false. If this method returns false, the run-time binder of the language determines the behavior. (In most cases, a language-specific run-time exception is thrown. + /// </returns> + public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value) + { + if (indexes == null) throw new ArgumentNullException("indexes"); + if (indexes.Length == 1) + { + ((IDictionary<string, object>)this)[(string)indexes[0]] = value; + return true; + } + return base.TrySetIndex(binder, indexes, value); + } + + /// <summary> + /// Provides the implementation for operations that set member values. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for operations such as setting a value for a property. + /// </summary> + /// <param name="binder">Provides information about the object that called the dynamic operation. The binder.Name property provides the name of the member to which the value is being assigned. For example, for the statement sampleObject.SampleProperty = "Test", where sampleObject is an instance of the class derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, binder.Name returns "SampleProperty". The binder.IgnoreCase property specifies whether the member name is case-sensitive.</param> + /// <param name="value">The value to set to the member. For example, for sampleObject.SampleProperty = "Test", where sampleObject is an instance of the class derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, the <paramref name="value"/> is "Test".</param> + /// <returns> + /// true if the operation is successful; otherwise, false. If this method returns false, the run-time binder of the language determines the behavior. (In most cases, a language-specific run-time exception is thrown.) + /// </returns> + public override bool TrySetMember(SetMemberBinder binder, object value) + { + // <pex> + if (binder == null) + throw new ArgumentNullException("binder"); + // </pex> + _members[binder.Name] = value; + return true; + } + + /// <summary> + /// Returns the enumeration of all dynamic member names. + /// </summary> + /// <returns> + /// A sequence that contains dynamic member names. + /// </returns> + public override IEnumerable<string> GetDynamicMemberNames() + { + foreach (var key in Keys) + yield return key; + } +#endif + } + + /// <summary> + /// This class encodes and decodes JSON strings. + /// Spec. details, see http://www.json.org/ + /// + /// JSON uses Arrays and Objects. These correspond here to the datatypes JsonArray(IList<object>) and JsonObject(IDictionary<string,object>). + /// All numbers are parsed to doubles. + /// </summary> + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + static class PlayFabSimpleJson + { + private enum TokenType : byte + { + NONE = 0, + CURLY_OPEN = 1, + CURLY_CLOSE = 2, + SQUARED_OPEN = 3, + SQUARED_CLOSE = 4, + COLON = 5, + COMMA = 6, + STRING = 7, + NUMBER = 8, + TRUE = 9, + FALSE = 10, + NULL = 11, + } + private const int BUILDER_INIT = 2000; + + private static readonly char[] EscapeTable; + private static readonly char[] EscapeCharacters = new char[] { '"', '\\', '\b', '\f', '\n', '\r', '\t' }; + // private static readonly string EscapeCharactersString = new string(EscapeCharacters); + internal static readonly List<Type> NumberTypes = new List<Type> { + typeof(bool), typeof(byte), typeof(ushort), typeof(uint), typeof(ulong), typeof(sbyte), typeof(short), typeof(int), typeof(long), typeof(double), typeof(float), typeof(decimal) + }; + + // Performance stuff + [ThreadStatic] + private static StringBuilder _serializeObjectBuilder; + [ThreadStatic] + private static StringBuilder _parseStringBuilder; + + static PlayFabSimpleJson() + { + EscapeTable = new char[93]; + EscapeTable['"'] = '"'; + EscapeTable['\\'] = '\\'; + EscapeTable['\b'] = 'b'; + EscapeTable['\f'] = 'f'; + EscapeTable['\n'] = 'n'; + EscapeTable['\r'] = 'r'; + EscapeTable['\t'] = 't'; + } + + /// <summary> + /// Parses the string json into a value + /// </summary> + /// <param name="json">A JSON string.</param> + /// <returns>An IList<object>, a IDictionary<string,object>, a double, a string, null, true, or false</returns> + public static object DeserializeObject(string json) + { + object obj; + if (TryDeserializeObject(json, out obj)) + return obj; + throw new SerializationException("Invalid JSON string"); + } + + /// <summary> + /// Try parsing the json string into a value. + /// </summary> + /// <param name="json"> + /// A JSON string. + /// </param> + /// <param name="obj"> + /// The object. + /// </param> + /// <returns> + /// Returns true if successfull otherwise false. + /// </returns> + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification = "Need to support .NET 2")] + public static bool TryDeserializeObject(string json, out object obj) + { + bool success = true; + if (json != null) + { + int index = 0; + obj = ParseValue(json, ref index, ref success); + } + else + obj = null; + + return success; + } + + public static object DeserializeObject(string json, Type type, IJsonSerializerStrategy jsonSerializerStrategy) + { + object jsonObject = DeserializeObject(json); + if (type == null || jsonObject != null && ReflectionUtils.IsAssignableFrom(jsonObject.GetType(), type)) + return jsonObject; + return (jsonSerializerStrategy ?? CurrentJsonSerializerStrategy).DeserializeObject(jsonObject, type); + } + + public static object DeserializeObject(string json, Type type) + { + return DeserializeObject(json, type, null); + } + + public static T DeserializeObject<T>(string json, IJsonSerializerStrategy jsonSerializerStrategy) + { + return (T)DeserializeObject(json, typeof(T), jsonSerializerStrategy); + } + + public static T DeserializeObject<T>(string json) + { + return (T)DeserializeObject(json, typeof(T), null); + } + + /// <summary> + /// Converts a IDictionary<string,object> / IList<object> object into a JSON string + /// </summary> + /// <param name="json">A IDictionary<string,object> / IList<object></param> + /// <param name="jsonSerializerStrategy">Serializer strategy to use</param> + /// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns> + public static string SerializeObject(object json, IJsonSerializerStrategy jsonSerializerStrategy = null) + { + if (_serializeObjectBuilder == null) + _serializeObjectBuilder = new StringBuilder(BUILDER_INIT); + _serializeObjectBuilder.Length = 0; + + if (jsonSerializerStrategy == null) + jsonSerializerStrategy = CurrentJsonSerializerStrategy; + + bool success = SerializeValue(jsonSerializerStrategy, json, _serializeObjectBuilder); + return (success ? _serializeObjectBuilder.ToString() : null); + } + + public static string EscapeToJavascriptString(string jsonString) + { + if (string.IsNullOrEmpty(jsonString)) + return jsonString; + + StringBuilder sb = new StringBuilder(); + char c; + + for (int i = 0; i < jsonString.Length;) + { + c = jsonString[i++]; + + if (c == '\\') + { + int remainingLength = jsonString.Length - i; + if (remainingLength >= 2) + { + char lookahead = jsonString[i]; + if (lookahead == '\\') + { + sb.Append('\\'); + ++i; + } + else if (lookahead == '"') + { + sb.Append("\""); + ++i; + } + else if (lookahead == 't') + { + sb.Append('\t'); + ++i; + } + else if (lookahead == 'b') + { + sb.Append('\b'); + ++i; + } + else if (lookahead == 'n') + { + sb.Append('\n'); + ++i; + } + else if (lookahead == 'r') + { + sb.Append('\r'); + ++i; + } + } + } + else + { + sb.Append(c); + } + } + return sb.ToString(); + } + + static IDictionary<string, object> ParseObject(string json, ref int index, ref bool success) + { + IDictionary<string, object> table = new JsonObject(); + TokenType token; + + // { + NextToken(json, ref index); + + bool done = false; + while (!done) + { + token = LookAhead(json, index); + if (token == TokenType.NONE) + { + success = false; + return null; + } + else if (token == TokenType.COMMA) + NextToken(json, ref index); + else if (token == TokenType.CURLY_CLOSE) + { + NextToken(json, ref index); + return table; + } + else + { + // name + string name = ParseString(json, ref index, ref success); + if (!success) + { + success = false; + return null; + } + // : + token = NextToken(json, ref index); + if (token != TokenType.COLON) + { + success = false; + return null; + } + // value + object value = ParseValue(json, ref index, ref success); + if (!success) + { + success = false; + return null; + } + table[name] = value; + } + } + return table; + } + + static JsonArray ParseArray(string json, ref int index, ref bool success) + { + JsonArray array = new JsonArray(); + + // [ + NextToken(json, ref index); + + bool done = false; + while (!done) + { + TokenType token = LookAhead(json, index); + if (token == TokenType.NONE) + { + success = false; + return null; + } + else if (token == TokenType.COMMA) + NextToken(json, ref index); + else if (token == TokenType.SQUARED_CLOSE) + { + NextToken(json, ref index); + break; + } + else + { + object value = ParseValue(json, ref index, ref success); + if (!success) + return null; + array.Add(value); + } + } + return array; + } + + static object ParseValue(string json, ref int index, ref bool success) + { + switch (LookAhead(json, index)) + { + case TokenType.STRING: + return ParseString(json, ref index, ref success); + case TokenType.NUMBER: + return ParseNumber(json, ref index, ref success); + case TokenType.CURLY_OPEN: + return ParseObject(json, ref index, ref success); + case TokenType.SQUARED_OPEN: + return ParseArray(json, ref index, ref success); + case TokenType.TRUE: + NextToken(json, ref index); + return true; + case TokenType.FALSE: + NextToken(json, ref index); + return false; + case TokenType.NULL: + NextToken(json, ref index); + return null; + case TokenType.NONE: + break; + } + success = false; + return null; + } + + static string ParseString(string json, ref int index, ref bool success) + { + if (_parseStringBuilder == null) + _parseStringBuilder = new StringBuilder(BUILDER_INIT); + _parseStringBuilder.Length = 0; + + EatWhitespace(json, ref index); + + // " + char c = json[index++]; + bool complete = false; + while (!complete) + { + if (index == json.Length) + break; + + c = json[index++]; + if (c == '"') + { + complete = true; + break; + } + else if (c == '\\') + { + if (index == json.Length) + break; + c = json[index++]; + if (c == '"') + _parseStringBuilder.Append('"'); + else if (c == '\\') + _parseStringBuilder.Append('\\'); + else if (c == '/') + _parseStringBuilder.Append('/'); + else if (c == 'b') + _parseStringBuilder.Append('\b'); + else if (c == 'f') + _parseStringBuilder.Append('\f'); + else if (c == 'n') + _parseStringBuilder.Append('\n'); + else if (c == 'r') + _parseStringBuilder.Append('\r'); + else if (c == 't') + _parseStringBuilder.Append('\t'); + else if (c == 'u') + { + int remainingLength = json.Length - index; + if (remainingLength >= 4) + { + // parse the 32 bit hex into an integer codepoint + uint codePoint; + if (!(success = UInt32.TryParse(json.Substring(index, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out codePoint))) + return ""; + + // convert the integer codepoint to a unicode char and add to string + if (0xD800 <= codePoint && codePoint <= 0xDBFF) // if high surrogate + { + index += 4; // skip 4 chars + remainingLength = json.Length - index; + if (remainingLength >= 6) + { + uint lowCodePoint; + if (json.Substring(index, 2) == "\\u" && UInt32.TryParse(json.Substring(index + 2, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out lowCodePoint)) + { + if (0xDC00 <= lowCodePoint && lowCodePoint <= 0xDFFF) // if low surrogate + { + _parseStringBuilder.Append((char)codePoint); + _parseStringBuilder.Append((char)lowCodePoint); + index += 6; // skip 6 chars + continue; + } + } + } + success = false; // invalid surrogate pair + return ""; + } + _parseStringBuilder.Append(ConvertFromUtf32((int)codePoint)); + // skip 4 chars + index += 4; + } + else + break; + } + } + else + _parseStringBuilder.Append(c); + } + if (!complete) + { + success = false; + return null; + } + return _parseStringBuilder.ToString(); + } + + private static string ConvertFromUtf32(int utf32) + { + // http://www.java2s.com/Open-Source/CSharp/2.6.4-mono-.net-core/System/System/Char.cs.htm + if (utf32 < 0 || utf32 > 0x10FFFF) + throw new ArgumentOutOfRangeException("utf32", "The argument must be from 0 to 0x10FFFF."); + if (0xD800 <= utf32 && utf32 <= 0xDFFF) + throw new ArgumentOutOfRangeException("utf32", "The argument must not be in surrogate pair range."); + if (utf32 < 0x10000) + return new string((char)utf32, 1); + utf32 -= 0x10000; + return new string(new char[] { (char)((utf32 >> 10) + 0xD800), (char)(utf32 % 0x0400 + 0xDC00) }); + } + + static object ParseNumber(string json, ref int index, ref bool success) + { + EatWhitespace(json, ref index); + int lastIndex = GetLastIndexOfNumber(json, index); + int charLength = (lastIndex - index) + 1; + object returnNumber; + string str = json.Substring(index, charLength); + if (str.IndexOf(".", StringComparison.OrdinalIgnoreCase) != -1 || str.IndexOf("e", StringComparison.OrdinalIgnoreCase) != -1) + { + double number; + success = double.TryParse(json.Substring(index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); + returnNumber = number; + } + else if (str.IndexOf("-", StringComparison.OrdinalIgnoreCase) == -1) + { + ulong number; + success = ulong.TryParse(json.Substring(index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); + returnNumber = number; + } + else + { + long number; + success = long.TryParse(json.Substring(index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); + returnNumber = number; + } + index = lastIndex + 1; + return returnNumber; + } + + static int GetLastIndexOfNumber(string json, int index) + { + int lastIndex; + for (lastIndex = index; lastIndex < json.Length; lastIndex++) + if ("0123456789+-.eE".IndexOf(json[lastIndex]) == -1) break; + return lastIndex - 1; + } + + static void EatWhitespace(string json, ref int index) + { + for (; index < json.Length; index++) + if (" \t\n\r\b\f".IndexOf(json[index]) == -1) break; + } + + static TokenType LookAhead(string json, int index) + { + int saveIndex = index; + return NextToken(json, ref saveIndex); + } + + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + static TokenType NextToken(string json, ref int index) + { + EatWhitespace(json, ref index); + if (index == json.Length) + return TokenType.NONE; + char c = json[index]; + index++; + switch (c) + { + case '{': + return TokenType.CURLY_OPEN; + case '}': + return TokenType.CURLY_CLOSE; + case '[': + return TokenType.SQUARED_OPEN; + case ']': + return TokenType.SQUARED_CLOSE; + case ',': + return TokenType.COMMA; + case '"': + return TokenType.STRING; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + return TokenType.NUMBER; + case ':': + return TokenType.COLON; + } + index--; + int remainingLength = json.Length - index; + // false + if (remainingLength >= 5) + { + if (json[index] == 'f' && json[index + 1] == 'a' && json[index + 2] == 'l' && json[index + 3] == 's' && json[index + 4] == 'e') + { + index += 5; + return TokenType.FALSE; + } + } + // true + if (remainingLength >= 4) + { + if (json[index] == 't' && json[index + 1] == 'r' && json[index + 2] == 'u' && json[index + 3] == 'e') + { + index += 4; + return TokenType.TRUE; + } + } + // null + if (remainingLength >= 4) + { + if (json[index] == 'n' && json[index + 1] == 'u' && json[index + 2] == 'l' && json[index + 3] == 'l') + { + index += 4; + return TokenType.NULL; + } + } + return TokenType.NONE; + } + + static bool SerializeValue(IJsonSerializerStrategy jsonSerializerStrategy, object value, StringBuilder builder) + { + bool success = true; + string stringValue = value as string; + if (value == null) + builder.Append("null"); + else if (stringValue != null) + success = SerializeString(stringValue, builder); + else + { + IDictionary<string, object> dict = value as IDictionary<string, object>; + Type type = value.GetType(); + Type[] genArgs = ReflectionUtils.GetGenericTypeArguments(type); + var isStringKeyDictionary = type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>) && genArgs[0] == typeof(string); + if (isStringKeyDictionary) + { + var strDictValue = value as IDictionary; + success = SerializeObject(jsonSerializerStrategy, strDictValue.Keys, strDictValue.Values, builder); + } + else if (dict != null) + { + success = SerializeObject(jsonSerializerStrategy, dict.Keys, dict.Values, builder); + } + else + { + IDictionary<string, string> stringDictionary = value as IDictionary<string, string>; + if (stringDictionary != null) + { + success = SerializeObject(jsonSerializerStrategy, stringDictionary.Keys, stringDictionary.Values, builder); + } + else + { + IEnumerable enumerableValue = value as IEnumerable; + if (enumerableValue != null) + success = SerializeArray(jsonSerializerStrategy, enumerableValue, builder); + else if (IsNumeric(value)) + success = SerializeNumber(value, builder); + else if (value is bool) + builder.Append((bool)value ? "true" : "false"); + else + { + object serializedObject; + success = jsonSerializerStrategy.TrySerializeNonPrimitiveObject(value, out serializedObject); + if (success) + SerializeValue(jsonSerializerStrategy, serializedObject, builder); + } + } + } + } + return success; + } + + static bool SerializeObject(IJsonSerializerStrategy jsonSerializerStrategy, IEnumerable keys, IEnumerable values, StringBuilder builder) + { + builder.Append("{"); + IEnumerator ke = keys.GetEnumerator(); + IEnumerator ve = values.GetEnumerator(); + bool first = true; + while (ke.MoveNext() && ve.MoveNext()) + { + object key = ke.Current; + object value = ve.Current; + if (!first) + builder.Append(","); + string stringKey = key as string; + if (stringKey != null) + SerializeString(stringKey, builder); + else + if (!SerializeValue(jsonSerializerStrategy, value, builder)) return false; + builder.Append(":"); + if (!SerializeValue(jsonSerializerStrategy, value, builder)) + return false; + first = false; + } + builder.Append("}"); + return true; + } + + static bool SerializeArray(IJsonSerializerStrategy jsonSerializerStrategy, IEnumerable anArray, StringBuilder builder) + { + builder.Append("["); + bool first = true; + foreach (object value in anArray) + { + if (!first) + builder.Append(","); + if (!SerializeValue(jsonSerializerStrategy, value, builder)) + return false; + first = false; + } + builder.Append("]"); + return true; + } + + static bool SerializeString(string aString, StringBuilder builder) + { + // Happy path if there's nothing to be escaped. IndexOfAny is highly optimized (and unmanaged) + if (aString.IndexOfAny(EscapeCharacters) == -1) + { + builder.Append('"'); + builder.Append(aString); + builder.Append('"'); + + return true; + } + + builder.Append('"'); + int safeCharacterCount = 0; + char[] charArray = aString.ToCharArray(); + + for (int i = 0; i < charArray.Length; i++) + { + char c = charArray[i]; + + // Non ascii characters are fine, buffer them up and send them to the builder + // in larger chunks if possible. The escape table is a 1:1 translation table + // with \0 [default(char)] denoting a safe character. + if (c >= EscapeTable.Length || EscapeTable[c] == default(char)) + { + safeCharacterCount++; + } + else + { + if (safeCharacterCount > 0) + { + builder.Append(charArray, i - safeCharacterCount, safeCharacterCount); + safeCharacterCount = 0; + } + + builder.Append('\\'); + builder.Append(EscapeTable[c]); + } + } + + if (safeCharacterCount > 0) + { + builder.Append(charArray, charArray.Length - safeCharacterCount, safeCharacterCount); + } + + builder.Append('"'); + return true; + } + + static bool SerializeNumber(object number, StringBuilder builder) + { + if (number is decimal) + builder.Append(((decimal)number).ToString("R", CultureInfo.InvariantCulture)); + else if (number is double) + builder.Append(((double)number).ToString("R", CultureInfo.InvariantCulture)); + else if (number is float) + builder.Append(((float)number).ToString("R", CultureInfo.InvariantCulture)); + else if (NumberTypes.IndexOf(number.GetType()) != -1) + builder.Append(number); + return true; + } + + /// <summary> + /// Determines if a given object is numeric in any way + /// (can be integer, double, null, etc). + /// </summary> + static bool IsNumeric(object value) + { + if (value is sbyte) return true; + if (value is byte) return true; + if (value is short) return true; + if (value is ushort) return true; + if (value is int) return true; + if (value is uint) return true; + if (value is long) return true; + if (value is ulong) return true; + if (value is float) return true; + if (value is double) return true; + if (value is decimal) return true; + return false; + } + + private static IJsonSerializerStrategy _currentJsonSerializerStrategy; + public static IJsonSerializerStrategy CurrentJsonSerializerStrategy + { + get + { + return _currentJsonSerializerStrategy ?? + (_currentJsonSerializerStrategy = +#if SIMPLE_JSON_DATACONTRACT + DataContractJsonSerializerStrategy +#else + PocoJsonSerializerStrategy +#endif +); + } + set + { + _currentJsonSerializerStrategy = value; + } + } + + private static PocoJsonSerializerStrategy _pocoJsonSerializerStrategy; + [EditorBrowsable(EditorBrowsableState.Advanced)] + public static PocoJsonSerializerStrategy PocoJsonSerializerStrategy + { + get + { + return _pocoJsonSerializerStrategy ?? (_pocoJsonSerializerStrategy = new PocoJsonSerializerStrategy()); + } + } + +#if SIMPLE_JSON_DATACONTRACT + + private static DataContractJsonSerializerStrategy _dataContractJsonSerializerStrategy; + [System.ComponentModel.EditorBrowsable(EditorBrowsableState.Advanced)] + public static DataContractJsonSerializerStrategy DataContractJsonSerializerStrategy + { + get + { + return _dataContractJsonSerializerStrategy ?? (_dataContractJsonSerializerStrategy = new DataContractJsonSerializerStrategy()); + } + } + +#endif + } + + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + interface IJsonSerializerStrategy + { + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification = "Need to support .NET 2")] + bool TrySerializeNonPrimitiveObject(object input, out object output); + object DeserializeObject(object value, Type type); + } + + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + class PocoJsonSerializerStrategy : IJsonSerializerStrategy + { + internal IDictionary<Type, ReflectionUtils.ConstructorDelegate> ConstructorCache; + internal IDictionary<Type, IDictionary<MemberInfo, ReflectionUtils.GetDelegate>> GetCache; + internal IDictionary<Type, IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>>> SetCache; + + internal static readonly Type[] EmptyTypes = new Type[0]; + internal static readonly Type[] ArrayConstructorParameterTypes = new Type[] { typeof(int) }; + + private static readonly string[] Iso8601Format = new string[] + { + @"yyyy-MM-dd\THH:mm:ss.FFFFFFF\Z", + @"yyyy-MM-dd\THH:mm:ss\Z", + @"yyyy-MM-dd\THH:mm:ssK" + }; + + public PocoJsonSerializerStrategy() + { + ConstructorCache = new ReflectionUtils.ThreadSafeDictionary<Type, ReflectionUtils.ConstructorDelegate>(ContructorDelegateFactory); + GetCache = new ReflectionUtils.ThreadSafeDictionary<Type, IDictionary<MemberInfo, ReflectionUtils.GetDelegate>>(GetterValueFactory); + SetCache = new ReflectionUtils.ThreadSafeDictionary<Type, IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>>>(SetterValueFactory); + } + + protected virtual string MapClrMemberNameToJsonFieldName(MemberInfo memberInfo) + { + // TODO: Optimize and/or cache + foreach (JsonProperty eachAttr in memberInfo.GetCustomAttributes(typeof(JsonProperty), true)) + if (!string.IsNullOrEmpty(eachAttr.PropertyName)) + return eachAttr.PropertyName; + return memberInfo.Name; + } + + protected virtual void MapClrMemberNameToJsonFieldName(MemberInfo memberInfo, out string jsonName, out JsonProperty jsonProp) + { + jsonName = memberInfo.Name; + jsonProp = null; + // TODO: Optimize and/or cache + foreach (JsonProperty eachAttr in memberInfo.GetCustomAttributes(typeof(JsonProperty), true)) + { + jsonProp = eachAttr; + if (!string.IsNullOrEmpty(eachAttr.PropertyName)) + jsonName = eachAttr.PropertyName; + } + } + + internal virtual ReflectionUtils.ConstructorDelegate ContructorDelegateFactory(Type key) + { + return ReflectionUtils.GetContructor(key, key.IsArray ? ArrayConstructorParameterTypes : EmptyTypes); + } + + internal virtual IDictionary<MemberInfo, ReflectionUtils.GetDelegate> GetterValueFactory(Type type) + { + IDictionary<MemberInfo, ReflectionUtils.GetDelegate> result = new Dictionary<MemberInfo, ReflectionUtils.GetDelegate>(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanRead) + { + MethodInfo getMethod = ReflectionUtils.GetGetterMethodInfo(propertyInfo); + if (getMethod.IsStatic || !getMethod.IsPublic) + continue; + result[propertyInfo] = ReflectionUtils.GetGetMethod(propertyInfo); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (fieldInfo.IsStatic || !fieldInfo.IsPublic) + continue; + result[fieldInfo] = ReflectionUtils.GetGetMethod(fieldInfo); + } + return result; + } + + internal virtual IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>> SetterValueFactory(Type type) + { + IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>> result = new Dictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>>(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanWrite) + { + MethodInfo setMethod = ReflectionUtils.GetSetterMethodInfo(propertyInfo); + if (setMethod.IsStatic || !setMethod.IsPublic) + continue; + result[MapClrMemberNameToJsonFieldName(propertyInfo)] = new KeyValuePair<Type, ReflectionUtils.SetDelegate>(propertyInfo.PropertyType, ReflectionUtils.GetSetMethod(propertyInfo)); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (fieldInfo.IsInitOnly || fieldInfo.IsStatic || !fieldInfo.IsPublic) + continue; + result[MapClrMemberNameToJsonFieldName(fieldInfo)] = new KeyValuePair<Type, ReflectionUtils.SetDelegate>(fieldInfo.FieldType, ReflectionUtils.GetSetMethod(fieldInfo)); + } + return result; + } + + public virtual bool TrySerializeNonPrimitiveObject(object input, out object output) + { + return TrySerializeKnownTypes(input, out output) || TrySerializeUnknownTypes(input, out output); + } + + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + public virtual object DeserializeObject(object value, Type type) + { + if (type == null) throw new ArgumentNullException("type"); + if (value != null && type.IsInstanceOfType(value)) return value; + + string str = value as string; + if (type == typeof(Guid) && string.IsNullOrEmpty(str)) + return default(Guid); + + if (value == null) + return null; + + object obj = null; + + if (str != null) + { + if (str.Length != 0) // We know it can't be null now. + { + if (type == typeof(DateTime) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(DateTime))) + return DateTime.ParseExact(str, Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal); + if (type == typeof(DateTimeOffset) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(DateTimeOffset))) + return DateTimeOffset.ParseExact(str, Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal); + if (type == typeof(Guid) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid))) + return new Guid(str); + if (type == typeof(Uri)) + { + bool isValid = Uri.IsWellFormedUriString(str, UriKind.RelativeOrAbsolute); + + Uri result; + if (isValid && Uri.TryCreate(str, UriKind.RelativeOrAbsolute, out result)) + return result; + + return null; + } + + if (type == typeof(string)) + return str; + + return Convert.ChangeType(str, type, CultureInfo.InvariantCulture); + } + else + { + if (type == typeof(Guid)) + obj = default(Guid); + else if (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid)) + obj = null; + else + obj = str; + } + // Empty string case + if (!ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid)) + return str; + } + else if (value is bool) + return value; + + bool valueIsLong = value is long; + bool valueIsUlong = value is ulong; + bool valueIsDouble = value is double; + Type nullableType = Nullable.GetUnderlyingType(type); + if (nullableType != null && PlayFabSimpleJson.NumberTypes.IndexOf(nullableType) != -1) + type = nullableType; // Just use the regular type for the conversion + bool isNumberType = PlayFabSimpleJson.NumberTypes.IndexOf(type) != -1; + bool isEnumType = type.GetTypeInfo().IsEnum; + if ((valueIsLong && type == typeof(long)) || (valueIsUlong && type == typeof(ulong)) || (valueIsDouble && type == typeof(double))) + return value; + if ((valueIsLong || valueIsUlong || valueIsDouble) && isEnumType) + return Enum.ToObject(type, Convert.ChangeType(value, Enum.GetUnderlyingType(type), CultureInfo.InvariantCulture)); + if ((valueIsLong || valueIsUlong || valueIsDouble) && isNumberType) + return Convert.ChangeType(value, type, CultureInfo.InvariantCulture); + + IDictionary<string, object> objects = value as IDictionary<string, object>; + if (objects != null) + { + IDictionary<string, object> jsonObject = objects; + + if (ReflectionUtils.IsTypeDictionary(type)) + { + // if dictionary then + Type[] types = ReflectionUtils.GetGenericTypeArguments(type); + Type keyType = types[0]; + Type valueType = types[1]; + + Type genericType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType); + + IDictionary dict = (IDictionary)ConstructorCache[genericType](); + + foreach (KeyValuePair<string, object> kvp in jsonObject) + dict.Add(kvp.Key, DeserializeObject(kvp.Value, valueType)); + + obj = dict; + } + else + { + if (type == typeof(object)) + obj = value; + else + { + obj = ConstructorCache[type](); + foreach (KeyValuePair<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>> setter in SetCache[type]) + { + object jsonValue; + if (jsonObject.TryGetValue(setter.Key, out jsonValue)) + { + jsonValue = DeserializeObject(jsonValue, setter.Value.Key); + setter.Value.Value(obj, jsonValue); + } + } + } + } + } + else + { + IList<object> valueAsList = value as IList<object>; + if (valueAsList != null) + { + IList<object> jsonObject = valueAsList; + IList list = null; + + if (type.IsArray) + { + list = (IList)ConstructorCache[type](jsonObject.Count); + int i = 0; + foreach (object o in jsonObject) + list[i++] = DeserializeObject(o, type.GetElementType()); + } + else if (ReflectionUtils.IsTypeGenericeCollectionInterface(type) || ReflectionUtils.IsAssignableFrom(typeof(IList), type) || type == typeof(object)) + { + Type innerType = ReflectionUtils.GetGenericListElementType(type); + ReflectionUtils.ConstructorDelegate ctrDelegate = null; + if (type != typeof(object)) + ctrDelegate = ConstructorCache[type]; + if (ctrDelegate == null) + ctrDelegate = ConstructorCache[typeof(List<>).MakeGenericType(innerType)]; + list = (IList)ctrDelegate(); + foreach (object o in jsonObject) + list.Add(DeserializeObject(o, innerType)); + } + obj = list; + } + return obj; + } + if (ReflectionUtils.IsNullableType(type)) + return ReflectionUtils.ToNullableType(obj, type); + return obj; + } + + protected virtual object SerializeEnum(Enum p) + { + return Convert.ToDouble(p, CultureInfo.InvariantCulture); + } + + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification = "Need to support .NET 2")] + protected virtual bool TrySerializeKnownTypes(object input, out object output) + { + bool returnValue = true; + if (input is DateTime) + output = ((DateTime)input).ToUniversalTime().ToString(Iso8601Format[0], CultureInfo.InvariantCulture); + else if (input is DateTimeOffset) + output = ((DateTimeOffset)input).ToUniversalTime().ToString(Iso8601Format[0], CultureInfo.InvariantCulture); + else if (input is Guid) + output = ((Guid)input).ToString("D"); + else if (input is Uri) + output = input.ToString(); + else + { + Enum inputEnum = input as Enum; + if (inputEnum != null) + output = SerializeEnum(inputEnum); + else + { + returnValue = false; + output = null; + } + } + return returnValue; + } + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification = "Need to support .NET 2")] + protected virtual bool TrySerializeUnknownTypes(object input, out object output) + { + if (input == null) throw new ArgumentNullException("input"); + output = null; + Type type = input.GetType(); + if (type.FullName == null) + return false; + IDictionary<string, object> obj = new JsonObject(); + IDictionary<MemberInfo, ReflectionUtils.GetDelegate> getters = GetCache[type]; + foreach (KeyValuePair<MemberInfo, ReflectionUtils.GetDelegate> getter in getters) + { + if (getter.Value == null) + continue; + string jsonKey; + JsonProperty jsonProp; + MapClrMemberNameToJsonFieldName(getter.Key, out jsonKey, out jsonProp); + if (obj.ContainsKey(jsonKey)) + throw new Exception("The given key is defined multiple times in the same type: " + input.GetType().Name + "." + jsonKey); + object value = getter.Value(input); + if (jsonProp == null || jsonProp.NullValueHandling == NullValueHandling.Include || value != null) + obj.Add(jsonKey, value); + } + output = obj; + return true; + } + } + +#if SIMPLE_JSON_DATACONTRACT + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + class DataContractJsonSerializerStrategy : PocoJsonSerializerStrategy + { + public DataContractJsonSerializerStrategy() + { + GetCache = new ReflectionUtils.ThreadSafeDictionary<Type, IDictionary<string, ReflectionUtils.GetDelegate>>(GetterValueFactory); + SetCache = new ReflectionUtils.ThreadSafeDictionary<Type, IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>>>(SetterValueFactory); + } + + internal override IDictionary<string, ReflectionUtils.GetDelegate> GetterValueFactory(Type type) + { + bool hasDataContract = ReflectionUtils.GetAttribute(type, typeof(DataContractAttribute)) != null; + if (!hasDataContract) + return base.GetterValueFactory(type); + string jsonKey; + IDictionary<string, ReflectionUtils.GetDelegate> result = new Dictionary<string, ReflectionUtils.GetDelegate>(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanRead) + { + MethodInfo getMethod = ReflectionUtils.GetGetterMethodInfo(propertyInfo); + if (!getMethod.IsStatic && CanAdd(propertyInfo, out jsonKey)) + result[jsonKey] = ReflectionUtils.GetGetMethod(propertyInfo); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (!fieldInfo.IsStatic && CanAdd(fieldInfo, out jsonKey)) + result[jsonKey] = ReflectionUtils.GetGetMethod(fieldInfo); + } + return result; + } + + internal override IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>> SetterValueFactory(Type type) + { + bool hasDataContract = ReflectionUtils.GetAttribute(type, typeof(DataContractAttribute)) != null; + if (!hasDataContract) + return base.SetterValueFactory(type); + string jsonKey; + IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>> result = new Dictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>>(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanWrite) + { + MethodInfo setMethod = ReflectionUtils.GetSetterMethodInfo(propertyInfo); + if (!setMethod.IsStatic && CanAdd(propertyInfo, out jsonKey)) + result[jsonKey] = new KeyValuePair<Type, ReflectionUtils.SetDelegate>(propertyInfo.PropertyType, ReflectionUtils.GetSetMethod(propertyInfo)); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (!fieldInfo.IsInitOnly && !fieldInfo.IsStatic && CanAdd(fieldInfo, out jsonKey)) + result[jsonKey] = new KeyValuePair<Type, ReflectionUtils.SetDelegate>(fieldInfo.FieldType, ReflectionUtils.GetSetMethod(fieldInfo)); + } + // todo implement sorting for DATACONTRACT. + return result; + } + + private static bool CanAdd(MemberInfo info, out string jsonKey) + { + jsonKey = null; + if (ReflectionUtils.GetAttribute(info, typeof(IgnoreDataMemberAttribute)) != null) + return false; + DataMemberAttribute dataMemberAttribute = (DataMemberAttribute)ReflectionUtils.GetAttribute(info, typeof(DataMemberAttribute)); + if (dataMemberAttribute == null) + return false; + jsonKey = string.IsNullOrEmpty(dataMemberAttribute.Name) ? info.Name : dataMemberAttribute.Name; + return true; + } + } + +#endif + + // This class is meant to be copied into other libraries. So we want to exclude it from Code Analysis rules + // that might be in place in the target project. + [GeneratedCode("reflection-utils", "1.0.0")] +#if SIMPLE_JSON_REFLECTION_UTILS_PUBLIC + public +#else + internal +#endif + class ReflectionUtils + { + private static readonly object[] EmptyObjects = new object[0]; + + public delegate object GetDelegate(object source); + public delegate void SetDelegate(object source, object value); + public delegate object ConstructorDelegate(params object[] args); + + public delegate TValue ThreadSafeDictionaryValueFactory<TKey, TValue>(TKey key); + + [ThreadStatic] + private static object[] _1ObjArray; + +#if SIMPLE_JSON_TYPEINFO + public static TypeInfo GetTypeInfo(Type type) + { + return type.GetTypeInfo(); + } +#else + public static Type GetTypeInfo(Type type) + { + return type; + } +#endif + + public static Attribute GetAttribute(MemberInfo info, Type type) + { +#if SIMPLE_JSON_TYPEINFO + if (info == null || type == null || !info.IsDefined(type)) + return null; + return info.GetCustomAttribute(type); +#else + if (info == null || type == null || !Attribute.IsDefined(info, type)) + return null; + return Attribute.GetCustomAttribute(info, type); +#endif + } + + public static Type GetGenericListElementType(Type type) + { + if (type == typeof(object)) + return type; + + IEnumerable<Type> interfaces; +#if SIMPLE_JSON_TYPEINFO + interfaces = type.GetTypeInfo().ImplementedInterfaces; +#else + interfaces = type.GetInterfaces(); +#endif + foreach (Type implementedInterface in interfaces) + { + if (IsTypeGeneric(implementedInterface) && + implementedInterface.GetGenericTypeDefinition() == typeof(IList<>)) + { + return GetGenericTypeArguments(implementedInterface)[0]; + } + } + return GetGenericTypeArguments(type)[0]; + } + + public static Attribute GetAttribute(Type objectType, Type attributeType) + { + +#if SIMPLE_JSON_TYPEINFO + if (objectType == null || attributeType == null || !objectType.GetTypeInfo().IsDefined(attributeType)) + return null; + return objectType.GetTypeInfo().GetCustomAttribute(attributeType); +#else + if (objectType == null || attributeType == null || !Attribute.IsDefined(objectType, attributeType)) + return null; + return Attribute.GetCustomAttribute(objectType, attributeType); +#endif + } + + public static Type[] GetGenericTypeArguments(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetTypeInfo().GenericTypeArguments; +#else + return type.GetGenericArguments(); +#endif + } + + public static bool IsTypeGeneric(Type type) + { + return GetTypeInfo(type).IsGenericType; + } + + public static bool IsTypeGenericeCollectionInterface(Type type) + { + if (!IsTypeGeneric(type)) + return false; + + Type genericDefinition = type.GetGenericTypeDefinition(); + + return (genericDefinition == typeof(IList<>) + || genericDefinition == typeof(ICollection<>) + || genericDefinition == typeof(IEnumerable<>) +#if SIMPLE_JSON_READONLY_COLLECTIONS + || genericDefinition == typeof(IReadOnlyCollection<>) + || genericDefinition == typeof(IReadOnlyList<>) +#endif +); + } + + public static bool IsAssignableFrom(Type type1, Type type2) + { + return GetTypeInfo(type1).IsAssignableFrom(GetTypeInfo(type2)); + } + + public static bool IsTypeDictionary(Type type) + { +#if SIMPLE_JSON_TYPEINFO + if (typeof(IDictionary<,>).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo())) + return true; +#else + if (typeof(System.Collections.IDictionary).IsAssignableFrom(type)) + return true; +#endif + if (!GetTypeInfo(type).IsGenericType) + return false; + + Type genericDefinition = type.GetGenericTypeDefinition(); + return genericDefinition == typeof(IDictionary<,>) || genericDefinition == typeof(Dictionary<,>); + } + + public static bool IsNullableType(Type type) + { + return GetTypeInfo(type).IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); + } + + public static object ToNullableType(object obj, Type nullableType) + { + return obj == null ? null : Convert.ChangeType(obj, Nullable.GetUnderlyingType(nullableType), CultureInfo.InvariantCulture); + } + + public static bool IsValueType(Type type) + { + return GetTypeInfo(type).IsValueType; + } + + public static IEnumerable<ConstructorInfo> GetConstructors(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetTypeInfo().DeclaredConstructors; +#else + return type.GetConstructors(); +#endif + } + + public static ConstructorInfo GetConstructorInfo(Type type, params Type[] argsType) + { + IEnumerable<ConstructorInfo> constructorInfos = GetConstructors(type); + int i; + bool matches; + foreach (ConstructorInfo constructorInfo in constructorInfos) + { + ParameterInfo[] parameters = constructorInfo.GetParameters(); + if (argsType.Length != parameters.Length) + continue; + + i = 0; + matches = true; + foreach (ParameterInfo parameterInfo in constructorInfo.GetParameters()) + { + if (parameterInfo.ParameterType != argsType[i]) + { + matches = false; + break; + } + } + + if (matches) + return constructorInfo; + } + + return null; + } + + public static IEnumerable<PropertyInfo> GetProperties(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetRuntimeProperties(); +#else + return type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); +#endif + } + + public static IEnumerable<FieldInfo> GetFields(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetRuntimeFields(); +#else + return type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); +#endif + } + + public static MethodInfo GetGetterMethodInfo(PropertyInfo propertyInfo) + { +#if SIMPLE_JSON_TYPEINFO + return propertyInfo.GetMethod; +#else + return propertyInfo.GetGetMethod(true); +#endif + } + + public static MethodInfo GetSetterMethodInfo(PropertyInfo propertyInfo) + { +#if SIMPLE_JSON_TYPEINFO + return propertyInfo.SetMethod; +#else + return propertyInfo.GetSetMethod(true); +#endif + } + + public static ConstructorDelegate GetContructor(ConstructorInfo constructorInfo) + { + return GetConstructorByReflection(constructorInfo); + } + + public static ConstructorDelegate GetContructor(Type type, params Type[] argsType) + { + return GetConstructorByReflection(type, argsType); + } + + public static ConstructorDelegate GetConstructorByReflection(ConstructorInfo constructorInfo) + { + return delegate (object[] args) + { + var x = constructorInfo; + return x.Invoke(args); + }; + } + + public static ConstructorDelegate GetConstructorByReflection(Type type, params Type[] argsType) + { + ConstructorInfo constructorInfo = GetConstructorInfo(type, argsType); + return constructorInfo == null ? null : GetConstructorByReflection(constructorInfo); + } + + public static GetDelegate GetGetMethod(PropertyInfo propertyInfo) + { + return GetGetMethodByReflection(propertyInfo); + } + + public static GetDelegate GetGetMethod(FieldInfo fieldInfo) + { + return GetGetMethodByReflection(fieldInfo); + } + + public static GetDelegate GetGetMethodByReflection(PropertyInfo propertyInfo) + { + MethodInfo methodInfo = GetGetterMethodInfo(propertyInfo); + return delegate (object source) { return methodInfo.Invoke(source, EmptyObjects); }; + } + + public static GetDelegate GetGetMethodByReflection(FieldInfo fieldInfo) + { + return delegate (object source) { return fieldInfo.GetValue(source); }; + } + + public static SetDelegate GetSetMethod(PropertyInfo propertyInfo) + { + return GetSetMethodByReflection(propertyInfo); + } + + public static SetDelegate GetSetMethod(FieldInfo fieldInfo) + { + return GetSetMethodByReflection(fieldInfo); + } + + public static SetDelegate GetSetMethodByReflection(PropertyInfo propertyInfo) + { + MethodInfo methodInfo = GetSetterMethodInfo(propertyInfo); + return delegate (object source, object value) + { + if (_1ObjArray == null) + _1ObjArray = new object[1]; + _1ObjArray[0] = value; + methodInfo.Invoke(source, _1ObjArray); + }; + } + + public static SetDelegate GetSetMethodByReflection(FieldInfo fieldInfo) + { + return delegate (object source, object value) { fieldInfo.SetValue(source, value); }; + } + + public sealed class ThreadSafeDictionary<TKey, TValue> : IDictionary<TKey, TValue> + { + private readonly object _lock = new object(); + private readonly ThreadSafeDictionaryValueFactory<TKey, TValue> _valueFactory; + private Dictionary<TKey, TValue> _dictionary; + + public ThreadSafeDictionary(ThreadSafeDictionaryValueFactory<TKey, TValue> valueFactory) + { + _valueFactory = valueFactory; + } + + private TValue Get(TKey key) + { + if (_dictionary == null) + return AddValue(key); + TValue value; + if (!_dictionary.TryGetValue(key, out value)) + return AddValue(key); + return value; + } + + private TValue AddValue(TKey key) + { + TValue value = _valueFactory(key); + lock (_lock) + { + if (_dictionary == null) + { + _dictionary = new Dictionary<TKey, TValue>(); + _dictionary[key] = value; + } + else + { + TValue val; + if (_dictionary.TryGetValue(key, out val)) + return val; + Dictionary<TKey, TValue> dict = new Dictionary<TKey, TValue>(_dictionary); + dict[key] = value; + _dictionary = dict; + } + } + return value; + } + + public void Add(TKey key, TValue value) + { + throw new NotImplementedException(); + } + + public bool ContainsKey(TKey key) + { + return _dictionary.ContainsKey(key); + } + + public ICollection<TKey> Keys + { + get { return _dictionary.Keys; } + } + + public bool Remove(TKey key) + { + throw new NotImplementedException(); + } + + public bool TryGetValue(TKey key, out TValue value) + { + value = this[key]; + return true; + } + + public ICollection<TValue> Values + { + get { return _dictionary.Values; } + } + + public TValue this[TKey key] + { + get { return Get(key); } + set { throw new NotImplementedException(); } + } + + public void Add(KeyValuePair<TKey, TValue> item) + { + throw new NotImplementedException(); + } + + public void Clear() + { + throw new NotImplementedException(); + } + + public bool Contains(KeyValuePair<TKey, TValue> item) + { + throw new NotImplementedException(); + } + + public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) + { + throw new NotImplementedException(); + } + + public int Count + { + get { return _dictionary.Count; } + } + + public bool IsReadOnly + { + get { throw new NotImplementedException(); } + } + + public bool Remove(KeyValuePair<TKey, TValue> item) + { + throw new NotImplementedException(); + } + + public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() + { + return _dictionary.GetEnumerator(); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return _dictionary.GetEnumerator(); + } + } + } +} + +// ReSharper restore LoopCanBeConvertedToQuery +// ReSharper restore RedundantExplicitArrayCreation +// ReSharper restore SuggestUseVarKeywordEvident diff --git a/PlayFabClientSDK/source/PlayFabClientAPI.cs b/PlayFabClientSDK/source/PlayFabClientAPI.cs index f1137e40..f354fa7e 100644 --- a/PlayFabClientSDK/source/PlayFabClientAPI.cs +++ b/PlayFabClientSDK/source/PlayFabClientAPI.cs @@ -1,13 +1,11 @@ -using Newtonsoft.Json; -using PlayFab.Internal; using PlayFab.ClientModels; +using PlayFab.Internal; +using PlayFab.Json; using System; -using System.IO; using System.Threading.Tasks; namespace PlayFab { - /// <summary> /// APIs which provide the full range of PlayFab features available to the client - authentication, account and data management, inventory, friends, matchmaking, reporting, and platform-specific functionality /// </summary> @@ -16,3067 +14,2825 @@ public class PlayFabClientAPI /// <summary> /// Gets a Photon custom authentication token that can be used to securely join the player into a Photon room. See https://api.playfab.com/docs/using-photon-with-playfab/ for more details. /// </summary> - public static async Task<PlayFabResult<GetPhotonAuthenticationTokenResult>> GetPhotonAuthenticationTokenAsync(GetPhotonAuthenticationTokenRequest request) + public static async Task<PlayFabResult<GetPhotonAuthenticationTokenResult>> GetPhotonAuthenticationTokenAsync(GetPhotonAuthenticationTokenRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPhotonAuthenticationToken", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPhotonAuthenticationToken", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPhotonAuthenticationTokenResult> { Error = error, }; + return new PlayFabResult<GetPhotonAuthenticationTokenResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPhotonAuthenticationTokenResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPhotonAuthenticationTokenResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPhotonAuthenticationTokenResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPhotonAuthenticationTokenResult> { Result = result }; + return new PlayFabResult<GetPhotonAuthenticationTokenResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user in using the Android device identifier, returning a session identifier that can subsequently be used for API calls which require an authenticated user /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithAndroidDeviceIDAsync(LoginWithAndroidDeviceIDRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithAndroidDeviceIDAsync(LoginWithAndroidDeviceIDRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithAndroidDeviceID", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithAndroidDeviceID", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user in using a custom unique identifier generated by the title, returning a session identifier that can subsequently be used for API calls which require an authenticated user /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithCustomIDAsync(LoginWithCustomIDRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithCustomIDAsync(LoginWithCustomIDRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithCustomID", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithCustomID", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user into the PlayFab account, returning a session identifier that can subsequently be used for API calls which require an authenticated user /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithEmailAddressAsync(LoginWithEmailAddressRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithEmailAddressAsync(LoginWithEmailAddressRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithEmailAddress", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithEmailAddress", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user in using a Facebook access token, returning a session identifier that can subsequently be used for API calls which require an authenticated user /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithFacebookAsync(LoginWithFacebookRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithFacebookAsync(LoginWithFacebookRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithFacebook", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithFacebook", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user in using an iOS Game Center player identifier, returning a session identifier that can subsequently be used for API calls which require an authenticated user /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithGameCenterAsync(LoginWithGameCenterRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithGameCenterAsync(LoginWithGameCenterRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithGameCenter", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithGameCenter", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user in using a Google account access token(https://developers.google.com/android/reference/com/google/android/gms/auth/GoogleAuthUtil#public-methods), returning a session identifier that can subsequently be used for API calls which require an authenticated user /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithGoogleAccountAsync(LoginWithGoogleAccountRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithGoogleAccountAsync(LoginWithGoogleAccountRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithGoogleAccount", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithGoogleAccount", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user in using the vendor-specific iOS device identifier, returning a session identifier that can subsequently be used for API calls which require an authenticated user /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithIOSDeviceIDAsync(LoginWithIOSDeviceIDRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithIOSDeviceIDAsync(LoginWithIOSDeviceIDRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithIOSDeviceID", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithIOSDeviceID", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user in using a Kongregate player account. /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithKongregateAsync(LoginWithKongregateRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithKongregateAsync(LoginWithKongregateRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithKongregate", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithKongregate", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user into the PlayFab account, returning a session identifier that can subsequently be used for API calls which require an authenticated user. Unlike other login API calls, LoginWithEmailAddress does not permit the creation of new accounts via the CreateAccountFlag. Email accounts must be created using the RegisterPlayFabUser API or added to existing accounts using AddUsernamePassword. /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithPlayFabAsync(LoginWithPlayFabRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithPlayFabAsync(LoginWithPlayFabRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithPlayFab", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithPlayFab", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user in using a Steam authentication ticket, returning a session identifier that can subsequently be used for API calls which require an authenticated user /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithSteamAsync(LoginWithSteamRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithSteamAsync(LoginWithSteamRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithSteam", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithSteam", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user in using a Twitch access token. /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithTwitchAsync(LoginWithTwitchRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithTwitchAsync(LoginWithTwitchRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithTwitch", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithTwitch", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Registers a new Playfab user account, returning a session identifier that can subsequently be used for API calls which require an authenticated user. You must supply either a username or an email address. /// </summary> - public static async Task<PlayFabResult<RegisterPlayFabUserResult>> RegisterPlayFabUserAsync(RegisterPlayFabUserRequest request) + public static async Task<PlayFabResult<RegisterPlayFabUserResult>> RegisterPlayFabUserAsync(RegisterPlayFabUserRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/RegisterPlayFabUser", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/RegisterPlayFabUser", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RegisterPlayFabUserResult> { Error = error, }; + return new PlayFabResult<RegisterPlayFabUserResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RegisterPlayFabUserResult>>(new JsonTextReader(new StringReader(resultRawJson))); - RegisterPlayFabUserResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RegisterPlayFabUserResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<RegisterPlayFabUserResult> { Result = result }; + return new PlayFabResult<RegisterPlayFabUserResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the specified generic service identifier to the player's PlayFab account. This is designed to allow for a PlayFab ID lookup of any arbitrary service identifier a title wants to add. This identifier should never be used as authentication credentials, as the intent is that it is easily accessible by other players. /// </summary> - public static async Task<PlayFabResult<AddGenericIDResult>> AddGenericIDAsync(AddGenericIDRequest request) + public static async Task<PlayFabResult<AddGenericIDResult>> AddGenericIDAsync(AddGenericIDRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/AddGenericID", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/AddGenericID", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AddGenericIDResult> { Error = error, }; + return new PlayFabResult<AddGenericIDResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AddGenericIDResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AddGenericIDResult>>(resultRawJson); + var result = resultData.data; - AddGenericIDResult result = resultData.data; - - return new PlayFabResult<AddGenericIDResult> { Result = result }; + return new PlayFabResult<AddGenericIDResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds playfab username/password auth to an existing account created via an anonymous auth method, e.g. automatic device ID login. /// </summary> - public static async Task<PlayFabResult<AddUsernamePasswordResult>> AddUsernamePasswordAsync(AddUsernamePasswordRequest request) + public static async Task<PlayFabResult<AddUsernamePasswordResult>> AddUsernamePasswordAsync(AddUsernamePasswordRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/AddUsernamePassword", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/AddUsernamePassword", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AddUsernamePasswordResult> { Error = error, }; + return new PlayFabResult<AddUsernamePasswordResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AddUsernamePasswordResult>>(new JsonTextReader(new StringReader(resultRawJson))); - AddUsernamePasswordResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AddUsernamePasswordResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AddUsernamePasswordResult> { Result = result }; + return new PlayFabResult<AddUsernamePasswordResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the user's PlayFab account details /// </summary> - public static async Task<PlayFabResult<GetAccountInfoResult>> GetAccountInfoAsync(GetAccountInfoRequest request) + public static async Task<PlayFabResult<GetAccountInfoResult>> GetAccountInfoAsync(GetAccountInfoRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetAccountInfo", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetAccountInfo", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetAccountInfoResult> { Error = error, }; + return new PlayFabResult<GetAccountInfoResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetAccountInfoResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetAccountInfoResult>>(resultRawJson); + var result = resultData.data; - GetAccountInfoResult result = resultData.data; - - return new PlayFabResult<GetAccountInfoResult> { Result = result }; + return new PlayFabResult<GetAccountInfoResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves all of the user's different kinds of info. /// </summary> - public static async Task<PlayFabResult<GetPlayerCombinedInfoResult>> GetPlayerCombinedInfoAsync(GetPlayerCombinedInfoRequest request) + public static async Task<PlayFabResult<GetPlayerCombinedInfoResult>> GetPlayerCombinedInfoAsync(GetPlayerCombinedInfoRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayerCombinedInfo", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayerCombinedInfo", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerCombinedInfoResult> { Error = error, }; + return new PlayFabResult<GetPlayerCombinedInfoResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerCombinedInfoResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerCombinedInfoResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerCombinedInfoResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerCombinedInfoResult> { Result = result }; + return new PlayFabResult<GetPlayerCombinedInfoResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the unique PlayFab identifiers for the given set of Facebook identifiers. /// </summary> - public static async Task<PlayFabResult<GetPlayFabIDsFromFacebookIDsResult>> GetPlayFabIDsFromFacebookIDsAsync(GetPlayFabIDsFromFacebookIDsRequest request) + public static async Task<PlayFabResult<GetPlayFabIDsFromFacebookIDsResult>> GetPlayFabIDsFromFacebookIDsAsync(GetPlayFabIDsFromFacebookIDsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayFabIDsFromFacebookIDs", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayFabIDsFromFacebookIDs", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayFabIDsFromFacebookIDsResult> { Error = error, }; + return new PlayFabResult<GetPlayFabIDsFromFacebookIDsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayFabIDsFromFacebookIDsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayFabIDsFromFacebookIDsResult>>(resultRawJson); + var result = resultData.data; - GetPlayFabIDsFromFacebookIDsResult result = resultData.data; - - return new PlayFabResult<GetPlayFabIDsFromFacebookIDsResult> { Result = result }; + return new PlayFabResult<GetPlayFabIDsFromFacebookIDsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the unique PlayFab identifiers for the given set of Game Center identifiers (referenced in the Game Center Programming Guide as the Player Identifier). /// </summary> - public static async Task<PlayFabResult<GetPlayFabIDsFromGameCenterIDsResult>> GetPlayFabIDsFromGameCenterIDsAsync(GetPlayFabIDsFromGameCenterIDsRequest request) + public static async Task<PlayFabResult<GetPlayFabIDsFromGameCenterIDsResult>> GetPlayFabIDsFromGameCenterIDsAsync(GetPlayFabIDsFromGameCenterIDsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayFabIDsFromGameCenterIDs", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayFabIDsFromGameCenterIDs", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayFabIDsFromGameCenterIDsResult> { Error = error, }; + return new PlayFabResult<GetPlayFabIDsFromGameCenterIDsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayFabIDsFromGameCenterIDsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayFabIDsFromGameCenterIDsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayFabIDsFromGameCenterIDsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayFabIDsFromGameCenterIDsResult> { Result = result }; + return new PlayFabResult<GetPlayFabIDsFromGameCenterIDsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the unique PlayFab identifiers for the given set of generic service identifiers. A generic identifier is the service name plus the service-specific ID for the player, as specified by the title when the generic identifier was added to the player account. /// </summary> - public static async Task<PlayFabResult<GetPlayFabIDsFromGenericIDsResult>> GetPlayFabIDsFromGenericIDsAsync(GetPlayFabIDsFromGenericIDsRequest request) + public static async Task<PlayFabResult<GetPlayFabIDsFromGenericIDsResult>> GetPlayFabIDsFromGenericIDsAsync(GetPlayFabIDsFromGenericIDsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayFabIDsFromGenericIDs", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayFabIDsFromGenericIDs", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayFabIDsFromGenericIDsResult> { Error = error, }; + return new PlayFabResult<GetPlayFabIDsFromGenericIDsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayFabIDsFromGenericIDsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayFabIDsFromGenericIDsResult>>(resultRawJson); + var result = resultData.data; - GetPlayFabIDsFromGenericIDsResult result = resultData.data; - - return new PlayFabResult<GetPlayFabIDsFromGenericIDsResult> { Result = result }; + return new PlayFabResult<GetPlayFabIDsFromGenericIDsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the unique PlayFab identifiers for the given set of Google identifiers. The Google identifiers are the IDs for the user accounts, available as "id" in the Google+ People API calls. /// </summary> - public static async Task<PlayFabResult<GetPlayFabIDsFromGoogleIDsResult>> GetPlayFabIDsFromGoogleIDsAsync(GetPlayFabIDsFromGoogleIDsRequest request) + public static async Task<PlayFabResult<GetPlayFabIDsFromGoogleIDsResult>> GetPlayFabIDsFromGoogleIDsAsync(GetPlayFabIDsFromGoogleIDsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayFabIDsFromGoogleIDs", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayFabIDsFromGoogleIDs", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayFabIDsFromGoogleIDsResult> { Error = error, }; + return new PlayFabResult<GetPlayFabIDsFromGoogleIDsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayFabIDsFromGoogleIDsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayFabIDsFromGoogleIDsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayFabIDsFromGoogleIDsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayFabIDsFromGoogleIDsResult> { Result = result }; + return new PlayFabResult<GetPlayFabIDsFromGoogleIDsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the unique PlayFab identifiers for the given set of Kongregate identifiers. The Kongregate identifiers are the IDs for the user accounts, available as "user_id" from the Kongregate API methods(ex: http://developers.kongregate.com/docs/client/getUserId). /// </summary> - public static async Task<PlayFabResult<GetPlayFabIDsFromKongregateIDsResult>> GetPlayFabIDsFromKongregateIDsAsync(GetPlayFabIDsFromKongregateIDsRequest request) + public static async Task<PlayFabResult<GetPlayFabIDsFromKongregateIDsResult>> GetPlayFabIDsFromKongregateIDsAsync(GetPlayFabIDsFromKongregateIDsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayFabIDsFromKongregateIDs", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayFabIDsFromKongregateIDs", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayFabIDsFromKongregateIDsResult> { Error = error, }; + return new PlayFabResult<GetPlayFabIDsFromKongregateIDsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayFabIDsFromKongregateIDsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayFabIDsFromKongregateIDsResult>>(resultRawJson); + var result = resultData.data; - GetPlayFabIDsFromKongregateIDsResult result = resultData.data; - - return new PlayFabResult<GetPlayFabIDsFromKongregateIDsResult> { Result = result }; + return new PlayFabResult<GetPlayFabIDsFromKongregateIDsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the unique PlayFab identifiers for the given set of Steam identifiers. The Steam identifiers are the profile IDs for the user accounts, available as SteamId in the Steamworks Community API calls. /// </summary> - public static async Task<PlayFabResult<GetPlayFabIDsFromSteamIDsResult>> GetPlayFabIDsFromSteamIDsAsync(GetPlayFabIDsFromSteamIDsRequest request) + public static async Task<PlayFabResult<GetPlayFabIDsFromSteamIDsResult>> GetPlayFabIDsFromSteamIDsAsync(GetPlayFabIDsFromSteamIDsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayFabIDsFromSteamIDs", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayFabIDsFromSteamIDs", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayFabIDsFromSteamIDsResult> { Error = error, }; + return new PlayFabResult<GetPlayFabIDsFromSteamIDsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayFabIDsFromSteamIDsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayFabIDsFromSteamIDsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayFabIDsFromSteamIDsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayFabIDsFromSteamIDsResult> { Result = result }; + return new PlayFabResult<GetPlayFabIDsFromSteamIDsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the unique PlayFab identifiers for the given set of Twitch identifiers. The Twitch identifiers are the IDs for the user accounts, available as "_id" from the Twitch API methods (ex: https://github.com/justintv/Twitch-API/blob/master/v3_resources/users.md#get-usersuser). /// </summary> - public static async Task<PlayFabResult<GetPlayFabIDsFromTwitchIDsResult>> GetPlayFabIDsFromTwitchIDsAsync(GetPlayFabIDsFromTwitchIDsRequest request) + public static async Task<PlayFabResult<GetPlayFabIDsFromTwitchIDsResult>> GetPlayFabIDsFromTwitchIDsAsync(GetPlayFabIDsFromTwitchIDsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayFabIDsFromTwitchIDs", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayFabIDsFromTwitchIDs", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayFabIDsFromTwitchIDsResult> { Error = error, }; + return new PlayFabResult<GetPlayFabIDsFromTwitchIDsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayFabIDsFromTwitchIDsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayFabIDsFromTwitchIDsResult>>(resultRawJson); + var result = resultData.data; - GetPlayFabIDsFromTwitchIDsResult result = resultData.data; - - return new PlayFabResult<GetPlayFabIDsFromTwitchIDsResult> { Result = result }; + return new PlayFabResult<GetPlayFabIDsFromTwitchIDsResult> { Result = result, CustomData = customData }; } /// <summary> /// NOTE: This call will be deprecated soon. For fetching the data for a given user use GetPlayerCombinedInfo. For looking up users from the client api, we are in the process of adding a new api call. Once that call is ready, this one will be deprecated. Retrieves all requested data for a user in one unified request. By default, this API returns all data for the locally signed-in user. The input parameters may be used to limit the data retrieved to any subset of the available data, as well as retrieve the available data for a different user. Note that certain data, including inventory, virtual currency balances, and personally identifying information, may only be retrieved for the locally signed-in user. In the example below, a request is made for the account details, virtual currency balances, and specified user data for the locally signed-in user. /// </summary> [Obsolete("Use 'GetPlayerCombinedInfo' instead", true)] - public static async Task<PlayFabResult<GetUserCombinedInfoResult>> GetUserCombinedInfoAsync(GetUserCombinedInfoRequest request) + public static async Task<PlayFabResult<GetUserCombinedInfoResult>> GetUserCombinedInfoAsync(GetUserCombinedInfoRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetUserCombinedInfo", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetUserCombinedInfo", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserCombinedInfoResult> { Error = error, }; + return new PlayFabResult<GetUserCombinedInfoResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserCombinedInfoResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserCombinedInfoResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserCombinedInfoResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserCombinedInfoResult> { Result = result }; + return new PlayFabResult<GetUserCombinedInfoResult> { Result = result, CustomData = customData }; } /// <summary> /// Links the Android device identifier to the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<LinkAndroidDeviceIDResult>> LinkAndroidDeviceIDAsync(LinkAndroidDeviceIDRequest request) + public static async Task<PlayFabResult<LinkAndroidDeviceIDResult>> LinkAndroidDeviceIDAsync(LinkAndroidDeviceIDRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LinkAndroidDeviceID", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/LinkAndroidDeviceID", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LinkAndroidDeviceIDResult> { Error = error, }; + return new PlayFabResult<LinkAndroidDeviceIDResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LinkAndroidDeviceIDResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LinkAndroidDeviceIDResult>>(resultRawJson); + var result = resultData.data; - LinkAndroidDeviceIDResult result = resultData.data; - - return new PlayFabResult<LinkAndroidDeviceIDResult> { Result = result }; + return new PlayFabResult<LinkAndroidDeviceIDResult> { Result = result, CustomData = customData }; } /// <summary> /// Links the custom identifier, generated by the title, to the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<LinkCustomIDResult>> LinkCustomIDAsync(LinkCustomIDRequest request) + public static async Task<PlayFabResult<LinkCustomIDResult>> LinkCustomIDAsync(LinkCustomIDRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LinkCustomID", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/LinkCustomID", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LinkCustomIDResult> { Error = error, }; + return new PlayFabResult<LinkCustomIDResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LinkCustomIDResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LinkCustomIDResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LinkCustomIDResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<LinkCustomIDResult> { Result = result }; + return new PlayFabResult<LinkCustomIDResult> { Result = result, CustomData = customData }; } /// <summary> /// Links the Facebook account associated with the provided Facebook access token to the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<LinkFacebookAccountResult>> LinkFacebookAccountAsync(LinkFacebookAccountRequest request) + public static async Task<PlayFabResult<LinkFacebookAccountResult>> LinkFacebookAccountAsync(LinkFacebookAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LinkFacebookAccount", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/LinkFacebookAccount", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LinkFacebookAccountResult> { Error = error, }; + return new PlayFabResult<LinkFacebookAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LinkFacebookAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LinkFacebookAccountResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LinkFacebookAccountResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<LinkFacebookAccountResult> { Result = result }; + return new PlayFabResult<LinkFacebookAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Links the Game Center account associated with the provided Game Center ID to the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<LinkGameCenterAccountResult>> LinkGameCenterAccountAsync(LinkGameCenterAccountRequest request) + public static async Task<PlayFabResult<LinkGameCenterAccountResult>> LinkGameCenterAccountAsync(LinkGameCenterAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LinkGameCenterAccount", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/LinkGameCenterAccount", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LinkGameCenterAccountResult> { Error = error, }; + return new PlayFabResult<LinkGameCenterAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LinkGameCenterAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LinkGameCenterAccountResult>>(resultRawJson); + var result = resultData.data; - LinkGameCenterAccountResult result = resultData.data; - - return new PlayFabResult<LinkGameCenterAccountResult> { Result = result }; + return new PlayFabResult<LinkGameCenterAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Links the currently signed-in user account to the Google account specified by the Google account access token (https://developers.google.com/android/reference/com/google/android/gms/auth/GoogleAuthUtil#public-methods). /// </summary> - public static async Task<PlayFabResult<LinkGoogleAccountResult>> LinkGoogleAccountAsync(LinkGoogleAccountRequest request) + public static async Task<PlayFabResult<LinkGoogleAccountResult>> LinkGoogleAccountAsync(LinkGoogleAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LinkGoogleAccount", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/LinkGoogleAccount", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LinkGoogleAccountResult> { Error = error, }; + return new PlayFabResult<LinkGoogleAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LinkGoogleAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LinkGoogleAccountResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LinkGoogleAccountResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<LinkGoogleAccountResult> { Result = result }; + return new PlayFabResult<LinkGoogleAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Links the vendor-specific iOS device identifier to the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<LinkIOSDeviceIDResult>> LinkIOSDeviceIDAsync(LinkIOSDeviceIDRequest request) + public static async Task<PlayFabResult<LinkIOSDeviceIDResult>> LinkIOSDeviceIDAsync(LinkIOSDeviceIDRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LinkIOSDeviceID", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/LinkIOSDeviceID", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LinkIOSDeviceIDResult> { Error = error, }; + return new PlayFabResult<LinkIOSDeviceIDResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LinkIOSDeviceIDResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LinkIOSDeviceIDResult>>(resultRawJson); + var result = resultData.data; - LinkIOSDeviceIDResult result = resultData.data; - - return new PlayFabResult<LinkIOSDeviceIDResult> { Result = result }; + return new PlayFabResult<LinkIOSDeviceIDResult> { Result = result, CustomData = customData }; } /// <summary> /// Links the Kongregate identifier to the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<LinkKongregateAccountResult>> LinkKongregateAsync(LinkKongregateAccountRequest request) + public static async Task<PlayFabResult<LinkKongregateAccountResult>> LinkKongregateAsync(LinkKongregateAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LinkKongregate", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/LinkKongregate", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LinkKongregateAccountResult> { Error = error, }; + return new PlayFabResult<LinkKongregateAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LinkKongregateAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LinkKongregateAccountResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LinkKongregateAccountResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<LinkKongregateAccountResult> { Result = result }; + return new PlayFabResult<LinkKongregateAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Links the Steam account associated with the provided Steam authentication ticket to the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<LinkSteamAccountResult>> LinkSteamAccountAsync(LinkSteamAccountRequest request) + public static async Task<PlayFabResult<LinkSteamAccountResult>> LinkSteamAccountAsync(LinkSteamAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LinkSteamAccount", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/LinkSteamAccount", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LinkSteamAccountResult> { Error = error, }; + return new PlayFabResult<LinkSteamAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LinkSteamAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LinkSteamAccountResult>>(resultRawJson); + var result = resultData.data; - LinkSteamAccountResult result = resultData.data; - - return new PlayFabResult<LinkSteamAccountResult> { Result = result }; + return new PlayFabResult<LinkSteamAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Links the Twitch account associated with the token to the user's PlayFab account. /// </summary> - public static async Task<PlayFabResult<LinkTwitchAccountResult>> LinkTwitchAsync(LinkTwitchAccountRequest request) + public static async Task<PlayFabResult<LinkTwitchAccountResult>> LinkTwitchAsync(LinkTwitchAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LinkTwitch", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/LinkTwitch", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LinkTwitchAccountResult> { Error = error, }; + return new PlayFabResult<LinkTwitchAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LinkTwitchAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LinkTwitchAccountResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LinkTwitchAccountResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<LinkTwitchAccountResult> { Result = result }; + return new PlayFabResult<LinkTwitchAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Removes the specified generic service identifier from the player's PlayFab account. /// </summary> - public static async Task<PlayFabResult<RemoveGenericIDResult>> RemoveGenericIDAsync(RemoveGenericIDRequest request) + public static async Task<PlayFabResult<RemoveGenericIDResult>> RemoveGenericIDAsync(RemoveGenericIDRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/RemoveGenericID", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/RemoveGenericID", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RemoveGenericIDResult> { Error = error, }; + return new PlayFabResult<RemoveGenericIDResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RemoveGenericIDResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RemoveGenericIDResult>>(resultRawJson); + var result = resultData.data; - RemoveGenericIDResult result = resultData.data; - - return new PlayFabResult<RemoveGenericIDResult> { Result = result }; + return new PlayFabResult<RemoveGenericIDResult> { Result = result, CustomData = customData }; } /// <summary> /// Submit a report for another player (due to bad bahavior, etc.), so that customer service representatives for the title can take action concerning potentially toxic players. /// </summary> - public static async Task<PlayFabResult<ReportPlayerClientResult>> ReportPlayerAsync(ReportPlayerClientRequest request) + public static async Task<PlayFabResult<ReportPlayerClientResult>> ReportPlayerAsync(ReportPlayerClientRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/ReportPlayer", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/ReportPlayer", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ReportPlayerClientResult> { Error = error, }; + return new PlayFabResult<ReportPlayerClientResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ReportPlayerClientResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ReportPlayerClientResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ReportPlayerClientResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ReportPlayerClientResult> { Result = result }; + return new PlayFabResult<ReportPlayerClientResult> { Result = result, CustomData = customData }; } /// <summary> /// Forces an email to be sent to the registered email address for the user's account, with a link allowing the user to change the password /// </summary> - public static async Task<PlayFabResult<SendAccountRecoveryEmailResult>> SendAccountRecoveryEmailAsync(SendAccountRecoveryEmailRequest request) + public static async Task<PlayFabResult<SendAccountRecoveryEmailResult>> SendAccountRecoveryEmailAsync(SendAccountRecoveryEmailRequest request, object customData = null) { - object httpResult = await PlayFabHTTP.DoPost("/Client/SendAccountRecoveryEmail", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/SendAccountRecoveryEmail", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SendAccountRecoveryEmailResult> { Error = error, }; + return new PlayFabResult<SendAccountRecoveryEmailResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SendAccountRecoveryEmailResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SendAccountRecoveryEmailResult>>(resultRawJson); + var result = resultData.data; - SendAccountRecoveryEmailResult result = resultData.data; - - return new PlayFabResult<SendAccountRecoveryEmailResult> { Result = result }; + return new PlayFabResult<SendAccountRecoveryEmailResult> { Result = result, CustomData = customData }; } /// <summary> /// Unlinks the related Android device identifier from the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<UnlinkAndroidDeviceIDResult>> UnlinkAndroidDeviceIDAsync(UnlinkAndroidDeviceIDRequest request) + public static async Task<PlayFabResult<UnlinkAndroidDeviceIDResult>> UnlinkAndroidDeviceIDAsync(UnlinkAndroidDeviceIDRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlinkAndroidDeviceID", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlinkAndroidDeviceID", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlinkAndroidDeviceIDResult> { Error = error, }; + return new PlayFabResult<UnlinkAndroidDeviceIDResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlinkAndroidDeviceIDResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UnlinkAndroidDeviceIDResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlinkAndroidDeviceIDResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UnlinkAndroidDeviceIDResult> { Result = result }; + return new PlayFabResult<UnlinkAndroidDeviceIDResult> { Result = result, CustomData = customData }; } /// <summary> /// Unlinks the related custom identifier from the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<UnlinkCustomIDResult>> UnlinkCustomIDAsync(UnlinkCustomIDRequest request) + public static async Task<PlayFabResult<UnlinkCustomIDResult>> UnlinkCustomIDAsync(UnlinkCustomIDRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlinkCustomID", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlinkCustomID", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlinkCustomIDResult> { Error = error, }; + return new PlayFabResult<UnlinkCustomIDResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlinkCustomIDResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlinkCustomIDResult>>(resultRawJson); + var result = resultData.data; - UnlinkCustomIDResult result = resultData.data; - - return new PlayFabResult<UnlinkCustomIDResult> { Result = result }; + return new PlayFabResult<UnlinkCustomIDResult> { Result = result, CustomData = customData }; } /// <summary> /// Unlinks the related Facebook account from the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<UnlinkFacebookAccountResult>> UnlinkFacebookAccountAsync(UnlinkFacebookAccountRequest request) + public static async Task<PlayFabResult<UnlinkFacebookAccountResult>> UnlinkFacebookAccountAsync(UnlinkFacebookAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlinkFacebookAccount", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlinkFacebookAccount", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlinkFacebookAccountResult> { Error = error, }; + return new PlayFabResult<UnlinkFacebookAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlinkFacebookAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UnlinkFacebookAccountResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlinkFacebookAccountResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UnlinkFacebookAccountResult> { Result = result }; + return new PlayFabResult<UnlinkFacebookAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Unlinks the related Game Center account from the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<UnlinkGameCenterAccountResult>> UnlinkGameCenterAccountAsync(UnlinkGameCenterAccountRequest request) + public static async Task<PlayFabResult<UnlinkGameCenterAccountResult>> UnlinkGameCenterAccountAsync(UnlinkGameCenterAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlinkGameCenterAccount", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlinkGameCenterAccount", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlinkGameCenterAccountResult> { Error = error, }; + return new PlayFabResult<UnlinkGameCenterAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlinkGameCenterAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlinkGameCenterAccountResult>>(resultRawJson); + var result = resultData.data; - UnlinkGameCenterAccountResult result = resultData.data; - - return new PlayFabResult<UnlinkGameCenterAccountResult> { Result = result }; + return new PlayFabResult<UnlinkGameCenterAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Unlinks the related Google account from the user's PlayFab account (https://developers.google.com/android/reference/com/google/android/gms/auth/GoogleAuthUtil#public-methods). /// </summary> - public static async Task<PlayFabResult<UnlinkGoogleAccountResult>> UnlinkGoogleAccountAsync(UnlinkGoogleAccountRequest request) + public static async Task<PlayFabResult<UnlinkGoogleAccountResult>> UnlinkGoogleAccountAsync(UnlinkGoogleAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlinkGoogleAccount", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlinkGoogleAccount", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlinkGoogleAccountResult> { Error = error, }; + return new PlayFabResult<UnlinkGoogleAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlinkGoogleAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UnlinkGoogleAccountResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlinkGoogleAccountResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UnlinkGoogleAccountResult> { Result = result }; + return new PlayFabResult<UnlinkGoogleAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Unlinks the related iOS device identifier from the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<UnlinkIOSDeviceIDResult>> UnlinkIOSDeviceIDAsync(UnlinkIOSDeviceIDRequest request) + public static async Task<PlayFabResult<UnlinkIOSDeviceIDResult>> UnlinkIOSDeviceIDAsync(UnlinkIOSDeviceIDRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlinkIOSDeviceID", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlinkIOSDeviceID", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlinkIOSDeviceIDResult> { Error = error, }; + return new PlayFabResult<UnlinkIOSDeviceIDResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlinkIOSDeviceIDResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlinkIOSDeviceIDResult>>(resultRawJson); + var result = resultData.data; - UnlinkIOSDeviceIDResult result = resultData.data; - - return new PlayFabResult<UnlinkIOSDeviceIDResult> { Result = result }; + return new PlayFabResult<UnlinkIOSDeviceIDResult> { Result = result, CustomData = customData }; } /// <summary> /// Unlinks the related Kongregate identifier from the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<UnlinkKongregateAccountResult>> UnlinkKongregateAsync(UnlinkKongregateAccountRequest request) + public static async Task<PlayFabResult<UnlinkKongregateAccountResult>> UnlinkKongregateAsync(UnlinkKongregateAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlinkKongregate", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlinkKongregate", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlinkKongregateAccountResult> { Error = error, }; + return new PlayFabResult<UnlinkKongregateAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlinkKongregateAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UnlinkKongregateAccountResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlinkKongregateAccountResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UnlinkKongregateAccountResult> { Result = result }; + return new PlayFabResult<UnlinkKongregateAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Unlinks the related Steam account from the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<UnlinkSteamAccountResult>> UnlinkSteamAccountAsync(UnlinkSteamAccountRequest request) + public static async Task<PlayFabResult<UnlinkSteamAccountResult>> UnlinkSteamAccountAsync(UnlinkSteamAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlinkSteamAccount", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlinkSteamAccount", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlinkSteamAccountResult> { Error = error, }; + return new PlayFabResult<UnlinkSteamAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlinkSteamAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlinkSteamAccountResult>>(resultRawJson); + var result = resultData.data; - UnlinkSteamAccountResult result = resultData.data; - - return new PlayFabResult<UnlinkSteamAccountResult> { Result = result }; + return new PlayFabResult<UnlinkSteamAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Unlinks the related Twitch account from the user's PlayFab account. /// </summary> - public static async Task<PlayFabResult<UnlinkTwitchAccountResult>> UnlinkTwitchAsync(UnlinkTwitchAccountRequest request) + public static async Task<PlayFabResult<UnlinkTwitchAccountResult>> UnlinkTwitchAsync(UnlinkTwitchAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlinkTwitch", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlinkTwitch", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlinkTwitchAccountResult> { Error = error, }; + return new PlayFabResult<UnlinkTwitchAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlinkTwitchAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UnlinkTwitchAccountResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlinkTwitchAccountResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UnlinkTwitchAccountResult> { Result = result }; + return new PlayFabResult<UnlinkTwitchAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title specific display name for the user /// </summary> - public static async Task<PlayFabResult<UpdateUserTitleDisplayNameResult>> UpdateUserTitleDisplayNameAsync(UpdateUserTitleDisplayNameRequest request) + public static async Task<PlayFabResult<UpdateUserTitleDisplayNameResult>> UpdateUserTitleDisplayNameAsync(UpdateUserTitleDisplayNameRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UpdateUserTitleDisplayName", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UpdateUserTitleDisplayName", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserTitleDisplayNameResult> { Error = error, }; + return new PlayFabResult<UpdateUserTitleDisplayNameResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserTitleDisplayNameResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserTitleDisplayNameResult>>(resultRawJson); + var result = resultData.data; - UpdateUserTitleDisplayNameResult result = resultData.data; - - return new PlayFabResult<UpdateUserTitleDisplayNameResult> { Result = result }; + return new PlayFabResult<UpdateUserTitleDisplayNameResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked friends of the current player for the given statistic, starting from the indicated point in the leaderboard /// </summary> - public static async Task<PlayFabResult<GetLeaderboardResult>> GetFriendLeaderboardAsync(GetFriendLeaderboardRequest request) + public static async Task<PlayFabResult<GetLeaderboardResult>> GetFriendLeaderboardAsync(GetFriendLeaderboardRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetFriendLeaderboard", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetFriendLeaderboard", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetLeaderboardResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetLeaderboardResult> { Result = result }; + return new PlayFabResult<GetLeaderboardResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked friends of the current player for the given statistic, centered on the requested PlayFab user. If PlayFabId is empty or null will return currently logged in user. /// </summary> - public static async Task<PlayFabResult<GetFriendLeaderboardAroundPlayerResult>> GetFriendLeaderboardAroundPlayerAsync(GetFriendLeaderboardAroundPlayerRequest request) + public static async Task<PlayFabResult<GetFriendLeaderboardAroundPlayerResult>> GetFriendLeaderboardAroundPlayerAsync(GetFriendLeaderboardAroundPlayerRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetFriendLeaderboardAroundPlayer", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetFriendLeaderboardAroundPlayer", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetFriendLeaderboardAroundPlayerResult> { Error = error, }; + return new PlayFabResult<GetFriendLeaderboardAroundPlayerResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetFriendLeaderboardAroundPlayerResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetFriendLeaderboardAroundPlayerResult>>(resultRawJson); + var result = resultData.data; - GetFriendLeaderboardAroundPlayerResult result = resultData.data; - - return new PlayFabResult<GetFriendLeaderboardAroundPlayerResult> { Result = result }; + return new PlayFabResult<GetFriendLeaderboardAroundPlayerResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked users for the given statistic, starting from the indicated point in the leaderboard /// </summary> - public static async Task<PlayFabResult<GetLeaderboardResult>> GetLeaderboardAsync(GetLeaderboardRequest request) + public static async Task<PlayFabResult<GetLeaderboardResult>> GetLeaderboardAsync(GetLeaderboardRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetLeaderboard", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetLeaderboard", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetLeaderboardResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetLeaderboardResult> { Result = result }; + return new PlayFabResult<GetLeaderboardResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked users for the given statistic, centered on the requested player. If PlayFabId is empty or null will return currently logged in user. /// </summary> - public static async Task<PlayFabResult<GetLeaderboardAroundPlayerResult>> GetLeaderboardAroundPlayerAsync(GetLeaderboardAroundPlayerRequest request) + public static async Task<PlayFabResult<GetLeaderboardAroundPlayerResult>> GetLeaderboardAroundPlayerAsync(GetLeaderboardAroundPlayerRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetLeaderboardAroundPlayer", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetLeaderboardAroundPlayer", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardAroundPlayerResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardAroundPlayerResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardAroundPlayerResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardAroundPlayerResult>>(resultRawJson); + var result = resultData.data; - GetLeaderboardAroundPlayerResult result = resultData.data; - - return new PlayFabResult<GetLeaderboardAroundPlayerResult> { Result = result }; + return new PlayFabResult<GetLeaderboardAroundPlayerResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the indicated statistics (current version and values for all statistics, if none are specified), for the local player. /// </summary> - public static async Task<PlayFabResult<GetPlayerStatisticsResult>> GetPlayerStatisticsAsync(GetPlayerStatisticsRequest request) + public static async Task<PlayFabResult<GetPlayerStatisticsResult>> GetPlayerStatisticsAsync(GetPlayerStatisticsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayerStatistics", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayerStatistics", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerStatisticsResult> { Error = error, }; + return new PlayFabResult<GetPlayerStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerStatisticsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerStatisticsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerStatisticsResult> { Result = result }; + return new PlayFabResult<GetPlayerStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the information on the available versions of the specified statistic. /// </summary> - public static async Task<PlayFabResult<GetPlayerStatisticVersionsResult>> GetPlayerStatisticVersionsAsync(GetPlayerStatisticVersionsRequest request) + public static async Task<PlayFabResult<GetPlayerStatisticVersionsResult>> GetPlayerStatisticVersionsAsync(GetPlayerStatisticVersionsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayerStatisticVersions", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayerStatisticVersions", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerStatisticVersionsResult> { Error = error, }; + return new PlayFabResult<GetPlayerStatisticVersionsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerStatisticVersionsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerStatisticVersionsResult>>(resultRawJson); + var result = resultData.data; - GetPlayerStatisticVersionsResult result = resultData.data; - - return new PlayFabResult<GetPlayerStatisticVersionsResult> { Result = result }; + return new PlayFabResult<GetPlayerStatisticVersionsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserDataAsync(GetUserDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetUserData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetUserData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the publisher-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherDataAsync(GetUserDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetUserPublisherData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetUserPublisherData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - GetUserDataResult result = resultData.data; - - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the publisher-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherReadOnlyDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherReadOnlyDataAsync(GetUserDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetUserPublisherReadOnlyData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetUserPublisherReadOnlyData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserReadOnlyDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserReadOnlyDataAsync(GetUserDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetUserReadOnlyData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetUserReadOnlyData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - GetUserDataResult result = resultData.data; - - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the values of the specified title-specific statistics for the user. By default, clients are not permitted to update statistics. Developers may override this setting in the Game Manager > Settings > API Features. /// </summary> - public static async Task<PlayFabResult<UpdatePlayerStatisticsResult>> UpdatePlayerStatisticsAsync(UpdatePlayerStatisticsRequest request) + public static async Task<PlayFabResult<UpdatePlayerStatisticsResult>> UpdatePlayerStatisticsAsync(UpdatePlayerStatisticsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UpdatePlayerStatistics", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UpdatePlayerStatistics", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdatePlayerStatisticsResult> { Error = error, }; + return new PlayFabResult<UpdatePlayerStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdatePlayerStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdatePlayerStatisticsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdatePlayerStatisticsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdatePlayerStatisticsResult> { Result = result }; + return new PlayFabResult<UpdatePlayerStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Creates and updates the title-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserDataAsync(UpdateUserDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UpdateUserData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UpdateUserData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Creates and updates the publisher-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherDataAsync(UpdateUserDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UpdateUserPublisherData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UpdateUserPublisherData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - UpdateUserDataResult result = resultData.data; - - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the specified version of the title's catalog of virtual goods, including all defined properties /// </summary> - public static async Task<PlayFabResult<GetCatalogItemsResult>> GetCatalogItemsAsync(GetCatalogItemsRequest request) + public static async Task<PlayFabResult<GetCatalogItemsResult>> GetCatalogItemsAsync(GetCatalogItemsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetCatalogItems", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetCatalogItems", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCatalogItemsResult> { Error = error, }; + return new PlayFabResult<GetCatalogItemsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCatalogItemsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetCatalogItemsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCatalogItemsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetCatalogItemsResult> { Result = result }; + return new PlayFabResult<GetCatalogItemsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the key-value store of custom publisher settings /// </summary> - public static async Task<PlayFabResult<GetPublisherDataResult>> GetPublisherDataAsync(GetPublisherDataRequest request) + public static async Task<PlayFabResult<GetPublisherDataResult>> GetPublisherDataAsync(GetPublisherDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPublisherData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPublisherData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPublisherDataResult> { Error = error, }; + return new PlayFabResult<GetPublisherDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPublisherDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPublisherDataResult>>(resultRawJson); + var result = resultData.data; - GetPublisherDataResult result = resultData.data; - - return new PlayFabResult<GetPublisherDataResult> { Result = result }; + return new PlayFabResult<GetPublisherDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the set of items defined for the specified store, including all prices defined /// </summary> - public static async Task<PlayFabResult<GetStoreItemsResult>> GetStoreItemsAsync(GetStoreItemsRequest request) + public static async Task<PlayFabResult<GetStoreItemsResult>> GetStoreItemsAsync(GetStoreItemsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetStoreItems", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetStoreItems", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetStoreItemsResult> { Error = error, }; + return new PlayFabResult<GetStoreItemsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetStoreItemsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetStoreItemsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetStoreItemsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetStoreItemsResult> { Result = result }; + return new PlayFabResult<GetStoreItemsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the current server time /// </summary> - public static async Task<PlayFabResult<GetTimeResult>> GetTimeAsync(GetTimeRequest request) + public static async Task<PlayFabResult<GetTimeResult>> GetTimeAsync(GetTimeRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetTime", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetTime", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTimeResult> { Error = error, }; + return new PlayFabResult<GetTimeResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTimeResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTimeResult>>(resultRawJson); + var result = resultData.data; - GetTimeResult result = resultData.data; - - return new PlayFabResult<GetTimeResult> { Result = result }; + return new PlayFabResult<GetTimeResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the key-value store of custom title settings /// </summary> - public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleDataAsync(GetTitleDataRequest request) + public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleDataAsync(GetTitleDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetTitleData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetTitleData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTitleDataResult> { Error = error, }; + return new PlayFabResult<GetTitleDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTitleDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetTitleDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTitleDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetTitleDataResult> { Result = result }; + return new PlayFabResult<GetTitleDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title news feed, as configured in the developer portal /// </summary> - public static async Task<PlayFabResult<GetTitleNewsResult>> GetTitleNewsAsync(GetTitleNewsRequest request) + public static async Task<PlayFabResult<GetTitleNewsResult>> GetTitleNewsAsync(GetTitleNewsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetTitleNews", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetTitleNews", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTitleNewsResult> { Error = error, }; + return new PlayFabResult<GetTitleNewsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTitleNewsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTitleNewsResult>>(resultRawJson); + var result = resultData.data; - GetTitleNewsResult result = resultData.data; - - return new PlayFabResult<GetTitleNewsResult> { Result = result }; + return new PlayFabResult<GetTitleNewsResult> { Result = result, CustomData = customData }; } /// <summary> /// Increments the user's balance of the specified virtual currency by the stated amount /// </summary> - public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> AddUserVirtualCurrencyAsync(AddUserVirtualCurrencyRequest request) + public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> AddUserVirtualCurrencyAsync(AddUserVirtualCurrencyRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/AddUserVirtualCurrency", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/AddUserVirtualCurrency", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ModifyUserVirtualCurrencyResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result, CustomData = customData }; } /// <summary> /// Confirms with the payment provider that the purchase was approved (if applicable) and adjusts inventory and virtual currency balances as appropriate /// </summary> - public static async Task<PlayFabResult<ConfirmPurchaseResult>> ConfirmPurchaseAsync(ConfirmPurchaseRequest request) + public static async Task<PlayFabResult<ConfirmPurchaseResult>> ConfirmPurchaseAsync(ConfirmPurchaseRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/ConfirmPurchase", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/ConfirmPurchase", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ConfirmPurchaseResult> { Error = error, }; + return new PlayFabResult<ConfirmPurchaseResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ConfirmPurchaseResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ConfirmPurchaseResult>>(resultRawJson); + var result = resultData.data; - ConfirmPurchaseResult result = resultData.data; - - return new PlayFabResult<ConfirmPurchaseResult> { Result = result }; + return new PlayFabResult<ConfirmPurchaseResult> { Result = result, CustomData = customData }; } /// <summary> /// Consume uses of a consumable item. When all uses are consumed, it will be removed from the player's inventory. /// </summary> - public static async Task<PlayFabResult<ConsumeItemResult>> ConsumeItemAsync(ConsumeItemRequest request) + public static async Task<PlayFabResult<ConsumeItemResult>> ConsumeItemAsync(ConsumeItemRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/ConsumeItem", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/ConsumeItem", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ConsumeItemResult> { Error = error, }; + return new PlayFabResult<ConsumeItemResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ConsumeItemResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ConsumeItemResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ConsumeItemResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ConsumeItemResult> { Result = result }; + return new PlayFabResult<ConsumeItemResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the specified character's current inventory of virtual goods /// </summary> - public static async Task<PlayFabResult<GetCharacterInventoryResult>> GetCharacterInventoryAsync(GetCharacterInventoryRequest request) + public static async Task<PlayFabResult<GetCharacterInventoryResult>> GetCharacterInventoryAsync(GetCharacterInventoryRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetCharacterInventory", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetCharacterInventory", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterInventoryResult> { Error = error, }; + return new PlayFabResult<GetCharacterInventoryResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterInventoryResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterInventoryResult>>(resultRawJson); + var result = resultData.data; - GetCharacterInventoryResult result = resultData.data; - - return new PlayFabResult<GetCharacterInventoryResult> { Result = result }; + return new PlayFabResult<GetCharacterInventoryResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a completed purchase along with its current PlayFab status. /// </summary> - public static async Task<PlayFabResult<GetPurchaseResult>> GetPurchaseAsync(GetPurchaseRequest request) + public static async Task<PlayFabResult<GetPurchaseResult>> GetPurchaseAsync(GetPurchaseRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPurchase", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPurchase", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPurchaseResult> { Error = error, }; + return new PlayFabResult<GetPurchaseResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPurchaseResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPurchaseResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPurchaseResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPurchaseResult> { Result = result }; + return new PlayFabResult<GetPurchaseResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the user's current inventory of virtual goods /// </summary> - public static async Task<PlayFabResult<GetUserInventoryResult>> GetUserInventoryAsync(GetUserInventoryRequest request) + public static async Task<PlayFabResult<GetUserInventoryResult>> GetUserInventoryAsync(GetUserInventoryRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetUserInventory", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetUserInventory", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserInventoryResult> { Error = error, }; + return new PlayFabResult<GetUserInventoryResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserInventoryResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserInventoryResult>>(resultRawJson); + var result = resultData.data; - GetUserInventoryResult result = resultData.data; - - return new PlayFabResult<GetUserInventoryResult> { Result = result }; + return new PlayFabResult<GetUserInventoryResult> { Result = result, CustomData = customData }; } /// <summary> /// Selects a payment option for purchase order created via StartPurchase /// </summary> - public static async Task<PlayFabResult<PayForPurchaseResult>> PayForPurchaseAsync(PayForPurchaseRequest request) + public static async Task<PlayFabResult<PayForPurchaseResult>> PayForPurchaseAsync(PayForPurchaseRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/PayForPurchase", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/PayForPurchase", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<PayForPurchaseResult> { Error = error, }; + return new PlayFabResult<PayForPurchaseResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<PayForPurchaseResult>>(new JsonTextReader(new StringReader(resultRawJson))); - PayForPurchaseResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<PayForPurchaseResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<PayForPurchaseResult> { Result = result }; + return new PlayFabResult<PayForPurchaseResult> { Result = result, CustomData = customData }; } /// <summary> /// Buys a single item with virtual currency. You must specify both the virtual currency to use to purchase, as well as what the client believes the price to be. This lets the server fail the purchase if the price has changed. /// </summary> - public static async Task<PlayFabResult<PurchaseItemResult>> PurchaseItemAsync(PurchaseItemRequest request) + public static async Task<PlayFabResult<PurchaseItemResult>> PurchaseItemAsync(PurchaseItemRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/PurchaseItem", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/PurchaseItem", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<PurchaseItemResult> { Error = error, }; + return new PlayFabResult<PurchaseItemResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<PurchaseItemResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<PurchaseItemResult>>(resultRawJson); + var result = resultData.data; - PurchaseItemResult result = resultData.data; - - return new PlayFabResult<PurchaseItemResult> { Result = result }; + return new PlayFabResult<PurchaseItemResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the virtual goods associated with the coupon to the user's inventory. Coupons can be generated via the Economy->Catalogs tab in the PlayFab Game Manager. /// </summary> - public static async Task<PlayFabResult<RedeemCouponResult>> RedeemCouponAsync(RedeemCouponRequest request) + public static async Task<PlayFabResult<RedeemCouponResult>> RedeemCouponAsync(RedeemCouponRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/RedeemCoupon", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/RedeemCoupon", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RedeemCouponResult> { Error = error, }; + return new PlayFabResult<RedeemCouponResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RedeemCouponResult>>(new JsonTextReader(new StringReader(resultRawJson))); - RedeemCouponResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RedeemCouponResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RedeemCouponResult> { Result = result }; + return new PlayFabResult<RedeemCouponResult> { Result = result, CustomData = customData }; } /// <summary> /// Creates an order for a list of items from the title catalog /// </summary> - public static async Task<PlayFabResult<StartPurchaseResult>> StartPurchaseAsync(StartPurchaseRequest request) + public static async Task<PlayFabResult<StartPurchaseResult>> StartPurchaseAsync(StartPurchaseRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/StartPurchase", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/StartPurchase", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<StartPurchaseResult> { Error = error, }; + return new PlayFabResult<StartPurchaseResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<StartPurchaseResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<StartPurchaseResult>>(resultRawJson); + var result = resultData.data; - StartPurchaseResult result = resultData.data; - - return new PlayFabResult<StartPurchaseResult> { Result = result }; + return new PlayFabResult<StartPurchaseResult> { Result = result, CustomData = customData }; } /// <summary> /// Decrements the user's balance of the specified virtual currency by the stated amount /// </summary> - public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> SubtractUserVirtualCurrencyAsync(SubtractUserVirtualCurrencyRequest request) + public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> SubtractUserVirtualCurrencyAsync(SubtractUserVirtualCurrencyRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/SubtractUserVirtualCurrency", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/SubtractUserVirtualCurrency", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ModifyUserVirtualCurrencyResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result, CustomData = customData }; } /// <summary> /// Opens the specified container, with the specified key (when required), and returns the contents of the opened container. If the container (and key when relevant) are consumable (RemainingUses > 0), their RemainingUses will be decremented, consistent with the operation of ConsumeItem. /// </summary> - public static async Task<PlayFabResult<UnlockContainerItemResult>> UnlockContainerInstanceAsync(UnlockContainerInstanceRequest request) + public static async Task<PlayFabResult<UnlockContainerItemResult>> UnlockContainerInstanceAsync(UnlockContainerInstanceRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlockContainerInstance", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlockContainerInstance", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlockContainerItemResult> { Error = error, }; + return new PlayFabResult<UnlockContainerItemResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlockContainerItemResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlockContainerItemResult>>(resultRawJson); + var result = resultData.data; - UnlockContainerItemResult result = resultData.data; - - return new PlayFabResult<UnlockContainerItemResult> { Result = result }; + return new PlayFabResult<UnlockContainerItemResult> { Result = result, CustomData = customData }; } /// <summary> /// Searches target inventory for an ItemInstance matching the given CatalogItemId, if necessary unlocks it using an appropriate key, and returns the contents of the opened container. If the container (and key when relevant) are consumable (RemainingUses > 0), their RemainingUses will be decremented, consistent with the operation of ConsumeItem. /// </summary> - public static async Task<PlayFabResult<UnlockContainerItemResult>> UnlockContainerItemAsync(UnlockContainerItemRequest request) + public static async Task<PlayFabResult<UnlockContainerItemResult>> UnlockContainerItemAsync(UnlockContainerItemRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlockContainerItem", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlockContainerItem", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlockContainerItemResult> { Error = error, }; + return new PlayFabResult<UnlockContainerItemResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlockContainerItemResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UnlockContainerItemResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlockContainerItemResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UnlockContainerItemResult> { Result = result }; + return new PlayFabResult<UnlockContainerItemResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the PlayFab user, based upon a match against a supplied unique identifier, to the friend list of the local user. At least one of FriendPlayFabId,FriendUsername,FriendEmail, or FriendTitleDisplayName should be initialized. /// </summary> - public static async Task<PlayFabResult<AddFriendResult>> AddFriendAsync(AddFriendRequest request) + public static async Task<PlayFabResult<AddFriendResult>> AddFriendAsync(AddFriendRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/AddFriend", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/AddFriend", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AddFriendResult> { Error = error, }; + return new PlayFabResult<AddFriendResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AddFriendResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AddFriendResult>>(resultRawJson); + var result = resultData.data; - AddFriendResult result = resultData.data; - - return new PlayFabResult<AddFriendResult> { Result = result }; + return new PlayFabResult<AddFriendResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the current friend list for the local user, constrained to users who have PlayFab accounts. Friends from linked accounts (Facebook, Steam) are also included. You may optionally exclude some linked services' friends. /// </summary> - public static async Task<PlayFabResult<GetFriendsListResult>> GetFriendsListAsync(GetFriendsListRequest request) + public static async Task<PlayFabResult<GetFriendsListResult>> GetFriendsListAsync(GetFriendsListRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetFriendsList", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetFriendsList", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetFriendsListResult> { Error = error, }; + return new PlayFabResult<GetFriendsListResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetFriendsListResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetFriendsListResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetFriendsListResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetFriendsListResult> { Result = result }; + return new PlayFabResult<GetFriendsListResult> { Result = result, CustomData = customData }; } /// <summary> /// Removes a specified user from the friend list of the local user /// </summary> - public static async Task<PlayFabResult<RemoveFriendResult>> RemoveFriendAsync(RemoveFriendRequest request) + public static async Task<PlayFabResult<RemoveFriendResult>> RemoveFriendAsync(RemoveFriendRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/RemoveFriend", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/RemoveFriend", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RemoveFriendResult> { Error = error, }; + return new PlayFabResult<RemoveFriendResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RemoveFriendResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RemoveFriendResult>>(resultRawJson); + var result = resultData.data; - RemoveFriendResult result = resultData.data; - - return new PlayFabResult<RemoveFriendResult> { Result = result }; + return new PlayFabResult<RemoveFriendResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the tag list for a specified user in the friend list of the local user /// </summary> - public static async Task<PlayFabResult<SetFriendTagsResult>> SetFriendTagsAsync(SetFriendTagsRequest request) + public static async Task<PlayFabResult<SetFriendTagsResult>> SetFriendTagsAsync(SetFriendTagsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/SetFriendTags", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/SetFriendTags", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetFriendTagsResult> { Error = error, }; + return new PlayFabResult<SetFriendTagsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetFriendTagsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - SetFriendTagsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetFriendTagsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<SetFriendTagsResult> { Result = result }; + return new PlayFabResult<SetFriendTagsResult> { Result = result, CustomData = customData }; } /// <summary> /// Registers the iOS device to receive push notifications /// </summary> - public static async Task<PlayFabResult<RegisterForIOSPushNotificationResult>> RegisterForIOSPushNotificationAsync(RegisterForIOSPushNotificationRequest request) + public static async Task<PlayFabResult<RegisterForIOSPushNotificationResult>> RegisterForIOSPushNotificationAsync(RegisterForIOSPushNotificationRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/RegisterForIOSPushNotification", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/RegisterForIOSPushNotification", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RegisterForIOSPushNotificationResult> { Error = error, }; + return new PlayFabResult<RegisterForIOSPushNotificationResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RegisterForIOSPushNotificationResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RegisterForIOSPushNotificationResult>>(resultRawJson); + var result = resultData.data; - RegisterForIOSPushNotificationResult result = resultData.data; - - return new PlayFabResult<RegisterForIOSPushNotificationResult> { Result = result }; + return new PlayFabResult<RegisterForIOSPushNotificationResult> { Result = result, CustomData = customData }; } /// <summary> /// Restores all in-app purchases based on the given refresh receipt. /// </summary> - public static async Task<PlayFabResult<RestoreIOSPurchasesResult>> RestoreIOSPurchasesAsync(RestoreIOSPurchasesRequest request) + public static async Task<PlayFabResult<RestoreIOSPurchasesResult>> RestoreIOSPurchasesAsync(RestoreIOSPurchasesRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/RestoreIOSPurchases", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/RestoreIOSPurchases", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RestoreIOSPurchasesResult> { Error = error, }; + return new PlayFabResult<RestoreIOSPurchasesResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RestoreIOSPurchasesResult>>(new JsonTextReader(new StringReader(resultRawJson))); - RestoreIOSPurchasesResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RestoreIOSPurchasesResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RestoreIOSPurchasesResult> { Result = result }; + return new PlayFabResult<RestoreIOSPurchasesResult> { Result = result, CustomData = customData }; } /// <summary> /// Validates with the Apple store that the receipt for an iOS in-app purchase is valid and that it matches the purchased catalog item /// </summary> - public static async Task<PlayFabResult<ValidateIOSReceiptResult>> ValidateIOSReceiptAsync(ValidateIOSReceiptRequest request) + public static async Task<PlayFabResult<ValidateIOSReceiptResult>> ValidateIOSReceiptAsync(ValidateIOSReceiptRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/ValidateIOSReceipt", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/ValidateIOSReceipt", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ValidateIOSReceiptResult> { Error = error, }; + return new PlayFabResult<ValidateIOSReceiptResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ValidateIOSReceiptResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ValidateIOSReceiptResult>>(resultRawJson); + var result = resultData.data; - ValidateIOSReceiptResult result = resultData.data; - - return new PlayFabResult<ValidateIOSReceiptResult> { Result = result }; + return new PlayFabResult<ValidateIOSReceiptResult> { Result = result, CustomData = customData }; } /// <summary> /// Get details about all current running game servers matching the given parameters. /// </summary> - public static async Task<PlayFabResult<CurrentGamesResult>> GetCurrentGamesAsync(CurrentGamesRequest request) + public static async Task<PlayFabResult<CurrentGamesResult>> GetCurrentGamesAsync(CurrentGamesRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetCurrentGames", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetCurrentGames", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<CurrentGamesResult> { Error = error, }; + return new PlayFabResult<CurrentGamesResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<CurrentGamesResult>>(new JsonTextReader(new StringReader(resultRawJson))); - CurrentGamesResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<CurrentGamesResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<CurrentGamesResult> { Result = result }; + return new PlayFabResult<CurrentGamesResult> { Result = result, CustomData = customData }; } /// <summary> /// Get details about the regions hosting game servers matching the given parameters. /// </summary> - public static async Task<PlayFabResult<GameServerRegionsResult>> GetGameServerRegionsAsync(GameServerRegionsRequest request) + public static async Task<PlayFabResult<GameServerRegionsResult>> GetGameServerRegionsAsync(GameServerRegionsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetGameServerRegions", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetGameServerRegions", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GameServerRegionsResult> { Error = error, }; + return new PlayFabResult<GameServerRegionsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GameServerRegionsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GameServerRegionsResult>>(resultRawJson); + var result = resultData.data; - GameServerRegionsResult result = resultData.data; - - return new PlayFabResult<GameServerRegionsResult> { Result = result }; + return new PlayFabResult<GameServerRegionsResult> { Result = result, CustomData = customData }; } /// <summary> /// Attempts to locate a game session matching the given parameters. If the goal is to match the player into a specific active session, only the LobbyId is required. Otherwise, the BuildVersion, GameMode, and Region are all required parameters. Note that parameters specified in the search are required (they are not weighting factors). If a slot is found in a server instance matching the parameters, the slot will be assigned to that player, removing it from the availabe set. In that case, the information on the game session will be returned, otherwise the Status returned will be GameNotFound. Note that EnableQueue is deprecated at this time. /// </summary> - public static async Task<PlayFabResult<MatchmakeResult>> MatchmakeAsync(MatchmakeRequest request) + public static async Task<PlayFabResult<MatchmakeResult>> MatchmakeAsync(MatchmakeRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/Matchmake", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/Matchmake", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<MatchmakeResult> { Error = error, }; + return new PlayFabResult<MatchmakeResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<MatchmakeResult>>(new JsonTextReader(new StringReader(resultRawJson))); - MatchmakeResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<MatchmakeResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<MatchmakeResult> { Result = result }; + return new PlayFabResult<MatchmakeResult> { Result = result, CustomData = customData }; } /// <summary> /// Start a new game server with a given configuration, add the current player and return the connection information. /// </summary> - public static async Task<PlayFabResult<StartGameResult>> StartGameAsync(StartGameRequest request) + public static async Task<PlayFabResult<StartGameResult>> StartGameAsync(StartGameRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/StartGame", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/StartGame", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<StartGameResult> { Error = error, }; + return new PlayFabResult<StartGameResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<StartGameResult>>(new JsonTextReader(new StringReader(resultRawJson))); - StartGameResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<StartGameResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<StartGameResult> { Result = result }; + return new PlayFabResult<StartGameResult> { Result = result, CustomData = customData }; } /// <summary> /// Registers the Android device to receive push notifications /// </summary> - public static async Task<PlayFabResult<AndroidDevicePushNotificationRegistrationResult>> AndroidDevicePushNotificationRegistrationAsync(AndroidDevicePushNotificationRegistrationRequest request) + public static async Task<PlayFabResult<AndroidDevicePushNotificationRegistrationResult>> AndroidDevicePushNotificationRegistrationAsync(AndroidDevicePushNotificationRegistrationRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/AndroidDevicePushNotificationRegistration", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/AndroidDevicePushNotificationRegistration", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AndroidDevicePushNotificationRegistrationResult> { Error = error, }; + return new PlayFabResult<AndroidDevicePushNotificationRegistrationResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AndroidDevicePushNotificationRegistrationResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AndroidDevicePushNotificationRegistrationResult>>(resultRawJson); + var result = resultData.data; - AndroidDevicePushNotificationRegistrationResult result = resultData.data; - - return new PlayFabResult<AndroidDevicePushNotificationRegistrationResult> { Result = result }; + return new PlayFabResult<AndroidDevicePushNotificationRegistrationResult> { Result = result, CustomData = customData }; } /// <summary> /// Validates a Google Play purchase and gives the corresponding item to the player. /// </summary> - public static async Task<PlayFabResult<ValidateGooglePlayPurchaseResult>> ValidateGooglePlayPurchaseAsync(ValidateGooglePlayPurchaseRequest request) + public static async Task<PlayFabResult<ValidateGooglePlayPurchaseResult>> ValidateGooglePlayPurchaseAsync(ValidateGooglePlayPurchaseRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/ValidateGooglePlayPurchase", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/ValidateGooglePlayPurchase", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ValidateGooglePlayPurchaseResult> { Error = error, }; + return new PlayFabResult<ValidateGooglePlayPurchaseResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ValidateGooglePlayPurchaseResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ValidateGooglePlayPurchaseResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ValidateGooglePlayPurchaseResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ValidateGooglePlayPurchaseResult> { Result = result }; + return new PlayFabResult<ValidateGooglePlayPurchaseResult> { Result = result, CustomData = customData }; } /// <summary> /// Writes a character-based event into PlayStream. /// </summary> - public static async Task<PlayFabResult<WriteEventResponse>> WriteCharacterEventAsync(WriteClientCharacterEventRequest request) + public static async Task<PlayFabResult<WriteEventResponse>> WriteCharacterEventAsync(WriteClientCharacterEventRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/WriteCharacterEvent", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/WriteCharacterEvent", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<WriteEventResponse> { Error = error, }; + return new PlayFabResult<WriteEventResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<WriteEventResponse>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<WriteEventResponse>>(resultRawJson); + var result = resultData.data; - WriteEventResponse result = resultData.data; - - return new PlayFabResult<WriteEventResponse> { Result = result }; + return new PlayFabResult<WriteEventResponse> { Result = result, CustomData = customData }; } /// <summary> /// Writes a player-based event into PlayStream. /// </summary> - public static async Task<PlayFabResult<WriteEventResponse>> WritePlayerEventAsync(WriteClientPlayerEventRequest request) + public static async Task<PlayFabResult<WriteEventResponse>> WritePlayerEventAsync(WriteClientPlayerEventRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/WritePlayerEvent", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/WritePlayerEvent", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<WriteEventResponse> { Error = error, }; + return new PlayFabResult<WriteEventResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<WriteEventResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - WriteEventResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<WriteEventResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<WriteEventResponse> { Result = result }; + return new PlayFabResult<WriteEventResponse> { Result = result, CustomData = customData }; } /// <summary> /// Writes a title-based event into PlayStream. /// </summary> - public static async Task<PlayFabResult<WriteEventResponse>> WriteTitleEventAsync(WriteTitleEventRequest request) + public static async Task<PlayFabResult<WriteEventResponse>> WriteTitleEventAsync(WriteTitleEventRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/WriteTitleEvent", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/WriteTitleEvent", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<WriteEventResponse> { Error = error, }; + return new PlayFabResult<WriteEventResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<WriteEventResponse>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<WriteEventResponse>>(resultRawJson); + var result = resultData.data; - WriteEventResponse result = resultData.data; - - return new PlayFabResult<WriteEventResponse> { Result = result }; + return new PlayFabResult<WriteEventResponse> { Result = result, CustomData = customData }; } /// <summary> /// Adds users to the set of those able to update both the shared data, as well as the set of users in the group. Only users in the group can add new members. /// </summary> - public static async Task<PlayFabResult<AddSharedGroupMembersResult>> AddSharedGroupMembersAsync(AddSharedGroupMembersRequest request) + public static async Task<PlayFabResult<AddSharedGroupMembersResult>> AddSharedGroupMembersAsync(AddSharedGroupMembersRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/AddSharedGroupMembers", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/AddSharedGroupMembers", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AddSharedGroupMembersResult> { Error = error, }; + return new PlayFabResult<AddSharedGroupMembersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AddSharedGroupMembersResult>>(new JsonTextReader(new StringReader(resultRawJson))); - AddSharedGroupMembersResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AddSharedGroupMembersResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AddSharedGroupMembersResult> { Result = result }; + return new PlayFabResult<AddSharedGroupMembersResult> { Result = result, CustomData = customData }; } /// <summary> /// Requests the creation of a shared group object, containing key/value pairs which may be updated by all members of the group. Upon creation, the current user will be the only member of the group. /// </summary> - public static async Task<PlayFabResult<CreateSharedGroupResult>> CreateSharedGroupAsync(CreateSharedGroupRequest request) + public static async Task<PlayFabResult<CreateSharedGroupResult>> CreateSharedGroupAsync(CreateSharedGroupRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/CreateSharedGroup", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/CreateSharedGroup", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<CreateSharedGroupResult> { Error = error, }; + return new PlayFabResult<CreateSharedGroupResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<CreateSharedGroupResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<CreateSharedGroupResult>>(resultRawJson); + var result = resultData.data; - CreateSharedGroupResult result = resultData.data; - - return new PlayFabResult<CreateSharedGroupResult> { Result = result }; + return new PlayFabResult<CreateSharedGroupResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves data stored in a shared group object, as well as the list of members in the group. Non-members of the group may use this to retrieve group data, including membership, but they will not receive data for keys marked as private. /// </summary> - public static async Task<PlayFabResult<GetSharedGroupDataResult>> GetSharedGroupDataAsync(GetSharedGroupDataRequest request) + public static async Task<PlayFabResult<GetSharedGroupDataResult>> GetSharedGroupDataAsync(GetSharedGroupDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetSharedGroupData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetSharedGroupData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetSharedGroupDataResult> { Error = error, }; + return new PlayFabResult<GetSharedGroupDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetSharedGroupDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetSharedGroupDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetSharedGroupDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetSharedGroupDataResult> { Result = result }; + return new PlayFabResult<GetSharedGroupDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Removes users from the set of those able to update the shared data and the set of users in the group. Only users in the group can remove members. If as a result of the call, zero users remain with access, the group and its associated data will be deleted. /// </summary> - public static async Task<PlayFabResult<RemoveSharedGroupMembersResult>> RemoveSharedGroupMembersAsync(RemoveSharedGroupMembersRequest request) + public static async Task<PlayFabResult<RemoveSharedGroupMembersResult>> RemoveSharedGroupMembersAsync(RemoveSharedGroupMembersRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/RemoveSharedGroupMembers", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/RemoveSharedGroupMembers", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RemoveSharedGroupMembersResult> { Error = error, }; + return new PlayFabResult<RemoveSharedGroupMembersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RemoveSharedGroupMembersResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RemoveSharedGroupMembersResult>>(resultRawJson); + var result = resultData.data; - RemoveSharedGroupMembersResult result = resultData.data; - - return new PlayFabResult<RemoveSharedGroupMembersResult> { Result = result }; + return new PlayFabResult<RemoveSharedGroupMembersResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds, updates, and removes data keys for a shared group object. If the permission is set to Public, all fields updated or added in this call will be readable by users not in the group. By default, data permissions are set to Private. Regardless of the permission setting, only members of the group can update the data. /// </summary> - public static async Task<PlayFabResult<UpdateSharedGroupDataResult>> UpdateSharedGroupDataAsync(UpdateSharedGroupDataRequest request) + public static async Task<PlayFabResult<UpdateSharedGroupDataResult>> UpdateSharedGroupDataAsync(UpdateSharedGroupDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UpdateSharedGroupData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UpdateSharedGroupData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateSharedGroupDataResult> { Error = error, }; + return new PlayFabResult<UpdateSharedGroupDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateSharedGroupDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateSharedGroupDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateSharedGroupDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateSharedGroupDataResult> { Result = result }; + return new PlayFabResult<UpdateSharedGroupDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Executes a CloudScript function, with the 'currentPlayerId' set to the PlayFab ID of the authenticated player. /// </summary> - public static async Task<PlayFabResult<ExecuteCloudScriptResult>> ExecuteCloudScriptAsync(ExecuteCloudScriptRequest request) + public static async Task<PlayFabResult<ExecuteCloudScriptResult>> ExecuteCloudScriptAsync(ExecuteCloudScriptRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/ExecuteCloudScript", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/ExecuteCloudScript", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ExecuteCloudScriptResult> { Error = error, }; + return new PlayFabResult<ExecuteCloudScriptResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ExecuteCloudScriptResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ExecuteCloudScriptResult>>(resultRawJson); + var result = resultData.data; - ExecuteCloudScriptResult result = resultData.data; - - return new PlayFabResult<ExecuteCloudScriptResult> { Result = result }; + return new PlayFabResult<ExecuteCloudScriptResult> { Result = result, CustomData = customData }; } /// <summary> /// This API retrieves a pre-signed URL for accessing a content file for the title. A subsequent HTTP GET to the returned URL will attempt to download the content. A HEAD query to the returned URL will attempt to retrieve the metadata of the content. Note that a successful result does not guarantee the existence of this content - if it has not been uploaded, the query to retrieve the data will fail. See this post for more information: https://community.playfab.com/hc/en-us/community/posts/205469488-How-to-upload-files-to-PlayFab-s-Content-Service /// </summary> - public static async Task<PlayFabResult<GetContentDownloadUrlResult>> GetContentDownloadUrlAsync(GetContentDownloadUrlRequest request) + public static async Task<PlayFabResult<GetContentDownloadUrlResult>> GetContentDownloadUrlAsync(GetContentDownloadUrlRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetContentDownloadUrl", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetContentDownloadUrl", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetContentDownloadUrlResult> { Error = error, }; + return new PlayFabResult<GetContentDownloadUrlResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetContentDownloadUrlResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetContentDownloadUrlResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetContentDownloadUrlResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetContentDownloadUrlResult> { Result = result }; + return new PlayFabResult<GetContentDownloadUrlResult> { Result = result, CustomData = customData }; } /// <summary> /// Lists all of the characters that belong to a specific user. CharacterIds are not globally unique; characterId must be evaluated with the parent PlayFabId to guarantee uniqueness. /// </summary> - public static async Task<PlayFabResult<ListUsersCharactersResult>> GetAllUsersCharactersAsync(ListUsersCharactersRequest request) + public static async Task<PlayFabResult<ListUsersCharactersResult>> GetAllUsersCharactersAsync(ListUsersCharactersRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetAllUsersCharacters", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetAllUsersCharacters", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ListUsersCharactersResult> { Error = error, }; + return new PlayFabResult<ListUsersCharactersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ListUsersCharactersResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ListUsersCharactersResult>>(resultRawJson); + var result = resultData.data; - ListUsersCharactersResult result = resultData.data; - - return new PlayFabResult<ListUsersCharactersResult> { Result = result }; + return new PlayFabResult<ListUsersCharactersResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked characters for the given statistic, starting from the indicated point in the leaderboard /// </summary> - public static async Task<PlayFabResult<GetCharacterLeaderboardResult>> GetCharacterLeaderboardAsync(GetCharacterLeaderboardRequest request) + public static async Task<PlayFabResult<GetCharacterLeaderboardResult>> GetCharacterLeaderboardAsync(GetCharacterLeaderboardRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetCharacterLeaderboard", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetCharacterLeaderboard", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterLeaderboardResult> { Error = error, }; + return new PlayFabResult<GetCharacterLeaderboardResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterLeaderboardResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetCharacterLeaderboardResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterLeaderboardResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetCharacterLeaderboardResult> { Result = result }; + return new PlayFabResult<GetCharacterLeaderboardResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the details of all title-specific statistics for the user /// </summary> - public static async Task<PlayFabResult<GetCharacterStatisticsResult>> GetCharacterStatisticsAsync(GetCharacterStatisticsRequest request) + public static async Task<PlayFabResult<GetCharacterStatisticsResult>> GetCharacterStatisticsAsync(GetCharacterStatisticsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetCharacterStatistics", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetCharacterStatistics", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterStatisticsResult> { Error = error, }; + return new PlayFabResult<GetCharacterStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterStatisticsResult>>(resultRawJson); + var result = resultData.data; - GetCharacterStatisticsResult result = resultData.data; - - return new PlayFabResult<GetCharacterStatisticsResult> { Result = result }; + return new PlayFabResult<GetCharacterStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked characters for the given statistic, centered on the requested Character ID /// </summary> - public static async Task<PlayFabResult<GetLeaderboardAroundCharacterResult>> GetLeaderboardAroundCharacterAsync(GetLeaderboardAroundCharacterRequest request) + public static async Task<PlayFabResult<GetLeaderboardAroundCharacterResult>> GetLeaderboardAroundCharacterAsync(GetLeaderboardAroundCharacterRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetLeaderboardAroundCharacter", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetLeaderboardAroundCharacter", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardAroundCharacterResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardAroundCharacterResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardAroundCharacterResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetLeaderboardAroundCharacterResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardAroundCharacterResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetLeaderboardAroundCharacterResult> { Result = result }; + return new PlayFabResult<GetLeaderboardAroundCharacterResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of all of the user's characters for the given statistic. /// </summary> - public static async Task<PlayFabResult<GetLeaderboardForUsersCharactersResult>> GetLeaderboardForUserCharactersAsync(GetLeaderboardForUsersCharactersRequest request) + public static async Task<PlayFabResult<GetLeaderboardForUsersCharactersResult>> GetLeaderboardForUserCharactersAsync(GetLeaderboardForUsersCharactersRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetLeaderboardForUserCharacters", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetLeaderboardForUserCharacters", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardForUsersCharactersResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardForUsersCharactersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardForUsersCharactersResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardForUsersCharactersResult>>(resultRawJson); + var result = resultData.data; - GetLeaderboardForUsersCharactersResult result = resultData.data; - - return new PlayFabResult<GetLeaderboardForUsersCharactersResult> { Result = result }; + return new PlayFabResult<GetLeaderboardForUsersCharactersResult> { Result = result, CustomData = customData }; } /// <summary> /// Grants the specified character type to the user. CharacterIds are not globally unique; characterId must be evaluated with the parent PlayFabId to guarantee uniqueness. /// </summary> - public static async Task<PlayFabResult<GrantCharacterToUserResult>> GrantCharacterToUserAsync(GrantCharacterToUserRequest request) + public static async Task<PlayFabResult<GrantCharacterToUserResult>> GrantCharacterToUserAsync(GrantCharacterToUserRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GrantCharacterToUser", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GrantCharacterToUser", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GrantCharacterToUserResult> { Error = error, }; + return new PlayFabResult<GrantCharacterToUserResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GrantCharacterToUserResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GrantCharacterToUserResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GrantCharacterToUserResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GrantCharacterToUserResult> { Result = result }; + return new PlayFabResult<GrantCharacterToUserResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the values of the specified title-specific statistics for the specific character. By default, clients are not permitted to update statistics. Developers may override this setting in the Game Manager > Settings > API Features. /// </summary> - public static async Task<PlayFabResult<UpdateCharacterStatisticsResult>> UpdateCharacterStatisticsAsync(UpdateCharacterStatisticsRequest request) + public static async Task<PlayFabResult<UpdateCharacterStatisticsResult>> UpdateCharacterStatisticsAsync(UpdateCharacterStatisticsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UpdateCharacterStatistics", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UpdateCharacterStatistics", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateCharacterStatisticsResult> { Error = error, }; + return new PlayFabResult<UpdateCharacterStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateCharacterStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateCharacterStatisticsResult>>(resultRawJson); + var result = resultData.data; - UpdateCharacterStatisticsResult result = resultData.data; - - return new PlayFabResult<UpdateCharacterStatisticsResult> { Result = result }; + return new PlayFabResult<UpdateCharacterStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the character which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterDataAsync(GetCharacterDataRequest request) + public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterDataAsync(GetCharacterDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetCharacterData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetCharacterData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterDataResult> { Error = error, }; + return new PlayFabResult<GetCharacterDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetCharacterDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetCharacterDataResult> { Result = result }; + return new PlayFabResult<GetCharacterDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the character which can only be read by the client /// </summary> - public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterReadOnlyDataAsync(GetCharacterDataRequest request) + public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterReadOnlyDataAsync(GetCharacterDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetCharacterReadOnlyData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetCharacterReadOnlyData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterDataResult> { Error = error, }; + return new PlayFabResult<GetCharacterDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterDataResult>>(resultRawJson); + var result = resultData.data; - GetCharacterDataResult result = resultData.data; - - return new PlayFabResult<GetCharacterDataResult> { Result = result }; + return new PlayFabResult<GetCharacterDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Creates and updates the title-specific custom data for the user's character which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<UpdateCharacterDataResult>> UpdateCharacterDataAsync(UpdateCharacterDataRequest request) + public static async Task<PlayFabResult<UpdateCharacterDataResult>> UpdateCharacterDataAsync(UpdateCharacterDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UpdateCharacterData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UpdateCharacterData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateCharacterDataResult> { Error = error, }; + return new PlayFabResult<UpdateCharacterDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateCharacterDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateCharacterDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateCharacterDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateCharacterDataResult> { Result = result }; + return new PlayFabResult<UpdateCharacterDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Validates with Amazon that the receipt for an Amazon App Store in-app purchase is valid and that it matches the purchased catalog item /// </summary> - public static async Task<PlayFabResult<ValidateAmazonReceiptResult>> ValidateAmazonIAPReceiptAsync(ValidateAmazonReceiptRequest request) + public static async Task<PlayFabResult<ValidateAmazonReceiptResult>> ValidateAmazonIAPReceiptAsync(ValidateAmazonReceiptRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/ValidateAmazonIAPReceipt", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/ValidateAmazonIAPReceipt", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ValidateAmazonReceiptResult> { Error = error, }; + return new PlayFabResult<ValidateAmazonReceiptResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ValidateAmazonReceiptResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ValidateAmazonReceiptResult>>(resultRawJson); + var result = resultData.data; - ValidateAmazonReceiptResult result = resultData.data; - - return new PlayFabResult<ValidateAmazonReceiptResult> { Result = result }; + return new PlayFabResult<ValidateAmazonReceiptResult> { Result = result, CustomData = customData }; } /// <summary> /// Accepts an open trade. If the call is successful, the offered and accepted items will be swapped between the two players' inventories. /// </summary> - public static async Task<PlayFabResult<AcceptTradeResponse>> AcceptTradeAsync(AcceptTradeRequest request) + public static async Task<PlayFabResult<AcceptTradeResponse>> AcceptTradeAsync(AcceptTradeRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/AcceptTrade", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/AcceptTrade", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AcceptTradeResponse> { Error = error, }; + return new PlayFabResult<AcceptTradeResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AcceptTradeResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - AcceptTradeResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AcceptTradeResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AcceptTradeResponse> { Result = result }; + return new PlayFabResult<AcceptTradeResponse> { Result = result, CustomData = customData }; } /// <summary> /// Cancels an open trade. /// </summary> - public static async Task<PlayFabResult<CancelTradeResponse>> CancelTradeAsync(CancelTradeRequest request) + public static async Task<PlayFabResult<CancelTradeResponse>> CancelTradeAsync(CancelTradeRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/CancelTrade", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/CancelTrade", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<CancelTradeResponse> { Error = error, }; + return new PlayFabResult<CancelTradeResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<CancelTradeResponse>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<CancelTradeResponse>>(resultRawJson); + var result = resultData.data; - CancelTradeResponse result = resultData.data; - - return new PlayFabResult<CancelTradeResponse> { Result = result }; + return new PlayFabResult<CancelTradeResponse> { Result = result, CustomData = customData }; } /// <summary> /// Gets all trades the player has either opened or accepted, optionally filtered by trade status. /// </summary> - public static async Task<PlayFabResult<GetPlayerTradesResponse>> GetPlayerTradesAsync(GetPlayerTradesRequest request) + public static async Task<PlayFabResult<GetPlayerTradesResponse>> GetPlayerTradesAsync(GetPlayerTradesRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayerTrades", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayerTrades", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerTradesResponse> { Error = error, }; + return new PlayFabResult<GetPlayerTradesResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerTradesResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerTradesResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerTradesResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerTradesResponse> { Result = result }; + return new PlayFabResult<GetPlayerTradesResponse> { Result = result, CustomData = customData }; } /// <summary> /// Gets the current status of an existing trade. /// </summary> - public static async Task<PlayFabResult<GetTradeStatusResponse>> GetTradeStatusAsync(GetTradeStatusRequest request) + public static async Task<PlayFabResult<GetTradeStatusResponse>> GetTradeStatusAsync(GetTradeStatusRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetTradeStatus", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetTradeStatus", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTradeStatusResponse> { Error = error, }; + return new PlayFabResult<GetTradeStatusResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTradeStatusResponse>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTradeStatusResponse>>(resultRawJson); + var result = resultData.data; - GetTradeStatusResponse result = resultData.data; - - return new PlayFabResult<GetTradeStatusResponse> { Result = result }; + return new PlayFabResult<GetTradeStatusResponse> { Result = result, CustomData = customData }; } /// <summary> /// Opens a new outstanding trade. /// </summary> - public static async Task<PlayFabResult<OpenTradeResponse>> OpenTradeAsync(OpenTradeRequest request) + public static async Task<PlayFabResult<OpenTradeResponse>> OpenTradeAsync(OpenTradeRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/OpenTrade", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/OpenTrade", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<OpenTradeResponse> { Error = error, }; + return new PlayFabResult<OpenTradeResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<OpenTradeResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - OpenTradeResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<OpenTradeResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<OpenTradeResponse> { Result = result }; + return new PlayFabResult<OpenTradeResponse> { Result = result, CustomData = customData }; } /// <summary> /// Attributes an install for advertisment. /// </summary> - public static async Task<PlayFabResult<AttributeInstallResult>> AttributeInstallAsync(AttributeInstallRequest request) + public static async Task<PlayFabResult<AttributeInstallResult>> AttributeInstallAsync(AttributeInstallRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/AttributeInstall", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/AttributeInstall", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AttributeInstallResult> { Error = error, }; + return new PlayFabResult<AttributeInstallResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AttributeInstallResult>>(new JsonTextReader(new StringReader(resultRawJson))); - - AttributeInstallResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AttributeInstallResult>>(resultRawJson); + var result = resultData.data; // Modify AdvertisingIdType: Prevents us from sending the id multiple times, and allows automated tests to determine id was sent successfully PlayFabSettings.AdvertisingIdType += "_Successful"; - return new PlayFabResult<AttributeInstallResult> { Result = result }; + return new PlayFabResult<AttributeInstallResult> { Result = result, CustomData = customData }; } /// <summary> /// List all segments that a player currently belongs to at this moment in time. /// </summary> - public static async Task<PlayFabResult<GetPlayerSegmentsResult>> GetPlayerSegmentsAsync(GetPlayerSegmentsRequest request) + public static async Task<PlayFabResult<GetPlayerSegmentsResult>> GetPlayerSegmentsAsync(GetPlayerSegmentsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayerSegments", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayerSegments", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerSegmentsResult> { Error = error, }; + return new PlayFabResult<GetPlayerSegmentsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerSegmentsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerSegmentsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerSegmentsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerSegmentsResult> { Result = result }; + return new PlayFabResult<GetPlayerSegmentsResult> { Result = result, CustomData = customData }; } /// <summary> /// Get all tags with a given Namespace (optional) from a player profile. /// </summary> - public static async Task<PlayFabResult<GetPlayerTagsResult>> GetPlayerTagsAsync(GetPlayerTagsRequest request) + public static async Task<PlayFabResult<GetPlayerTagsResult>> GetPlayerTagsAsync(GetPlayerTagsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayerTags", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayerTags", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerTagsResult> { Error = error, }; + return new PlayFabResult<GetPlayerTagsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerTagsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerTagsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerTagsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerTagsResult> { Result = result }; + return new PlayFabResult<GetPlayerTagsResult> { Result = result, CustomData = customData }; } - private static string _authKey = null; + private static string _authKey; // Determine if the _authKey is set, without actually making it public public static bool IsClientLoggedIn() @@ -3088,15 +2844,14 @@ private static async Task<PlayFabResult<AttributeInstallResult>> MultiStepClient { if (needsAttribution && !PlayFabSettings.DisableAdvertising && !string.IsNullOrEmpty(PlayFabSettings.AdvertisingIdType) && !string.IsNullOrEmpty(PlayFabSettings.AdvertisingIdValue)) { - AttributeInstallRequest request = new AttributeInstallRequest(); + var request = new AttributeInstallRequest(); if (PlayFabSettings.AdvertisingIdType == PlayFabSettings.AD_TYPE_IDFA) request.Idfa = PlayFabSettings.AdvertisingIdValue; else if (PlayFabSettings.AdvertisingIdType == PlayFabSettings.AD_TYPE_ANDROID_ID) request.Adid = PlayFabSettings.AdvertisingIdValue; else return null; - var output = await AttributeInstallAsync(request); - return output; + return await AttributeInstallAsync(request); } return null; } diff --git a/PlayFabClientSDK/source/PlayFabClientModels.cs b/PlayFabClientSDK/source/PlayFabClientModels.cs index 1d6970d7..28fc2e4b 100644 --- a/PlayFabClientSDK/source/PlayFabClientModels.cs +++ b/PlayFabClientSDK/source/PlayFabClientModels.cs @@ -1,12 +1,10 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; using PlayFab.Internal; using System; using System.Collections.Generic; namespace PlayFab.ClientModels { - public class AcceptTradeRequest + public class AcceptTradeRequest : PlayFabRequestCommon { /// <summary> /// Player who opened the trade. @@ -34,7 +32,7 @@ public class AcceptTradeResponse : PlayFabResultCommon } - public class AddFriendRequest + public class AddFriendRequest : PlayFabRequestCommon { /// <summary> /// PlayFab identifier of the user to attempt to add to the local user's friend list. @@ -67,7 +65,7 @@ public class AddFriendResult : PlayFabResultCommon } - public class AddGenericIDRequest + public class AddGenericIDRequest : PlayFabRequestCommon { /// <summary> /// Generic service identifier to add to the player account. @@ -80,7 +78,7 @@ public class AddGenericIDResult : PlayFabResultCommon { } - public class AddSharedGroupMembersRequest + public class AddSharedGroupMembersRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group. @@ -98,7 +96,7 @@ public class AddSharedGroupMembersResult : PlayFabResultCommon { } - public class AddUsernamePasswordRequest + public class AddUsernamePasswordRequest : PlayFabRequestCommon { /// <summary> /// PlayFab username for the account (3-20 characters) @@ -126,7 +124,7 @@ public class AddUsernamePasswordResult : PlayFabResultCommon } - public class AddUserVirtualCurrencyRequest + public class AddUserVirtualCurrencyRequest : PlayFabRequestCommon { /// <summary> /// Name of the virtual currency which is to be incremented. @@ -140,7 +138,7 @@ public class AddUserVirtualCurrencyRequest } - public class AndroidDevicePushNotificationRegistrationRequest + public class AndroidDevicePushNotificationRegistrationRequest : PlayFabRequestCommon { /// <summary> /// Registration ID provided by the Google Cloud Messaging service when the title registered to receive push notifications (see the GCM documentation, here: http://developer.android.com/google/gcm/client.html). @@ -163,7 +161,7 @@ public class AndroidDevicePushNotificationRegistrationResult : PlayFabResultComm { } - public class AttributeInstallRequest + public class AttributeInstallRequest : PlayFabRequestCommon { /// <summary> /// The IdentifierForAdvertisers for iOS Devices. @@ -187,7 +185,7 @@ public class AttributeInstallResult : PlayFabResultCommon { } - public class CancelTradeRequest + public class CancelTradeRequest : PlayFabRequestCommon { /// <summary> /// Trade identifier. @@ -341,7 +339,7 @@ public class CatalogItem : IComparable<CatalogItem> public bool IsLimitedEdition; /// <summary> - /// BETA: If IsLImitedEdition is true, then this determines amount of the item initially available. Note that this fieldis ignored if the catalog item already existed in this catalog, or the field is less than 1. + /// If IsLImitedEdition is true, then this determines amount of the item initially available. Note that this fieldis ignored if the catalog item already existed in this catalog, or the field is less than 1. /// </summary> public int InitialLimitedEditionCount; @@ -520,7 +518,7 @@ public class CollectionFilter } - public class ConfirmPurchaseRequest + public class ConfirmPurchaseRequest : PlayFabRequestCommon { /// <summary> /// Purchase order identifier returned from StartPurchase. @@ -548,7 +546,7 @@ public class ConfirmPurchaseResult : PlayFabResultCommon } - public class ConsumeItemRequest + public class ConsumeItemRequest : PlayFabRequestCommon { /// <summary> /// Unique instance identifier of the item to be consumed. @@ -593,7 +591,7 @@ public class Container_Dictionary_String_String } - public class CreateSharedGroupRequest + public class CreateSharedGroupRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group (a random identifier will be assigned, if one is not specified). @@ -778,12 +776,11 @@ public enum Currency ZWD } - public class CurrentGamesRequest + public class CurrentGamesRequest : PlayFabRequestCommon { /// <summary> /// Region to check for Game Server Instances. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Region? Region; /// <summary> @@ -831,7 +828,7 @@ public class EmptyResult : PlayFabResultCommon { } - public class ExecuteCloudScriptRequest + public class ExecuteCloudScriptRequest : PlayFabRequestCommon { /// <summary> /// The name of the CloudScript function to execute @@ -846,7 +843,6 @@ public class ExecuteCloudScriptRequest /// <summary> /// Option for which revision of the CloudScript to execute. 'Latest' executes the most recently created revision, 'Live' executes the current live, published revision, and 'Specific' executes the specified revision. The default value is 'Specific', if the SpeificRevision parameter is specified, otherwise it is 'Live'. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public CloudScriptRevisionOption? RevisionSelection; /// <summary> @@ -986,7 +982,6 @@ public class GameInfo /// <summary> /// region to which this server is associated /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Region? Region; /// <summary> @@ -1027,7 +1022,6 @@ public class GameInfo /// <summary> /// game specific string denoting server configuration /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public GameInstanceState? GameServerState; /// <summary> @@ -1045,6 +1039,16 @@ public class GameInfo /// </summary> public DateTime? LastHeartbeat; + /// <summary> + /// IP address of the server + /// </summary> + public string ServerHostname; + + /// <summary> + /// port number to use for non-http communications with the server + /// </summary> + public int? ServerPort; + } @@ -1054,7 +1058,7 @@ public enum GameInstanceState Closed } - public class GameServerRegionsRequest + public class GameServerRegionsRequest : PlayFabRequestCommon { /// <summary> /// version of game server for which stats are being requested @@ -1105,7 +1109,7 @@ public class GenericServiceId } - public class GetAccountInfoRequest + public class GetAccountInfoRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab identifier of the user whose info is being requested. Optional, defaults to the authenticated user if no other lookup identifier set. @@ -1123,7 +1127,7 @@ public class GetAccountInfoRequest public string Email; /// <summary> - /// Title-specific username for the account to find (if no Email is set). + /// Title-specific username for the account to find (if no Email is set). Note that if the non-unique Title Display Names option is enabled for the title, attempts to look up users by Title Display Name will always return AccountNotFound. /// </summary> public string TitleDisplayName; @@ -1138,7 +1142,7 @@ public class GetAccountInfoResult : PlayFabResultCommon } - public class GetCatalogItemsRequest + public class GetCatalogItemsRequest : PlayFabRequestCommon { /// <summary> /// Which catalog is being requested. If null, uses the default catalog. @@ -1157,7 +1161,7 @@ public class GetCatalogItemsResult : PlayFabResultCommon } - public class GetCharacterDataRequest + public class GetCharacterDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab identifier of the user to load data for. Optional, defaults to yourself if not set. @@ -1200,7 +1204,7 @@ public class GetCharacterDataResult : PlayFabResultCommon } - public class GetCharacterInventoryRequest + public class GetCharacterInventoryRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID for a specific character owned by a user @@ -1239,7 +1243,7 @@ public class GetCharacterInventoryResult : PlayFabResultCommon } - public class GetCharacterLeaderboardRequest + public class GetCharacterLeaderboardRequest : PlayFabRequestCommon { /// <summary> /// Optional character type on which to filter the leaderboard entries. @@ -1272,7 +1276,7 @@ public class GetCharacterLeaderboardResult : PlayFabResultCommon } - public class GetCharacterStatisticsRequest + public class GetCharacterStatisticsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID for a specific character owned by a user @@ -1290,7 +1294,7 @@ public class GetCharacterStatisticsResult : PlayFabResultCommon } - public class GetContentDownloadUrlRequest + public class GetContentDownloadUrlRequest : PlayFabRequestCommon { /// <summary> /// Key of the content item to fetch, usually formatted as a path, e.g. images/a.png @@ -1318,7 +1322,7 @@ public class GetContentDownloadUrlResult : PlayFabResultCommon } - public class GetFriendLeaderboardAroundPlayerRequest + public class GetFriendLeaderboardAroundPlayerRequest : PlayFabRequestCommon { /// <summary> /// Statistic used to rank players for this leaderboard. @@ -1356,7 +1360,7 @@ public class GetFriendLeaderboardAroundPlayerResult : PlayFabResultCommon } - public class GetFriendLeaderboardRequest + public class GetFriendLeaderboardRequest : PlayFabRequestCommon { /// <summary> /// Statistic used to rank friends for this leaderboard. @@ -1385,7 +1389,7 @@ public class GetFriendLeaderboardRequest } - public class GetFriendsListRequest + public class GetFriendsListRequest : PlayFabRequestCommon { /// <summary> /// Indicates whether Steam service friends should be included in the response. Default is true. @@ -1408,7 +1412,7 @@ public class GetFriendsListResult : PlayFabResultCommon } - public class GetLeaderboardAroundCharacterRequest + public class GetLeaderboardAroundCharacterRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title-specific statistic for the leaderboard. @@ -1441,7 +1445,7 @@ public class GetLeaderboardAroundCharacterResult : PlayFabResultCommon } - public class GetLeaderboardAroundPlayerRequest + public class GetLeaderboardAroundPlayerRequest : PlayFabRequestCommon { /// <summary> /// PlayFab unique identifier of the user to center the leaderboard around. If null will center on the logged in user. @@ -1469,7 +1473,7 @@ public class GetLeaderboardAroundPlayerResult : PlayFabResultCommon } - public class GetLeaderboardForUsersCharactersRequest + public class GetLeaderboardForUsersCharactersRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title-specific statistic for the leaderboard. @@ -1492,7 +1496,7 @@ public class GetLeaderboardForUsersCharactersResult : PlayFabResultCommon } - public class GetLeaderboardRequest + public class GetLeaderboardRequest : PlayFabRequestCommon { /// <summary> /// Statistic used to rank players for this leaderboard. @@ -1520,7 +1524,7 @@ public class GetLeaderboardResult : PlayFabResultCommon } - public class GetPhotonAuthenticationTokenRequest + public class GetPhotonAuthenticationTokenRequest : PlayFabRequestCommon { /// <summary> /// The Photon applicationId for the game you wish to log into. @@ -1538,7 +1542,7 @@ public class GetPhotonAuthenticationTokenResult : PlayFabResultCommon } - public class GetPlayerCombinedInfoRequest + public class GetPlayerCombinedInfoRequest : PlayFabRequestCommon { /// <summary> /// PlayFabId of the user whose data will be returned. If not filled included, we return the data for the calling player. @@ -1635,7 +1639,7 @@ public class GetPlayerCombinedInfoResult : PlayFabResultCommon } - public class GetPlayerCombinedInfoResultPayload : PlayFabResultCommon + public class GetPlayerCombinedInfoResultPayload { /// <summary> /// Account information for the user. This is always retrieved. @@ -1700,7 +1704,7 @@ public class GetPlayerCombinedInfoResultPayload : PlayFabResultCommon } - public class GetPlayerSegmentsRequest + public class GetPlayerSegmentsRequest : PlayFabRequestCommon { } @@ -1713,7 +1717,7 @@ public class GetPlayerSegmentsResult : PlayFabResultCommon } - public class GetPlayerStatisticsRequest + public class GetPlayerStatisticsRequest : PlayFabRequestCommon { /// <summary> /// statistics to return (current version will be returned for each) @@ -1736,7 +1740,7 @@ public class GetPlayerStatisticsResult : PlayFabResultCommon } - public class GetPlayerStatisticVersionsRequest + public class GetPlayerStatisticVersionsRequest : PlayFabRequestCommon { /// <summary> /// unique name of the statistic @@ -1754,7 +1758,7 @@ public class GetPlayerStatisticVersionsResult : PlayFabResultCommon } - public class GetPlayerTagsRequest + public class GetPlayerTagsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1782,12 +1786,11 @@ public class GetPlayerTagsResult : PlayFabResultCommon } - public class GetPlayerTradesRequest + public class GetPlayerTradesRequest : PlayFabRequestCommon { /// <summary> /// Returns only trades with the given status. If null, returns all trades. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public TradeStatus? StatusFilter; } @@ -1806,7 +1809,7 @@ public class GetPlayerTradesResponse : PlayFabResultCommon } - public class GetPlayFabIDsFromFacebookIDsRequest + public class GetPlayFabIDsFromFacebookIDsRequest : PlayFabRequestCommon { /// <summary> /// Array of unique Facebook identifiers for which the title needs to get PlayFab identifiers. @@ -1824,7 +1827,7 @@ public class GetPlayFabIDsFromFacebookIDsResult : PlayFabResultCommon } - public class GetPlayFabIDsFromGameCenterIDsRequest + public class GetPlayFabIDsFromGameCenterIDsRequest : PlayFabRequestCommon { /// <summary> /// Array of unique Game Center identifiers (the Player Identifier) for which the title needs to get PlayFab identifiers. @@ -1842,7 +1845,7 @@ public class GetPlayFabIDsFromGameCenterIDsResult : PlayFabResultCommon } - public class GetPlayFabIDsFromGenericIDsRequest + public class GetPlayFabIDsFromGenericIDsRequest : PlayFabRequestCommon { /// <summary> /// Array of unique generic service identifiers for which the title needs to get PlayFab identifiers. Currently limited to a maximum of 10 in a single request. @@ -1860,7 +1863,7 @@ public class GetPlayFabIDsFromGenericIDsResult : PlayFabResultCommon } - public class GetPlayFabIDsFromGoogleIDsRequest + public class GetPlayFabIDsFromGoogleIDsRequest : PlayFabRequestCommon { /// <summary> /// Array of unique Google identifiers (Google+ user IDs) for which the title needs to get PlayFab identifiers. @@ -1878,7 +1881,7 @@ public class GetPlayFabIDsFromGoogleIDsResult : PlayFabResultCommon } - public class GetPlayFabIDsFromKongregateIDsRequest + public class GetPlayFabIDsFromKongregateIDsRequest : PlayFabRequestCommon { /// <summary> /// Array of unique Kongregate identifiers (Kongregate's user_id) for which the title needs to get PlayFab identifiers. @@ -1896,7 +1899,7 @@ public class GetPlayFabIDsFromKongregateIDsResult : PlayFabResultCommon } - public class GetPlayFabIDsFromSteamIDsRequest + public class GetPlayFabIDsFromSteamIDsRequest : PlayFabRequestCommon { /// <summary> /// Array of unique Steam identifiers (Steam profile IDs) for which the title needs to get PlayFab identifiers. @@ -1914,7 +1917,7 @@ public class GetPlayFabIDsFromSteamIDsResult : PlayFabResultCommon } - public class GetPlayFabIDsFromTwitchIDsRequest + public class GetPlayFabIDsFromTwitchIDsRequest : PlayFabRequestCommon { /// <summary> /// Array of unique Twitch identifiers (Twitch's _id) for which the title needs to get PlayFab identifiers. @@ -1932,7 +1935,7 @@ public class GetPlayFabIDsFromTwitchIDsResult : PlayFabResultCommon } - public class GetPublisherDataRequest + public class GetPublisherDataRequest : PlayFabRequestCommon { /// <summary> /// array of keys to get back data from the Publisher data blob, set by the admin tools @@ -1950,7 +1953,7 @@ public class GetPublisherDataResult : PlayFabResultCommon } - public class GetPurchaseRequest + public class GetPurchaseRequest : PlayFabRequestCommon { /// <summary> /// Purchase order identifier. @@ -2012,7 +2015,7 @@ public class GetSegmentResult : PlayFabResultCommon } - public class GetSharedGroupDataRequest + public class GetSharedGroupDataRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group. @@ -2045,7 +2048,7 @@ public class GetSharedGroupDataResult : PlayFabResultCommon } - public class GetStoreItemsRequest + public class GetStoreItemsRequest : PlayFabRequestCommon { /// <summary> /// catalog version to store items from. Use default catalog version if null @@ -2070,7 +2073,6 @@ public class GetStoreItemsResult : PlayFabResultCommon /// <summary> /// How the store was last updated (Admin or a third party). /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public SourceType? Source; /// <summary> @@ -2090,7 +2092,7 @@ public class GetStoreItemsResult : PlayFabResultCommon } - public class GetTimeRequest + public class GetTimeRequest : PlayFabRequestCommon { } @@ -2103,7 +2105,7 @@ public class GetTimeResult : PlayFabResultCommon } - public class GetTitleDataRequest + public class GetTitleDataRequest : PlayFabRequestCommon { /// <summary> /// Specific keys to search for in the title data (leave null to get all keys) @@ -2121,7 +2123,7 @@ public class GetTitleDataResult : PlayFabResultCommon } - public class GetTitleNewsRequest + public class GetTitleNewsRequest : PlayFabRequestCommon { /// <summary> /// Limits the results to the last n entries. Defaults to 10 if not set. @@ -2139,7 +2141,7 @@ public class GetTitleNewsResult : PlayFabResultCommon } - public class GetTradeStatusRequest + public class GetTradeStatusRequest : PlayFabRequestCommon { /// <summary> /// Player who opened trade. @@ -2163,7 +2165,7 @@ public class GetTradeStatusResponse : PlayFabResultCommon } [Obsolete("No longer available", true)] - public class GetUserCombinedInfoRequest + public class GetUserCombinedInfoRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab identifier of the user whose info is being requested. Optional, defaults to the authenticated user if no other lookup identifier set. @@ -2273,7 +2275,7 @@ public class GetUserCombinedInfoResult : PlayFabResultCommon } - public class GetUserDataRequest + public class GetUserDataRequest : PlayFabRequestCommon { /// <summary> /// Specific keys to search for in the custom data. Leave null to get all keys. @@ -2306,7 +2308,7 @@ public class GetUserDataResult : PlayFabResultCommon } - public class GetUserInventoryRequest + public class GetUserInventoryRequest : PlayFabRequestCommon { } @@ -2344,7 +2346,7 @@ public class GooglePlayFabIdPair } - public class GrantCharacterToUserRequest + public class GrantCharacterToUserRequest : PlayFabRequestCommon { /// <summary> /// Catalog version from which items are to be granted. @@ -2471,7 +2473,7 @@ public int CompareTo(ItemInstance other) } - public class ItemPurchaseRequest + public class ItemPurchaseRequest : PlayFabRequestCommon { /// <summary> /// Unique ItemId of the item to purchase. @@ -2509,7 +2511,7 @@ public class KongregatePlayFabIdPair } - public class LinkAndroidDeviceIDRequest + public class LinkAndroidDeviceIDRequest : PlayFabRequestCommon { /// <summary> /// Android device identifier for the user's device. @@ -2537,7 +2539,7 @@ public class LinkAndroidDeviceIDResult : PlayFabResultCommon { } - public class LinkCustomIDRequest + public class LinkCustomIDRequest : PlayFabRequestCommon { /// <summary> /// Custom unique identifier for the user, generated by the title. @@ -2555,7 +2557,7 @@ public class LinkCustomIDResult : PlayFabResultCommon { } - public class LinkFacebookAccountRequest + public class LinkFacebookAccountRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier from Facebook for the user. @@ -2573,7 +2575,7 @@ public class LinkFacebookAccountResult : PlayFabResultCommon { } - public class LinkGameCenterAccountRequest + public class LinkGameCenterAccountRequest : PlayFabRequestCommon { /// <summary> /// Game Center identifier for the player account to be linked. @@ -2591,7 +2593,7 @@ public class LinkGameCenterAccountResult : PlayFabResultCommon { } - public class LinkGoogleAccountRequest + public class LinkGoogleAccountRequest : PlayFabRequestCommon { /// <summary> /// Unique token (https://developers.google.com/android/reference/com/google/android/gms/auth/GoogleAuthUtil#public-methods) from Google Play for the user. @@ -2609,7 +2611,7 @@ public class LinkGoogleAccountResult : PlayFabResultCommon { } - public class LinkIOSDeviceIDRequest + public class LinkIOSDeviceIDRequest : PlayFabRequestCommon { /// <summary> /// Vendor-specific iOS identifier for the user's device. @@ -2637,7 +2639,7 @@ public class LinkIOSDeviceIDResult : PlayFabResultCommon { } - public class LinkKongregateAccountRequest + public class LinkKongregateAccountRequest : PlayFabRequestCommon { /// <summary> /// Numeric user ID assigned by Kongregate @@ -2660,7 +2662,7 @@ public class LinkKongregateAccountResult : PlayFabResultCommon { } - public class LinkSteamAccountRequest + public class LinkSteamAccountRequest : PlayFabRequestCommon { /// <summary> /// Authentication token for the user, returned as a byte array from Steam, and converted to a string (for example, the byte 0x08 should become "08"). @@ -2678,7 +2680,7 @@ public class LinkSteamAccountResult : PlayFabResultCommon { } - public class LinkTwitchAccountRequest + public class LinkTwitchAccountRequest : PlayFabRequestCommon { /// <summary> /// Valid token issued by Twitch @@ -2696,7 +2698,7 @@ public class LinkTwitchAccountResult : PlayFabResultCommon { } - public class ListUsersCharactersRequest + public class ListUsersCharactersRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2748,7 +2750,7 @@ public class LoginResult : PlayFabResultCommon } - public class LoginWithAndroidDeviceIDRequest + public class LoginWithAndroidDeviceIDRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -2782,7 +2784,7 @@ public class LoginWithAndroidDeviceIDRequest } - public class LoginWithCustomIDRequest + public class LoginWithCustomIDRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -2806,7 +2808,7 @@ public class LoginWithCustomIDRequest } - public class LoginWithEmailAddressRequest + public class LoginWithEmailAddressRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -2830,7 +2832,7 @@ public class LoginWithEmailAddressRequest } - public class LoginWithFacebookRequest + public class LoginWithFacebookRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -2854,7 +2856,7 @@ public class LoginWithFacebookRequest } - public class LoginWithGameCenterRequest + public class LoginWithGameCenterRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -2878,7 +2880,7 @@ public class LoginWithGameCenterRequest } - public class LoginWithGoogleAccountRequest + public class LoginWithGoogleAccountRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -2902,7 +2904,7 @@ public class LoginWithGoogleAccountRequest } - public class LoginWithIOSDeviceIDRequest + public class LoginWithIOSDeviceIDRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -2936,7 +2938,7 @@ public class LoginWithIOSDeviceIDRequest } - public class LoginWithKongregateRequest + public class LoginWithKongregateRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -2965,7 +2967,7 @@ public class LoginWithKongregateRequest } - public class LoginWithPlayFabRequest + public class LoginWithPlayFabRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -2989,7 +2991,7 @@ public class LoginWithPlayFabRequest } - public class LoginWithSteamRequest + public class LoginWithSteamRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -3013,7 +3015,7 @@ public class LoginWithSteamRequest } - public class LoginWithTwitchRequest + public class LoginWithTwitchRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -3053,7 +3055,7 @@ public class LogStatement } - public class MatchmakeRequest + public class MatchmakeRequest : PlayFabRequestCommon { /// <summary> /// Build version to match against. [Note: Required if LobbyId is not specified] @@ -3063,7 +3065,6 @@ public class MatchmakeRequest /// <summary> /// Region to match make against. [Note: Required if LobbyId is not specified] /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Region? Region; /// <summary> @@ -3133,7 +3134,6 @@ public class MatchmakeResult : PlayFabResultCommon /// <summary> /// result of match making process /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public MatchmakeStatus? Status; } @@ -3172,7 +3172,7 @@ public class ModifyUserVirtualCurrencyResult : PlayFabResultCommon } - public class OpenTradeRequest + public class OpenTradeRequest : PlayFabRequestCommon { /// <summary> /// Player inventory items offered for trade. If not set, the trade is effectively a gift request @@ -3200,7 +3200,7 @@ public class OpenTradeResponse : PlayFabResultCommon } - public class PayForPurchaseRequest + public class PayForPurchaseRequest : PlayFabRequestCommon { /// <summary> /// Purchase order identifier returned from StartPurchase. @@ -3234,7 +3234,6 @@ public class PayForPurchaseResult : PlayFabResultCommon /// <summary> /// Status of the transaction. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public TransactionStatus? Status; /// <summary> @@ -3361,7 +3360,7 @@ public class PlayerStatisticVersion } - public class PurchaseItemRequest + public class PurchaseItemRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier of the item to purchase. @@ -3404,7 +3403,7 @@ public class PurchaseItemResult : PlayFabResultCommon } - public class RedeemCouponRequest + public class RedeemCouponRequest : PlayFabRequestCommon { /// <summary> /// Generated coupon code to redeem. @@ -3416,6 +3415,11 @@ public class RedeemCouponRequest /// </summary> public string CatalogVersion; + /// <summary> + /// Optional identifier for the Character that should receive the item. If null, item is added to the player + /// </summary> + public string CharacterId; + } public class RedeemCouponResult : PlayFabResultCommon @@ -3444,7 +3448,6 @@ public class RegionInfo /// <summary> /// unique identifier for the region /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Region? Region; /// <summary> @@ -3464,7 +3467,7 @@ public class RegionInfo } - public class RegisterForIOSPushNotificationRequest + public class RegisterForIOSPushNotificationRequest : PlayFabRequestCommon { /// <summary> /// Unique token generated by the Apple Push Notification service when the title registered to receive push notifications. @@ -3487,7 +3490,7 @@ public class RegisterForIOSPushNotificationResult : PlayFabResultCommon { } - public class RegisterPlayFabUserRequest + public class RegisterPlayFabUserRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -3545,7 +3548,7 @@ public class RegisterPlayFabUserResult : PlayFabResultCommon } - public class RemoveFriendRequest + public class RemoveFriendRequest : PlayFabRequestCommon { /// <summary> /// PlayFab identifier of the friend account which is to be removed. @@ -3558,7 +3561,7 @@ public class RemoveFriendResult : PlayFabResultCommon { } - public class RemoveGenericIDRequest + public class RemoveGenericIDRequest : PlayFabRequestCommon { /// <summary> /// Generic service identifier to be removed from the player. @@ -3571,7 +3574,7 @@ public class RemoveGenericIDResult : PlayFabResultCommon { } - public class RemoveSharedGroupMembersRequest + public class RemoveSharedGroupMembersRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group. @@ -3589,7 +3592,7 @@ public class RemoveSharedGroupMembersResult : PlayFabResultCommon { } - public class ReportPlayerClientRequest + public class ReportPlayerClientRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab identifier of the reported player. @@ -3617,7 +3620,7 @@ public class ReportPlayerClientResult : PlayFabResultCommon } - public class RestoreIOSPurchasesRequest + public class RestoreIOSPurchasesRequest : PlayFabRequestCommon { /// <summary> /// Base64 encoded receipt data, passed back by the App Store as a result of a successful purchase. @@ -3649,7 +3652,7 @@ public class ScriptExecutionError } - public class SendAccountRecoveryEmailRequest + public class SendAccountRecoveryEmailRequest : PlayFabRequestCommon { /// <summary> /// User email address attached to their account @@ -3667,7 +3670,7 @@ public class SendAccountRecoveryEmailResult : PlayFabResultCommon { } - public class SetFriendTagsRequest + public class SetFriendTagsRequest : PlayFabRequestCommon { /// <summary> /// PlayFab identifier of the friend account to which the tag(s) should be applied. @@ -3705,7 +3708,6 @@ public class SharedGroupDataRecord /// <summary> /// Indicates whether this data can be read by all users (public) or only members of the group (private). /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -3720,7 +3722,7 @@ public enum SourceType Partner } - public class StartGameRequest + public class StartGameRequest : PlayFabRequestCommon { /// <summary> /// version information for the build of the game server which is to be started @@ -3730,7 +3732,6 @@ public class StartGameRequest /// <summary> /// the region to associate this server with for match filtering /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Region Region; /// <summary> @@ -3789,7 +3790,7 @@ public class StartGameResult : PlayFabResultCommon } - public class StartPurchaseRequest + public class StartPurchaseRequest : PlayFabRequestCommon { /// <summary> /// Catalog version for the items to be purchased. Defaults to most recent catalog. @@ -3959,7 +3960,7 @@ public class StoreMarketingModel } - public class SubtractUserVirtualCurrencyRequest + public class SubtractUserVirtualCurrencyRequest : PlayFabRequestCommon { /// <summary> /// Name of the virtual currency which is to be decremented. @@ -4012,7 +4013,6 @@ public class TradeInfo /// <summary> /// Describes the current state of this trade. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public TradeStatus? Status; /// <summary> @@ -4128,7 +4128,7 @@ public class TwitchPlayFabIdPair } - public class UnlinkAndroidDeviceIDRequest + public class UnlinkAndroidDeviceIDRequest : PlayFabRequestCommon { /// <summary> /// Android device identifier for the user's device. If not specified, the most recently signed in Android Device ID will be used. @@ -4141,7 +4141,7 @@ public class UnlinkAndroidDeviceIDResult : PlayFabResultCommon { } - public class UnlinkCustomIDRequest + public class UnlinkCustomIDRequest : PlayFabRequestCommon { /// <summary> /// Custom unique identifier for the user, generated by the title. If not specified, the most recently signed in Custom ID will be used. @@ -4154,7 +4154,7 @@ public class UnlinkCustomIDResult : PlayFabResultCommon { } - public class UnlinkFacebookAccountRequest + public class UnlinkFacebookAccountRequest : PlayFabRequestCommon { } @@ -4162,7 +4162,7 @@ public class UnlinkFacebookAccountResult : PlayFabResultCommon { } - public class UnlinkGameCenterAccountRequest + public class UnlinkGameCenterAccountRequest : PlayFabRequestCommon { } @@ -4170,7 +4170,7 @@ public class UnlinkGameCenterAccountResult : PlayFabResultCommon { } - public class UnlinkGoogleAccountRequest + public class UnlinkGoogleAccountRequest : PlayFabRequestCommon { } @@ -4178,7 +4178,7 @@ public class UnlinkGoogleAccountResult : PlayFabResultCommon { } - public class UnlinkIOSDeviceIDRequest + public class UnlinkIOSDeviceIDRequest : PlayFabRequestCommon { /// <summary> /// Vendor-specific iOS identifier for the user's device. If not specified, the most recently signed in iOS Device ID will be used. @@ -4191,7 +4191,7 @@ public class UnlinkIOSDeviceIDResult : PlayFabResultCommon { } - public class UnlinkKongregateAccountRequest + public class UnlinkKongregateAccountRequest : PlayFabRequestCommon { } @@ -4199,7 +4199,7 @@ public class UnlinkKongregateAccountResult : PlayFabResultCommon { } - public class UnlinkSteamAccountRequest + public class UnlinkSteamAccountRequest : PlayFabRequestCommon { } @@ -4207,7 +4207,7 @@ public class UnlinkSteamAccountResult : PlayFabResultCommon { } - public class UnlinkTwitchAccountRequest + public class UnlinkTwitchAccountRequest : PlayFabRequestCommon { } @@ -4215,7 +4215,7 @@ public class UnlinkTwitchAccountResult : PlayFabResultCommon { } - public class UnlockContainerInstanceRequest + public class UnlockContainerInstanceRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID for a specific character owned by a user @@ -4239,7 +4239,7 @@ public class UnlockContainerInstanceRequest } - public class UnlockContainerItemRequest + public class UnlockContainerItemRequest : PlayFabRequestCommon { /// <summary> /// Catalog ItemId of the container type to unlock. @@ -4282,7 +4282,7 @@ public class UnlockContainerItemResult : PlayFabResultCommon } - public class UpdateCharacterDataRequest + public class UpdateCharacterDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID for a specific character owned by a user @@ -4302,7 +4302,6 @@ public class UpdateCharacterDataRequest /// <summary> /// Permission to be applied to all user data keys written in this request. Defaults to "private" if not set. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -4316,7 +4315,7 @@ public class UpdateCharacterDataResult : PlayFabResultCommon } - public class UpdateCharacterStatisticsRequest + public class UpdateCharacterStatisticsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID for a specific character owned by a user @@ -4334,7 +4333,7 @@ public class UpdateCharacterStatisticsResult : PlayFabResultCommon { } - public class UpdatePlayerStatisticsRequest + public class UpdatePlayerStatisticsRequest : PlayFabRequestCommon { /// <summary> /// Statistics to be updated with the provided values @@ -4347,7 +4346,7 @@ public class UpdatePlayerStatisticsResult : PlayFabResultCommon { } - public class UpdateSharedGroupDataRequest + public class UpdateSharedGroupDataRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group. @@ -4367,7 +4366,6 @@ public class UpdateSharedGroupDataRequest /// <summary> /// Permission to be applied to all user data keys in this request. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -4376,7 +4374,7 @@ public class UpdateSharedGroupDataResult : PlayFabResultCommon { } - public class UpdateUserDataRequest + public class UpdateUserDataRequest : PlayFabRequestCommon { /// <summary> /// Key-value pairs to be written to the custom data. Note that keys are trimmed of whitespace, are limited in size, and may not begin with a '!' character. @@ -4391,7 +4389,6 @@ public class UpdateUserDataRequest /// <summary> /// Permission to be applied to all user data keys written in this request. Defaults to "private" if not set. This is used for requests by one player for information about another player; those requests will only return Public keys. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -4405,7 +4402,7 @@ public class UpdateUserDataResult : PlayFabResultCommon } - public class UpdateUserTitleDisplayNameRequest + public class UpdateUserTitleDisplayNameRequest : PlayFabRequestCommon { /// <summary> /// New title display name for the user - must be between 3 and 25 characters. @@ -4550,7 +4547,6 @@ public class UserDataRecord /// <summary> /// Indicates whether this data can be read by all users (public) or only the user (private). This is used for GetUserData requests being made by one player about another player. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -4694,13 +4690,11 @@ public class UserSteamInfo /// <summary> /// currency type set in the user Steam account /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Currency? SteamCurrency; /// <summary> /// what stage of game ownership the user is listed as being in, from Steam /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public TitleActivationStatus? SteamActivationStatus; } @@ -4715,7 +4709,6 @@ public class UserTitleInfo /// <summary> /// source by which the user first joined the game, if known /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserOrigination? Origination; /// <summary> @@ -4763,7 +4756,7 @@ public class UserXboxInfo } - public class ValidateAmazonReceiptRequest + public class ValidateAmazonReceiptRequest : PlayFabRequestCommon { /// <summary> /// ReceiptId returned by the Amazon App Store in-app purchase API @@ -4796,7 +4789,7 @@ public class ValidateAmazonReceiptResult : PlayFabResultCommon { } - public class ValidateGooglePlayPurchaseRequest + public class ValidateGooglePlayPurchaseRequest : PlayFabRequestCommon { /// <summary> /// Original JSON string returned by the Google Play IAB API. @@ -4824,7 +4817,7 @@ public class ValidateGooglePlayPurchaseResult : PlayFabResultCommon { } - public class ValidateIOSReceiptRequest + public class ValidateIOSReceiptRequest : PlayFabRequestCommon { /// <summary> /// Base64 encoded receipt data, passed back by the App Store as a result of a successful purchase. @@ -4866,7 +4859,7 @@ public class VirtualCurrencyRechargeTime } - public class WriteClientCharacterEventRequest + public class WriteClientCharacterEventRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID for a specific character owned by a user @@ -4890,7 +4883,7 @@ public class WriteClientCharacterEventRequest } - public class WriteClientPlayerEventRequest + public class WriteClientPlayerEventRequest : PlayFabRequestCommon { /// <summary> /// The name of the event, within the namespace scoped to the title. The naming convention is up to the caller, but it commonly follows the subject_verb_object pattern (e.g. player_logged_in). @@ -4912,13 +4905,13 @@ public class WriteClientPlayerEventRequest public class WriteEventResponse : PlayFabResultCommon { /// <summary> - /// The unique identifier of the event. This can be used to retrieve the event's properties using the GetEvent API. The values of this identifier consist of ASCII characters and are not constrained to any particular format. + /// The unique identifier of the event. The values of this identifier consist of ASCII characters and are not constrained to any particular format. /// </summary> public string EventId; } - public class WriteTitleEventRequest + public class WriteTitleEventRequest : PlayFabRequestCommon { /// <summary> /// The name of the event, within the namespace scoped to the title. The naming convention is up to the caller, but it commonly follows the subject_verb_object pattern (e.g. player_logged_in). diff --git a/PlayFabClientSDK/source/PlayFabErrors.cs b/PlayFabClientSDK/source/PlayFabErrors.cs index 20cb9c0d..189cd3ff 100644 --- a/PlayFabClientSDK/source/PlayFabErrors.cs +++ b/PlayFabClientSDK/source/PlayFabErrors.cs @@ -1,5 +1,6 @@ using PlayFab.Internal; using System.Collections.Generic; +using System.Text; namespace PlayFab { @@ -259,7 +260,11 @@ public enum PlayFabErrorCode ScheduledTaskCreateConflict = 1255, InvalidScheduledTaskName = 1256, InvalidTaskSchedule = 1257, - SteamNotEnabledForTitle = 1258 + SteamNotEnabledForTitle = 1258, + LimitNotAnUpgradeOption = 1259, + NoSecretKeyEnabledForCloudScript = 1260, + TaskNotFound = 1261, + TaskInstanceNotFound = 1262 } public class PlayFabError @@ -269,12 +274,30 @@ public class PlayFabError public PlayFabErrorCode Error; public string ErrorMessage; public Dictionary<string, string[] > ErrorDetails; + + private static readonly StringBuilder Sb = new StringBuilder(); + public string GenerateErrorReport() + { + Sb.Length = 0; + if (ErrorMessage != null) + Sb.Append(ErrorMessage); + if (ErrorDetails == null) + return Sb.ToString(); + + foreach (var pair in ErrorDetails) + { + foreach (var eachMsg in pair.Value) + Sb.Append(pair.Key).Append(": ").Append(eachMsg); + } + return Sb.ToString(); + } }; public class PlayFabResult<TResult> where TResult : PlayFabResultCommon { public PlayFabError Error; public TResult Result; + public object CustomData; } public delegate void ErrorCallback(PlayFabError error); diff --git a/PlayFabClientSDK/source/PlayFabFileUtil.cs b/PlayFabClientSDK/source/PlayFabFileUtil.cs new file mode 100644 index 00000000..598d875f --- /dev/null +++ b/PlayFabClientSDK/source/PlayFabFileUtil.cs @@ -0,0 +1,71 @@ +#if XAMARIN + +using PlayFab.Json; +using System; +using System.IO; +using System.Text; +using System.Threading.Tasks; + +namespace PlayFab +{ + public static partial class PlayFabUtil + { +#if !NETFX_CORE + [ThreadStatic] + private static StringBuilder _sb; + /// <summary> + /// A threadsafe way to block and load a text file + /// + /// Load a text file, and return the file as text. + /// Used for small (usually json) files. + /// </summary> + public static string ReadAllFileText(string filename) + { + if (!File.Exists(filename)) + return ""; + + if (_sb == null) + _sb = new StringBuilder(); + _sb.Length = 0; + + var fs = new FileStream(filename, FileMode.Open); + var br = new BinaryReader(fs); + while (br.BaseStream.Position != br.BaseStream.Length) + _sb.Append(br.ReadChar()); + + return _sb.ToString(); + } +#else + public static string ReadAllFileText(string filename) + { + var task = ReadAllFileTextAsync(filename); + + var output = ""; + try + { + output = task.Result; + } + catch (AggregateException agEx) + { + foreach (var eachEx in agEx.InnerExceptions) + { + System.Diagnostics.Debug.WriteLine("Each Exception:"); + System.Diagnostics.Debug.WriteLine(eachEx.Message); + } + } + + return output; + } + + public static async Task<string> ReadAllFileTextAsync(string fullpath) + { + var foldername = Path.GetDirectoryName(fullpath); + var filename = Path.GetFileName(fullpath); + var folder = await Windows.Storage.StorageFolder.GetFolderFromPathAsync(foldername); + var file = await folder.GetFileAsync(filename); + return await Windows.Storage.FileIO.ReadTextAsync(file); + } +#endif + } +} +#endif diff --git a/PlayFabClientSDK/source/PlayFabHttp/IPlayFabHttp.cs b/PlayFabClientSDK/source/PlayFabHttp/IPlayFabHttp.cs new file mode 100644 index 00000000..a83051f7 --- /dev/null +++ b/PlayFabClientSDK/source/PlayFabHttp/IPlayFabHttp.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace PlayFab.Internal +{ + public interface IPlayFabHttp + { + Task<object> DoPost(string urlPath, PlayFabRequestCommon request, string authType, string authKey); + } +} diff --git a/PlayFabClientSDK/source/PlayFabHttp/PlayFabHttp.cs b/PlayFabClientSDK/source/PlayFabHttp/PlayFabHttp.cs new file mode 100644 index 00000000..b4014a05 --- /dev/null +++ b/PlayFabClientSDK/source/PlayFabHttp/PlayFabHttp.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace PlayFab.Internal +{ + /// <summary> + /// This is a base-class for all Api-request objects. + /// It is currently unfinished, but we will add result-specific properties, + /// and add template where-conditions to make some code easier to follow + /// </summary> + public class PlayFabRequestCommon + { + } + + /// <summary> + /// This is a base-class for all Api-result objects. + /// It is currently unfinished, but we will add result-specific properties, + /// and add template where-conditions to make some code easier to follow + /// </summary> + public class PlayFabResultCommon + { + } + + public class PlayFabJsonError + { + public int code; + public string status; + public string error; + public int errorCode; + public string errorMessage; + public Dictionary<string, string[]> errorDetails = null; + } + + public class PlayFabJsonSuccess<TResult> where TResult : PlayFabResultCommon + { + public int code; + public string status; + public TResult data; + } + + public static class PlayFabHttp + { + private static IPlayFabHttp _http; + + static PlayFabHttp() + { + var httpInterfaceType = typeof(IPlayFabHttp); + var types = typeof(PlayFabHttp).GetAssembly().GetTypes(); + foreach (var eachType in types) + { + if (httpInterfaceType.IsAssignableFrom(eachType) && !eachType.IsAbstract) + { + _http = (IPlayFabHttp)Activator.CreateInstance(eachType.AsType()); + return; + } + } + throw new Exception("Cannot find a valid IPlayFabHttp type"); + } + + public static async Task<object> DoPost(string urlPath, PlayFabRequestCommon request, string authType, string authKey) + { + if (PlayFabSettings.TitleId == null) + throw new Exception("You must set your titleId before making an api call"); + return await _http.DoPost(urlPath, request, authType, authKey); + } + } +} diff --git a/PlayFabClientSDK/source/PlayFabHttp/PlayFabSysHttp.cs b/PlayFabClientSDK/source/PlayFabHttp/PlayFabSysHttp.cs new file mode 100644 index 00000000..6203261d --- /dev/null +++ b/PlayFabClientSDK/source/PlayFabHttp/PlayFabSysHttp.cs @@ -0,0 +1,107 @@ +#if !NETFX_CORE || !XAMARIN + +using System; +using System.IO; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using PlayFab.Json; + +namespace PlayFab.Internal +{ + public class PlayFabSysHttp : IPlayFabHttp + { + public async Task<object> DoPost(string urlPath, PlayFabRequestCommon request, string authType, string authKey) + { + var fullUrl = PlayFabSettings.GetFullUrl(urlPath); + string bodyString; + + if (request == null) + { + bodyString = "{}"; + } + else + { + bodyString = JsonWrapper.SerializeObject(request); + } + + var client = new HttpClient(); + HttpResponseMessage httpResponse; + string httpResponseString; + using (var postBody = new ByteArrayContent(Encoding.UTF8.GetBytes(bodyString))) + { + postBody.Headers.Add("Content-Type", "application/json"); + if (authType != null) + postBody.Headers.Add(authType, authKey); + postBody.Headers.Add("X-PlayFabSDK", PlayFabSettings.SdkVersionString); + + try + { + httpResponse = await client.PostAsync(fullUrl, postBody); + httpResponseString = await httpResponse.Content.ReadAsStringAsync(); + } + catch (HttpRequestException e) + { + return new PlayFabError + { + Error = PlayFabErrorCode.ConnectionError, + ErrorMessage = e.InnerException.Message + }; + } + catch (Exception e) + { + return new PlayFabError + { + Error = PlayFabErrorCode.ConnectionError, + ErrorMessage = e.Message + }; + } + } + + if (!httpResponse.IsSuccessStatusCode) + { + var error = new PlayFabError(); + + if (string.IsNullOrEmpty(httpResponseString) || httpResponse.StatusCode == System.Net.HttpStatusCode.NotFound) + { + error.HttpCode = (int)httpResponse.StatusCode; + error.HttpStatus = httpResponse.StatusCode.ToString(); + return error; + } + + PlayFabJsonError errorResult; + try + { + errorResult = JsonWrapper.DeserializeObject<PlayFabJsonError>(httpResponseString); + } + catch (Exception e) + { + error.HttpCode = (int)httpResponse.StatusCode; + error.HttpStatus = httpResponse.StatusCode.ToString(); + error.Error = PlayFabErrorCode.JsonParseError; + error.ErrorMessage = e.Message; + return error; + } + + error.HttpCode = errorResult.code; + error.HttpStatus = errorResult.status; + error.Error = (PlayFabErrorCode)errorResult.errorCode; + error.ErrorMessage = errorResult.errorMessage; + error.ErrorDetails = errorResult.errorDetails; + return error; + } + + if (string.IsNullOrEmpty(httpResponseString)) + { + return new PlayFabError + { + Error = PlayFabErrorCode.Unknown, + ErrorMessage = "Internal server error" + }; + } + + return httpResponseString; + } + } +} +#endif diff --git a/PlayFabClientSDK/source/PlayFabHttp/PlayFabWinHttp.cs b/PlayFabClientSDK/source/PlayFabHttp/PlayFabWinHttp.cs new file mode 100644 index 00000000..cab057c5 --- /dev/null +++ b/PlayFabClientSDK/source/PlayFabHttp/PlayFabWinHttp.cs @@ -0,0 +1,96 @@ +#if NETFX_CORE && XAMARIN + +using PlayFab.Json; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Windows.Web.Http; + +namespace PlayFab.Internal +{ + public class PlayFabWinHttp : IPlayFabHttp + { + public async Task<object> DoPost(string urlPath, PlayFabRequestCommon request, string authType, string authKey) + { + var fullUrl = PlayFabSettings.GetFullUrl(urlPath); + string bodyString; + + if (request == null) + { + bodyString = "{}"; + } + else + { + bodyString = JsonWrapper.SerializeObject(request); + } + + var httpClient = new HttpClient(); + var requestMessage = new HttpRequestMessage(HttpMethod.Post, new Uri(fullUrl)); + requestMessage.Content = new HttpStringContent(bodyString, Windows.Storage.Streams.UnicodeEncoding.Utf8, "application/json"); + if (authType != null) + requestMessage.Headers.Add(new KeyValuePair<string, string>(authType, authKey)); + requestMessage.Headers.Add(new KeyValuePair<string, string>("X-PlayFabSDK", PlayFabSettings.SdkVersionString)); + + HttpResponseMessage httpResponse; + string httpResponseString; + try + { + httpResponse = await httpClient.SendRequestAsync(requestMessage); + httpResponseString = await httpResponse.Content.ReadAsStringAsync(); + } + catch (Exception e) + { + return new PlayFabError + { + Error = PlayFabErrorCode.ConnectionError, + ErrorMessage = e.Message + }; + } + + if (!httpResponse.IsSuccessStatusCode) + { + var error = new PlayFabError(); + + if (string.IsNullOrEmpty(httpResponseString) || httpResponse.StatusCode == HttpStatusCode.NotFound) + { + error.HttpCode = (int)httpResponse.StatusCode; + error.HttpStatus = httpResponse.StatusCode.ToString(); + return error; + } + + PlayFabJsonError errorResult; + try + { + errorResult = JsonWrapper.DeserializeObject<PlayFabJsonError>(httpResponseString); + } + catch (Exception e) + { + error.HttpCode = (int)httpResponse.StatusCode; + error.HttpStatus = httpResponse.StatusCode.ToString(); + error.Error = PlayFabErrorCode.JsonParseError; + error.ErrorMessage = e.Message; + return error; + } + + error.HttpCode = errorResult.code; + error.HttpStatus = errorResult.status; + error.Error = (PlayFabErrorCode)errorResult.errorCode; + error.ErrorMessage = errorResult.errorMessage; + error.ErrorDetails = errorResult.errorDetails; + return error; + } + + if (string.IsNullOrEmpty(httpResponseString)) + { + return new PlayFabError + { + Error = PlayFabErrorCode.Unknown, + ErrorMessage = "Internal server error" + }; + } + + return httpResponseString; + } + } +} +#endif diff --git a/PlayFabClientSDK/source/PlayFabSettings.cs b/PlayFabClientSDK/source/PlayFabSettings.cs index c1203bc1..4b7ba65d 100644 --- a/PlayFabClientSDK/source/PlayFabSettings.cs +++ b/PlayFabClientSDK/source/PlayFabSettings.cs @@ -1,13 +1,11 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; namespace PlayFab { public class PlayFabSettings { - public const string SdkVersion = "0.40.161017"; + public const string SdkVersion = "1.0.161107"; public const string BuildIdentifier = "jbuild_csharpsdk_1"; - public const string SdkVersionString = "CSharpSDK-0.40.161017"; + public const string SdkVersionString = "CSharpSDK-1.0.161107"; /// <summary> This is for PlayFab internal debugging. Generally you shouldn't touch this </summary> public static bool UseDevelopmentEnvironment = false; @@ -33,7 +31,7 @@ public class PlayFabSettings public static string GetFullUrl(string apiCall) { - string baseUrl = UseDevelopmentEnvironment ? DevelopmentEnvironmentUrl : ProductionEnvironmentUrl; + var baseUrl = UseDevelopmentEnvironment ? DevelopmentEnvironmentUrl : ProductionEnvironmentUrl; if (baseUrl.StartsWith("http")) return baseUrl; return "https://" + TitleId + baseUrl + apiCall; diff --git a/PlayFabClientSDK/source/PlayFabUtil.cs b/PlayFabClientSDK/source/PlayFabUtil.cs index e4a9d64b..c28ea6d6 100644 --- a/PlayFabClientSDK/source/PlayFabUtil.cs +++ b/PlayFabClientSDK/source/PlayFabUtil.cs @@ -1,7 +1,8 @@ +using PlayFab.Json; using System; +using System.IO; using System.Text; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; +using System.Threading.Tasks; using PlayFab.ClientModels; namespace PlayFab @@ -19,7 +20,7 @@ public Unordered(string sortProperty) } } - public static class PlayFabUtil + public static partial class PlayFabUtil { public static readonly string[] DefaultDateTimeFormats = { // All parseable ISO 8601 formats for DateTime.[Try]ParseExact - Lets us deserialize any legacy timestamps in one of these formats // These are the standard format with ISO 8601 UTC markers (T/Z) @@ -38,32 +39,13 @@ public static class PlayFabUtil }; public const int DEFAULT_UTC_OUTPUT_INDEX = 2; // The default format everybody should use public const int DEFAULT_LOCAL_OUTPUT_INDEX = 7; // The default format if you want to use local time (This doesn't have universal support in all PlayFab code) - public static JsonSerializerSettings JsonSettings = new JsonSerializerSettings - { - NullValueHandling = NullValueHandling.Ignore, - Converters = { new IsoDateTimeConverter { DateTimeFormat = DefaultDateTimeFormats[0] } }, - }; - public static Formatting JsonFormatting = Formatting.None; - private static readonly StringBuilder Sb = new StringBuilder(); public static string GetErrorReport(PlayFabError error) { - if (error == null) - return null; - Sb.Length = 0; - if (error.ErrorMessage != null) - Sb.Append(error.ErrorMessage); - if (error.ErrorDetails == null) - return Sb.ToString(); - - foreach (var pair in error.ErrorDetails) - { - foreach (var eachMsg in pair.Value) - Sb.Append(pair.Key).Append(": ").Append(eachMsg); - } - return Sb.ToString(); + return error?.GenerateErrorReport(); } + private static readonly StringBuilder Sb = new StringBuilder(); public static string GetCloudScriptErrorReport(PlayFabResult<ExecuteCloudScriptResult> result) { if (result.Error != null) @@ -89,28 +71,9 @@ public static string GetCloudScriptErrorReport(PlayFabResult<ExecuteCloudScriptR if (!string.IsNullOrEmpty(eachLog.Message)) Sb.Append(" - ").Append(eachLog.Message); if (eachLog.Data != null) - Sb.Append("\n").Append(JsonConvert.SerializeObject(eachLog.Data, Formatting.Indented)); + Sb.Append("\n").Append(JsonWrapper.SerializeObject(eachLog.Data)); } return Sb.ToString(); } - - public class TimeSpanFloatSeconds : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - var timeSpan = (TimeSpan)value; - serializer.Serialize(writer, timeSpan.TotalSeconds); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - return TimeSpan.FromSeconds(serializer.Deserialize<float>(reader)); - } - - public override bool CanConvert(Type objectType) - { - return objectType == typeof(TimeSpan); - } - } } } diff --git a/PlayFabClientSDK/source/Uunit/PlayFabApiTest.cs b/PlayFabClientSDK/source/Uunit/PlayFabApiTest.cs new file mode 100644 index 00000000..14b0a3e3 --- /dev/null +++ b/PlayFabClientSDK/source/Uunit/PlayFabApiTest.cs @@ -0,0 +1,431 @@ +#if !DISABLE_PLAYFABCLIENT_API + +using PlayFab.ClientModels; +using PlayFab.Internal; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using PlayFab.Json; + +namespace PlayFab.UUnit +{ + /// <summary> + /// A real system would potentially run only the client or server API, and not both. + /// But, they still interact with eachother directly. + /// The tests can't be independent for Client/Server, as the sequence of calls isn't really independent for real-world scenarios. + /// The client logs in, which triggers a server, and then back and forth. + /// For the purpose of testing, they each have pieces of information they share with one another, and that sharing makes various calls possible. + /// </summary> + public class PlayFabApiTest : UUnitTestCase + { + private const string TEST_STAT_NAME = "str"; + private const string TEST_DATA_KEY = "testCounter"; + + private int _testInteger; + + // Functional + private static bool TITLE_INFO_SET = false; + + // Fixed values provided from testInputs + private static string USER_EMAIL; + + // Information fetched by appropriate API calls + public static string PlayFabId; + + // Performance + [ThreadStatic] + private static StringBuilder _sb; + + /// <summary> + /// PlayFab Title cannot be created from SDK tests, so you must provide your titleId to run unit tests. + /// (Also, we don't want lots of excess unused titles) + /// </summary> + public static void SetTitleInfo(Dictionary<string, string> testInputs) + { + string eachValue; + + TITLE_INFO_SET = true; + + // Parse all the inputs + TITLE_INFO_SET &= testInputs.TryGetValue("titleId", out eachValue); + PlayFabSettings.TitleId = eachValue; + + TITLE_INFO_SET &= testInputs.TryGetValue("userEmail", out USER_EMAIL); + + // Verify all the inputs won't cause crashes in the tests + TITLE_INFO_SET &= !string.IsNullOrEmpty(PlayFabSettings.TitleId) + && !string.IsNullOrEmpty(USER_EMAIL); + } + + public override void SetUp(UUnitTestContext testContext) + { + if (!TITLE_INFO_SET) + testContext.Skip(); // We cannot do client tests if the titleId is not given + } + + public override void Tick(UUnitTestContext testContext) + { + // No work needed, async tests will end themselves + } + + public override void TearDown(UUnitTestContext testContext) + { + } + + private static void ContinueWithContext<T>(Task<PlayFabResult<T>> srcTask, UUnitTestContext testContext, Action<PlayFabResult<T>, UUnitTestContext, string> continueAction, bool expectSuccess, string failMessage, bool endTest) where T : PlayFabResultCommon + { + srcTask.ContinueWith(task => + { + var failed = true; + try + { + if (expectSuccess) + { + testContext.NotNull(task.Result, failMessage); + testContext.IsNull(task.Result.Error, PlayFabUtil.GetErrorReport(task.Result.Error)); + testContext.NotNull(task.Result.Result, failMessage); + } + continueAction?.Invoke(task.Result, testContext, failMessage); + failed = false; + } + catch (UUnitSkipException uu) + { + // Silence the assert and ensure the test is marked as complete - The exception is just to halt the test process + testContext.EndTest(UUnitFinishState.SKIPPED, uu.Message); + } + catch (UUnitException uu) + { + // Silence the assert and ensure the test is marked as complete - The exception is just to halt the test process + testContext.EndTest(UUnitFinishState.FAILED, uu.Message + "\n" + uu.StackTrace); + } + catch (Exception e) + { + // Report this exception as an unhandled failure in the test + testContext.EndTest(UUnitFinishState.FAILED, e.ToString()); + } + if (!failed && endTest) + testContext.EndTest(UUnitFinishState.PASSED, null); + } + ); + } + + private static string CompileErrorReport(PlayFabError error) + { + if (_sb == null) + _sb = new StringBuilder(); + _sb.Length = 0; + _sb.Append(error.ErrorMessage); + foreach (var detailPair in error.ErrorDetails) + foreach (var msg in detailPair.Value) + _sb.Append("\n").Append(detailPair.Key).Append(": ").Append(msg); + return _sb.ToString(); + } + + /// <summary> + /// CLIENT API + /// Try to deliberately log in with an inappropriate password, + /// and verify that the error displays as expected. + /// </summary> + [UUnitTest] + public void InvalidLogin(UUnitTestContext testContext) + { + // If the setup failed to log in a user, we need to create one. + var request = new LoginWithEmailAddressRequest + { + TitleId = PlayFabSettings.TitleId, + Email = USER_EMAIL, + Password = "INVALID", + }; + var loginTask = PlayFabClientAPI.LoginWithEmailAddressAsync(request); + ContinueWithContext(loginTask, testContext, InvalidLoginContinued, false, "Login should fail", true); + } + private void InvalidLoginContinued(PlayFabResult<LoginResult> loginResult, UUnitTestContext testContext, string failMessage) + { + testContext.NotNull(loginResult, failMessage); + testContext.IsNull(loginResult.Result, failMessage); + testContext.NotNull(loginResult.Error, failMessage); + testContext.True(loginResult.Error.ErrorMessage.Contains("password"), loginResult.Error.ErrorMessage); + } + + /// <summary> + /// CLIENT API + /// Try to deliberately register a user with an invalid email and password + /// Verify that errorDetails are populated correctly. + /// </summary> + [UUnitTest] + public void InvalidRegistration(UUnitTestContext testContext) + { + var registerRequest = new RegisterPlayFabUserRequest + { + TitleId = PlayFabSettings.TitleId, + Username = "x", + Email = "x", + Password = "x", + }; + var registerTask = PlayFabClientAPI.RegisterPlayFabUserAsync(registerRequest); + ContinueWithContext(registerTask, testContext, InvalidRegistrationContinued, false, "Registration should fail", true); + } + private void InvalidRegistrationContinued(PlayFabResult<RegisterPlayFabUserResult> registerResult, UUnitTestContext testContext, string failMessage) + { + testContext.NotNull(registerResult, failMessage); + testContext.IsNull(registerResult.Result, failMessage); + testContext.NotNull(registerResult.Error, failMessage); + + var expectedEmailMsg = "email address is not valid."; + var expectedPasswordMsg = "password must be between"; + var fullReport = CompileErrorReport(registerResult.Error); + + testContext.True(fullReport.ToLower().Contains(expectedEmailMsg), "Expected an error about bad email address: " + fullReport); + testContext.True(fullReport.ToLower().Contains(expectedPasswordMsg), "Expected an error about bad password: " + fullReport); + } + + /// <summary> + /// CLIENT API + /// Log in or create a user, track their PlayFabId + /// </summary> + [UUnitTest] + public void LoginOrRegister(UUnitTestContext testContext) + { + var loginRequest = new LoginWithCustomIDRequest + { + TitleId = PlayFabSettings.TitleId, + CustomId = PlayFabSettings.BuildIdentifier, + CreateAccount = true + }; + var loginTask = PlayFabClientAPI.LoginWithCustomIDAsync(loginRequest); + ContinueWithContext(loginTask, testContext, LoginOrRegisterContinued, true, "User login failed", true); + } + private void LoginOrRegisterContinued(PlayFabResult<LoginResult> loginResult, UUnitTestContext testContext, string failMessage) + { + PlayFabId = loginResult.Result.PlayFabId; // Needed for subsequent tests + testContext.True(PlayFabClientAPI.IsClientLoggedIn(), "User login failed"); + } + + /// <summary> + /// CLIENT API + /// Test that the login call sequence sends the AdvertisingId when set + /// </summary> + [UUnitTest] + public void LoginWithAdvertisingId(UUnitTestContext testContext) + { + PlayFabSettings.AdvertisingIdType = PlayFabSettings.AD_TYPE_ANDROID_ID; + PlayFabSettings.AdvertisingIdValue = "PlayFabTestId"; + + var loginRequest = new LoginWithCustomIDRequest + { + TitleId = PlayFabSettings.TitleId, + CustomId = PlayFabSettings.BuildIdentifier, + CreateAccount = true + }; + var loginTask = PlayFabClientAPI.LoginWithCustomIDAsync(loginRequest); + ContinueWithContext(loginTask, testContext, LoginWithAdvertisingIdContinued, true, "Login with advertId failed", true); + } + private void LoginWithAdvertisingIdContinued(PlayFabResult<LoginResult> loginResult, UUnitTestContext testContext, string failMessage) + { + PlayFabId = loginResult.Result.PlayFabId; // Needed for subsequent tests + testContext.True(PlayFabClientAPI.IsClientLoggedIn(), "User login failed"); + + testContext.StringEquals(PlayFabSettings.AD_TYPE_ANDROID_ID + "_Successful", PlayFabSettings.AdvertisingIdType); + } + + /// <summary> + /// CLIENT API + /// Test a sequence of calls that modifies saved data, + /// and verifies that the next sequential API call contains updated data. + /// Verify that the data is correctly modified on the next call. + /// Parameter types tested: string, Dictionary>string, string>, DateTime + /// </summary> + [UUnitTest] + public void UserDataApi(UUnitTestContext testContext) + { + var getRequest = new GetUserDataRequest(); + var getDataTask1 = PlayFabClientAPI.GetUserDataAsync(getRequest); + ContinueWithContext(getDataTask1, testContext, UserDataApiContinued1, true, "GetUserData1 call failed", false); + } + private void UserDataApiContinued1(PlayFabResult<GetUserDataResult> getDataResult1, UUnitTestContext testContext, string failMessage) + { + UserDataRecord testCounter; + if (!getDataResult1.Result.Data.TryGetValue(TEST_DATA_KEY, out testCounter)) + testCounter = new UserDataRecord { Value = "0" }; + int.TryParse(testCounter.Value, out _testInteger); + _testInteger = (_testInteger + 1) % 100; // This test is about the expected value changing - but not testing more complicated issues like bounds + + var updateRequest = new UpdateUserDataRequest { Data = new Dictionary<string, string> { { TEST_DATA_KEY, _testInteger.ToString() } } }; + var updateTask = PlayFabClientAPI.UpdateUserDataAsync(updateRequest); + ContinueWithContext(updateTask, testContext, UserDataApiContinued2, true, "UpdateUserData call failed", false); // The update doesn't return anything interesting except versionID. It's better to just re-call GetUserData again below to verify the update + } + private void UserDataApiContinued2(PlayFabResult<UpdateUserDataResult> updateResult, UUnitTestContext testContext, string failMessage) + { + var getRequest = new GetUserDataRequest(); + var getDataTask2 = PlayFabClientAPI.GetUserDataAsync(getRequest); + ContinueWithContext(getDataTask2, testContext, UserDataApiContinued3, true, "GetUserData2 call failed", true); + } + private void UserDataApiContinued3(PlayFabResult<GetUserDataResult> getDataResult2, UUnitTestContext testContext, string failMessage) + { + int testCounterValueActual; + UserDataRecord testCounter; + getDataResult2.Result.Data.TryGetValue(TEST_DATA_KEY, out testCounter); + testContext.NotNull(testCounter, "The updated UserData was not found in the Api results"); + int.TryParse(testCounter.Value, out testCounterValueActual); + testContext.IntEquals(_testInteger, testCounterValueActual); + + var timeUpdated = testCounter.LastUpdated; + var testMin = DateTime.UtcNow - TimeSpan.FromMinutes(5); + var testMax = testMin + TimeSpan.FromMinutes(10); + testContext.True(testMin <= timeUpdated && timeUpdated <= testMax); + } + + /// <summary> + /// CLIENT API + /// Test a sequence of calls that modifies saved data, + /// and verifies that the next sequential API call contains updated data. + /// Verify that the data is saved correctly, and that specific types are tested + /// Parameter types tested: Dictionary>string, int> + /// </summary> + [UUnitTest] + public void PlayerStatisticsApi(UUnitTestContext testContext) + { + var getRequest = new GetPlayerStatisticsRequest(); + var getStatTask1 = PlayFabClientAPI.GetPlayerStatisticsAsync(getRequest); + ContinueWithContext(getStatTask1, testContext, PlayerStatisticsApiContinued1, true, "GetPlayerStatistics1 call failed", false); + } + private void PlayerStatisticsApiContinued1(PlayFabResult<GetPlayerStatisticsResult> getStatResult1, UUnitTestContext testContext, string failMessage) + { + foreach (var eachStat in getStatResult1.Result.Statistics) + if (eachStat.StatisticName == TEST_STAT_NAME) + _testInteger = eachStat.Value; + _testInteger = (_testInteger + 1) % 100; // This test is about the expected value changing (incrementing through from TEST_STAT_BASE to TEST_STAT_BASE * 2 - 1) + + var updateRequest = new UpdatePlayerStatisticsRequest { Statistics = new List<StatisticUpdate> { new StatisticUpdate { StatisticName = TEST_STAT_NAME, Value = _testInteger } } }; + var updateTask = PlayFabClientAPI.UpdatePlayerStatisticsAsync(updateRequest); + ContinueWithContext(updateTask, testContext, PlayerStatisticsApiContinued2, true, "UpdatePlayerStatistics call failed", false); + } + private void PlayerStatisticsApiContinued2(PlayFabResult<UpdatePlayerStatisticsResult> updateResult, UUnitTestContext testContext, string failMessage) + { + var getRequest = new GetPlayerStatisticsRequest(); + var getStatTask2 = PlayFabClientAPI.GetPlayerStatisticsAsync(getRequest); + ContinueWithContext(getStatTask2, testContext, PlayerStatisticsApiContinued3, true, "GetPlayerStatistics2 call failed", true); + } + private void PlayerStatisticsApiContinued3(PlayFabResult<GetPlayerStatisticsResult> getStatResult2, UUnitTestContext testContext, string failMessage) + { + var testStatActual = int.MinValue; + foreach (var eachStat in getStatResult2.Result.Statistics) + if (eachStat.StatisticName == TEST_STAT_NAME) + testStatActual = eachStat.Value; + testContext.IntEquals(_testInteger, testStatActual); + } + + /// <summary> + /// SERVER API + /// Get or create the given test character for the given user + /// Parameter types tested: Contained-Classes, string + /// </summary> + [UUnitTest] + public void UserCharacter(UUnitTestContext testContext) + { + var request = new ListUsersCharactersRequest { PlayFabId = PlayFabId }; + var getCharsTask = PlayFabClientAPI.GetAllUsersCharactersAsync(request); + ContinueWithContext(getCharsTask, testContext, null, true, "Failed to GetChars", true); + } + + /// <summary> + /// CLIENT AND SERVER API + /// Test that leaderboard results can be requested + /// Parameter types tested: List of contained-classes + /// </summary> + [UUnitTest] + public void LeaderBoard(UUnitTestContext testContext) + { + var clientRequest = new GetLeaderboardRequest + { + MaxResultsCount = 3, + StatisticName = TEST_STAT_NAME, + }; + var clientTask = PlayFabClientAPI.GetLeaderboardAsync(clientRequest); + ContinueWithContext(clientTask, testContext, LeaderBoardContinued, true, "Failed to get client leaderboard", true); + } + private void LeaderBoardContinued(PlayFabResult<GetLeaderboardResult> clientResult, UUnitTestContext testContext, string failMessage) + { + testContext.True(clientResult.Result.Leaderboard.Count > 0, "Leaderboard does not contain enough entries."); + } + + /// <summary> + /// CLIENT API + /// Test that AccountInfo can be requested + /// Parameter types tested: List of enum-as-strings converted to list of enums + /// </summary> + [UUnitTest] + public void AccountInfo(UUnitTestContext testContext) + { + var request = new GetAccountInfoRequest { PlayFabId = PlayFabId }; + var accountTask = PlayFabClientAPI.GetAccountInfoAsync(request); + ContinueWithContext(accountTask, testContext, LeaderBoardContinued, true, "Failed to get accountInfo", true); + } + private void LeaderBoardContinued(PlayFabResult<GetAccountInfoResult> accountResult, UUnitTestContext testContext, string failMessage) + { + testContext.True(Enum.IsDefined(typeof(UserOrigination), accountResult.Result.AccountInfo.TitleInfo.Origination.Value), "Origination Enum not valid"); + } + + /// <summary> + /// CLIENT API + /// Test that CloudScript can be properly set up and invoked + /// </summary> + [UUnitTest] + public void CloudScript(UUnitTestContext testContext) + { + var request = new ExecuteCloudScriptRequest { FunctionName = "helloWorld" }; + var cloudTask = PlayFabClientAPI.ExecuteCloudScriptAsync(request); + ContinueWithContext(cloudTask, testContext, CloudScriptContinued, true, "Failed to Execute CloudScript", true); + } + private void CloudScriptContinued(PlayFabResult<ExecuteCloudScriptResult> cloudResult, UUnitTestContext testContext, string failMessage) + { + // Get the helloWorld return message + testContext.NotNull(cloudResult.Result.FunctionResult); + var jobj = (JsonObject)cloudResult.Result.FunctionResult; + var messageValue = jobj["messageValue"] as string; + testContext.StringEquals("Hello " + PlayFabId + "!", messageValue); + } + + /// <summary> + /// CLIENT API + /// Test that CloudScript errors can be deciphered + /// </summary> + [UUnitTest] + public void CloudScriptError(UUnitTestContext testContext) + { + var request = new ExecuteCloudScriptRequest { FunctionName = "throwError" }; + var cloudTask = PlayFabClientAPI.ExecuteCloudScriptAsync(request); + ContinueWithContext(cloudTask, testContext, CloudScriptErrorContinued, true, "Failed to Execute CloudScript", true); + } + private void CloudScriptErrorContinued(PlayFabResult<ExecuteCloudScriptResult> cloudResult, UUnitTestContext testContext, string failMessage) + { + // Get the JavascriptException result + testContext.IsNull(cloudResult.Result.FunctionResult); + testContext.NotNull(cloudResult.Result.Error); + testContext.StringEquals(cloudResult.Result.Error.Error, "JavascriptException"); + } + + /// <summary> + /// CLIENT API + /// Test that the client can publish custom PlayStream events + /// </summary> + [UUnitTest] + public void WriteEvent(UUnitTestContext testContext) + { + var request = new WriteClientPlayerEventRequest + { + EventName = "ForumPostEvent", + Timestamp = DateTime.UtcNow, + Body = new Dictionary<string, object> { + { "Subject", "My First Post" }, + { "Body", "My awesome Post." }, + } + }; + + var writeTask = PlayFabClientAPI.WritePlayerEventAsync(request); + ContinueWithContext(writeTask, testContext, null, true, "PlayStream WriteEvent failed", true); + } + } +} +#endif diff --git a/PlayFabClientSDK/source/Uunit/UUnitAssertException.cs b/PlayFabClientSDK/source/Uunit/UUnitAssertException.cs index 94ce32f8..96130a17 100644 --- a/PlayFabClientSDK/source/Uunit/UUnitAssertException.cs +++ b/PlayFabClientSDK/source/Uunit/UUnitAssertException.cs @@ -10,34 +10,29 @@ namespace PlayFab.UUnit { + /// <summary> + /// The internal uunit exception base class, which you can use to capture all UUnit exceptions + /// </summary> + public class UUnitException : Exception + { + public UUnitException(string message) : base(message) { } + } + /// <summary> /// Throw this exception, via UUnitAssert utility function, in order to define when a test has been skipped. /// The only information shown will be the "skipped" notification /// </summary> - public class UUnitSkipException : Exception { } + public class UUnitSkipException : UUnitException + { + public UUnitSkipException(string message) : base(message) { } + } - /// <summary> + /// <summary> /// Throw this exception, via UUnitAssert utility functions, in order to define when a test has failed. - /// The traceback and message will automatically be displayed as a failure + /// The traceback and Message will automatically be displayed as a failure /// </summary> - public class UUnitAssertException : Exception + public class UUnitAssertException : UUnitException { - public object expected; - public object received; - public string message; - - public UUnitAssertException(string message) - : base(message) - { - this.message = message; - } - - public UUnitAssertException(object expected, object received, string message) - : base("[UUnit] - Assert Failed - Expected: " + expected + " Received: " + received + "\n\t\t(" + message + ")") - { - this.expected = (expected == null) ? "null" : expected; - this.received = (received == null) ? "null" : received; - this.message = (message == null) ? "" : message; - } + public UUnitAssertException(string message) : base(message) { } } } diff --git a/PlayFabClientSDK/source/Uunit/UUnitIncrementalTestRunner.cs b/PlayFabClientSDK/source/Uunit/UUnitIncrementalTestRunner.cs new file mode 100644 index 00000000..7f2d7624 --- /dev/null +++ b/PlayFabClientSDK/source/Uunit/UUnitIncrementalTestRunner.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +#if !DISABLE_PLAYFABCLIENT_API +using PlayFab.ClientModels; +#endif + +namespace PlayFab.UUnit +{ + public static class UUnitIncrementalTestRunner + { + public static bool SuiteFinished { get; private set; } + public static bool AllTestsPassed { get; private set; } + public static string Summary { get; private set; } + private static UUnitTestSuite _suite; + private static bool _postResultsToCloudscript; +#if !DISABLE_PLAYFABCLIENT_API + private static Action<PlayFabResult<ExecuteCloudScriptResult>> _onComplete; +#endif + + public static void Start(bool postResultsToCloudscript = true, string filter = null, Dictionary<string, string> testInputs = null +#if !DISABLE_PLAYFABCLIENT_API + , Action<PlayFabResult<ExecuteCloudScriptResult>> onComplete = null +#endif + ) + { + // Fall back on hard coded testTitleData if necessary (Put your own data here) + if (testInputs == null) + testInputs = new Dictionary<string, string> { { "titleId", "6195" }, { "userEmail", "paul@playfab.com" } }; +#if !DISABLE_PLAYFABCLIENT_API + PlayFabApiTest.SetTitleInfo(testInputs); +#endif + + SuiteFinished = false; + AllTestsPassed = false; + _postResultsToCloudscript = postResultsToCloudscript; + _suite = new UUnitTestSuite(); + _suite.FindAndAddAllTestCases(typeof(UUnitTestCase), filter); +#if !DISABLE_PLAYFABCLIENT_API + _onComplete = onComplete; +#endif + } + + public static string Tick() + { + if (SuiteFinished) + return Summary; + + SuiteFinished = _suite.TickTestSuite(); + Summary = _suite.GenerateSummary(); + AllTestsPassed = _suite.AllTestsPassed(); + + if (SuiteFinished) + OnSuiteFinish(); + + return Summary; + } + + private static void OnSuiteFinish() + { + if (_postResultsToCloudscript) + PostTestResultsToCloudScript(_suite.GetInternalReport()); + } + + private static void PostTestResultsToCloudScript(TestSuiteReport testReport) + { +#if !DISABLE_PLAYFABCLIENT_API + var request = new ExecuteCloudScriptRequest + { + FunctionName = "SaveTestData", + FunctionParameter = new Dictionary<string, object> { { "customId", PlayFabSettings.BuildIdentifier }, { "testReport", new[] { testReport } } }, + GeneratePlayStreamEvent = true + }; + var saveTask = PlayFabClientAPI.ExecuteCloudScriptAsync(request); + saveTask.ContinueWith(task => + { + if (_onComplete != null) + _onComplete(task.Result); + } + ); +#endif + } + } +} diff --git a/PlayFabClientSDK/source/Uunit/UUnitTestCase.cs b/PlayFabClientSDK/source/Uunit/UUnitTestCase.cs index 0ecc07ef..f9287dd1 100644 --- a/PlayFabClientSDK/source/Uunit/UUnitTestCase.cs +++ b/PlayFabClientSDK/source/Uunit/UUnitTestCase.cs @@ -7,102 +7,54 @@ */ using System; -using System.Diagnostics; -using System.Reflection; namespace PlayFab.UUnit { public class UUnitTestCase { - private delegate void UUnitTestDelegate(); - private static Type[] EMPTY_PARAMETER_TYPES = new Type[0]; - private static object[] EMPTY_PARAMETERS = new object[0]; - - Stopwatch setUpStopwatch = new Stopwatch(); - Stopwatch tearDownStopwatch = new Stopwatch(); - Stopwatch eachTestStopwatch = new Stopwatch(); - private string testMethodName; - - public void SetTest(string testMethodName) + /// <summary> + /// During testing, this is the first function that will be called for each UUnitTestCase. + /// This is run exactly once for this type. + /// It is not considered part of any test. A failure or exception in this method will halt the test framework. + /// </summary> + public virtual void ClassSetUp() { - this.testMethodName = testMethodName; } - public void Run(UUnitTestResults testResults) + /// <summary> + /// During testing, this will be called once before every test function with the [UUnitTest] attribute + /// This is run once for each test. + /// This is considered part of the active test. A failure or exception in this method will be considered a failure for the active test. + /// </summary> + public virtual void SetUp(UUnitTestContext testContext) { - TestFinishState testFinishState = TestFinishState.FAILED; - string message = null, stacktrace = null; - eachTestStopwatch.Reset(); - setUpStopwatch.Reset(); - tearDownStopwatch.Reset(); - - try - { - testResults.TestStarted(); - - setUpStopwatch.Start(); - SetUp(); - setUpStopwatch.Stop(); - - Type type = this.GetType(); - MethodInfo method = type.GetRuntimeMethod(testMethodName, EMPTY_PARAMETER_TYPES); // Test methods must contain no parameters - UUnitAssert.NotNull(method, "Could not execute: " + testMethodName + ", it's probably not public."); // Limited access to loaded assemblies - eachTestStopwatch.Start(); - ((UUnitTestDelegate)method.CreateDelegate(typeof(UUnitTestDelegate), this))(); // This creates a delegate of the test function, and calls it - testFinishState = TestFinishState.PASSED; - } - catch (UUnitAssertException e) - { - message = e.message; - stacktrace = e.StackTrace; - testFinishState = TestFinishState.FAILED; - } - catch (UUnitSkipException) - { - // message remains null - testFinishState = TestFinishState.SKIPPED; - } - catch (TargetInvocationException e) - { - message = e.InnerException.Message; - stacktrace = e.InnerException.StackTrace; - testFinishState = TestFinishState.FAILED; - } - catch (Exception e) - { - message = e.Message; - stacktrace = e.StackTrace; - testFinishState = TestFinishState.FAILED; - } - finally - { - eachTestStopwatch.Stop(); - - if (testFinishState != TestFinishState.SKIPPED) - { - try - { - tearDownStopwatch.Start(); - TearDown(); - tearDownStopwatch.Stop(); - } - catch (Exception e) - { - message = e.Message; - stacktrace = e.StackTrace; - testFinishState = TestFinishState.FAILED; - } - } - } + } - testResults.TestComplete(testMethodName, testFinishState, eachTestStopwatch.ElapsedMilliseconds, message, stacktrace); + /// <summary> + /// During testing, this will be called every tick that a test is asynchronous. + /// This is run every unity tick until testContext.EndTest() is called, or until the test times out. + /// This is considered part of the active test. A failure or exception in this method will be considered a failure for the active test. + /// </summary> + public virtual void Tick(UUnitTestContext testContext) + { + testContext.Fail(GetType().Name + "." + testContext.Name + ": Async TestCase does not implement Tick(). To fix this error, implement \"" + GetType().Name + ".Tick()\" in your async test, or call testContext.EndTest() in your syncronous test."); } - protected virtual void SetUp() + /// <summary> + /// During testing, this will be called once after every test function with the [UUnitTest] attribute. + /// This is run once for each test. + /// This is considered part of the active test. A failure or exception in this method will be considered a failure for the active test. + /// </summary> + public virtual void TearDown(UUnitTestContext testContext) { } - protected virtual void TearDown() + /// <summary> + /// During testing, this is the last function that will be called for each UUnitTestCase. + /// This is run exactly once for this type. + /// It is not considered part of any test. A failure or exception in this method will halt the test framework. + /// </summary> + public virtual void ClassTearDown() { } } diff --git a/PlayFabClientSDK/source/Uunit/UUnitTestContext.cs b/PlayFabClientSDK/source/Uunit/UUnitTestContext.cs new file mode 100644 index 00000000..d9c9aca3 --- /dev/null +++ b/PlayFabClientSDK/source/Uunit/UUnitTestContext.cs @@ -0,0 +1,254 @@ +/* + * UUnit system from UnityCommunity + * Heavily modified + * 0.4 release by pboechat + * http://wiki.unity3d.com/index.php?title=UUnit + * http://creativecommons.org/licenses/by-sa/3.0/ +*/ + +using System; +using System.Collections.Generic; + +namespace PlayFab.UUnit +{ + public enum UUnitActiveState + { + PENDING, // Not started + ACTIVE, // Currently testing + READY, // An answer is sent by the http thread, but the main thread hasn't finalized the test yet + COMPLETE, // Test is finalized and recorded + ABORTED // todo + }; + + public class UUnitTestContext + { + public const float DefaultFloatPrecision = 0.0001f; + public const double DefaultDoublePrecision = 0.000001; + + public UUnitActiveState ActiveState; + public UUnitFinishState FinishState; + public Action<UUnitTestContext> TestDelegate; + public UUnitTestCase TestInstance; + public DateTime StartTime; + public DateTime EndTime; + public string TestResultMsg; + public string Name; + + public UUnitTestContext(UUnitTestCase testInstance, Action<UUnitTestContext> testDelegate, string name) + { + TestInstance = testInstance; + TestDelegate = testDelegate; + ActiveState = UUnitActiveState.PENDING; + Name = name; + } + + internal void EndTest(UUnitFinishState finishState, string resultMsg) + { + EndTime = DateTime.UtcNow; + TestResultMsg = resultMsg; + FinishState = finishState; + ActiveState = UUnitActiveState.READY; + } + + public void Skip(string message = "") + { + EndTime = DateTime.UtcNow; + EndTest(UUnitFinishState.SKIPPED, message); + throw new UUnitSkipException(message); + } + + public void Fail(string message = null) + { + if (string.IsNullOrEmpty(message)) + message = "fail"; + EndTest(UUnitFinishState.FAILED, message); + throw new UUnitAssertException(message); + } + + public void True(bool boolean, string message = null) + { + if (boolean) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: true, Actual: false"; + Fail(message); + } + + public void False(bool boolean, string message = null) + { + if (!boolean) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: false, Actual: true"; + Fail(message); + } + + public void NotNull(object something, string message = null) + { + if (something != null) + return; // Success + + if (string.IsNullOrEmpty(message)) + message = "Null object"; + Fail(message); + } + + public void IsNull(object something, string message = null) + { + if (something == null) + return; + + if (string.IsNullOrEmpty(message)) + message = "Not null object"; + Fail(message); + } + + public void StringEquals(string wanted, string got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void SbyteEquals(sbyte? wanted, sbyte? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void ByteEquals(byte? wanted, byte? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void ShortEquals(short? wanted, short? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void UshortEquals(ushort? wanted, ushort? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void IntEquals(int? wanted, int? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void UintEquals(uint? wanted, uint? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void LongEquals(long? wanted, long? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void ULongEquals(ulong? wanted, ulong? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void FloatEquals(float? wanted, float? got, float precision = DefaultFloatPrecision, string message = null) + { + if (wanted == null && got == null) + return; + if (wanted != null && got != null && Math.Abs(wanted.Value - got.Value) < precision) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void DoubleEquals(double? wanted, double? got, double precision = DefaultDoublePrecision, string message = null) + { + if (wanted == null && got == null) + return; + if (wanted != null && got != null && Math.Abs(wanted.Value - got.Value) < precision) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void ObjEquals(object wanted, object got, string message = null) + { + if (wanted == null && got == null) + return; + if (wanted != null && got != null && wanted.Equals(got)) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void SequenceEquals<T>(IEnumerable<T> wanted, IEnumerable<T> got, string message = null) + { + var wEnum = wanted.GetEnumerator(); + var gEnum = got.GetEnumerator(); + + bool wNext, gNext; + int count = 0; + while (true) + { + wNext = wEnum.MoveNext(); + gNext = gEnum.MoveNext(); + if (wNext != gNext) + Fail(message); + if (!wNext) + break; + count++; + ObjEquals(wEnum.Current, gEnum.Current, "Element at " + count + ": " + message); + } + } + } +} diff --git a/PlayFabClientSDK/source/Uunit/UUnitTestReport.cs b/PlayFabClientSDK/source/Uunit/UUnitTestReport.cs new file mode 100644 index 00000000..65e37236 --- /dev/null +++ b/PlayFabClientSDK/source/Uunit/UUnitTestReport.cs @@ -0,0 +1,115 @@ +/* + * UUnit system from UnityCommunity + * Heavily modified + * 0.4 release by pboechat + * http://wiki.unity3d.com/index.php?title=UUnit + * http://creativecommons.org/licenses/by-sa/3.0/ +*/ + +using System; +using System.Collections.Generic; + +namespace PlayFab.UUnit +{ + public enum UUnitFinishState + { + PENDING, + PASSED, + FAILED, + SKIPPED, + TIMEDOUT + } + + /// <summary> + /// This is a wrapper around TestSuiteReport with the callbacks that let UUnitTestSuite manipulate/append results, and UUnitTestRunner display them + /// </summary> + public class UUnitTestReport + { + public readonly TestSuiteReport InternalReport = new TestSuiteReport(); + + public UUnitTestReport(string classname) + { + InternalReport.name = classname; + InternalReport.timestamp = DateTime.UtcNow; + } + + public void TestStarted() + { + InternalReport.tests += 1; + } + + public void TestComplete(string testName, UUnitFinishState finishState, long stopwatchMs, string message, string stacktrace) + { + var report = new TestCaseReport + { + message = message, + classname = InternalReport.name, + failureText = finishState.ToString(), + finishState = finishState, + name = testName, + time = TimeSpan.FromMilliseconds(stopwatchMs) + }; + if (InternalReport.testResults == null) + InternalReport.testResults = new List<TestCaseReport>(); + InternalReport.testResults.Add(report); + + switch (finishState) + { + case (UUnitFinishState.PASSED): + InternalReport.passed += 1; break; + case (UUnitFinishState.FAILED): + InternalReport.failures += 1; break; + case (UUnitFinishState.SKIPPED): + InternalReport.skipped += 1; break; + } + + // TODO: Add hooks for SuiteSetUp and SuiteTearDown, so this can be estimated more accurately + InternalReport.time = DateTime.UtcNow - InternalReport.timestamp; // For now, update the duration on every test complete - the last one will be essentially correct + } + + /// <summary> + /// Return that tests were run, and all of them reported FinishState + /// </summary> + public bool AllTestsPassed() + { + return InternalReport.tests > 0 && InternalReport.tests == (InternalReport.passed + InternalReport.skipped) && InternalReport.failures == 0; + } + } + + /// <summary> + /// Data container defining the test-suite data saved to JUnit XML format + /// </summary> + public class TestSuiteReport + { + // Part of the XML spec + public List<TestCaseReport> testResults; + public string name; + public int tests; + public int failures; + public int errors; + public int skipped; + public TimeSpan time; + public DateTime timestamp; + public Dictionary<string, string> properties; + // Useful for debugging but not part of the serialized format + public int passed; // Could be calculated from the others, but sometimes knowing if they don't add up means something + } + + /// <summary> + /// Data container defining the test-case data saved to JUnit XML format + /// </summary> + public class TestCaseReport + { + public string classname; + public string name; + public TimeSpan time; + // Sub-Fields in the XML spec + /// <summary> message is the descriptive text used to debug the test failure </summary> + public string message; + /// <summary> The xml spec allows failureText to be an arbitrary string. When possible it should match FinishState (But not required) </summary> + public string failureText; + public UUnitFinishState finishState; + // Other parameters not part of the xml spec, used for internal debugging + public string stacktrace; + } +} diff --git a/PlayFabClientSDK/source/Uunit/UUnitTestSuite.cs b/PlayFabClientSDK/source/Uunit/UUnitTestSuite.cs index b2197856..d5feee87 100644 --- a/PlayFabClientSDK/source/Uunit/UUnitTestSuite.cs +++ b/PlayFabClientSDK/source/Uunit/UUnitTestSuite.cs @@ -7,6 +7,7 @@ */ using System; +using System.Text; using System.Collections.Generic; using System.Reflection; @@ -19,95 +20,295 @@ public class UUnitTestAttribute : Attribute public class UUnitTestSuite { - private readonly List<UUnitTestCase> _tests = new List<UUnitTestCase>(); - private int _lastTestIndex = -1; - private readonly UUnitTestResults _testResults; + private const int TIME_ALIGNMENT_WIDTH = 10; + private static readonly TimeSpan TestTimeout = TimeSpan.FromSeconds(15); + private static readonly StringBuilder sb = new StringBuilder(); - public UUnitTestSuite(string classname) + private readonly List<UUnitTestContext> _testContexts = new List<UUnitTestContext>(); + private int _activeIndex = 0; + private readonly UUnitTestReport _testReport = new UUnitTestReport(PlayFabSettings.BuildIdentifier); + private UUnitActiveState _suiteState = UUnitActiveState.PENDING; + private UUnitTestCase activeTestInstance = null; + + public string GenerateSummary() { - _testResults = new UUnitTestResults(classname); + sb.Length = 0; + + DateTime now = DateTime.UtcNow, eachStartTime, eachEndTime; + int finished = 0, passed = 0, failed = 0, skipped = 0; + + foreach (var eachContext in _testContexts) + { + // Count tests + if (eachContext.ActiveState == UUnitActiveState.COMPLETE) + { + finished++; + eachStartTime = eachContext.StartTime; + eachEndTime = eachContext.EndTime; + if (eachContext.FinishState == UUnitFinishState.PASSED) + passed++; + else if (eachContext.FinishState == UUnitFinishState.SKIPPED) + skipped++; + else + failed++; + } + else + { + eachStartTime = eachContext.ActiveState == UUnitActiveState.PENDING ? now : eachContext.StartTime; + eachEndTime = now; + } + + // line for each test report + if (sb.Length != 0) + sb.Append("\n"); + var ms = (eachEndTime - eachStartTime).TotalMilliseconds.ToString("0"); + for (var i = ms.Length; i < TIME_ALIGNMENT_WIDTH; i++) + sb.Append(' '); + sb.Append(ms).Append(" ms - ").Append(eachContext.FinishState); + sb.Append(" - ").Append(eachContext.Name); + if (!string.IsNullOrEmpty(eachContext.TestResultMsg)) + { + sb.Append(" - ").Append(eachContext.TestResultMsg); + // TODO: stacktrace + } + } + + sb.AppendFormat("\nTesting complete: {0}/{1} test run, {2} tests passed, {3} tests failed, {4} tests skipped.", finished, _testContexts.Count, passed, failed, skipped); + + return sb.ToString(); } - public void Add(UUnitTestCase testCase) + public TestSuiteReport GetInternalReport() { - _tests.Add(testCase); + return _testReport.InternalReport; } - public void RunAllTests() + public void FindAndAddAllTestCases(Type parent, string filter = null) { - bool eachResult = false; - while (eachResult == false) - eachResult = RunOneTest(); + if (_suiteState != UUnitActiveState.PENDING) + throw new Exception("Must add all tests before executing tests."); + +#if NETFX_CORE + var eachAssembly = typeof(UUnitTestCase).GetTypeInfo().Assembly; // We can only load assemblies known in advance on WSA +#else + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + foreach (var eachAssembly in assemblies) +#endif + FindAndAddAllTestCases(eachAssembly, parent, filter); } - /// <summary> - /// Run a single test, and return whether the test suite is finished - /// </summary> - /// <returns>True when all _tests are finished</returns> - public bool RunOneTest() + public void FindAndAddAllTestCases(Assembly assembly, Type parent, string filter = null) + { + if (_suiteState != UUnitActiveState.PENDING) + throw new Exception("Must add all tests before executing tests."); + + var types = assembly.GetTypes(); + foreach (var t in types) + if (!t.GetTypeInfo().IsAbstract && t.GetTypeInfo().IsSubclassOf(parent)) + AddTestsForType(t.AsType(), filter); + } + + private void AddTestsForType(Type testCaseType, string filter = null) { - // Abort if we've already finished testing - bool doneTesting = _lastTestIndex >= _tests.Count; - if (doneTesting) return true; + if (_suiteState != UUnitActiveState.PENDING) + throw new Exception("Must add all tests before executing tests."); + + var filterSet = AssembleFilter(filter); + + UUnitTestCase newTestCase = null; + foreach (var constructorInfo in testCaseType.GetTypeInfo().GetConstructors()) + { + try + { + newTestCase = (UUnitTestCase)constructorInfo.Invoke(null); + } + catch (Exception) { } // Ignore it and try the next one + } + if (newTestCase == null) + throw new Exception(testCaseType.Name + " must have a parameter-less constructor."); + + var methods = testCaseType.GetTypeInfo().GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + var attributesList = new List<object>(); + foreach (var methodInfo in methods) + { + attributesList.Clear(); + attributesList.AddRange(methodInfo.GetCustomAttributes(typeof(UUnitTestAttribute), false)); + if (attributesList.Count == 0 || !MatchesFilters(methodInfo.Name, filterSet)) // There can only be 1, and we only care about attribute existence (no data on attribute), and it has to match the filter + continue; + + Action<UUnitTestContext> eachTestDelegate = CreateDelegate<UUnitTestContext>(testCaseType.Name, newTestCase, methodInfo); + if (eachTestDelegate != null) + _testContexts.Add(new UUnitTestContext(newTestCase, eachTestDelegate, methodInfo.Name)); + } + } - _lastTestIndex++; - doneTesting = _lastTestIndex >= _tests.Count; - if (!doneTesting) + private static Action<T> CreateDelegate<T>(string typeName, object instance, MethodInfo methodInfo) + { + Action<T> eachTestDelegate; + try + { + eachTestDelegate = methodInfo.CreateDelegate(typeof(Action<T>), instance) as Action<T>; + } + catch (Exception e) { - _tests[_lastTestIndex].Run(_testResults); + var sb = new StringBuilder(); + sb.Append(typeName).Append(".").Append(methodInfo.Name).Append(" must match the test delegate signature: Action<T>"); + sb.Append("\n").Append(e); + + sb.Append("\nExpected Params: ["); + var actionInfo = typeof(Action<T>).GetMethod("Invoke"); + foreach (var param in actionInfo.GetParameters()) + sb.Append(param.Name).Append(","); + sb.Append("]"); + + sb.Append("\nActual Params: ["); + foreach (var param in methodInfo.GetParameters()) + sb.Append(param.Name).Append(","); + sb.Append("]"); + throw new Exception(sb.ToString()); } - return doneTesting; + return eachTestDelegate; + } + + private HashSet<string> AssembleFilter(string filter) + { + if (string.IsNullOrEmpty(filter)) + return null; + var filterWords = filter.ToLower().Split(new char[] { '\n', ',', ' ' }, StringSplitOptions.RemoveEmptyEntries); + if (filterWords.Length > 0) + return new HashSet<string>(filterWords); + return null; } - public UUnitTestResults GetResults() + private bool MatchesFilters(string name, HashSet<string> filterSet) { - bool doneTesting = _lastTestIndex >= _tests.Count; - return doneTesting ? _testResults : null; // Only return the results when finished + if (filterSet == null) + return true; + var nameLc = name.ToLower(); + foreach (var eachFilter in filterSet) + if (nameLc.Contains(eachFilter)) + return true; + return false; } /// <summary> - /// If using WinStore/WinPhone, you should call via: - /// suite.FindAndAddAllTestCases(typeof(UUnitTestSuite).GetTypeInfo().Assembly, typeof(UUnitTestCase)) - /// If you have full reflection (IE everything else), call via: - /// foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) - /// suite.FindAndAddAllTestCases(assembly, typeof(UUnitTestCase)); - /// Don't add the same assembly/parent multiple times, or it'll repeat the same test multiple times + /// Return that tests were run, and all of them reported success /// </summary> - /// <param name="assembly"></param> - /// <param name="parent"></param> - public void FindAndAddAllTestCases(Assembly assembly, Type parent) + public bool AllTestsPassed() { - foreach (var t in assembly.DefinedTypes) - if (!t.IsAbstract && t.IsSubclassOf(parent)) - AddAll(t); + return _testReport.AllTestsPassed(); } - private void AddAll(TypeInfo testCaseType) + /// <summary> + /// Tick the test suite. + /// This should be called once per Update until it returns true. + /// Once it returns true, testing is complete + /// </summary> + public bool TickTestSuite() { - foreach (MethodInfo m in testCaseType.DeclaredMethods) + if (_suiteState == UUnitActiveState.COMPLETE) + return true; + if (_suiteState == UUnitActiveState.PENDING) + _suiteState = UUnitActiveState.ACTIVE; + + var nextTest = _activeIndex < _testContexts.Count ? _testContexts[_activeIndex] : null; + if (nextTest != null && nextTest.ActiveState == UUnitActiveState.COMPLETE) { - var attributes = m.GetCustomAttributes(typeof(UUnitTestAttribute), false); - foreach (var attr in attributes) - { - var constructors = testCaseType.DeclaredConstructors; - foreach (var constructor in constructors) - { - UUnitTestCase newTestCase = (UUnitTestCase)constructor.Invoke(null); - newTestCase.SetTest(m.Name); - Add(newTestCase); - break; // We only want 1 constructor, if relevant - } - break; // We only want 1 attribute, if relevant - } + _activeIndex++; + nextTest = (_activeIndex >= _testContexts.Count) ? null : _testContexts[_activeIndex]; + } + + if (nextTest != null && nextTest.ActiveState == UUnitActiveState.PENDING) + StartTest(nextTest); + else if (nextTest != null) + TickTest(nextTest); + + var testsDone = _activeIndex >= _testContexts.Count; + if (testsDone && _suiteState == UUnitActiveState.ACTIVE) + { + _suiteState = UUnitActiveState.READY; + ManageInstance(null, activeTestInstance); // Ensure that the final test is cleaned up } + return _suiteState == UUnitActiveState.READY; } /// <summary> - /// Return that _tests were run, and all of them reported success + /// Start a test, track which test is active, and manage timers /// </summary> - public bool AllTestsPassed() + private void StartTest(UUnitTestContext testContext) + { + ManageInstance(testContext.TestInstance, activeTestInstance); + + testContext.StartTime = DateTime.UtcNow; + testContext.ActiveState = UUnitActiveState.ACTIVE; + _testReport.TestStarted(); + + if (testContext.ActiveState == UUnitActiveState.ACTIVE) + Wrap(testContext, testContext.TestInstance.SetUp); + if (testContext.ActiveState == UUnitActiveState.ACTIVE) + Wrap(testContext, testContext.TestDelegate); + // Async tests can't resolve this tick, so just return + } + + /// <summary> + /// Ensure that exceptions in any test-functions are relayed to the testContext as failures + /// </summary> + private void Wrap(UUnitTestContext testContext, Action<UUnitTestContext> testFunc) + { + try + { + testFunc(testContext); + } + catch (UUnitSkipException uu) + { + // Silence the assert and ensure the test is marked as complete - The exception is just to halt the test process + testContext.EndTest(UUnitFinishState.SKIPPED, uu.Message); + } + catch (UUnitException uu) + { + // Silence the assert and ensure the test is marked as complete - The exception is just to halt the test process + testContext.EndTest(UUnitFinishState.FAILED, uu.Message + "\n" + uu.StackTrace); + } + catch (Exception e) + { + // Report this exception as an unhandled failure in the test + testContext.EndTest(UUnitFinishState.FAILED, e.ToString()); + } + } + + /// <summary> + /// Manage the ClassSetUp and ClassTearDown functions for each UUnitTestCase + /// </summary> + private void ManageInstance(UUnitTestCase newtestInstance, UUnitTestCase oldTestInstance) + { + if (ReferenceEquals(newtestInstance, oldTestInstance)) + return; + + if (oldTestInstance != null) + oldTestInstance.ClassTearDown(); + if (newtestInstance != null) + newtestInstance.ClassSetUp(); + activeTestInstance = newtestInstance; + } + + private void TickTest(UUnitTestContext testContext) { - return _testResults.AllTestsPassed(); + var now = DateTime.UtcNow; + var timedOut = (now - testContext.StartTime) > TestTimeout; + if (testContext.ActiveState != UUnitActiveState.READY && !timedOut) // Not finished & not timed out + { + testContext.TestInstance.Tick(testContext); + return; + } + else if (testContext.ActiveState == UUnitActiveState.ACTIVE && timedOut) + { + testContext.EndTest(UUnitFinishState.TIMEDOUT, "Test duration exceeded maxumum"); + } + + testContext.EndTime = now; + testContext.ActiveState = UUnitActiveState.COMPLETE; + Wrap(testContext, testContext.TestInstance.TearDown); + _testReport.TestComplete(testContext.TestDelegate.Target.GetType().Name + "." + testContext.Name, testContext.FinishState, (int)(testContext.EndTime - testContext.StartTime).TotalMilliseconds, testContext.TestResultMsg, null); } } } diff --git a/PlayFabClientSDK/source/WsaReflectionExtensions.cs b/PlayFabClientSDK/source/WsaReflectionExtensions.cs new file mode 100644 index 00000000..d4991f22 --- /dev/null +++ b/PlayFabClientSDK/source/WsaReflectionExtensions.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +#if NETFX_CORE +/// <summary>Specifies flags that control binding and the way in which the search for members and types is conducted by reflection.</summary> +[Flags] +public enum BindingFlags +{ + IgnoreCase = 1, + DeclaredOnly = 2, + Instance = 4, + Static = 8, + Public = 16, + NonPublic = 32, + FlattenHierarchy = 64, +} +#endif + +public static class WsaReflectionExtensions +{ + public static Type AsType(this Type type) + { + return type; + } +#if !NETFX_CORE + public static Delegate CreateDelegate(this MethodInfo methodInfo, Type delegateType, object instance) + { + return Delegate.CreateDelegate(delegateType, instance, methodInfo); + } + public static Assembly GetAssembly(this Type type) + { + return type.Assembly; + } + public static Type GetTypeInfo(this Type type) + { + return type; + } + public static string GetDelegateName(this Delegate delegateInstance) + { + return delegateInstance.Method.Name; + } +#else + public static bool IsAssignableFrom(this Type type, Type other) + { + return type.GetTypeInfo().IsAssignableFrom(other.GetTypeInfo()); + } + public static bool IsAssignableFrom(this Type type, TypeInfo other) + { + return type.GetTypeInfo().IsAssignableFrom(other); + } + public static Assembly GetAssembly(this Type type) + { + return type.GetTypeInfo().Assembly; + } + public static bool IsInstanceOfType(this Type type, object obj) + { + return obj != null && type.GetTypeInfo().IsAssignableFrom(obj.GetType().GetTypeInfo()); + } + public static string GetDelegateName(this Delegate delegateInstance) + { + return delegateInstance.ToString(); + } + public static MethodInfo GetMethod(this Type type, string methodName) + { + return type.GetTypeInfo().GetDeclaredMethod(methodName); + } + public static IEnumerable<FieldInfo> GetFields(this TypeInfo typeInfo) + { + return typeInfo.DeclaredFields; + } + public static TypeInfo GetTypeInfo(this TypeInfo typeInfo) + { + return typeInfo; + } + public static IEnumerable<ConstructorInfo> GetConstructors(this TypeInfo typeInfo) + { + return typeInfo.DeclaredConstructors; + } + public static IEnumerable<MethodInfo> GetMethods(this TypeInfo typeInfo, BindingFlags ignored) + { + return typeInfo.DeclaredMethods; + } + public static IEnumerable<TypeInfo> GetTypes(this Assembly assembly) + { + return assembly.DefinedTypes; + } +#endif +} diff --git a/PlayFabSDK/PlayFabSDK.csproj b/PlayFabSDK/PlayFabSDK.csproj index ae95d015..0dd5a52a 100644 --- a/PlayFabSDK/PlayFabSDK.csproj +++ b/PlayFabSDK/PlayFabSDK.csproj @@ -21,7 +21,7 @@ <DebugType>full</DebugType> <Optimize>false</Optimize> <OutputPath>bin\Debug\</OutputPath> - <DefineConstants>DEBUG;TRACE</DefineConstants> + <DefineConstants>TRACE;DEBUG;NETFX_CORE;SIMPLE_JSON_TYPEINFO</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> </PropertyGroup> @@ -29,11 +29,18 @@ <DebugType>pdbonly</DebugType> <Optimize>true</Optimize> <OutputPath>bin\Release\</OutputPath> - <DefineConstants>TRACE</DefineConstants> + <DefineConstants>TRACE;NETFX_CORE;SIMPLE_JSON_TYPEINFO</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> </PropertyGroup> <ItemGroup> + <Compile Include="source\Json\ISerializer.cs" /> + <Compile Include="source\Json\NewtonsoftWrapper.cs" /> + <Compile Include="source\Json\SimpleJson.cs" /> + <Compile Include="source\PlayFabHttp\IPlayFabHttp.cs" /> + <Compile Include="source\PlayFabHttp\PlayFabHttp.cs" /> + <Compile Include="source\PlayFabHttp\PlayFabSysHttp.cs" /> + <Compile Include="source\PlayFabHttp\PlayFabWinHttp.cs" /> <Compile Include="source\PlayFabAdminAPI.cs" /> <Compile Include="source\PlayFabAdminModels.cs" /> <Compile Include="source\PlayFabMatchmakerAPI.cs" /> @@ -43,15 +50,18 @@ <Compile Include="source\PlayFabClientAPI.cs" /> <Compile Include="source\PlayFabClientModels.cs" /> <Compile Include="source\PlayFabErrors.cs" /> - <Compile Include="source\PlayFabHTTP.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="source\PlayFabSettings.cs" /> + <Compile Include="source\PlayFabFileUtil.cs" /> <Compile Include="source\PlayFabUtil.cs" /> - <Compile Include="source\Uunit\UUnitAssert.cs" /> + <Compile Include="source\Uunit\PlayFabApiTest.cs" /> <Compile Include="source\Uunit\UUnitAssertException.cs" /> + <Compile Include="source\Uunit\UUnitIncrementalTestRunner.cs" /> <Compile Include="source\Uunit\UUnitTestCase.cs" /> - <Compile Include="source\Uunit\UUnitTestResult.cs" /> + <Compile Include="source\Uunit\UUnitTestContext.cs" /> + <Compile Include="source\Uunit\UUnitTestReport.cs" /> <Compile Include="source\Uunit\UUnitTestSuite.cs" /> + <Compile Include="source\WsaReflectionExtensions.cs" /> </ItemGroup> <ItemGroup> <Reference Include="Newtonsoft.Json"> diff --git a/PlayFabSDK/UnittestRunner/UUnitTestRunner.cs b/PlayFabSDK/UnittestRunner/UUnitTestRunner.cs index a3074a03..94fd535c 100644 --- a/PlayFabSDK/UnittestRunner/UUnitTestRunner.cs +++ b/PlayFabSDK/UnittestRunner/UUnitTestRunner.cs @@ -1,35 +1,36 @@ using PlayFab; using PlayFab.UUnit; -using System.Reflection; using System; using System.IO; -using Newtonsoft.Json; using System.Collections.Generic; +using System.Threading; using PlayFab.ClientModels; +using PlayFab.Json; namespace UnittestRunner { static class UUnitTestRunner { + private static bool _onCompleted = false; public class CsSaveRequest { public string customId; public TestSuiteReport[] testReport; } - static int Main(string[] args) + private static int Main(string[] args) { - for (int i = 0; i < args.Length; i++) + Dictionary<string, string> testInputs = null; + + for (var i = 0; i < args.Length; i++) { if (args[i] == "-testInputsFile" && (i + 1) < args.Length) { - string filename = args[i + 1]; + var filename = args[i + 1]; if (File.Exists(filename)) { - string testInputsFile = File.ReadAllText(filename); - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var testInputs = serializer.Deserialize<Dictionary<string, string>>(new JsonTextReader(new StringReader(testInputsFile))); - PlayFabApiTest.SetTitleInfo(testInputs); + var testInputsFile = File.ReadAllText(filename); + testInputs = JsonWrapper.DeserializeObject<Dictionary<string, string>>(testInputsFile); } else { @@ -39,34 +40,33 @@ static int Main(string[] args) } } - UUnitTestSuite suite = new UUnitTestSuite(PlayFab.PlayFabSettings.BuildIdentifier); - // With this call, we should only expect the unittests within PlayFabSDK to run - This could be expanded by adding other assemblies manually - foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) - suite.FindAndAddAllTestCases(assembly, typeof(UUnitTestCase)); + UUnitIncrementalTestRunner.Start(true, null, testInputs, OnComplete); + while (!UUnitIncrementalTestRunner.SuiteFinished) + UUnitIncrementalTestRunner.Tick(); - // Display the test results - suite.RunAllTests(); - UUnitTestResults results = suite.GetResults(); - Console.WriteLine(results.Summary()); + Console.WriteLine(UUnitIncrementalTestRunner.Summary); Console.WriteLine(); - // Submit the test results to CloudScript - ExecuteCloudScriptRequest request = new ExecuteCloudScriptRequest - { - FunctionName = "SaveTestData", - FunctionParameter = new CsSaveRequest { customId = PlayFabSettings.BuildIdentifier, testReport = new[] { results.InternalReport } }, - GeneratePlayStreamEvent = true - }; + // Wait for OnComplete + var timeout = DateTime.UtcNow + TimeSpan.FromSeconds(30); + while (!_onCompleted && DateTime.UtcNow < timeout) + Thread.Sleep(100); - var task = PlayFabClientAPI.ExecuteCloudScriptAsync(request); - task.Wait(); - if (task.Result.Error != null || task.Result.Result.Error != null) - Console.WriteLine("Error posting results to cloudscript:" + PlayFabUtil.GetCloudScriptErrorReport(task.Result)); - else - Console.WriteLine("Results posted to cloudscript successfully: " + PlayFabSettings.BuildIdentifier); - Console.WriteLine("Debugging: " + PlayFabUtil.GetCloudScriptErrorReport(task.Result)); + return UUnitIncrementalTestRunner.AllTestsPassed ? 0 : 1; + } - return results.AllTestsPassed() ? 0 : 1; + private static void OnComplete(PlayFabResult<ExecuteCloudScriptResult> result) + { + Console.WriteLine("Save to CloudScript result for: " + PlayFabSettings.BuildIdentifier + " => " + PlayFabApiTest.PlayFabId); + if (result.Error != null) + { + Console.WriteLine(result.Error.GenerateErrorReport()); + } + else if (result.Result != null) + { + Console.WriteLine("Successful!"); + } + _onCompleted = true; } } } diff --git a/PlayFabSDK/UnittestRunner/UnittestRunner.csproj b/PlayFabSDK/UnittestRunner/UnittestRunner.csproj index 87acd392..3d31d434 100644 --- a/PlayFabSDK/UnittestRunner/UnittestRunner.csproj +++ b/PlayFabSDK/UnittestRunner/UnittestRunner.csproj @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <PropertyGroup> @@ -63,7 +63,6 @@ <Reference Include="System.Xml" /> </ItemGroup> <ItemGroup> - <Compile Include="PlayFabApiTest.cs" /> <Compile Include="UUnitTestRunner.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> </ItemGroup> @@ -101,4 +100,4 @@ <Target Name="AfterBuild"> </Target> --> -</Project> \ No newline at end of file +</Project> diff --git a/PlayFabSDK/source/Json/ISerializer.cs b/PlayFabSDK/source/Json/ISerializer.cs new file mode 100644 index 00000000..012cd8ab --- /dev/null +++ b/PlayFabSDK/source/Json/ISerializer.cs @@ -0,0 +1,155 @@ + +using System; +using System.Globalization; +using System.Reflection; + +namespace PlayFab.Json +{ + public interface ISerializer + { + T DeserializeObject<T>(string json); + T DeserializeObject<T>(string json, object jsonSerializerStrategy); + object DeserializeObject(string json); + + string SerializeObject(object json); + string SerializeObject(object json, object jsonSerializerStrategy); + } + + + public static class JsonWrapper + { + private static ISerializer _instance = new SimpleJsonInstance(); + + /// <summary> + /// Use this property to override the Serialization for the SDK. + /// </summary> + public static ISerializer Instance + { + get { return _instance; } + set { _instance = value; } + } + + public static T DeserializeObject<T>(string json) + { + return _instance.DeserializeObject<T>(json); + } + + public static T DeserializeObject<T>(string json, object jsonSerializerStrategy) + { + return _instance.DeserializeObject<T>(json, jsonSerializerStrategy); + } + + public static object DeserializeObject(string json) + { + return _instance.DeserializeObject(json); + } + + public static string SerializeObject(object json) + { + return _instance.SerializeObject(json); + } + + public static string SerializeObject(object json, object jsonSerializerStrategy) + { + return _instance.SerializeObject(json, jsonSerializerStrategy); + } + } + + public class SimpleJsonInstance : ISerializer + { + public static PlayFabJsonSerializerStrategy ApiSerializerStrategy = new PlayFabJsonSerializerStrategy(); + private static DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind; + public class PlayFabJsonSerializerStrategy : PocoJsonSerializerStrategy + { + /// <summary> + /// Convert the json value into the destination field/property + /// </summary> + public override object DeserializeObject(object value, Type type) + { + var valueStr = value as string; + if (valueStr == null) // For all of our custom conversions, value is a string + return base.DeserializeObject(value, type); + + var underType = Nullable.GetUnderlyingType(type); + if (underType != null) + return DeserializeObject(value, underType); + else if (type.GetTypeInfo().IsEnum) + return Enum.Parse(type, (string)value, true); + else if (type == typeof(DateTime)) + { + DateTime output; + var result = DateTime.TryParseExact(valueStr, PlayFabUtil.DefaultDateTimeFormats, CultureInfo.CurrentCulture, _dateTimeStyles, out output); + if (result) + return output; + } + else if (type == typeof(DateTimeOffset)) + { + DateTimeOffset output; + var result = DateTimeOffset.TryParseExact(valueStr, PlayFabUtil.DefaultDateTimeFormats, CultureInfo.CurrentCulture, _dateTimeStyles, out output); + if (result) + return output; + } + else if (type == typeof(TimeSpan)) + { + double seconds; + if (double.TryParse(valueStr, out seconds)) + return TimeSpan.FromSeconds(seconds); + } + return base.DeserializeObject(value, type); + } + + /// <summary> + /// Set output to a string that represents the input object + /// </summary> + protected override bool TrySerializeKnownTypes(object input, out object output) + { + if (input.GetType().GetTypeInfo().IsEnum) + { + output = input.ToString(); + return true; + } + else if (input is DateTime) + { + output = ((DateTime)input).ToString(PlayFabUtil.DefaultDateTimeFormats[PlayFabUtil.DEFAULT_UTC_OUTPUT_INDEX], CultureInfo.CurrentCulture); + return true; + } + else if (input is DateTimeOffset) + { + output = ((DateTimeOffset)input).ToString(PlayFabUtil.DefaultDateTimeFormats[PlayFabUtil.DEFAULT_UTC_OUTPUT_INDEX], CultureInfo.CurrentCulture); + return true; + } + else if (input is TimeSpan) + { + output = ((TimeSpan)input).TotalSeconds; + return true; + } + return base.TrySerializeKnownTypes(input, out output); + } + } + + public T DeserializeObject<T>(string json) + { + return PlayFabSimpleJson.DeserializeObject<T>(json, ApiSerializerStrategy); + } + + public T DeserializeObject<T>(string json, object jsonSerializerStrategy) + { + return PlayFabSimpleJson.DeserializeObject<T>(json, (IJsonSerializerStrategy)jsonSerializerStrategy); + } + + public object DeserializeObject(string json) + { + return PlayFabSimpleJson.DeserializeObject(json, typeof(object), ApiSerializerStrategy); + } + + public string SerializeObject(object json) + { + return PlayFabSimpleJson.SerializeObject(json, ApiSerializerStrategy); + } + + public string SerializeObject(object json, object jsonSerializerStrategy) + { + return PlayFabSimpleJson.SerializeObject(json, (IJsonSerializerStrategy)jsonSerializerStrategy); + } + } +} diff --git a/PlayFabSDK/source/Json/NewtonsoftWrapper.cs b/PlayFabSDK/source/Json/NewtonsoftWrapper.cs new file mode 100644 index 00000000..9f1f7007 --- /dev/null +++ b/PlayFabSDK/source/Json/NewtonsoftWrapper.cs @@ -0,0 +1,73 @@ +#if USING_NEWTONSOFT +using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.IO; + +namespace PlayFab.Json +{ + public class NewtonsofJsonInstance : ISerializer + { + public static JsonSerializerSettings JsonSettings = new JsonSerializerSettings + { + NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore, + Converters = { new StringEnumConverter(), new TimeSpanFloatSeconds(), new IsoDateTimeConverter { DateTimeFormat = PlayFabUtil.DefaultDateTimeFormats[0] } }, + }; + private static Formatting JsonFormatting = Formatting.None; + + private readonly JsonSerializer _serializer = JsonSerializer.Create(JsonSettings); + + public T DeserializeObject<T>(string json) + { + return _serializer.Deserialize<T>(new JsonTextReader(new StringReader(json))); + } + + public T DeserializeObject<T>(string json, object jsonSerializerStrategy) + { + var customSerializer = JsonSerializer.Create((JsonSerializerSettings)jsonSerializerStrategy); + return customSerializer.Deserialize<T>(new JsonTextReader(new StringReader(json))); + } + + public object DeserializeObject(string json) + { + return _serializer.Deserialize(new JsonTextReader(new StringReader(json))); + } + + public string SerializeObject(object json) + { + var jsonString = new StringWriter(); + var writer = new JsonTextWriter(jsonString) { Formatting = JsonFormatting }; + _serializer.Serialize(writer, json); + return jsonString.ToString(); + } + + public string SerializeObject(object json, object jsonSerializerStrategy) + { + var customSerializer = JsonSerializer.Create((JsonSerializerSettings)jsonSerializerStrategy); + var jsonString = new StringWriter(); + var writer = new JsonTextWriter(jsonString) { Formatting = JsonFormatting }; + customSerializer.Serialize(writer, json); + return jsonString.ToString(); + } + } + + public class TimeSpanFloatSeconds : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var timeSpan = (TimeSpan)value; + serializer.Serialize(writer, timeSpan.TotalSeconds); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + return TimeSpan.FromSeconds(serializer.Deserialize<float>(reader)); + } + + public override bool CanConvert(Type objectType) + { + return objectType == typeof(TimeSpan); + } + } +} +#endif diff --git a/PlayFabSDK/source/Json/SimpleJson.cs b/PlayFabSDK/source/Json/SimpleJson.cs new file mode 100644 index 00000000..231b4f41 --- /dev/null +++ b/PlayFabSDK/source/Json/SimpleJson.cs @@ -0,0 +1,2078 @@ +//----------------------------------------------------------------------- +// <copyright file="SimpleJson.cs" company="The Outercurve Foundation"> +// Copyright (c) 2011, The Outercurve Foundation. +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.opensource.org/licenses/mit-license.php +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// </copyright> +// <author>Nathan Totten (ntotten.com), Jim Zimmerman (jimzimmerman.com) and Prabir Shrestha (prabir.me)</author> +// <website>https://github.com/facebook-csharp-sdk/simple-json</website> +//----------------------------------------------------------------------- + +// VERSION: + +// NOTE: uncomment the following line to make SimpleJson class internal. +//#define SIMPLE_JSON_INTERNAL + +// NOTE: uncomment the following line to make JsonArray and JsonObject class internal. +//#define SIMPLE_JSON_OBJARRAYINTERNAL + +// NOTE: uncomment the following line to enable dynamic support. +//#define SIMPLE_JSON_DYNAMIC + +// NOTE: uncomment the following line to enable DataContract support. +//#define SIMPLE_JSON_DATACONTRACT + +// NOTE: uncomment the following line to enable IReadOnlyCollection<T> and IReadOnlyList<T> support. +//#define SIMPLE_JSON_READONLY_COLLECTIONS + +// original json parsing code from http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html + +#if NETFX_CORE +#define SIMPLE_JSON_TYPEINFO +#endif + +using System; +using System.CodeDom.Compiler; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +#if SIMPLE_JSON_DYNAMIC +using System.Dynamic; +#endif +using System.Globalization; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.Serialization; +using System.Text; + +// ReSharper disable LoopCanBeConvertedToQuery +// ReSharper disable RedundantExplicitArrayCreation +// ReSharper disable SuggestUseVarKeywordEvident +namespace PlayFab.Json +{ + public enum NullValueHandling + { + Include, // Include null values when serializing and deserializing objects + Ignore // Ignore null values when serializing and deserializing objects + } + + /// <summary> + /// Customize the json output of a field or property + /// </summary> + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] + public class JsonProperty : Attribute + { + public string PropertyName = null; + public NullValueHandling NullValueHandling = NullValueHandling.Include; + } + + /// <summary> + /// Represents the json array. + /// </summary> + [GeneratedCode("simple-json", "1.0.0")] + [EditorBrowsable(EditorBrowsableState.Never)] + [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")] +#if SIMPLE_JSON_OBJARRAYINTERNAL + internal +#else + public +#endif + class JsonArray : List<object> + { + /// <summary> + /// Initializes a new instance of the <see cref="JsonArray"/> class. + /// </summary> + public JsonArray() { } + + /// <summary> + /// Initializes a new instance of the <see cref="JsonArray"/> class. + /// </summary> + /// <param name="capacity">The capacity of the json array.</param> + public JsonArray(int capacity) : base(capacity) { } + + /// <summary> + /// The json representation of the array. + /// </summary> + /// <returns>The json representation of the array.</returns> + public override string ToString() + { + return PlayFabSimpleJson.SerializeObject(this) ?? string.Empty; + } + } + + /// <summary> + /// Represents the json object. + /// </summary> + [GeneratedCode("simple-json", "1.0.0")] + [EditorBrowsable(EditorBrowsableState.Never)] + [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")] +#if SIMPLE_JSON_OBJARRAYINTERNAL + internal +#else + public +#endif + class JsonObject : +#if SIMPLE_JSON_DYNAMIC + DynamicObject, +#endif + IDictionary<string, object> + { + private const int DICTIONARY_DEFAULT_SIZE = 16; + /// <summary> + /// The internal member dictionary. + /// </summary> + private readonly Dictionary<string, object> _members; + + /// <summary> + /// Initializes a new instance of <see cref="JsonObject"/>. + /// </summary> + public JsonObject() + { + _members = new Dictionary<string, object>(DICTIONARY_DEFAULT_SIZE); + } + + /// <summary> + /// Initializes a new instance of <see cref="JsonObject"/>. + /// </summary> + /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer`1"/> implementation to use when comparing keys, or null to use the default <see cref="T:System.Collections.Generic.EqualityComparer`1"/> for the type of the key.</param> + public JsonObject(IEqualityComparer<string> comparer) + { + _members = new Dictionary<string, object>(comparer); + } + + /// <summary> + /// Gets the <see cref="System.Object"/> at the specified index. + /// </summary> + /// <value></value> + public object this[int index] + { + get { return GetAtIndex(_members, index); } + } + + internal static object GetAtIndex(IDictionary<string, object> obj, int index) + { + if (obj == null) + throw new ArgumentNullException("obj"); + if (index >= obj.Count) + throw new ArgumentOutOfRangeException("index"); + int i = 0; + foreach (KeyValuePair<string, object> o in obj) + if (i++ == index) return o.Value; + return null; + } + + /// <summary> + /// Adds the specified key. + /// </summary> + /// <param name="key">The key.</param> + /// <param name="value">The value.</param> + public void Add(string key, object value) + { + _members.Add(key, value); + } + + /// <summary> + /// Determines whether the specified key contains key. + /// </summary> + /// <param name="key">The key.</param> + /// <returns> + /// <c>true</c> if the specified key contains key; otherwise, <c>false</c>. + /// </returns> + public bool ContainsKey(string key) + { + return _members.ContainsKey(key); + } + + /// <summary> + /// Gets the keys. + /// </summary> + /// <value>The keys.</value> + public ICollection<string> Keys + { + get { return _members.Keys; } + } + + /// <summary> + /// Removes the specified key. + /// </summary> + /// <param name="key">The key.</param> + /// <returns></returns> + public bool Remove(string key) + { + return _members.Remove(key); + } + + /// <summary> + /// Tries the get value. + /// </summary> + /// <param name="key">The key.</param> + /// <param name="value">The value.</param> + /// <returns></returns> + public bool TryGetValue(string key, out object value) + { + return _members.TryGetValue(key, out value); + } + + /// <summary> + /// Gets the values. + /// </summary> + /// <value>The values.</value> + public ICollection<object> Values + { + get { return _members.Values; } + } + + /// <summary> + /// Gets or sets the <see cref="System.Object"/> with the specified key. + /// </summary> + /// <value></value> + public object this[string key] + { + get { return _members[key]; } + set { _members[key] = value; } + } + + /// <summary> + /// Adds the specified item. + /// </summary> + /// <param name="item">The item.</param> + public void Add(KeyValuePair<string, object> item) + { + _members.Add(item.Key, item.Value); + } + + /// <summary> + /// Clears this instance. + /// </summary> + public void Clear() + { + _members.Clear(); + } + + /// <summary> + /// Determines whether [contains] [the specified item]. + /// </summary> + /// <param name="item">The item.</param> + /// <returns> + /// <c>true</c> if [contains] [the specified item]; otherwise, <c>false</c>. + /// </returns> + public bool Contains(KeyValuePair<string, object> item) + { + return _members.ContainsKey(item.Key) && _members[item.Key] == item.Value; + } + + /// <summary> + /// Copies to. + /// </summary> + /// <param name="array">The array.</param> + /// <param name="arrayIndex">Index of the array.</param> + public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex) + { + if (array == null) throw new ArgumentNullException("array"); + int num = Count; + foreach (KeyValuePair<string, object> kvp in _members) + { + array[arrayIndex++] = kvp; + if (--num <= 0) + return; + } + } + + /// <summary> + /// Gets the count. + /// </summary> + /// <value>The count.</value> + public int Count + { + get { return _members.Count; } + } + + /// <summary> + /// Gets a value indicating whether this instance is read only. + /// </summary> + /// <value> + /// <c>true</c> if this instance is read only; otherwise, <c>false</c>. + /// </value> + public bool IsReadOnly + { + get { return false; } + } + + /// <summary> + /// Removes the specified item. + /// </summary> + /// <param name="item">The item.</param> + /// <returns></returns> + public bool Remove(KeyValuePair<string, object> item) + { + return _members.Remove(item.Key); + } + + /// <summary> + /// Gets the enumerator. + /// </summary> + /// <returns></returns> + public IEnumerator<KeyValuePair<string, object>> GetEnumerator() + { + return _members.GetEnumerator(); + } + + /// <summary> + /// Returns an enumerator that iterates through a collection. + /// </summary> + /// <returns> + /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection. + /// </returns> + IEnumerator IEnumerable.GetEnumerator() + { + return _members.GetEnumerator(); + } + + /// <summary> + /// Returns a json <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>. + /// </summary> + /// <returns> + /// A json <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>. + /// </returns> + public override string ToString() + { + return PlayFabSimpleJson.SerializeObject(_members); + } + +#if SIMPLE_JSON_DYNAMIC + /// <summary> + /// Provides implementation for type conversion operations. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for operations that convert an object from one type to another. + /// </summary> + /// <param name="binder">Provides information about the conversion operation. The binder.Type property provides the type to which the object must be converted. For example, for the statement (String)sampleObject in C# (CType(sampleObject, Type) in Visual Basic), where sampleObject is an instance of the class derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, binder.Type returns the <see cref="T:System.String"/> type. The binder.Explicit property provides information about the kind of conversion that occurs. It returns true for explicit conversion and false for implicit conversion.</param> + /// <param name="result">The result of the type conversion operation.</param> + /// <returns> + /// Alwasy returns true. + /// </returns> + public override bool TryConvert(ConvertBinder binder, out object result) + { + // <pex> + if (binder == null) + throw new ArgumentNullException("binder"); + // </pex> + Type targetType = binder.Type; + + if ((targetType == typeof(IEnumerable)) || + (targetType == typeof(IEnumerable<KeyValuePair<string, object>>)) || + (targetType == typeof(IDictionary<string, object>)) || + (targetType == typeof(IDictionary))) + { + result = this; + return true; + } + + return base.TryConvert(binder, out result); + } + + /// <summary> + /// Provides the implementation for operations that delete an object member. This method is not intended for use in C# or Visual Basic. + /// </summary> + /// <param name="binder">Provides information about the deletion.</param> + /// <returns> + /// Alwasy returns true. + /// </returns> + public override bool TryDeleteMember(DeleteMemberBinder binder) + { + // <pex> + if (binder == null) + throw new ArgumentNullException("binder"); + // </pex> + return _members.Remove(binder.Name); + } + + /// <summary> + /// Provides the implementation for operations that get a value by index. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for indexing operations. + /// </summary> + /// <param name="binder">Provides information about the operation.</param> + /// <param name="indexes">The indexes that are used in the operation. For example, for the sampleObject[3] operation in C# (sampleObject(3) in Visual Basic), where sampleObject is derived from the DynamicObject class, <paramref name="indexes"/> is equal to 3.</param> + /// <param name="result">The result of the index operation.</param> + /// <returns> + /// Alwasy returns true. + /// </returns> + public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) + { + if (indexes == null) throw new ArgumentNullException("indexes"); + if (indexes.Length == 1) + { + result = ((IDictionary<string, object>)this)[(string)indexes[0]]; + return true; + } + result = null; + return true; + } + + /// <summary> + /// Provides the implementation for operations that get member values. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for operations such as getting a value for a property. + /// </summary> + /// <param name="binder">Provides information about the object that called the dynamic operation. The binder.Name property provides the name of the member on which the dynamic operation is performed. For example, for the Console.WriteLine(sampleObject.SampleProperty) statement, where sampleObject is an instance of the class derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, binder.Name returns "SampleProperty". The binder.IgnoreCase property specifies whether the member name is case-sensitive.</param> + /// <param name="result">The result of the get operation. For example, if the method is called for a property, you can assign the property value to <paramref name="result"/>.</param> + /// <returns> + /// Alwasy returns true. + /// </returns> + public override bool TryGetMember(GetMemberBinder binder, out object result) + { + object value; + if (_members.TryGetValue(binder.Name, out value)) + { + result = value; + return true; + } + result = null; + return true; + } + + /// <summary> + /// Provides the implementation for operations that set a value by index. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for operations that access objects by a specified index. + /// </summary> + /// <param name="binder">Provides information about the operation.</param> + /// <param name="indexes">The indexes that are used in the operation. For example, for the sampleObject[3] = 10 operation in C# (sampleObject(3) = 10 in Visual Basic), where sampleObject is derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, <paramref name="indexes"/> is equal to 3.</param> + /// <param name="value">The value to set to the object that has the specified index. For example, for the sampleObject[3] = 10 operation in C# (sampleObject(3) = 10 in Visual Basic), where sampleObject is derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, <paramref name="value"/> is equal to 10.</param> + /// <returns> + /// true if the operation is successful; otherwise, false. If this method returns false, the run-time binder of the language determines the behavior. (In most cases, a language-specific run-time exception is thrown. + /// </returns> + public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value) + { + if (indexes == null) throw new ArgumentNullException("indexes"); + if (indexes.Length == 1) + { + ((IDictionary<string, object>)this)[(string)indexes[0]] = value; + return true; + } + return base.TrySetIndex(binder, indexes, value); + } + + /// <summary> + /// Provides the implementation for operations that set member values. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for operations such as setting a value for a property. + /// </summary> + /// <param name="binder">Provides information about the object that called the dynamic operation. The binder.Name property provides the name of the member to which the value is being assigned. For example, for the statement sampleObject.SampleProperty = "Test", where sampleObject is an instance of the class derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, binder.Name returns "SampleProperty". The binder.IgnoreCase property specifies whether the member name is case-sensitive.</param> + /// <param name="value">The value to set to the member. For example, for sampleObject.SampleProperty = "Test", where sampleObject is an instance of the class derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, the <paramref name="value"/> is "Test".</param> + /// <returns> + /// true if the operation is successful; otherwise, false. If this method returns false, the run-time binder of the language determines the behavior. (In most cases, a language-specific run-time exception is thrown.) + /// </returns> + public override bool TrySetMember(SetMemberBinder binder, object value) + { + // <pex> + if (binder == null) + throw new ArgumentNullException("binder"); + // </pex> + _members[binder.Name] = value; + return true; + } + + /// <summary> + /// Returns the enumeration of all dynamic member names. + /// </summary> + /// <returns> + /// A sequence that contains dynamic member names. + /// </returns> + public override IEnumerable<string> GetDynamicMemberNames() + { + foreach (var key in Keys) + yield return key; + } +#endif + } + + /// <summary> + /// This class encodes and decodes JSON strings. + /// Spec. details, see http://www.json.org/ + /// + /// JSON uses Arrays and Objects. These correspond here to the datatypes JsonArray(IList<object>) and JsonObject(IDictionary<string,object>). + /// All numbers are parsed to doubles. + /// </summary> + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + static class PlayFabSimpleJson + { + private enum TokenType : byte + { + NONE = 0, + CURLY_OPEN = 1, + CURLY_CLOSE = 2, + SQUARED_OPEN = 3, + SQUARED_CLOSE = 4, + COLON = 5, + COMMA = 6, + STRING = 7, + NUMBER = 8, + TRUE = 9, + FALSE = 10, + NULL = 11, + } + private const int BUILDER_INIT = 2000; + + private static readonly char[] EscapeTable; + private static readonly char[] EscapeCharacters = new char[] { '"', '\\', '\b', '\f', '\n', '\r', '\t' }; + // private static readonly string EscapeCharactersString = new string(EscapeCharacters); + internal static readonly List<Type> NumberTypes = new List<Type> { + typeof(bool), typeof(byte), typeof(ushort), typeof(uint), typeof(ulong), typeof(sbyte), typeof(short), typeof(int), typeof(long), typeof(double), typeof(float), typeof(decimal) + }; + + // Performance stuff + [ThreadStatic] + private static StringBuilder _serializeObjectBuilder; + [ThreadStatic] + private static StringBuilder _parseStringBuilder; + + static PlayFabSimpleJson() + { + EscapeTable = new char[93]; + EscapeTable['"'] = '"'; + EscapeTable['\\'] = '\\'; + EscapeTable['\b'] = 'b'; + EscapeTable['\f'] = 'f'; + EscapeTable['\n'] = 'n'; + EscapeTable['\r'] = 'r'; + EscapeTable['\t'] = 't'; + } + + /// <summary> + /// Parses the string json into a value + /// </summary> + /// <param name="json">A JSON string.</param> + /// <returns>An IList<object>, a IDictionary<string,object>, a double, a string, null, true, or false</returns> + public static object DeserializeObject(string json) + { + object obj; + if (TryDeserializeObject(json, out obj)) + return obj; + throw new SerializationException("Invalid JSON string"); + } + + /// <summary> + /// Try parsing the json string into a value. + /// </summary> + /// <param name="json"> + /// A JSON string. + /// </param> + /// <param name="obj"> + /// The object. + /// </param> + /// <returns> + /// Returns true if successfull otherwise false. + /// </returns> + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification = "Need to support .NET 2")] + public static bool TryDeserializeObject(string json, out object obj) + { + bool success = true; + if (json != null) + { + int index = 0; + obj = ParseValue(json, ref index, ref success); + } + else + obj = null; + + return success; + } + + public static object DeserializeObject(string json, Type type, IJsonSerializerStrategy jsonSerializerStrategy) + { + object jsonObject = DeserializeObject(json); + if (type == null || jsonObject != null && ReflectionUtils.IsAssignableFrom(jsonObject.GetType(), type)) + return jsonObject; + return (jsonSerializerStrategy ?? CurrentJsonSerializerStrategy).DeserializeObject(jsonObject, type); + } + + public static object DeserializeObject(string json, Type type) + { + return DeserializeObject(json, type, null); + } + + public static T DeserializeObject<T>(string json, IJsonSerializerStrategy jsonSerializerStrategy) + { + return (T)DeserializeObject(json, typeof(T), jsonSerializerStrategy); + } + + public static T DeserializeObject<T>(string json) + { + return (T)DeserializeObject(json, typeof(T), null); + } + + /// <summary> + /// Converts a IDictionary<string,object> / IList<object> object into a JSON string + /// </summary> + /// <param name="json">A IDictionary<string,object> / IList<object></param> + /// <param name="jsonSerializerStrategy">Serializer strategy to use</param> + /// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns> + public static string SerializeObject(object json, IJsonSerializerStrategy jsonSerializerStrategy = null) + { + if (_serializeObjectBuilder == null) + _serializeObjectBuilder = new StringBuilder(BUILDER_INIT); + _serializeObjectBuilder.Length = 0; + + if (jsonSerializerStrategy == null) + jsonSerializerStrategy = CurrentJsonSerializerStrategy; + + bool success = SerializeValue(jsonSerializerStrategy, json, _serializeObjectBuilder); + return (success ? _serializeObjectBuilder.ToString() : null); + } + + public static string EscapeToJavascriptString(string jsonString) + { + if (string.IsNullOrEmpty(jsonString)) + return jsonString; + + StringBuilder sb = new StringBuilder(); + char c; + + for (int i = 0; i < jsonString.Length;) + { + c = jsonString[i++]; + + if (c == '\\') + { + int remainingLength = jsonString.Length - i; + if (remainingLength >= 2) + { + char lookahead = jsonString[i]; + if (lookahead == '\\') + { + sb.Append('\\'); + ++i; + } + else if (lookahead == '"') + { + sb.Append("\""); + ++i; + } + else if (lookahead == 't') + { + sb.Append('\t'); + ++i; + } + else if (lookahead == 'b') + { + sb.Append('\b'); + ++i; + } + else if (lookahead == 'n') + { + sb.Append('\n'); + ++i; + } + else if (lookahead == 'r') + { + sb.Append('\r'); + ++i; + } + } + } + else + { + sb.Append(c); + } + } + return sb.ToString(); + } + + static IDictionary<string, object> ParseObject(string json, ref int index, ref bool success) + { + IDictionary<string, object> table = new JsonObject(); + TokenType token; + + // { + NextToken(json, ref index); + + bool done = false; + while (!done) + { + token = LookAhead(json, index); + if (token == TokenType.NONE) + { + success = false; + return null; + } + else if (token == TokenType.COMMA) + NextToken(json, ref index); + else if (token == TokenType.CURLY_CLOSE) + { + NextToken(json, ref index); + return table; + } + else + { + // name + string name = ParseString(json, ref index, ref success); + if (!success) + { + success = false; + return null; + } + // : + token = NextToken(json, ref index); + if (token != TokenType.COLON) + { + success = false; + return null; + } + // value + object value = ParseValue(json, ref index, ref success); + if (!success) + { + success = false; + return null; + } + table[name] = value; + } + } + return table; + } + + static JsonArray ParseArray(string json, ref int index, ref bool success) + { + JsonArray array = new JsonArray(); + + // [ + NextToken(json, ref index); + + bool done = false; + while (!done) + { + TokenType token = LookAhead(json, index); + if (token == TokenType.NONE) + { + success = false; + return null; + } + else if (token == TokenType.COMMA) + NextToken(json, ref index); + else if (token == TokenType.SQUARED_CLOSE) + { + NextToken(json, ref index); + break; + } + else + { + object value = ParseValue(json, ref index, ref success); + if (!success) + return null; + array.Add(value); + } + } + return array; + } + + static object ParseValue(string json, ref int index, ref bool success) + { + switch (LookAhead(json, index)) + { + case TokenType.STRING: + return ParseString(json, ref index, ref success); + case TokenType.NUMBER: + return ParseNumber(json, ref index, ref success); + case TokenType.CURLY_OPEN: + return ParseObject(json, ref index, ref success); + case TokenType.SQUARED_OPEN: + return ParseArray(json, ref index, ref success); + case TokenType.TRUE: + NextToken(json, ref index); + return true; + case TokenType.FALSE: + NextToken(json, ref index); + return false; + case TokenType.NULL: + NextToken(json, ref index); + return null; + case TokenType.NONE: + break; + } + success = false; + return null; + } + + static string ParseString(string json, ref int index, ref bool success) + { + if (_parseStringBuilder == null) + _parseStringBuilder = new StringBuilder(BUILDER_INIT); + _parseStringBuilder.Length = 0; + + EatWhitespace(json, ref index); + + // " + char c = json[index++]; + bool complete = false; + while (!complete) + { + if (index == json.Length) + break; + + c = json[index++]; + if (c == '"') + { + complete = true; + break; + } + else if (c == '\\') + { + if (index == json.Length) + break; + c = json[index++]; + if (c == '"') + _parseStringBuilder.Append('"'); + else if (c == '\\') + _parseStringBuilder.Append('\\'); + else if (c == '/') + _parseStringBuilder.Append('/'); + else if (c == 'b') + _parseStringBuilder.Append('\b'); + else if (c == 'f') + _parseStringBuilder.Append('\f'); + else if (c == 'n') + _parseStringBuilder.Append('\n'); + else if (c == 'r') + _parseStringBuilder.Append('\r'); + else if (c == 't') + _parseStringBuilder.Append('\t'); + else if (c == 'u') + { + int remainingLength = json.Length - index; + if (remainingLength >= 4) + { + // parse the 32 bit hex into an integer codepoint + uint codePoint; + if (!(success = UInt32.TryParse(json.Substring(index, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out codePoint))) + return ""; + + // convert the integer codepoint to a unicode char and add to string + if (0xD800 <= codePoint && codePoint <= 0xDBFF) // if high surrogate + { + index += 4; // skip 4 chars + remainingLength = json.Length - index; + if (remainingLength >= 6) + { + uint lowCodePoint; + if (json.Substring(index, 2) == "\\u" && UInt32.TryParse(json.Substring(index + 2, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out lowCodePoint)) + { + if (0xDC00 <= lowCodePoint && lowCodePoint <= 0xDFFF) // if low surrogate + { + _parseStringBuilder.Append((char)codePoint); + _parseStringBuilder.Append((char)lowCodePoint); + index += 6; // skip 6 chars + continue; + } + } + } + success = false; // invalid surrogate pair + return ""; + } + _parseStringBuilder.Append(ConvertFromUtf32((int)codePoint)); + // skip 4 chars + index += 4; + } + else + break; + } + } + else + _parseStringBuilder.Append(c); + } + if (!complete) + { + success = false; + return null; + } + return _parseStringBuilder.ToString(); + } + + private static string ConvertFromUtf32(int utf32) + { + // http://www.java2s.com/Open-Source/CSharp/2.6.4-mono-.net-core/System/System/Char.cs.htm + if (utf32 < 0 || utf32 > 0x10FFFF) + throw new ArgumentOutOfRangeException("utf32", "The argument must be from 0 to 0x10FFFF."); + if (0xD800 <= utf32 && utf32 <= 0xDFFF) + throw new ArgumentOutOfRangeException("utf32", "The argument must not be in surrogate pair range."); + if (utf32 < 0x10000) + return new string((char)utf32, 1); + utf32 -= 0x10000; + return new string(new char[] { (char)((utf32 >> 10) + 0xD800), (char)(utf32 % 0x0400 + 0xDC00) }); + } + + static object ParseNumber(string json, ref int index, ref bool success) + { + EatWhitespace(json, ref index); + int lastIndex = GetLastIndexOfNumber(json, index); + int charLength = (lastIndex - index) + 1; + object returnNumber; + string str = json.Substring(index, charLength); + if (str.IndexOf(".", StringComparison.OrdinalIgnoreCase) != -1 || str.IndexOf("e", StringComparison.OrdinalIgnoreCase) != -1) + { + double number; + success = double.TryParse(json.Substring(index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); + returnNumber = number; + } + else if (str.IndexOf("-", StringComparison.OrdinalIgnoreCase) == -1) + { + ulong number; + success = ulong.TryParse(json.Substring(index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); + returnNumber = number; + } + else + { + long number; + success = long.TryParse(json.Substring(index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); + returnNumber = number; + } + index = lastIndex + 1; + return returnNumber; + } + + static int GetLastIndexOfNumber(string json, int index) + { + int lastIndex; + for (lastIndex = index; lastIndex < json.Length; lastIndex++) + if ("0123456789+-.eE".IndexOf(json[lastIndex]) == -1) break; + return lastIndex - 1; + } + + static void EatWhitespace(string json, ref int index) + { + for (; index < json.Length; index++) + if (" \t\n\r\b\f".IndexOf(json[index]) == -1) break; + } + + static TokenType LookAhead(string json, int index) + { + int saveIndex = index; + return NextToken(json, ref saveIndex); + } + + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + static TokenType NextToken(string json, ref int index) + { + EatWhitespace(json, ref index); + if (index == json.Length) + return TokenType.NONE; + char c = json[index]; + index++; + switch (c) + { + case '{': + return TokenType.CURLY_OPEN; + case '}': + return TokenType.CURLY_CLOSE; + case '[': + return TokenType.SQUARED_OPEN; + case ']': + return TokenType.SQUARED_CLOSE; + case ',': + return TokenType.COMMA; + case '"': + return TokenType.STRING; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + return TokenType.NUMBER; + case ':': + return TokenType.COLON; + } + index--; + int remainingLength = json.Length - index; + // false + if (remainingLength >= 5) + { + if (json[index] == 'f' && json[index + 1] == 'a' && json[index + 2] == 'l' && json[index + 3] == 's' && json[index + 4] == 'e') + { + index += 5; + return TokenType.FALSE; + } + } + // true + if (remainingLength >= 4) + { + if (json[index] == 't' && json[index + 1] == 'r' && json[index + 2] == 'u' && json[index + 3] == 'e') + { + index += 4; + return TokenType.TRUE; + } + } + // null + if (remainingLength >= 4) + { + if (json[index] == 'n' && json[index + 1] == 'u' && json[index + 2] == 'l' && json[index + 3] == 'l') + { + index += 4; + return TokenType.NULL; + } + } + return TokenType.NONE; + } + + static bool SerializeValue(IJsonSerializerStrategy jsonSerializerStrategy, object value, StringBuilder builder) + { + bool success = true; + string stringValue = value as string; + if (value == null) + builder.Append("null"); + else if (stringValue != null) + success = SerializeString(stringValue, builder); + else + { + IDictionary<string, object> dict = value as IDictionary<string, object>; + Type type = value.GetType(); + Type[] genArgs = ReflectionUtils.GetGenericTypeArguments(type); + var isStringKeyDictionary = type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>) && genArgs[0] == typeof(string); + if (isStringKeyDictionary) + { + var strDictValue = value as IDictionary; + success = SerializeObject(jsonSerializerStrategy, strDictValue.Keys, strDictValue.Values, builder); + } + else if (dict != null) + { + success = SerializeObject(jsonSerializerStrategy, dict.Keys, dict.Values, builder); + } + else + { + IDictionary<string, string> stringDictionary = value as IDictionary<string, string>; + if (stringDictionary != null) + { + success = SerializeObject(jsonSerializerStrategy, stringDictionary.Keys, stringDictionary.Values, builder); + } + else + { + IEnumerable enumerableValue = value as IEnumerable; + if (enumerableValue != null) + success = SerializeArray(jsonSerializerStrategy, enumerableValue, builder); + else if (IsNumeric(value)) + success = SerializeNumber(value, builder); + else if (value is bool) + builder.Append((bool)value ? "true" : "false"); + else + { + object serializedObject; + success = jsonSerializerStrategy.TrySerializeNonPrimitiveObject(value, out serializedObject); + if (success) + SerializeValue(jsonSerializerStrategy, serializedObject, builder); + } + } + } + } + return success; + } + + static bool SerializeObject(IJsonSerializerStrategy jsonSerializerStrategy, IEnumerable keys, IEnumerable values, StringBuilder builder) + { + builder.Append("{"); + IEnumerator ke = keys.GetEnumerator(); + IEnumerator ve = values.GetEnumerator(); + bool first = true; + while (ke.MoveNext() && ve.MoveNext()) + { + object key = ke.Current; + object value = ve.Current; + if (!first) + builder.Append(","); + string stringKey = key as string; + if (stringKey != null) + SerializeString(stringKey, builder); + else + if (!SerializeValue(jsonSerializerStrategy, value, builder)) return false; + builder.Append(":"); + if (!SerializeValue(jsonSerializerStrategy, value, builder)) + return false; + first = false; + } + builder.Append("}"); + return true; + } + + static bool SerializeArray(IJsonSerializerStrategy jsonSerializerStrategy, IEnumerable anArray, StringBuilder builder) + { + builder.Append("["); + bool first = true; + foreach (object value in anArray) + { + if (!first) + builder.Append(","); + if (!SerializeValue(jsonSerializerStrategy, value, builder)) + return false; + first = false; + } + builder.Append("]"); + return true; + } + + static bool SerializeString(string aString, StringBuilder builder) + { + // Happy path if there's nothing to be escaped. IndexOfAny is highly optimized (and unmanaged) + if (aString.IndexOfAny(EscapeCharacters) == -1) + { + builder.Append('"'); + builder.Append(aString); + builder.Append('"'); + + return true; + } + + builder.Append('"'); + int safeCharacterCount = 0; + char[] charArray = aString.ToCharArray(); + + for (int i = 0; i < charArray.Length; i++) + { + char c = charArray[i]; + + // Non ascii characters are fine, buffer them up and send them to the builder + // in larger chunks if possible. The escape table is a 1:1 translation table + // with \0 [default(char)] denoting a safe character. + if (c >= EscapeTable.Length || EscapeTable[c] == default(char)) + { + safeCharacterCount++; + } + else + { + if (safeCharacterCount > 0) + { + builder.Append(charArray, i - safeCharacterCount, safeCharacterCount); + safeCharacterCount = 0; + } + + builder.Append('\\'); + builder.Append(EscapeTable[c]); + } + } + + if (safeCharacterCount > 0) + { + builder.Append(charArray, charArray.Length - safeCharacterCount, safeCharacterCount); + } + + builder.Append('"'); + return true; + } + + static bool SerializeNumber(object number, StringBuilder builder) + { + if (number is decimal) + builder.Append(((decimal)number).ToString("R", CultureInfo.InvariantCulture)); + else if (number is double) + builder.Append(((double)number).ToString("R", CultureInfo.InvariantCulture)); + else if (number is float) + builder.Append(((float)number).ToString("R", CultureInfo.InvariantCulture)); + else if (NumberTypes.IndexOf(number.GetType()) != -1) + builder.Append(number); + return true; + } + + /// <summary> + /// Determines if a given object is numeric in any way + /// (can be integer, double, null, etc). + /// </summary> + static bool IsNumeric(object value) + { + if (value is sbyte) return true; + if (value is byte) return true; + if (value is short) return true; + if (value is ushort) return true; + if (value is int) return true; + if (value is uint) return true; + if (value is long) return true; + if (value is ulong) return true; + if (value is float) return true; + if (value is double) return true; + if (value is decimal) return true; + return false; + } + + private static IJsonSerializerStrategy _currentJsonSerializerStrategy; + public static IJsonSerializerStrategy CurrentJsonSerializerStrategy + { + get + { + return _currentJsonSerializerStrategy ?? + (_currentJsonSerializerStrategy = +#if SIMPLE_JSON_DATACONTRACT + DataContractJsonSerializerStrategy +#else + PocoJsonSerializerStrategy +#endif +); + } + set + { + _currentJsonSerializerStrategy = value; + } + } + + private static PocoJsonSerializerStrategy _pocoJsonSerializerStrategy; + [EditorBrowsable(EditorBrowsableState.Advanced)] + public static PocoJsonSerializerStrategy PocoJsonSerializerStrategy + { + get + { + return _pocoJsonSerializerStrategy ?? (_pocoJsonSerializerStrategy = new PocoJsonSerializerStrategy()); + } + } + +#if SIMPLE_JSON_DATACONTRACT + + private static DataContractJsonSerializerStrategy _dataContractJsonSerializerStrategy; + [System.ComponentModel.EditorBrowsable(EditorBrowsableState.Advanced)] + public static DataContractJsonSerializerStrategy DataContractJsonSerializerStrategy + { + get + { + return _dataContractJsonSerializerStrategy ?? (_dataContractJsonSerializerStrategy = new DataContractJsonSerializerStrategy()); + } + } + +#endif + } + + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + interface IJsonSerializerStrategy + { + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification = "Need to support .NET 2")] + bool TrySerializeNonPrimitiveObject(object input, out object output); + object DeserializeObject(object value, Type type); + } + + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + class PocoJsonSerializerStrategy : IJsonSerializerStrategy + { + internal IDictionary<Type, ReflectionUtils.ConstructorDelegate> ConstructorCache; + internal IDictionary<Type, IDictionary<MemberInfo, ReflectionUtils.GetDelegate>> GetCache; + internal IDictionary<Type, IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>>> SetCache; + + internal static readonly Type[] EmptyTypes = new Type[0]; + internal static readonly Type[] ArrayConstructorParameterTypes = new Type[] { typeof(int) }; + + private static readonly string[] Iso8601Format = new string[] + { + @"yyyy-MM-dd\THH:mm:ss.FFFFFFF\Z", + @"yyyy-MM-dd\THH:mm:ss\Z", + @"yyyy-MM-dd\THH:mm:ssK" + }; + + public PocoJsonSerializerStrategy() + { + ConstructorCache = new ReflectionUtils.ThreadSafeDictionary<Type, ReflectionUtils.ConstructorDelegate>(ContructorDelegateFactory); + GetCache = new ReflectionUtils.ThreadSafeDictionary<Type, IDictionary<MemberInfo, ReflectionUtils.GetDelegate>>(GetterValueFactory); + SetCache = new ReflectionUtils.ThreadSafeDictionary<Type, IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>>>(SetterValueFactory); + } + + protected virtual string MapClrMemberNameToJsonFieldName(MemberInfo memberInfo) + { + // TODO: Optimize and/or cache + foreach (JsonProperty eachAttr in memberInfo.GetCustomAttributes(typeof(JsonProperty), true)) + if (!string.IsNullOrEmpty(eachAttr.PropertyName)) + return eachAttr.PropertyName; + return memberInfo.Name; + } + + protected virtual void MapClrMemberNameToJsonFieldName(MemberInfo memberInfo, out string jsonName, out JsonProperty jsonProp) + { + jsonName = memberInfo.Name; + jsonProp = null; + // TODO: Optimize and/or cache + foreach (JsonProperty eachAttr in memberInfo.GetCustomAttributes(typeof(JsonProperty), true)) + { + jsonProp = eachAttr; + if (!string.IsNullOrEmpty(eachAttr.PropertyName)) + jsonName = eachAttr.PropertyName; + } + } + + internal virtual ReflectionUtils.ConstructorDelegate ContructorDelegateFactory(Type key) + { + return ReflectionUtils.GetContructor(key, key.IsArray ? ArrayConstructorParameterTypes : EmptyTypes); + } + + internal virtual IDictionary<MemberInfo, ReflectionUtils.GetDelegate> GetterValueFactory(Type type) + { + IDictionary<MemberInfo, ReflectionUtils.GetDelegate> result = new Dictionary<MemberInfo, ReflectionUtils.GetDelegate>(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanRead) + { + MethodInfo getMethod = ReflectionUtils.GetGetterMethodInfo(propertyInfo); + if (getMethod.IsStatic || !getMethod.IsPublic) + continue; + result[propertyInfo] = ReflectionUtils.GetGetMethod(propertyInfo); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (fieldInfo.IsStatic || !fieldInfo.IsPublic) + continue; + result[fieldInfo] = ReflectionUtils.GetGetMethod(fieldInfo); + } + return result; + } + + internal virtual IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>> SetterValueFactory(Type type) + { + IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>> result = new Dictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>>(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanWrite) + { + MethodInfo setMethod = ReflectionUtils.GetSetterMethodInfo(propertyInfo); + if (setMethod.IsStatic || !setMethod.IsPublic) + continue; + result[MapClrMemberNameToJsonFieldName(propertyInfo)] = new KeyValuePair<Type, ReflectionUtils.SetDelegate>(propertyInfo.PropertyType, ReflectionUtils.GetSetMethod(propertyInfo)); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (fieldInfo.IsInitOnly || fieldInfo.IsStatic || !fieldInfo.IsPublic) + continue; + result[MapClrMemberNameToJsonFieldName(fieldInfo)] = new KeyValuePair<Type, ReflectionUtils.SetDelegate>(fieldInfo.FieldType, ReflectionUtils.GetSetMethod(fieldInfo)); + } + return result; + } + + public virtual bool TrySerializeNonPrimitiveObject(object input, out object output) + { + return TrySerializeKnownTypes(input, out output) || TrySerializeUnknownTypes(input, out output); + } + + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + public virtual object DeserializeObject(object value, Type type) + { + if (type == null) throw new ArgumentNullException("type"); + if (value != null && type.IsInstanceOfType(value)) return value; + + string str = value as string; + if (type == typeof(Guid) && string.IsNullOrEmpty(str)) + return default(Guid); + + if (value == null) + return null; + + object obj = null; + + if (str != null) + { + if (str.Length != 0) // We know it can't be null now. + { + if (type == typeof(DateTime) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(DateTime))) + return DateTime.ParseExact(str, Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal); + if (type == typeof(DateTimeOffset) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(DateTimeOffset))) + return DateTimeOffset.ParseExact(str, Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal); + if (type == typeof(Guid) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid))) + return new Guid(str); + if (type == typeof(Uri)) + { + bool isValid = Uri.IsWellFormedUriString(str, UriKind.RelativeOrAbsolute); + + Uri result; + if (isValid && Uri.TryCreate(str, UriKind.RelativeOrAbsolute, out result)) + return result; + + return null; + } + + if (type == typeof(string)) + return str; + + return Convert.ChangeType(str, type, CultureInfo.InvariantCulture); + } + else + { + if (type == typeof(Guid)) + obj = default(Guid); + else if (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid)) + obj = null; + else + obj = str; + } + // Empty string case + if (!ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid)) + return str; + } + else if (value is bool) + return value; + + bool valueIsLong = value is long; + bool valueIsUlong = value is ulong; + bool valueIsDouble = value is double; + Type nullableType = Nullable.GetUnderlyingType(type); + if (nullableType != null && PlayFabSimpleJson.NumberTypes.IndexOf(nullableType) != -1) + type = nullableType; // Just use the regular type for the conversion + bool isNumberType = PlayFabSimpleJson.NumberTypes.IndexOf(type) != -1; + bool isEnumType = type.GetTypeInfo().IsEnum; + if ((valueIsLong && type == typeof(long)) || (valueIsUlong && type == typeof(ulong)) || (valueIsDouble && type == typeof(double))) + return value; + if ((valueIsLong || valueIsUlong || valueIsDouble) && isEnumType) + return Enum.ToObject(type, Convert.ChangeType(value, Enum.GetUnderlyingType(type), CultureInfo.InvariantCulture)); + if ((valueIsLong || valueIsUlong || valueIsDouble) && isNumberType) + return Convert.ChangeType(value, type, CultureInfo.InvariantCulture); + + IDictionary<string, object> objects = value as IDictionary<string, object>; + if (objects != null) + { + IDictionary<string, object> jsonObject = objects; + + if (ReflectionUtils.IsTypeDictionary(type)) + { + // if dictionary then + Type[] types = ReflectionUtils.GetGenericTypeArguments(type); + Type keyType = types[0]; + Type valueType = types[1]; + + Type genericType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType); + + IDictionary dict = (IDictionary)ConstructorCache[genericType](); + + foreach (KeyValuePair<string, object> kvp in jsonObject) + dict.Add(kvp.Key, DeserializeObject(kvp.Value, valueType)); + + obj = dict; + } + else + { + if (type == typeof(object)) + obj = value; + else + { + obj = ConstructorCache[type](); + foreach (KeyValuePair<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>> setter in SetCache[type]) + { + object jsonValue; + if (jsonObject.TryGetValue(setter.Key, out jsonValue)) + { + jsonValue = DeserializeObject(jsonValue, setter.Value.Key); + setter.Value.Value(obj, jsonValue); + } + } + } + } + } + else + { + IList<object> valueAsList = value as IList<object>; + if (valueAsList != null) + { + IList<object> jsonObject = valueAsList; + IList list = null; + + if (type.IsArray) + { + list = (IList)ConstructorCache[type](jsonObject.Count); + int i = 0; + foreach (object o in jsonObject) + list[i++] = DeserializeObject(o, type.GetElementType()); + } + else if (ReflectionUtils.IsTypeGenericeCollectionInterface(type) || ReflectionUtils.IsAssignableFrom(typeof(IList), type) || type == typeof(object)) + { + Type innerType = ReflectionUtils.GetGenericListElementType(type); + ReflectionUtils.ConstructorDelegate ctrDelegate = null; + if (type != typeof(object)) + ctrDelegate = ConstructorCache[type]; + if (ctrDelegate == null) + ctrDelegate = ConstructorCache[typeof(List<>).MakeGenericType(innerType)]; + list = (IList)ctrDelegate(); + foreach (object o in jsonObject) + list.Add(DeserializeObject(o, innerType)); + } + obj = list; + } + return obj; + } + if (ReflectionUtils.IsNullableType(type)) + return ReflectionUtils.ToNullableType(obj, type); + return obj; + } + + protected virtual object SerializeEnum(Enum p) + { + return Convert.ToDouble(p, CultureInfo.InvariantCulture); + } + + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification = "Need to support .NET 2")] + protected virtual bool TrySerializeKnownTypes(object input, out object output) + { + bool returnValue = true; + if (input is DateTime) + output = ((DateTime)input).ToUniversalTime().ToString(Iso8601Format[0], CultureInfo.InvariantCulture); + else if (input is DateTimeOffset) + output = ((DateTimeOffset)input).ToUniversalTime().ToString(Iso8601Format[0], CultureInfo.InvariantCulture); + else if (input is Guid) + output = ((Guid)input).ToString("D"); + else if (input is Uri) + output = input.ToString(); + else + { + Enum inputEnum = input as Enum; + if (inputEnum != null) + output = SerializeEnum(inputEnum); + else + { + returnValue = false; + output = null; + } + } + return returnValue; + } + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification = "Need to support .NET 2")] + protected virtual bool TrySerializeUnknownTypes(object input, out object output) + { + if (input == null) throw new ArgumentNullException("input"); + output = null; + Type type = input.GetType(); + if (type.FullName == null) + return false; + IDictionary<string, object> obj = new JsonObject(); + IDictionary<MemberInfo, ReflectionUtils.GetDelegate> getters = GetCache[type]; + foreach (KeyValuePair<MemberInfo, ReflectionUtils.GetDelegate> getter in getters) + { + if (getter.Value == null) + continue; + string jsonKey; + JsonProperty jsonProp; + MapClrMemberNameToJsonFieldName(getter.Key, out jsonKey, out jsonProp); + if (obj.ContainsKey(jsonKey)) + throw new Exception("The given key is defined multiple times in the same type: " + input.GetType().Name + "." + jsonKey); + object value = getter.Value(input); + if (jsonProp == null || jsonProp.NullValueHandling == NullValueHandling.Include || value != null) + obj.Add(jsonKey, value); + } + output = obj; + return true; + } + } + +#if SIMPLE_JSON_DATACONTRACT + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + class DataContractJsonSerializerStrategy : PocoJsonSerializerStrategy + { + public DataContractJsonSerializerStrategy() + { + GetCache = new ReflectionUtils.ThreadSafeDictionary<Type, IDictionary<string, ReflectionUtils.GetDelegate>>(GetterValueFactory); + SetCache = new ReflectionUtils.ThreadSafeDictionary<Type, IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>>>(SetterValueFactory); + } + + internal override IDictionary<string, ReflectionUtils.GetDelegate> GetterValueFactory(Type type) + { + bool hasDataContract = ReflectionUtils.GetAttribute(type, typeof(DataContractAttribute)) != null; + if (!hasDataContract) + return base.GetterValueFactory(type); + string jsonKey; + IDictionary<string, ReflectionUtils.GetDelegate> result = new Dictionary<string, ReflectionUtils.GetDelegate>(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanRead) + { + MethodInfo getMethod = ReflectionUtils.GetGetterMethodInfo(propertyInfo); + if (!getMethod.IsStatic && CanAdd(propertyInfo, out jsonKey)) + result[jsonKey] = ReflectionUtils.GetGetMethod(propertyInfo); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (!fieldInfo.IsStatic && CanAdd(fieldInfo, out jsonKey)) + result[jsonKey] = ReflectionUtils.GetGetMethod(fieldInfo); + } + return result; + } + + internal override IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>> SetterValueFactory(Type type) + { + bool hasDataContract = ReflectionUtils.GetAttribute(type, typeof(DataContractAttribute)) != null; + if (!hasDataContract) + return base.SetterValueFactory(type); + string jsonKey; + IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>> result = new Dictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>>(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanWrite) + { + MethodInfo setMethod = ReflectionUtils.GetSetterMethodInfo(propertyInfo); + if (!setMethod.IsStatic && CanAdd(propertyInfo, out jsonKey)) + result[jsonKey] = new KeyValuePair<Type, ReflectionUtils.SetDelegate>(propertyInfo.PropertyType, ReflectionUtils.GetSetMethod(propertyInfo)); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (!fieldInfo.IsInitOnly && !fieldInfo.IsStatic && CanAdd(fieldInfo, out jsonKey)) + result[jsonKey] = new KeyValuePair<Type, ReflectionUtils.SetDelegate>(fieldInfo.FieldType, ReflectionUtils.GetSetMethod(fieldInfo)); + } + // todo implement sorting for DATACONTRACT. + return result; + } + + private static bool CanAdd(MemberInfo info, out string jsonKey) + { + jsonKey = null; + if (ReflectionUtils.GetAttribute(info, typeof(IgnoreDataMemberAttribute)) != null) + return false; + DataMemberAttribute dataMemberAttribute = (DataMemberAttribute)ReflectionUtils.GetAttribute(info, typeof(DataMemberAttribute)); + if (dataMemberAttribute == null) + return false; + jsonKey = string.IsNullOrEmpty(dataMemberAttribute.Name) ? info.Name : dataMemberAttribute.Name; + return true; + } + } + +#endif + + // This class is meant to be copied into other libraries. So we want to exclude it from Code Analysis rules + // that might be in place in the target project. + [GeneratedCode("reflection-utils", "1.0.0")] +#if SIMPLE_JSON_REFLECTION_UTILS_PUBLIC + public +#else + internal +#endif + class ReflectionUtils + { + private static readonly object[] EmptyObjects = new object[0]; + + public delegate object GetDelegate(object source); + public delegate void SetDelegate(object source, object value); + public delegate object ConstructorDelegate(params object[] args); + + public delegate TValue ThreadSafeDictionaryValueFactory<TKey, TValue>(TKey key); + + [ThreadStatic] + private static object[] _1ObjArray; + +#if SIMPLE_JSON_TYPEINFO + public static TypeInfo GetTypeInfo(Type type) + { + return type.GetTypeInfo(); + } +#else + public static Type GetTypeInfo(Type type) + { + return type; + } +#endif + + public static Attribute GetAttribute(MemberInfo info, Type type) + { +#if SIMPLE_JSON_TYPEINFO + if (info == null || type == null || !info.IsDefined(type)) + return null; + return info.GetCustomAttribute(type); +#else + if (info == null || type == null || !Attribute.IsDefined(info, type)) + return null; + return Attribute.GetCustomAttribute(info, type); +#endif + } + + public static Type GetGenericListElementType(Type type) + { + if (type == typeof(object)) + return type; + + IEnumerable<Type> interfaces; +#if SIMPLE_JSON_TYPEINFO + interfaces = type.GetTypeInfo().ImplementedInterfaces; +#else + interfaces = type.GetInterfaces(); +#endif + foreach (Type implementedInterface in interfaces) + { + if (IsTypeGeneric(implementedInterface) && + implementedInterface.GetGenericTypeDefinition() == typeof(IList<>)) + { + return GetGenericTypeArguments(implementedInterface)[0]; + } + } + return GetGenericTypeArguments(type)[0]; + } + + public static Attribute GetAttribute(Type objectType, Type attributeType) + { + +#if SIMPLE_JSON_TYPEINFO + if (objectType == null || attributeType == null || !objectType.GetTypeInfo().IsDefined(attributeType)) + return null; + return objectType.GetTypeInfo().GetCustomAttribute(attributeType); +#else + if (objectType == null || attributeType == null || !Attribute.IsDefined(objectType, attributeType)) + return null; + return Attribute.GetCustomAttribute(objectType, attributeType); +#endif + } + + public static Type[] GetGenericTypeArguments(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetTypeInfo().GenericTypeArguments; +#else + return type.GetGenericArguments(); +#endif + } + + public static bool IsTypeGeneric(Type type) + { + return GetTypeInfo(type).IsGenericType; + } + + public static bool IsTypeGenericeCollectionInterface(Type type) + { + if (!IsTypeGeneric(type)) + return false; + + Type genericDefinition = type.GetGenericTypeDefinition(); + + return (genericDefinition == typeof(IList<>) + || genericDefinition == typeof(ICollection<>) + || genericDefinition == typeof(IEnumerable<>) +#if SIMPLE_JSON_READONLY_COLLECTIONS + || genericDefinition == typeof(IReadOnlyCollection<>) + || genericDefinition == typeof(IReadOnlyList<>) +#endif +); + } + + public static bool IsAssignableFrom(Type type1, Type type2) + { + return GetTypeInfo(type1).IsAssignableFrom(GetTypeInfo(type2)); + } + + public static bool IsTypeDictionary(Type type) + { +#if SIMPLE_JSON_TYPEINFO + if (typeof(IDictionary<,>).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo())) + return true; +#else + if (typeof(System.Collections.IDictionary).IsAssignableFrom(type)) + return true; +#endif + if (!GetTypeInfo(type).IsGenericType) + return false; + + Type genericDefinition = type.GetGenericTypeDefinition(); + return genericDefinition == typeof(IDictionary<,>) || genericDefinition == typeof(Dictionary<,>); + } + + public static bool IsNullableType(Type type) + { + return GetTypeInfo(type).IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); + } + + public static object ToNullableType(object obj, Type nullableType) + { + return obj == null ? null : Convert.ChangeType(obj, Nullable.GetUnderlyingType(nullableType), CultureInfo.InvariantCulture); + } + + public static bool IsValueType(Type type) + { + return GetTypeInfo(type).IsValueType; + } + + public static IEnumerable<ConstructorInfo> GetConstructors(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetTypeInfo().DeclaredConstructors; +#else + return type.GetConstructors(); +#endif + } + + public static ConstructorInfo GetConstructorInfo(Type type, params Type[] argsType) + { + IEnumerable<ConstructorInfo> constructorInfos = GetConstructors(type); + int i; + bool matches; + foreach (ConstructorInfo constructorInfo in constructorInfos) + { + ParameterInfo[] parameters = constructorInfo.GetParameters(); + if (argsType.Length != parameters.Length) + continue; + + i = 0; + matches = true; + foreach (ParameterInfo parameterInfo in constructorInfo.GetParameters()) + { + if (parameterInfo.ParameterType != argsType[i]) + { + matches = false; + break; + } + } + + if (matches) + return constructorInfo; + } + + return null; + } + + public static IEnumerable<PropertyInfo> GetProperties(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetRuntimeProperties(); +#else + return type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); +#endif + } + + public static IEnumerable<FieldInfo> GetFields(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetRuntimeFields(); +#else + return type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); +#endif + } + + public static MethodInfo GetGetterMethodInfo(PropertyInfo propertyInfo) + { +#if SIMPLE_JSON_TYPEINFO + return propertyInfo.GetMethod; +#else + return propertyInfo.GetGetMethod(true); +#endif + } + + public static MethodInfo GetSetterMethodInfo(PropertyInfo propertyInfo) + { +#if SIMPLE_JSON_TYPEINFO + return propertyInfo.SetMethod; +#else + return propertyInfo.GetSetMethod(true); +#endif + } + + public static ConstructorDelegate GetContructor(ConstructorInfo constructorInfo) + { + return GetConstructorByReflection(constructorInfo); + } + + public static ConstructorDelegate GetContructor(Type type, params Type[] argsType) + { + return GetConstructorByReflection(type, argsType); + } + + public static ConstructorDelegate GetConstructorByReflection(ConstructorInfo constructorInfo) + { + return delegate (object[] args) + { + var x = constructorInfo; + return x.Invoke(args); + }; + } + + public static ConstructorDelegate GetConstructorByReflection(Type type, params Type[] argsType) + { + ConstructorInfo constructorInfo = GetConstructorInfo(type, argsType); + return constructorInfo == null ? null : GetConstructorByReflection(constructorInfo); + } + + public static GetDelegate GetGetMethod(PropertyInfo propertyInfo) + { + return GetGetMethodByReflection(propertyInfo); + } + + public static GetDelegate GetGetMethod(FieldInfo fieldInfo) + { + return GetGetMethodByReflection(fieldInfo); + } + + public static GetDelegate GetGetMethodByReflection(PropertyInfo propertyInfo) + { + MethodInfo methodInfo = GetGetterMethodInfo(propertyInfo); + return delegate (object source) { return methodInfo.Invoke(source, EmptyObjects); }; + } + + public static GetDelegate GetGetMethodByReflection(FieldInfo fieldInfo) + { + return delegate (object source) { return fieldInfo.GetValue(source); }; + } + + public static SetDelegate GetSetMethod(PropertyInfo propertyInfo) + { + return GetSetMethodByReflection(propertyInfo); + } + + public static SetDelegate GetSetMethod(FieldInfo fieldInfo) + { + return GetSetMethodByReflection(fieldInfo); + } + + public static SetDelegate GetSetMethodByReflection(PropertyInfo propertyInfo) + { + MethodInfo methodInfo = GetSetterMethodInfo(propertyInfo); + return delegate (object source, object value) + { + if (_1ObjArray == null) + _1ObjArray = new object[1]; + _1ObjArray[0] = value; + methodInfo.Invoke(source, _1ObjArray); + }; + } + + public static SetDelegate GetSetMethodByReflection(FieldInfo fieldInfo) + { + return delegate (object source, object value) { fieldInfo.SetValue(source, value); }; + } + + public sealed class ThreadSafeDictionary<TKey, TValue> : IDictionary<TKey, TValue> + { + private readonly object _lock = new object(); + private readonly ThreadSafeDictionaryValueFactory<TKey, TValue> _valueFactory; + private Dictionary<TKey, TValue> _dictionary; + + public ThreadSafeDictionary(ThreadSafeDictionaryValueFactory<TKey, TValue> valueFactory) + { + _valueFactory = valueFactory; + } + + private TValue Get(TKey key) + { + if (_dictionary == null) + return AddValue(key); + TValue value; + if (!_dictionary.TryGetValue(key, out value)) + return AddValue(key); + return value; + } + + private TValue AddValue(TKey key) + { + TValue value = _valueFactory(key); + lock (_lock) + { + if (_dictionary == null) + { + _dictionary = new Dictionary<TKey, TValue>(); + _dictionary[key] = value; + } + else + { + TValue val; + if (_dictionary.TryGetValue(key, out val)) + return val; + Dictionary<TKey, TValue> dict = new Dictionary<TKey, TValue>(_dictionary); + dict[key] = value; + _dictionary = dict; + } + } + return value; + } + + public void Add(TKey key, TValue value) + { + throw new NotImplementedException(); + } + + public bool ContainsKey(TKey key) + { + return _dictionary.ContainsKey(key); + } + + public ICollection<TKey> Keys + { + get { return _dictionary.Keys; } + } + + public bool Remove(TKey key) + { + throw new NotImplementedException(); + } + + public bool TryGetValue(TKey key, out TValue value) + { + value = this[key]; + return true; + } + + public ICollection<TValue> Values + { + get { return _dictionary.Values; } + } + + public TValue this[TKey key] + { + get { return Get(key); } + set { throw new NotImplementedException(); } + } + + public void Add(KeyValuePair<TKey, TValue> item) + { + throw new NotImplementedException(); + } + + public void Clear() + { + throw new NotImplementedException(); + } + + public bool Contains(KeyValuePair<TKey, TValue> item) + { + throw new NotImplementedException(); + } + + public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) + { + throw new NotImplementedException(); + } + + public int Count + { + get { return _dictionary.Count; } + } + + public bool IsReadOnly + { + get { throw new NotImplementedException(); } + } + + public bool Remove(KeyValuePair<TKey, TValue> item) + { + throw new NotImplementedException(); + } + + public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() + { + return _dictionary.GetEnumerator(); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return _dictionary.GetEnumerator(); + } + } + } +} + +// ReSharper restore LoopCanBeConvertedToQuery +// ReSharper restore RedundantExplicitArrayCreation +// ReSharper restore SuggestUseVarKeywordEvident diff --git a/PlayFabSDK/source/PlayFabAdminAPI.cs b/PlayFabSDK/source/PlayFabAdminAPI.cs index ce48141c..f65ba2a4 100644 --- a/PlayFabSDK/source/PlayFabAdminAPI.cs +++ b/PlayFabSDK/source/PlayFabAdminAPI.cs @@ -1,13 +1,11 @@ -using Newtonsoft.Json; -using PlayFab.Internal; using PlayFab.AdminModels; +using PlayFab.Internal; +using PlayFab.Json; using System; -using System.IO; using System.Threading.Tasks; namespace PlayFab { - /// <summary> /// APIs for managing title configurations, uploaded Game Server code executables, and user data /// </summary> @@ -16,2001 +14,2071 @@ public class PlayFabAdminAPI /// <summary> /// Bans users by PlayFab ID with optional IP address, or MAC address for the provided game. /// </summary> - public static async Task<PlayFabResult<BanUsersResult>> BanUsersAsync(BanUsersRequest request) + public static async Task<PlayFabResult<BanUsersResult>> BanUsersAsync(BanUsersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/BanUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/BanUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<BanUsersResult> { Error = error, }; + return new PlayFabResult<BanUsersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<BanUsersResult>>(new JsonTextReader(new StringReader(resultRawJson))); - BanUsersResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<BanUsersResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<BanUsersResult> { Result = result }; + return new PlayFabResult<BanUsersResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the relevant details for a specified user, based upon a match against a supplied unique identifier /// </summary> - public static async Task<PlayFabResult<LookupUserAccountInfoResult>> GetUserAccountInfoAsync(LookupUserAccountInfoRequest request) + public static async Task<PlayFabResult<LookupUserAccountInfoResult>> GetUserAccountInfoAsync(LookupUserAccountInfoRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetUserAccountInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetUserAccountInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LookupUserAccountInfoResult> { Error = error, }; + return new PlayFabResult<LookupUserAccountInfoResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LookupUserAccountInfoResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LookupUserAccountInfoResult>>(resultRawJson); + var result = resultData.data; - LookupUserAccountInfoResult result = resultData.data; - - return new PlayFabResult<LookupUserAccountInfoResult> { Result = result }; + return new PlayFabResult<LookupUserAccountInfoResult> { Result = result, CustomData = customData }; } /// <summary> /// Gets all bans for a user. /// </summary> - public static async Task<PlayFabResult<GetUserBansResult>> GetUserBansAsync(GetUserBansRequest request) + public static async Task<PlayFabResult<GetUserBansResult>> GetUserBansAsync(GetUserBansRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetUserBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetUserBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserBansResult> { Error = error, }; + return new PlayFabResult<GetUserBansResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserBansResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserBansResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserBansResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserBansResult> { Result = result }; + return new PlayFabResult<GetUserBansResult> { Result = result, CustomData = customData }; } /// <summary> /// Resets all title-specific information about a particular account, including user data, virtual currency balances, inventory, purchase history, and statistics /// </summary> - public static async Task<PlayFabResult<BlankResult>> ResetUsersAsync(ResetUsersRequest request) + public static async Task<PlayFabResult<BlankResult>> ResetUsersAsync(ResetUsersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/ResetUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/ResetUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<BlankResult> { Error = error, }; + return new PlayFabResult<BlankResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<BlankResult>>(new JsonTextReader(new StringReader(resultRawJson))); - BlankResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<BlankResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<BlankResult> { Result = result }; + return new PlayFabResult<BlankResult> { Result = result, CustomData = customData }; } /// <summary> /// Revoke all active bans for a user. /// </summary> - public static async Task<PlayFabResult<RevokeAllBansForUserResult>> RevokeAllBansForUserAsync(RevokeAllBansForUserRequest request) + public static async Task<PlayFabResult<RevokeAllBansForUserResult>> RevokeAllBansForUserAsync(RevokeAllBansForUserRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/RevokeAllBansForUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/RevokeAllBansForUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RevokeAllBansForUserResult> { Error = error, }; + return new PlayFabResult<RevokeAllBansForUserResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RevokeAllBansForUserResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RevokeAllBansForUserResult>>(resultRawJson); + var result = resultData.data; - RevokeAllBansForUserResult result = resultData.data; - - return new PlayFabResult<RevokeAllBansForUserResult> { Result = result }; + return new PlayFabResult<RevokeAllBansForUserResult> { Result = result, CustomData = customData }; } /// <summary> /// Revoke all active bans specified with BanId. /// </summary> - public static async Task<PlayFabResult<RevokeBansResult>> RevokeBansAsync(RevokeBansRequest request) + public static async Task<PlayFabResult<RevokeBansResult>> RevokeBansAsync(RevokeBansRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/RevokeBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/RevokeBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RevokeBansResult> { Error = error, }; + return new PlayFabResult<RevokeBansResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RevokeBansResult>>(new JsonTextReader(new StringReader(resultRawJson))); - RevokeBansResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RevokeBansResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RevokeBansResult> { Result = result }; + return new PlayFabResult<RevokeBansResult> { Result = result, CustomData = customData }; } /// <summary> /// Forces an email to be sent to the registered email address for the specified account, with a link allowing the user to change the password /// </summary> - public static async Task<PlayFabResult<SendAccountRecoveryEmailResult>> SendAccountRecoveryEmailAsync(SendAccountRecoveryEmailRequest request) + public static async Task<PlayFabResult<SendAccountRecoveryEmailResult>> SendAccountRecoveryEmailAsync(SendAccountRecoveryEmailRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/SendAccountRecoveryEmail", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/SendAccountRecoveryEmail", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SendAccountRecoveryEmailResult> { Error = error, }; + return new PlayFabResult<SendAccountRecoveryEmailResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SendAccountRecoveryEmailResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SendAccountRecoveryEmailResult>>(resultRawJson); + var result = resultData.data; - SendAccountRecoveryEmailResult result = resultData.data; - - return new PlayFabResult<SendAccountRecoveryEmailResult> { Result = result }; + return new PlayFabResult<SendAccountRecoveryEmailResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates information of a list of existing bans specified with Ban Ids. /// </summary> - public static async Task<PlayFabResult<UpdateBansResult>> UpdateBansAsync(UpdateBansRequest request) + public static async Task<PlayFabResult<UpdateBansResult>> UpdateBansAsync(UpdateBansRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateBansResult> { Error = error, }; + return new PlayFabResult<UpdateBansResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateBansResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateBansResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateBansResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateBansResult> { Result = result }; + return new PlayFabResult<UpdateBansResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title specific display name for a user /// </summary> - public static async Task<PlayFabResult<UpdateUserTitleDisplayNameResult>> UpdateUserTitleDisplayNameAsync(UpdateUserTitleDisplayNameRequest request) + public static async Task<PlayFabResult<UpdateUserTitleDisplayNameResult>> UpdateUserTitleDisplayNameAsync(UpdateUserTitleDisplayNameRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateUserTitleDisplayName", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateUserTitleDisplayName", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserTitleDisplayNameResult> { Error = error, }; + return new PlayFabResult<UpdateUserTitleDisplayNameResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserTitleDisplayNameResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserTitleDisplayNameResult>>(resultRawJson); + var result = resultData.data; - UpdateUserTitleDisplayNameResult result = resultData.data; - - return new PlayFabResult<UpdateUserTitleDisplayNameResult> { Result = result }; + return new PlayFabResult<UpdateUserTitleDisplayNameResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds a new player statistic configuration to the title, optionally allowing the developer to specify a reset interval and an aggregation method. /// </summary> - public static async Task<PlayFabResult<CreatePlayerStatisticDefinitionResult>> CreatePlayerStatisticDefinitionAsync(CreatePlayerStatisticDefinitionRequest request) + public static async Task<PlayFabResult<CreatePlayerStatisticDefinitionResult>> CreatePlayerStatisticDefinitionAsync(CreatePlayerStatisticDefinitionRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/CreatePlayerStatisticDefinition", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/CreatePlayerStatisticDefinition", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<CreatePlayerStatisticDefinitionResult> { Error = error, }; + return new PlayFabResult<CreatePlayerStatisticDefinitionResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<CreatePlayerStatisticDefinitionResult>>(new JsonTextReader(new StringReader(resultRawJson))); - CreatePlayerStatisticDefinitionResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<CreatePlayerStatisticDefinitionResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<CreatePlayerStatisticDefinitionResult> { Result = result }; + return new PlayFabResult<CreatePlayerStatisticDefinitionResult> { Result = result, CustomData = customData }; } /// <summary> /// Deletes the users for the provided game. Deletes custom data, all account linkages, and statistics. This method does not remove the player's event history, login history, inventory items, nor virtual currencies. /// </summary> - public static async Task<PlayFabResult<DeleteUsersResult>> DeleteUsersAsync(DeleteUsersRequest request) + public static async Task<PlayFabResult<DeleteUsersResult>> DeleteUsersAsync(DeleteUsersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/DeleteUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/DeleteUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<DeleteUsersResult> { Error = error, }; + return new PlayFabResult<DeleteUsersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<DeleteUsersResult>>(new JsonTextReader(new StringReader(resultRawJson))); - DeleteUsersResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<DeleteUsersResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<DeleteUsersResult> { Result = result }; + return new PlayFabResult<DeleteUsersResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a download URL for the requested report /// </summary> - public static async Task<PlayFabResult<GetDataReportResult>> GetDataReportAsync(GetDataReportRequest request) + public static async Task<PlayFabResult<GetDataReportResult>> GetDataReportAsync(GetDataReportRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetDataReport", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetDataReport", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetDataReportResult> { Error = error, }; + return new PlayFabResult<GetDataReportResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetDataReportResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetDataReportResult>>(resultRawJson); + var result = resultData.data; - GetDataReportResult result = resultData.data; - - return new PlayFabResult<GetDataReportResult> { Result = result }; + return new PlayFabResult<GetDataReportResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the configuration information for all player statistics defined in the title, regardless of whether they have a reset interval. /// </summary> - public static async Task<PlayFabResult<GetPlayerStatisticDefinitionsResult>> GetPlayerStatisticDefinitionsAsync(GetPlayerStatisticDefinitionsRequest request) + public static async Task<PlayFabResult<GetPlayerStatisticDefinitionsResult>> GetPlayerStatisticDefinitionsAsync(GetPlayerStatisticDefinitionsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetPlayerStatisticDefinitions", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetPlayerStatisticDefinitions", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerStatisticDefinitionsResult> { Error = error, }; + return new PlayFabResult<GetPlayerStatisticDefinitionsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerStatisticDefinitionsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerStatisticDefinitionsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerStatisticDefinitionsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerStatisticDefinitionsResult> { Result = result }; + return new PlayFabResult<GetPlayerStatisticDefinitionsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the information on the available versions of the specified statistic. /// </summary> - public static async Task<PlayFabResult<GetPlayerStatisticVersionsResult>> GetPlayerStatisticVersionsAsync(GetPlayerStatisticVersionsRequest request) + public static async Task<PlayFabResult<GetPlayerStatisticVersionsResult>> GetPlayerStatisticVersionsAsync(GetPlayerStatisticVersionsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetPlayerStatisticVersions", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetPlayerStatisticVersions", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerStatisticVersionsResult> { Error = error, }; + return new PlayFabResult<GetPlayerStatisticVersionsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerStatisticVersionsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerStatisticVersionsResult>>(resultRawJson); + var result = resultData.data; - GetPlayerStatisticVersionsResult result = resultData.data; - - return new PlayFabResult<GetPlayerStatisticVersionsResult> { Result = result }; + return new PlayFabResult<GetPlayerStatisticVersionsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetUserData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetUserData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserInternalDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserInternalDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetUserInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetUserInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - GetUserDataResult result = resultData.data; - - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the publisher-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetUserPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetUserPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the publisher-specific custom data for the user which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherInternalDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherInternalDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetUserPublisherInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetUserPublisherInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the publisher-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherReadOnlyDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherReadOnlyDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetUserPublisherReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetUserPublisherReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - GetUserDataResult result = resultData.data; - - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserReadOnlyDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserReadOnlyDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetUserReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetUserReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Resets the indicated statistic, removing all player entries for it and backing up the old values. /// </summary> - public static async Task<PlayFabResult<IncrementPlayerStatisticVersionResult>> IncrementPlayerStatisticVersionAsync(IncrementPlayerStatisticVersionRequest request) + public static async Task<PlayFabResult<IncrementPlayerStatisticVersionResult>> IncrementPlayerStatisticVersionAsync(IncrementPlayerStatisticVersionRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/IncrementPlayerStatisticVersion", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/IncrementPlayerStatisticVersion", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<IncrementPlayerStatisticVersionResult> { Error = error, }; + return new PlayFabResult<IncrementPlayerStatisticVersionResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<IncrementPlayerStatisticVersionResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<IncrementPlayerStatisticVersionResult>>(resultRawJson); + var result = resultData.data; - IncrementPlayerStatisticVersionResult result = resultData.data; - - return new PlayFabResult<IncrementPlayerStatisticVersionResult> { Result = result }; + return new PlayFabResult<IncrementPlayerStatisticVersionResult> { Result = result, CustomData = customData }; } /// <summary> /// Attempts to process an order refund through the original real money payment provider. /// </summary> - public static async Task<PlayFabResult<RefundPurchaseResponse>> RefundPurchaseAsync(RefundPurchaseRequest request) + public static async Task<PlayFabResult<RefundPurchaseResponse>> RefundPurchaseAsync(RefundPurchaseRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/RefundPurchase", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/RefundPurchase", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RefundPurchaseResponse> { Error = error, }; + return new PlayFabResult<RefundPurchaseResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RefundPurchaseResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - RefundPurchaseResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RefundPurchaseResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RefundPurchaseResponse> { Result = result }; + return new PlayFabResult<RefundPurchaseResponse> { Result = result, CustomData = customData }; } /// <summary> /// Completely removes all statistics for the specified user, for the current game /// </summary> - public static async Task<PlayFabResult<ResetUserStatisticsResult>> ResetUserStatisticsAsync(ResetUserStatisticsRequest request) + public static async Task<PlayFabResult<ResetUserStatisticsResult>> ResetUserStatisticsAsync(ResetUserStatisticsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/ResetUserStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/ResetUserStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ResetUserStatisticsResult> { Error = error, }; + return new PlayFabResult<ResetUserStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ResetUserStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ResetUserStatisticsResult>>(resultRawJson); + var result = resultData.data; - ResetUserStatisticsResult result = resultData.data; - - return new PlayFabResult<ResetUserStatisticsResult> { Result = result }; + return new PlayFabResult<ResetUserStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Attempts to resolve a dispute with the original order's payment provider. /// </summary> - public static async Task<PlayFabResult<ResolvePurchaseDisputeResponse>> ResolvePurchaseDisputeAsync(ResolvePurchaseDisputeRequest request) + public static async Task<PlayFabResult<ResolvePurchaseDisputeResponse>> ResolvePurchaseDisputeAsync(ResolvePurchaseDisputeRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/ResolvePurchaseDispute", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/ResolvePurchaseDispute", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ResolvePurchaseDisputeResponse> { Error = error, }; + return new PlayFabResult<ResolvePurchaseDisputeResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ResolvePurchaseDisputeResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - ResolvePurchaseDisputeResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ResolvePurchaseDisputeResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ResolvePurchaseDisputeResponse> { Result = result }; + return new PlayFabResult<ResolvePurchaseDisputeResponse> { Result = result, CustomData = customData }; } /// <summary> /// Updates a player statistic configuration for the title, optionally allowing the developer to specify a reset interval. /// </summary> - public static async Task<PlayFabResult<UpdatePlayerStatisticDefinitionResult>> UpdatePlayerStatisticDefinitionAsync(UpdatePlayerStatisticDefinitionRequest request) + public static async Task<PlayFabResult<UpdatePlayerStatisticDefinitionResult>> UpdatePlayerStatisticDefinitionAsync(UpdatePlayerStatisticDefinitionRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdatePlayerStatisticDefinition", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdatePlayerStatisticDefinition", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdatePlayerStatisticDefinitionResult> { Error = error, }; + return new PlayFabResult<UpdatePlayerStatisticDefinitionResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdatePlayerStatisticDefinitionResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdatePlayerStatisticDefinitionResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdatePlayerStatisticDefinitionResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdatePlayerStatisticDefinitionResult> { Result = result }; + return new PlayFabResult<UpdatePlayerStatisticDefinitionResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserDataAsync(UpdateUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateUserData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateUserData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - UpdateUserDataResult result = resultData.data; - - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title-specific custom data for the user which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserInternalDataAsync(UpdateUserInternalDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserInternalDataAsync(UpdateUserInternalDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateUserInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateUserInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the publisher-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherDataAsync(UpdateUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateUserPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateUserPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - UpdateUserDataResult result = resultData.data; - - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the publisher-specific custom data for the user which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherInternalDataAsync(UpdateUserInternalDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherInternalDataAsync(UpdateUserInternalDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateUserPublisherInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateUserPublisherInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the publisher-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherReadOnlyDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherReadOnlyDataAsync(UpdateUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateUserPublisherReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateUserPublisherReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - UpdateUserDataResult result = resultData.data; - - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserReadOnlyDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserReadOnlyDataAsync(UpdateUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateUserReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateUserReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds a new news item to the title's news feed /// </summary> - public static async Task<PlayFabResult<AddNewsResult>> AddNewsAsync(AddNewsRequest request) + public static async Task<PlayFabResult<AddNewsResult>> AddNewsAsync(AddNewsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/AddNews", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/AddNews", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AddNewsResult> { Error = error, }; + return new PlayFabResult<AddNewsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AddNewsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - AddNewsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AddNewsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AddNewsResult> { Result = result }; + return new PlayFabResult<AddNewsResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds one or more virtual currencies to the set defined for the title. Virtual Currencies have a maximum value of 2,147,483,647 when granted to a player. Any value over that will be discarded. /// </summary> - public static async Task<PlayFabResult<BlankResult>> AddVirtualCurrencyTypesAsync(AddVirtualCurrencyTypesRequest request) + public static async Task<PlayFabResult<BlankResult>> AddVirtualCurrencyTypesAsync(AddVirtualCurrencyTypesRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/AddVirtualCurrencyTypes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/AddVirtualCurrencyTypes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<BlankResult> { Error = error, }; + return new PlayFabResult<BlankResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<BlankResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<BlankResult>>(resultRawJson); + var result = resultData.data; - BlankResult result = resultData.data; - - return new PlayFabResult<BlankResult> { Result = result }; + return new PlayFabResult<BlankResult> { Result = result, CustomData = customData }; } /// <summary> /// Deletes an existing virtual item store /// </summary> - public static async Task<PlayFabResult<DeleteStoreResult>> DeleteStoreAsync(DeleteStoreRequest request) + public static async Task<PlayFabResult<DeleteStoreResult>> DeleteStoreAsync(DeleteStoreRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/DeleteStore", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/DeleteStore", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<DeleteStoreResult> { Error = error, }; + return new PlayFabResult<DeleteStoreResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<DeleteStoreResult>>(new JsonTextReader(new StringReader(resultRawJson))); - DeleteStoreResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<DeleteStoreResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<DeleteStoreResult> { Result = result }; + return new PlayFabResult<DeleteStoreResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the specified version of the title's catalog of virtual goods, including all defined properties /// </summary> - public static async Task<PlayFabResult<GetCatalogItemsResult>> GetCatalogItemsAsync(GetCatalogItemsRequest request) + public static async Task<PlayFabResult<GetCatalogItemsResult>> GetCatalogItemsAsync(GetCatalogItemsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetCatalogItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetCatalogItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCatalogItemsResult> { Error = error, }; + return new PlayFabResult<GetCatalogItemsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCatalogItemsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCatalogItemsResult>>(resultRawJson); + var result = resultData.data; - GetCatalogItemsResult result = resultData.data; - - return new PlayFabResult<GetCatalogItemsResult> { Result = result }; + return new PlayFabResult<GetCatalogItemsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the key-value store of custom publisher settings /// </summary> - public static async Task<PlayFabResult<GetPublisherDataResult>> GetPublisherDataAsync(GetPublisherDataRequest request) + public static async Task<PlayFabResult<GetPublisherDataResult>> GetPublisherDataAsync(GetPublisherDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPublisherDataResult> { Error = error, }; + return new PlayFabResult<GetPublisherDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPublisherDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPublisherDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPublisherDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPublisherDataResult> { Result = result }; + return new PlayFabResult<GetPublisherDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the random drop table configuration for the title /// </summary> - public static async Task<PlayFabResult<GetRandomResultTablesResult>> GetRandomResultTablesAsync(GetRandomResultTablesRequest request) + public static async Task<PlayFabResult<GetRandomResultTablesResult>> GetRandomResultTablesAsync(GetRandomResultTablesRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetRandomResultTables", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetRandomResultTables", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetRandomResultTablesResult> { Error = error, }; + return new PlayFabResult<GetRandomResultTablesResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetRandomResultTablesResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetRandomResultTablesResult>>(resultRawJson); + var result = resultData.data; - GetRandomResultTablesResult result = resultData.data; - - return new PlayFabResult<GetRandomResultTablesResult> { Result = result }; + return new PlayFabResult<GetRandomResultTablesResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the set of items defined for the specified store, including all prices defined /// </summary> - public static async Task<PlayFabResult<GetStoreItemsResult>> GetStoreItemsAsync(GetStoreItemsRequest request) + public static async Task<PlayFabResult<GetStoreItemsResult>> GetStoreItemsAsync(GetStoreItemsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetStoreItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetStoreItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetStoreItemsResult> { Error = error, }; + return new PlayFabResult<GetStoreItemsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetStoreItemsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetStoreItemsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetStoreItemsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetStoreItemsResult> { Result = result }; + return new PlayFabResult<GetStoreItemsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the key-value store of custom title settings which can be read by the client /// </summary> - public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleDataAsync(GetTitleDataRequest request) + public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleDataAsync(GetTitleDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetTitleData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetTitleData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTitleDataResult> { Error = error, }; + return new PlayFabResult<GetTitleDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTitleDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetTitleDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTitleDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetTitleDataResult> { Result = result }; + return new PlayFabResult<GetTitleDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the key-value store of custom title settings which cannot be read by the client /// </summary> - public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleInternalDataAsync(GetTitleDataRequest request) + public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleInternalDataAsync(GetTitleDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetTitleInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetTitleInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTitleDataResult> { Error = error, }; + return new PlayFabResult<GetTitleDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTitleDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTitleDataResult>>(resultRawJson); + var result = resultData.data; - GetTitleDataResult result = resultData.data; - - return new PlayFabResult<GetTitleDataResult> { Result = result }; + return new PlayFabResult<GetTitleDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retuns the list of all defined virtual currencies for the title /// </summary> - public static async Task<PlayFabResult<ListVirtualCurrencyTypesResult>> ListVirtualCurrencyTypesAsync(ListVirtualCurrencyTypesRequest request) + public static async Task<PlayFabResult<ListVirtualCurrencyTypesResult>> ListVirtualCurrencyTypesAsync(ListVirtualCurrencyTypesRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/ListVirtualCurrencyTypes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/ListVirtualCurrencyTypes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ListVirtualCurrencyTypesResult> { Error = error, }; + return new PlayFabResult<ListVirtualCurrencyTypesResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ListVirtualCurrencyTypesResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ListVirtualCurrencyTypesResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ListVirtualCurrencyTypesResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ListVirtualCurrencyTypesResult> { Result = result }; + return new PlayFabResult<ListVirtualCurrencyTypesResult> { Result = result, CustomData = customData }; } /// <summary> /// Removes one or more virtual currencies from the set defined for the title. /// </summary> - public static async Task<PlayFabResult<BlankResult>> RemoveVirtualCurrencyTypesAsync(RemoveVirtualCurrencyTypesRequest request) + public static async Task<PlayFabResult<BlankResult>> RemoveVirtualCurrencyTypesAsync(RemoveVirtualCurrencyTypesRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/RemoveVirtualCurrencyTypes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/RemoveVirtualCurrencyTypes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<BlankResult> { Error = error, }; + return new PlayFabResult<BlankResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<BlankResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<BlankResult>>(resultRawJson); + var result = resultData.data; - BlankResult result = resultData.data; - - return new PlayFabResult<BlankResult> { Result = result }; + return new PlayFabResult<BlankResult> { Result = result, CustomData = customData }; } /// <summary> /// Creates the catalog configuration of all virtual goods for the specified catalog version /// </summary> - public static async Task<PlayFabResult<UpdateCatalogItemsResult>> SetCatalogItemsAsync(UpdateCatalogItemsRequest request) + public static async Task<PlayFabResult<UpdateCatalogItemsResult>> SetCatalogItemsAsync(UpdateCatalogItemsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/SetCatalogItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/SetCatalogItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateCatalogItemsResult> { Error = error, }; + return new PlayFabResult<UpdateCatalogItemsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateCatalogItemsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateCatalogItemsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateCatalogItemsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateCatalogItemsResult> { Result = result }; + return new PlayFabResult<UpdateCatalogItemsResult> { Result = result, CustomData = customData }; } /// <summary> /// Sets all the items in one virtual store /// </summary> - public static async Task<PlayFabResult<UpdateStoreItemsResult>> SetStoreItemsAsync(UpdateStoreItemsRequest request) + public static async Task<PlayFabResult<UpdateStoreItemsResult>> SetStoreItemsAsync(UpdateStoreItemsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/SetStoreItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/SetStoreItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateStoreItemsResult> { Error = error, }; + return new PlayFabResult<UpdateStoreItemsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateStoreItemsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateStoreItemsResult>>(resultRawJson); + var result = resultData.data; - UpdateStoreItemsResult result = resultData.data; - - return new PlayFabResult<UpdateStoreItemsResult> { Result = result }; + return new PlayFabResult<UpdateStoreItemsResult> { Result = result, CustomData = customData }; } /// <summary> /// Creates and updates the key-value store of custom title settings which can be read by the client /// </summary> - public static async Task<PlayFabResult<SetTitleDataResult>> SetTitleDataAsync(SetTitleDataRequest request) + public static async Task<PlayFabResult<SetTitleDataResult>> SetTitleDataAsync(SetTitleDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/SetTitleData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/SetTitleData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetTitleDataResult> { Error = error, }; + return new PlayFabResult<SetTitleDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetTitleDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - SetTitleDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetTitleDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<SetTitleDataResult> { Result = result }; + return new PlayFabResult<SetTitleDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the key-value store of custom title settings which cannot be read by the client /// </summary> - public static async Task<PlayFabResult<SetTitleDataResult>> SetTitleInternalDataAsync(SetTitleDataRequest request) + public static async Task<PlayFabResult<SetTitleDataResult>> SetTitleInternalDataAsync(SetTitleDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/SetTitleInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/SetTitleInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetTitleDataResult> { Error = error, }; + return new PlayFabResult<SetTitleDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetTitleDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - SetTitleDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetTitleDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<SetTitleDataResult> { Result = result }; + return new PlayFabResult<SetTitleDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Sets the Amazon Resource Name (ARN) for iOS and Android push notifications. Documentation on the exact restrictions can be found at: http://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html. Currently, Amazon device Messaging is not supported. /// </summary> - public static async Task<PlayFabResult<SetupPushNotificationResult>> SetupPushNotificationAsync(SetupPushNotificationRequest request) + public static async Task<PlayFabResult<SetupPushNotificationResult>> SetupPushNotificationAsync(SetupPushNotificationRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/SetupPushNotification", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/SetupPushNotification", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetupPushNotificationResult> { Error = error, }; + return new PlayFabResult<SetupPushNotificationResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetupPushNotificationResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetupPushNotificationResult>>(resultRawJson); + var result = resultData.data; - SetupPushNotificationResult result = resultData.data; - - return new PlayFabResult<SetupPushNotificationResult> { Result = result }; + return new PlayFabResult<SetupPushNotificationResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the catalog configuration for virtual goods in the specified catalog version /// </summary> - public static async Task<PlayFabResult<UpdateCatalogItemsResult>> UpdateCatalogItemsAsync(UpdateCatalogItemsRequest request) + public static async Task<PlayFabResult<UpdateCatalogItemsResult>> UpdateCatalogItemsAsync(UpdateCatalogItemsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateCatalogItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateCatalogItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateCatalogItemsResult> { Error = error, }; + return new PlayFabResult<UpdateCatalogItemsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateCatalogItemsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateCatalogItemsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateCatalogItemsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateCatalogItemsResult> { Result = result }; + return new PlayFabResult<UpdateCatalogItemsResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the random drop table configuration for the title /// </summary> - public static async Task<PlayFabResult<UpdateRandomResultTablesResult>> UpdateRandomResultTablesAsync(UpdateRandomResultTablesRequest request) + public static async Task<PlayFabResult<UpdateRandomResultTablesResult>> UpdateRandomResultTablesAsync(UpdateRandomResultTablesRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateRandomResultTables", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateRandomResultTables", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateRandomResultTablesResult> { Error = error, }; + return new PlayFabResult<UpdateRandomResultTablesResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateRandomResultTablesResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateRandomResultTablesResult>>(resultRawJson); + var result = resultData.data; - UpdateRandomResultTablesResult result = resultData.data; - - return new PlayFabResult<UpdateRandomResultTablesResult> { Result = result }; + return new PlayFabResult<UpdateRandomResultTablesResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates an existing virtual item store with new or modified items /// </summary> - public static async Task<PlayFabResult<UpdateStoreItemsResult>> UpdateStoreItemsAsync(UpdateStoreItemsRequest request) + public static async Task<PlayFabResult<UpdateStoreItemsResult>> UpdateStoreItemsAsync(UpdateStoreItemsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateStoreItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateStoreItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateStoreItemsResult> { Error = error, }; + return new PlayFabResult<UpdateStoreItemsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateStoreItemsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateStoreItemsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateStoreItemsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateStoreItemsResult> { Result = result }; + return new PlayFabResult<UpdateStoreItemsResult> { Result = result, CustomData = customData }; } /// <summary> /// Increments the specified virtual currency by the stated amount /// </summary> - public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> AddUserVirtualCurrencyAsync(AddUserVirtualCurrencyRequest request) + public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> AddUserVirtualCurrencyAsync(AddUserVirtualCurrencyRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/AddUserVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/AddUserVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(resultRawJson); + var result = resultData.data; - ModifyUserVirtualCurrencyResult result = resultData.data; - - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the specified user's current inventory of virtual goods /// </summary> - public static async Task<PlayFabResult<GetUserInventoryResult>> GetUserInventoryAsync(GetUserInventoryRequest request) + public static async Task<PlayFabResult<GetUserInventoryResult>> GetUserInventoryAsync(GetUserInventoryRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetUserInventory", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetUserInventory", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserInventoryResult> { Error = error, }; + return new PlayFabResult<GetUserInventoryResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserInventoryResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserInventoryResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserInventoryResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserInventoryResult> { Result = result }; + return new PlayFabResult<GetUserInventoryResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the specified items to the specified user inventories /// </summary> - public static async Task<PlayFabResult<GrantItemsToUsersResult>> GrantItemsToUsersAsync(GrantItemsToUsersRequest request) + public static async Task<PlayFabResult<GrantItemsToUsersResult>> GrantItemsToUsersAsync(GrantItemsToUsersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GrantItemsToUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GrantItemsToUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GrantItemsToUsersResult> { Error = error, }; + return new PlayFabResult<GrantItemsToUsersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GrantItemsToUsersResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GrantItemsToUsersResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GrantItemsToUsersResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GrantItemsToUsersResult> { Result = result }; + return new PlayFabResult<GrantItemsToUsersResult> { Result = result, CustomData = customData }; } /// <summary> /// Revokes access to an item in a user's inventory /// </summary> - public static async Task<PlayFabResult<RevokeInventoryResult>> RevokeInventoryItemAsync(RevokeInventoryItemRequest request) + public static async Task<PlayFabResult<RevokeInventoryResult>> RevokeInventoryItemAsync(RevokeInventoryItemRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/RevokeInventoryItem", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/RevokeInventoryItem", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RevokeInventoryResult> { Error = error, }; + return new PlayFabResult<RevokeInventoryResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RevokeInventoryResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RevokeInventoryResult>>(resultRawJson); + var result = resultData.data; - RevokeInventoryResult result = resultData.data; - - return new PlayFabResult<RevokeInventoryResult> { Result = result }; + return new PlayFabResult<RevokeInventoryResult> { Result = result, CustomData = customData }; } /// <summary> /// Decrements the specified virtual currency by the stated amount /// </summary> - public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> SubtractUserVirtualCurrencyAsync(SubtractUserVirtualCurrencyRequest request) + public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> SubtractUserVirtualCurrencyAsync(SubtractUserVirtualCurrencyRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/SubtractUserVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/SubtractUserVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ModifyUserVirtualCurrencyResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the details for a specific completed session, including links to standard out and standard error logs /// </summary> - public static async Task<PlayFabResult<GetMatchmakerGameInfoResult>> GetMatchmakerGameInfoAsync(GetMatchmakerGameInfoRequest request) + public static async Task<PlayFabResult<GetMatchmakerGameInfoResult>> GetMatchmakerGameInfoAsync(GetMatchmakerGameInfoRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetMatchmakerGameInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetMatchmakerGameInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetMatchmakerGameInfoResult> { Error = error, }; + return new PlayFabResult<GetMatchmakerGameInfoResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetMatchmakerGameInfoResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetMatchmakerGameInfoResult>>(resultRawJson); + var result = resultData.data; - GetMatchmakerGameInfoResult result = resultData.data; - - return new PlayFabResult<GetMatchmakerGameInfoResult> { Result = result }; + return new PlayFabResult<GetMatchmakerGameInfoResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the details of defined game modes for the specified game server executable /// </summary> - public static async Task<PlayFabResult<GetMatchmakerGameModesResult>> GetMatchmakerGameModesAsync(GetMatchmakerGameModesRequest request) + public static async Task<PlayFabResult<GetMatchmakerGameModesResult>> GetMatchmakerGameModesAsync(GetMatchmakerGameModesRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetMatchmakerGameModes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetMatchmakerGameModes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetMatchmakerGameModesResult> { Error = error, }; + return new PlayFabResult<GetMatchmakerGameModesResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetMatchmakerGameModesResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetMatchmakerGameModesResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetMatchmakerGameModesResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetMatchmakerGameModesResult> { Result = result }; + return new PlayFabResult<GetMatchmakerGameModesResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the game server mode details for the specified game server executable /// </summary> - public static async Task<PlayFabResult<ModifyMatchmakerGameModesResult>> ModifyMatchmakerGameModesAsync(ModifyMatchmakerGameModesRequest request) + public static async Task<PlayFabResult<ModifyMatchmakerGameModesResult>> ModifyMatchmakerGameModesAsync(ModifyMatchmakerGameModesRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/ModifyMatchmakerGameModes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/ModifyMatchmakerGameModes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyMatchmakerGameModesResult> { Error = error, }; + return new PlayFabResult<ModifyMatchmakerGameModesResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyMatchmakerGameModesResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyMatchmakerGameModesResult>>(resultRawJson); + var result = resultData.data; - ModifyMatchmakerGameModesResult result = resultData.data; - - return new PlayFabResult<ModifyMatchmakerGameModesResult> { Result = result }; + return new PlayFabResult<ModifyMatchmakerGameModesResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the game server executable specified (previously uploaded - see GetServerBuildUploadUrl) to the set of those a client is permitted to request in a call to StartGame /// </summary> - public static async Task<PlayFabResult<AddServerBuildResult>> AddServerBuildAsync(AddServerBuildRequest request) + public static async Task<PlayFabResult<AddServerBuildResult>> AddServerBuildAsync(AddServerBuildRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/AddServerBuild", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/AddServerBuild", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AddServerBuildResult> { Error = error, }; + return new PlayFabResult<AddServerBuildResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AddServerBuildResult>>(new JsonTextReader(new StringReader(resultRawJson))); - AddServerBuildResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AddServerBuildResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AddServerBuildResult> { Result = result }; + return new PlayFabResult<AddServerBuildResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the build details for the specified game server executable /// </summary> - public static async Task<PlayFabResult<GetServerBuildInfoResult>> GetServerBuildInfoAsync(GetServerBuildInfoRequest request) + public static async Task<PlayFabResult<GetServerBuildInfoResult>> GetServerBuildInfoAsync(GetServerBuildInfoRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetServerBuildInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetServerBuildInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetServerBuildInfoResult> { Error = error, }; + return new PlayFabResult<GetServerBuildInfoResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetServerBuildInfoResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetServerBuildInfoResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetServerBuildInfoResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetServerBuildInfoResult> { Result = result }; + return new PlayFabResult<GetServerBuildInfoResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the pre-authorized URL for uploading a game server package containing a build (does not enable the build for use - see AddServerBuild) /// </summary> - public static async Task<PlayFabResult<GetServerBuildUploadURLResult>> GetServerBuildUploadUrlAsync(GetServerBuildUploadURLRequest request) + public static async Task<PlayFabResult<GetServerBuildUploadURLResult>> GetServerBuildUploadUrlAsync(GetServerBuildUploadURLRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetServerBuildUploadUrl", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetServerBuildUploadUrl", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetServerBuildUploadURLResult> { Error = error, }; + return new PlayFabResult<GetServerBuildUploadURLResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetServerBuildUploadURLResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetServerBuildUploadURLResult>>(resultRawJson); + var result = resultData.data; - GetServerBuildUploadURLResult result = resultData.data; - - return new PlayFabResult<GetServerBuildUploadURLResult> { Result = result }; + return new PlayFabResult<GetServerBuildUploadURLResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the build details for all game server executables which are currently defined for the title /// </summary> - public static async Task<PlayFabResult<ListBuildsResult>> ListServerBuildsAsync(ListBuildsRequest request) + public static async Task<PlayFabResult<ListBuildsResult>> ListServerBuildsAsync(ListBuildsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/ListServerBuilds", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/ListServerBuilds", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ListBuildsResult> { Error = error, }; + return new PlayFabResult<ListBuildsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ListBuildsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ListBuildsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ListBuildsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ListBuildsResult> { Result = result }; + return new PlayFabResult<ListBuildsResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the build details for the specified game server executable /// </summary> - public static async Task<PlayFabResult<ModifyServerBuildResult>> ModifyServerBuildAsync(ModifyServerBuildRequest request) + public static async Task<PlayFabResult<ModifyServerBuildResult>> ModifyServerBuildAsync(ModifyServerBuildRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/ModifyServerBuild", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/ModifyServerBuild", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyServerBuildResult> { Error = error, }; + return new PlayFabResult<ModifyServerBuildResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyServerBuildResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyServerBuildResult>>(resultRawJson); + var result = resultData.data; - ModifyServerBuildResult result = resultData.data; - - return new PlayFabResult<ModifyServerBuildResult> { Result = result }; + return new PlayFabResult<ModifyServerBuildResult> { Result = result, CustomData = customData }; } /// <summary> /// Removes the game server executable specified from the set of those a client is permitted to request in a call to StartGame /// </summary> - public static async Task<PlayFabResult<RemoveServerBuildResult>> RemoveServerBuildAsync(RemoveServerBuildRequest request) + public static async Task<PlayFabResult<RemoveServerBuildResult>> RemoveServerBuildAsync(RemoveServerBuildRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/RemoveServerBuild", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/RemoveServerBuild", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RemoveServerBuildResult> { Error = error, }; + return new PlayFabResult<RemoveServerBuildResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RemoveServerBuildResult>>(new JsonTextReader(new StringReader(resultRawJson))); - RemoveServerBuildResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RemoveServerBuildResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RemoveServerBuildResult> { Result = result }; + return new PlayFabResult<RemoveServerBuildResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the key-value store of custom publisher settings /// </summary> - public static async Task<PlayFabResult<SetPublisherDataResult>> SetPublisherDataAsync(SetPublisherDataRequest request) + public static async Task<PlayFabResult<SetPublisherDataResult>> SetPublisherDataAsync(SetPublisherDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/SetPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/SetPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetPublisherDataResult> { Error = error, }; + return new PlayFabResult<SetPublisherDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetPublisherDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetPublisherDataResult>>(resultRawJson); + var result = resultData.data; - SetPublisherDataResult result = resultData.data; - - return new PlayFabResult<SetPublisherDataResult> { Result = result }; + return new PlayFabResult<SetPublisherDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Gets the contents and information of a specific Cloud Script revision. /// </summary> - public static async Task<PlayFabResult<GetCloudScriptRevisionResult>> GetCloudScriptRevisionAsync(GetCloudScriptRevisionRequest request) + public static async Task<PlayFabResult<GetCloudScriptRevisionResult>> GetCloudScriptRevisionAsync(GetCloudScriptRevisionRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetCloudScriptRevision", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetCloudScriptRevision", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCloudScriptRevisionResult> { Error = error, }; + return new PlayFabResult<GetCloudScriptRevisionResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCloudScriptRevisionResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetCloudScriptRevisionResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCloudScriptRevisionResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetCloudScriptRevisionResult> { Result = result }; + return new PlayFabResult<GetCloudScriptRevisionResult> { Result = result, CustomData = customData }; } /// <summary> /// Lists all the current cloud script versions. For each version, information about the current published and latest revisions is also listed. /// </summary> - public static async Task<PlayFabResult<GetCloudScriptVersionsResult>> GetCloudScriptVersionsAsync(GetCloudScriptVersionsRequest request) + public static async Task<PlayFabResult<GetCloudScriptVersionsResult>> GetCloudScriptVersionsAsync(GetCloudScriptVersionsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetCloudScriptVersions", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetCloudScriptVersions", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCloudScriptVersionsResult> { Error = error, }; + return new PlayFabResult<GetCloudScriptVersionsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCloudScriptVersionsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetCloudScriptVersionsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCloudScriptVersionsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetCloudScriptVersionsResult> { Result = result }; + return new PlayFabResult<GetCloudScriptVersionsResult> { Result = result, CustomData = customData }; } /// <summary> /// Sets the currently published revision of a title Cloud Script /// </summary> - public static async Task<PlayFabResult<SetPublishedRevisionResult>> SetPublishedRevisionAsync(SetPublishedRevisionRequest request) + public static async Task<PlayFabResult<SetPublishedRevisionResult>> SetPublishedRevisionAsync(SetPublishedRevisionRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/SetPublishedRevision", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/SetPublishedRevision", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetPublishedRevisionResult> { Error = error, }; + return new PlayFabResult<SetPublishedRevisionResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetPublishedRevisionResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetPublishedRevisionResult>>(resultRawJson); + var result = resultData.data; - SetPublishedRevisionResult result = resultData.data; - - return new PlayFabResult<SetPublishedRevisionResult> { Result = result }; + return new PlayFabResult<SetPublishedRevisionResult> { Result = result, CustomData = customData }; } /// <summary> /// Creates a new Cloud Script revision and uploads source code to it. Note that at this time, only one file should be submitted in the revision. /// </summary> - public static async Task<PlayFabResult<UpdateCloudScriptResult>> UpdateCloudScriptAsync(UpdateCloudScriptRequest request) + public static async Task<PlayFabResult<UpdateCloudScriptResult>> UpdateCloudScriptAsync(UpdateCloudScriptRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateCloudScript", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateCloudScript", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateCloudScriptResult> { Error = error, }; + return new PlayFabResult<UpdateCloudScriptResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateCloudScriptResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateCloudScriptResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateCloudScriptResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateCloudScriptResult> { Result = result }; + return new PlayFabResult<UpdateCloudScriptResult> { Result = result, CustomData = customData }; } /// <summary> /// Delete a content file from the title /// </summary> - public static async Task<PlayFabResult<BlankResult>> DeleteContentAsync(DeleteContentRequest request) + public static async Task<PlayFabResult<BlankResult>> DeleteContentAsync(DeleteContentRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/DeleteContent", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/DeleteContent", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<BlankResult> { Error = error, }; + return new PlayFabResult<BlankResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<BlankResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<BlankResult>>(resultRawJson); + var result = resultData.data; - BlankResult result = resultData.data; - - return new PlayFabResult<BlankResult> { Result = result }; + return new PlayFabResult<BlankResult> { Result = result, CustomData = customData }; } /// <summary> /// List all contents of the title and get statistics such as size /// </summary> - public static async Task<PlayFabResult<GetContentListResult>> GetContentListAsync(GetContentListRequest request) + public static async Task<PlayFabResult<GetContentListResult>> GetContentListAsync(GetContentListRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetContentList", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetContentList", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetContentListResult> { Error = error, }; + return new PlayFabResult<GetContentListResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetContentListResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetContentListResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetContentListResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetContentListResult> { Result = result }; + return new PlayFabResult<GetContentListResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the pre-signed URL for uploading a content file. A subsequent HTTP PUT to the returned URL uploads the content. /// </summary> - public static async Task<PlayFabResult<GetContentUploadUrlResult>> GetContentUploadUrlAsync(GetContentUploadUrlRequest request) + public static async Task<PlayFabResult<GetContentUploadUrlResult>> GetContentUploadUrlAsync(GetContentUploadUrlRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetContentUploadUrl", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetContentUploadUrl", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetContentUploadUrlResult> { Error = error, }; + return new PlayFabResult<GetContentUploadUrlResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetContentUploadUrlResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetContentUploadUrlResult>>(resultRawJson); + var result = resultData.data; - GetContentUploadUrlResult result = resultData.data; - - return new PlayFabResult<GetContentUploadUrlResult> { Result = result }; + return new PlayFabResult<GetContentUploadUrlResult> { Result = result, CustomData = customData }; } /// <summary> /// Completely removes all statistics for the specified character, for the current game /// </summary> - public static async Task<PlayFabResult<ResetCharacterStatisticsResult>> ResetCharacterStatisticsAsync(ResetCharacterStatisticsRequest request) + public static async Task<PlayFabResult<ResetCharacterStatisticsResult>> ResetCharacterStatisticsAsync(ResetCharacterStatisticsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/ResetCharacterStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/ResetCharacterStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ResetCharacterStatisticsResult> { Error = error, }; + return new PlayFabResult<ResetCharacterStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ResetCharacterStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ResetCharacterStatisticsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ResetCharacterStatisticsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ResetCharacterStatisticsResult> { Result = result }; + return new PlayFabResult<ResetCharacterStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds a given tag to a player profile. The tag's namespace is automatically generated based on the source of the tag. /// </summary> - public static async Task<PlayFabResult<AddPlayerTagResult>> AddPlayerTagAsync(AddPlayerTagRequest request) + public static async Task<PlayFabResult<AddPlayerTagResult>> AddPlayerTagAsync(AddPlayerTagRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/AddPlayerTag", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/AddPlayerTag", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AddPlayerTagResult> { Error = error, }; + return new PlayFabResult<AddPlayerTagResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AddPlayerTagResult>>(new JsonTextReader(new StringReader(resultRawJson))); - AddPlayerTagResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AddPlayerTagResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AddPlayerTagResult> { Result = result }; + return new PlayFabResult<AddPlayerTagResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieve a list of all PlayStream actions groups. /// </summary> - public static async Task<PlayFabResult<GetAllActionGroupsResult>> GetAllActionGroupsAsync(GetAllActionGroupsRequest request) + public static async Task<PlayFabResult<GetAllActionGroupsResult>> GetAllActionGroupsAsync(GetAllActionGroupsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetAllActionGroups", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetAllActionGroups", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetAllActionGroupsResult> { Error = error, }; + return new PlayFabResult<GetAllActionGroupsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetAllActionGroupsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetAllActionGroupsResult>>(resultRawJson); + var result = resultData.data; - GetAllActionGroupsResult result = resultData.data; - - return new PlayFabResult<GetAllActionGroupsResult> { Result = result }; + return new PlayFabResult<GetAllActionGroupsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves an array of player segment definitions. Results from this can be used in subsequent API calls such as GetPlayersInSegment which requires a Segment ID. While segment names can change the ID for that segment will not change. /// </summary> - public static async Task<PlayFabResult<GetAllSegmentsResult>> GetAllSegmentsAsync(GetAllSegmentsRequest request) + public static async Task<PlayFabResult<GetAllSegmentsResult>> GetAllSegmentsAsync(GetAllSegmentsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetAllSegments", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetAllSegments", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetAllSegmentsResult> { Error = error, }; + return new PlayFabResult<GetAllSegmentsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetAllSegmentsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetAllSegmentsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetAllSegmentsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetAllSegmentsResult> { Result = result }; + return new PlayFabResult<GetAllSegmentsResult> { Result = result, CustomData = customData }; } /// <summary> /// List all segments that a player currently belongs to at this moment in time. /// </summary> - public static async Task<PlayFabResult<GetPlayerSegmentsResult>> GetPlayerSegmentsAsync(GetPlayersSegmentsRequest request) + public static async Task<PlayFabResult<GetPlayerSegmentsResult>> GetPlayerSegmentsAsync(GetPlayersSegmentsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetPlayerSegments", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetPlayerSegments", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerSegmentsResult> { Error = error, }; + return new PlayFabResult<GetPlayerSegmentsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerSegmentsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerSegmentsResult>>(resultRawJson); + var result = resultData.data; - GetPlayerSegmentsResult result = resultData.data; - - return new PlayFabResult<GetPlayerSegmentsResult> { Result = result }; + return new PlayFabResult<GetPlayerSegmentsResult> { Result = result, CustomData = customData }; } /// <summary> /// Allows for paging through all players in a given segment. This API creates a snapshot of all player profiles that match the segment definition at the time of its creation and lives through the Total Seconds to Live, refreshing its life span on each subsequent use of the Continuation Token. Profiles that change during the course of paging will not be reflected in the results. AB Test segments are currently not supported by this operation. /// </summary> - public static async Task<PlayFabResult<GetPlayersInSegmentResult>> GetPlayersInSegmentAsync(GetPlayersInSegmentRequest request) + public static async Task<PlayFabResult<GetPlayersInSegmentResult>> GetPlayersInSegmentAsync(GetPlayersInSegmentRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetPlayersInSegment", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetPlayersInSegment", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayersInSegmentResult> { Error = error, }; + return new PlayFabResult<GetPlayersInSegmentResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayersInSegmentResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayersInSegmentResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayersInSegmentResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayersInSegmentResult> { Result = result }; + return new PlayFabResult<GetPlayersInSegmentResult> { Result = result, CustomData = customData }; } /// <summary> /// Get all tags with a given Namespace (optional) from a player profile. /// </summary> - public static async Task<PlayFabResult<GetPlayerTagsResult>> GetPlayerTagsAsync(GetPlayerTagsRequest request) + public static async Task<PlayFabResult<GetPlayerTagsResult>> GetPlayerTagsAsync(GetPlayerTagsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetPlayerTags", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetPlayerTags", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerTagsResult> { Error = error, }; + return new PlayFabResult<GetPlayerTagsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerTagsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerTagsResult>>(resultRawJson); + var result = resultData.data; - GetPlayerTagsResult result = resultData.data; - - return new PlayFabResult<GetPlayerTagsResult> { Result = result }; + return new PlayFabResult<GetPlayerTagsResult> { Result = result, CustomData = customData }; } /// <summary> /// Remove a given tag from a player profile. The tag's namespace is automatically generated based on the source of the tag. /// </summary> - public static async Task<PlayFabResult<RemovePlayerTagResult>> RemovePlayerTagAsync(RemovePlayerTagRequest request) + public static async Task<PlayFabResult<RemovePlayerTagResult>> RemovePlayerTagAsync(RemovePlayerTagRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/RemovePlayerTag", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/RemovePlayerTag", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RemovePlayerTagResult> { Error = error, }; + return new PlayFabResult<RemovePlayerTagResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RemovePlayerTagResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RemovePlayerTagResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<RemovePlayerTagResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Abort an ongoing task instance. + /// </summary> + public static async Task<PlayFabResult<EmptyResult>> AbortTaskInstanceAsync(AbortTaskInstanceRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/AbortTaskInstance", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<EmptyResult> { Error = error, CustomData = customData }; + } + + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<EmptyResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<EmptyResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Create an ActionsOnPlayersInSegment task, which iterates through all players in a segment to execute action. + /// </summary> + public static async Task<PlayFabResult<CreateTaskResult>> CreateActionsOnPlayersInSegmentTaskAsync(CreateActionsOnPlayerSegmentTaskRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/CreateActionsOnPlayersInSegmentTask", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<CreateTaskResult> { Error = error, CustomData = customData }; + } + + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<CreateTaskResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<CreateTaskResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Create a CloudScript task, which can run a CloudScript on a schedule. + /// </summary> + public static async Task<PlayFabResult<CreateTaskResult>> CreateCloudScriptTaskAsync(CreateCloudScriptTaskRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/CreateCloudScriptTask", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<CreateTaskResult> { Error = error, CustomData = customData }; + } + + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<CreateTaskResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<CreateTaskResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Delete a task. + /// </summary> + public static async Task<PlayFabResult<EmptyResult>> DeleteTaskAsync(DeleteTaskRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/DeleteTask", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<EmptyResult> { Error = error, CustomData = customData }; + } + + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<EmptyResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<EmptyResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Get information about a ActionsOnPlayersInSegment task instance. + /// </summary> + public static async Task<PlayFabResult<GetActionsOnPlayersInSegmentTaskInstanceResult>> GetActionsOnPlayersInSegmentTaskInstanceAsync(GetTaskInstanceRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/GetActionsOnPlayersInSegmentTaskInstance", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<GetActionsOnPlayersInSegmentTaskInstanceResult> { Error = error, CustomData = customData }; + } + + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetActionsOnPlayersInSegmentTaskInstanceResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<GetActionsOnPlayersInSegmentTaskInstanceResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Get detail information about a CloudScript task instance. + /// </summary> + public static async Task<PlayFabResult<GetCloudScriptTaskInstanceResult>> GetCloudScriptTaskInstanceAsync(GetTaskInstanceRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/GetCloudScriptTaskInstance", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<GetCloudScriptTaskInstanceResult> { Error = error, CustomData = customData }; + } + + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCloudScriptTaskInstanceResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<GetCloudScriptTaskInstanceResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Query for task instances by task, status, or time range. + /// </summary> + public static async Task<PlayFabResult<GetTaskInstancesResult>> GetTaskInstancesAsync(GetTaskInstancesRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/GetTaskInstances", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<GetTaskInstancesResult> { Error = error, CustomData = customData }; + } + + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTaskInstancesResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<GetTaskInstancesResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Get definition information on a specified task or all tasks within a title. + /// </summary> + public static async Task<PlayFabResult<GetTasksResult>> GetTasksAsync(GetTasksRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/GetTasks", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<GetTasksResult> { Error = error, CustomData = customData }; + } + + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTasksResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<GetTasksResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Run a task immediately regardless of its schedule. + /// </summary> + public static async Task<PlayFabResult<RunTaskResult>> RunTaskAsync(RunTaskRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/RunTask", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<RunTaskResult> { Error = error, CustomData = customData }; + } + + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RunTaskResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<RunTaskResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Update an existing task. + /// </summary> + public static async Task<PlayFabResult<EmptyResult>> UpdateTaskAsync(UpdateTaskRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateTask", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<EmptyResult> { Error = error, CustomData = customData }; + } - RemovePlayerTagResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<EmptyResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RemovePlayerTagResult> { Result = result }; + return new PlayFabResult<EmptyResult> { Result = result, CustomData = customData }; } } diff --git a/PlayFabSDK/source/PlayFabAdminModels.cs b/PlayFabSDK/source/PlayFabAdminModels.cs index ac3abeb9..1fbe81f8 100644 --- a/PlayFabSDK/source/PlayFabAdminModels.cs +++ b/PlayFabSDK/source/PlayFabAdminModels.cs @@ -1,11 +1,96 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; using PlayFab.Internal; using System; using System.Collections.Generic; namespace PlayFab.AdminModels { + public class AbortTaskInstanceRequest : PlayFabRequestCommon + { + /// <summary> + /// ID of a task instance that is being aborted. + /// </summary> + public string TaskInstanceId; + + } + + public class ActionsOnPlayersInSegmentTaskParameter + { + /// <summary> + /// ID of the segment to perform actions on. + /// </summary> + public string SegmentId; + + /// <summary> + /// ID of the action to perform on each player in segment. + /// </summary> + public string ActionId; + + } + + public class ActionsOnPlayersInSegmentTaskSummary + { + /// <summary> + /// ID of the task instance. + /// </summary> + public string TaskInstanceId; + + /// <summary> + /// Identifier of the task this instance belongs to. + /// </summary> + public NameIdentifier TaskIdentifier; + + /// <summary> + /// UTC timestamp when the task started. + /// </summary> + public DateTime StartedAt; + + /// <summary> + /// UTC timestamp when the task completed. + /// </summary> + public DateTime? CompletedAt; + + /// <summary> + /// Current status of the task instance. + /// </summary> + public TaskInstanceStatus? Status; + + /// <summary> + /// Progress represented as percentage. + /// </summary> + public double? PercentComplete; + + /// <summary> + /// Estimated time remaining in seconds. + /// </summary> + public double? EstimatedSecondsRemaining; + + /// <summary> + /// If manually scheduled, ID of user who scheduled the task. + /// </summary> + public string ScheduledByUserId; + + /// <summary> + /// Error message for last processing attempt, if an error occured. + /// </summary> + public string ErrorMessage; + + /// <summary> + /// Flag indicating if the error was fatal, if false job will be retried. + /// </summary> + public bool? ErrorWasFatal; + + /// <summary> + /// Total players in segment when task was started. + /// </summary> + public int? TotalPlayersInSegment; + + /// <summary> + /// Total number of players that have had the actions applied to. + /// </summary> + public int? TotalPlayersProcessed; + + } + public class AdCampaignAttribution { /// <summary> @@ -25,7 +110,7 @@ public class AdCampaignAttribution } - public class AddNewsRequest + public class AddNewsRequest : PlayFabRequestCommon { /// <summary> /// Time this news was published. If not set, defaults to now. @@ -53,7 +138,7 @@ public class AddNewsResult : PlayFabResultCommon } - public class AddPlayerTagRequest + public class AddPlayerTagRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -71,7 +156,7 @@ public class AddPlayerTagResult : PlayFabResultCommon { } - public class AddServerBuildRequest + public class AddServerBuildRequest : PlayFabRequestCommon { /// <summary> /// unique identifier for the build executable @@ -91,7 +176,6 @@ public class AddServerBuildRequest /// <summary> /// server host regions in which this build should be running and available /// </summary> - [JsonProperty(ItemConverterType = typeof(StringEnumConverter))] public List<Region> ActiveRegions; /// <summary> @@ -121,7 +205,6 @@ public class AddServerBuildResult : PlayFabResultCommon /// <summary> /// array of regions where this build can used, when it is active /// </summary> - [JsonProperty(ItemConverterType = typeof(StringEnumConverter))] public List<Region> ActiveRegions; /// <summary> @@ -162,12 +245,11 @@ public class AddServerBuildResult : PlayFabResultCommon /// <summary> /// the current status of the build validation and processing steps /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public GameBuildStatus? Status; } - public class AddUserVirtualCurrencyRequest + public class AddUserVirtualCurrencyRequest : PlayFabRequestCommon { /// <summary> /// PlayFab unique identifier of the user whose virtual currency balance is to be increased. @@ -186,7 +268,7 @@ public class AddUserVirtualCurrencyRequest } - public class AddVirtualCurrencyTypesRequest + public class AddVirtualCurrencyTypesRequest : PlayFabRequestCommon { /// <summary> /// List of virtual currencies and their initial deposits (the amount a user is granted when signing in for the first time) to the title @@ -245,7 +327,7 @@ public class BanInfo /// <summary> /// Represents a single ban request. /// </summary> - public class BanRequest + public class BanRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -274,7 +356,7 @@ public class BanRequest } - public class BanUsersRequest + public class BanUsersRequest : PlayFabRequestCommon { /// <summary> /// List of ban requests to be applied. Maximum 100. @@ -388,7 +470,7 @@ public class CatalogItem : IComparable<CatalogItem> public bool IsLimitedEdition; /// <summary> - /// BETA: If IsLImitedEdition is true, then this determines amount of the item initially available. Note that this fieldis ignored if the catalog item already existed in this catalog, or the field is less than 1. + /// If IsLImitedEdition is true, then this determines amount of the item initially available. Note that this fieldis ignored if the catalog item already existed in this catalog, or the field is less than 1. /// </summary> public int InitialLimitedEditionCount; @@ -484,6 +566,69 @@ public class CloudScriptFile } + public class CloudScriptTaskParameter + { + /// <summary> + /// Name of the CloudScript function to execute. + /// </summary> + public string FunctionName; + + /// <summary> + /// Argument to pass to the CloudScript function. + /// </summary> + public object Argument; + + } + + public class CloudScriptTaskSummary + { + /// <summary> + /// ID of the task instance. + /// </summary> + public string TaskInstanceId; + + /// <summary> + /// Identifier of the task this instance belongs to. + /// </summary> + public NameIdentifier TaskIdentifier; + + /// <summary> + /// UTC timestamp when the task started. + /// </summary> + public DateTime StartedAt; + + /// <summary> + /// UTC timestamp when the task completed. + /// </summary> + public DateTime? CompletedAt; + + /// <summary> + /// Current status of the task instance. + /// </summary> + public TaskInstanceStatus? Status; + + /// <summary> + /// Progress represented as percentage. + /// </summary> + public double? PercentComplete; + + /// <summary> + /// Estimated time remaining in seconds. + /// </summary> + public double? EstimatedSecondsRemaining; + + /// <summary> + /// If manually scheduled, ID of user who scheduled the task. + /// </summary> + public string ScheduledByUserId; + + /// <summary> + /// Result of CloudScript execution + /// </summary> + public ExecuteCloudScriptResult Result; + + } + public class CloudScriptVersionStatus { /// <summary> @@ -522,7 +667,331 @@ public class ContentInfo } - public class CreatePlayerStatisticDefinitionRequest + + public enum ContinentCode + { + AF, + AN, + AS, + EU, + NA, + OC, + SA + } + + + public enum CountryCode + { + AF, + AX, + AL, + DZ, + AS, + AD, + AO, + AI, + AQ, + AG, + AR, + AM, + AW, + AU, + AT, + AZ, + BS, + BH, + BD, + BB, + BY, + BE, + BZ, + BJ, + BM, + BT, + BO, + BQ, + BA, + BW, + BV, + BR, + IO, + BN, + BG, + BF, + BI, + KH, + CM, + CA, + CV, + KY, + CF, + TD, + CL, + CN, + CX, + CC, + CO, + KM, + CG, + CD, + CK, + CR, + CI, + HR, + CU, + CW, + CY, + CZ, + DK, + DJ, + DM, + DO, + EC, + EG, + SV, + GQ, + ER, + EE, + ET, + FK, + FO, + FJ, + FI, + FR, + GF, + PF, + TF, + GA, + GM, + GE, + DE, + GH, + GI, + GR, + GL, + GD, + GP, + GU, + GT, + GG, + GN, + GW, + GY, + HT, + HM, + VA, + HN, + HK, + HU, + IS, + IN, + ID, + IR, + IQ, + IE, + IM, + IL, + IT, + JM, + JP, + JE, + JO, + KZ, + KE, + KI, + KP, + KR, + KW, + KG, + LA, + LV, + LB, + LS, + LR, + LY, + LI, + LT, + LU, + MO, + MK, + MG, + MW, + MY, + MV, + ML, + MT, + MH, + MQ, + MR, + MU, + YT, + MX, + FM, + MD, + MC, + MN, + ME, + MS, + MA, + MZ, + MM, + NA, + NR, + NP, + NL, + NC, + NZ, + NI, + NE, + NG, + NU, + NF, + MP, + NO, + OM, + PK, + PW, + PS, + PA, + PG, + PY, + PE, + PH, + PN, + PL, + PT, + PR, + QA, + RE, + RO, + RU, + RW, + BL, + SH, + KN, + LC, + MF, + PM, + VC, + WS, + SM, + ST, + SA, + SN, + RS, + SC, + SL, + SG, + SX, + SK, + SI, + SB, + SO, + ZA, + GS, + SS, + ES, + LK, + SD, + SR, + SJ, + SZ, + SE, + CH, + SY, + TW, + TJ, + TZ, + TH, + TL, + TG, + TK, + TO, + TT, + TN, + TR, + TM, + TC, + TV, + UG, + UA, + AE, + GB, + US, + UM, + UY, + UZ, + VU, + VE, + VN, + VG, + VI, + WF, + EH, + YE, + ZM, + ZW + } + + public class CreateActionsOnPlayerSegmentTaskRequest : PlayFabRequestCommon + { + /// <summary> + /// Name of the task. This is a unique identifier for tasks in the title. + /// </summary> + public string Name; + + /// <summary> + /// Description the task + /// </summary> + public string Description; + + /// <summary> + /// Cron expression for the run schedule of the task. The expression should be in UTC. + /// </summary> + public string Schedule; + + /// <summary> + /// Whether the schedule is active. Inactive schedule will not trigger task execution. + /// </summary> + public bool IsActive; + + /// <summary> + /// Task details related to segment and action + /// </summary> + public ActionsOnPlayersInSegmentTaskParameter Parameter; + + } + + public class CreateCloudScriptTaskRequest : PlayFabRequestCommon + { + /// <summary> + /// Name of the task. This is a unique identifier for tasks in the title. + /// </summary> + public string Name; + + /// <summary> + /// Description the task + /// </summary> + public string Description; + + /// <summary> + /// Cron expression for the run schedule of the task. The expression should be in UTC. + /// </summary> + public string Schedule; + + /// <summary> + /// Whether the schedule is active. Inactive schedule will not trigger task execution. + /// </summary> + public bool IsActive; + + /// <summary> + /// Task details related to CloudScript + /// </summary> + public CloudScriptTaskParameter Parameter; + + } + + public class CreatePlayerStatisticDefinitionRequest : PlayFabRequestCommon { /// <summary> /// unique name of the statistic @@ -532,13 +1001,11 @@ public class CreatePlayerStatisticDefinitionRequest /// <summary> /// interval at which the values of the statistic for all players are reset (resets begin at the next interval boundary) /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public StatisticResetIntervalOption? VersionChangeInterval; /// <summary> /// the aggregation method to use in updating the statistic (defaults to last) /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public StatisticAggregationMethod? AggregationMethod; } @@ -552,6 +1019,15 @@ public class CreatePlayerStatisticDefinitionResult : PlayFabResultCommon } + public class CreateTaskResult : PlayFabResultCommon + { + /// <summary> + /// ID of the task + /// </summary> + public string TaskId; + + } + public enum Currency { @@ -719,7 +1195,7 @@ public enum Currency ZWD } - public class DeleteContentRequest + public class DeleteContentRequest : PlayFabRequestCommon { /// <summary> /// Key of the content item to be deleted @@ -728,7 +1204,7 @@ public class DeleteContentRequest } - public class DeleteStoreRequest + public class DeleteStoreRequest : PlayFabRequestCommon { /// <summary> /// catalog version of the store to delete. If null, uses the default catalog. @@ -746,7 +1222,16 @@ public class DeleteStoreResult : PlayFabResultCommon { } - public class DeleteUsersRequest + public class DeleteTaskRequest : PlayFabRequestCommon + { + /// <summary> + /// Specify either the task ID or the name of task to be deleted. + /// </summary> + public NameIdentifier Identifier; + + } + + public class DeleteUsersRequest : PlayFabRequestCommon { /// <summary> /// An array of unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -764,6 +1249,58 @@ public class DeleteUsersResult : PlayFabResultCommon { } + public class EmptyResult : PlayFabResultCommon + { + } + + public class ExecuteCloudScriptResult : PlayFabResultCommon + { + /// <summary> + /// The name of the function that executed + /// </summary> + public string FunctionName; + + /// <summary> + /// The revision of the CloudScript that executed + /// </summary> + public int Revision; + + /// <summary> + /// The object returned from the CloudScript function, if any + /// </summary> + public object FunctionResult; + + /// <summary> + /// Entries logged during the function execution. These include both entries logged in the function code using log.info() and log.error() and error entries for API and HTTP request failures. + /// </summary> + public List<LogStatement> Logs; + + public double ExecutionTimeSeconds; + + /// <summary> + /// Processor time consumed while executing the function. This does not include time spent waiting on API calls or HTTP requests. + /// </summary> + public double ProcessorTimeSeconds; + + public uint MemoryConsumedBytes; + + /// <summary> + /// Number of PlayFab API requests issued by the CloudScript function + /// </summary> + public int APIRequestsIssued; + + /// <summary> + /// Number of external HTTP requests issued by the CloudScript function + /// </summary> + public int HttpRequestsIssued; + + /// <summary> + /// Information about the error, if any, that occured during execution + /// </summary> + public ScriptExecutionError Error; + + } + public enum GameBuildStatus { @@ -812,7 +1349,21 @@ public class GetActionGroupResult : PlayFabResultCommon } - public class GetAllActionGroupsRequest + public class GetActionsOnPlayersInSegmentTaskInstanceResult : PlayFabResultCommon + { + /// <summary> + /// Status summary of the actions-on-players-in-segment task instance + /// </summary> + public ActionsOnPlayersInSegmentTaskSummary Summary; + + /// <summary> + /// Parameter of this task instance + /// </summary> + public ActionsOnPlayersInSegmentTaskParameter Parameter; + + } + + public class GetAllActionGroupsRequest : PlayFabRequestCommon { } @@ -825,7 +1376,7 @@ public class GetAllActionGroupsResult : PlayFabResultCommon } - public class GetAllSegmentsRequest + public class GetAllSegmentsRequest : PlayFabRequestCommon { } @@ -838,7 +1389,7 @@ public class GetAllSegmentsResult : PlayFabResultCommon } - public class GetCatalogItemsRequest + public class GetCatalogItemsRequest : PlayFabRequestCommon { /// <summary> /// Which catalog is being requested. If null, uses the default catalog. @@ -857,7 +1408,7 @@ public class GetCatalogItemsResult : PlayFabResultCommon } - public class GetCloudScriptRevisionRequest + public class GetCloudScriptRevisionRequest : PlayFabRequestCommon { /// <summary> /// Version number. If left null, defaults to the latest version @@ -900,7 +1451,21 @@ public class GetCloudScriptRevisionResult : PlayFabResultCommon } - public class GetCloudScriptVersionsRequest + public class GetCloudScriptTaskInstanceResult : PlayFabResultCommon + { + /// <summary> + /// Status summary of the CloudScript task instance + /// </summary> + public CloudScriptTaskSummary Summary; + + /// <summary> + /// Parameter of this task instance + /// </summary> + public CloudScriptTaskParameter Parameter; + + } + + public class GetCloudScriptVersionsRequest : PlayFabRequestCommon { } @@ -913,7 +1478,7 @@ public class GetCloudScriptVersionsResult : PlayFabResultCommon } - public class GetContentListRequest + public class GetContentListRequest : PlayFabRequestCommon { /// <summary> /// Limits the response to keys that begin with the specified prefix. You can use prefixes to list contents under a folder, or for a specified version, etc. @@ -941,7 +1506,7 @@ public class GetContentListResult : PlayFabResultCommon } - public class GetContentUploadUrlRequest + public class GetContentUploadUrlRequest : PlayFabRequestCommon { /// <summary> /// Key of the content item to upload, usually formatted as a path, e.g. images/a.png @@ -964,7 +1529,7 @@ public class GetContentUploadUrlResult : PlayFabResultCommon } - public class GetDataReportRequest + public class GetDataReportRequest : PlayFabRequestCommon { /// <summary> /// Report name @@ -997,7 +1562,7 @@ public class GetDataReportResult : PlayFabResultCommon } - public class GetMatchmakerGameInfoRequest + public class GetMatchmakerGameInfoRequest : PlayFabRequestCommon { /// <summary> /// unique identifier of the lobby for which info is being requested @@ -1041,7 +1606,6 @@ public class GetMatchmakerGameInfoResult : PlayFabResultCommon /// <summary> /// region in which the Game Server Instance is running /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Region? Region; /// <summary> @@ -1062,7 +1626,7 @@ public class GetMatchmakerGameInfoResult : PlayFabResultCommon } - public class GetMatchmakerGameModesRequest + public class GetMatchmakerGameModesRequest : PlayFabRequestCommon { /// <summary> /// previously uploaded build version for which game modes are being requested @@ -1089,7 +1653,7 @@ public class GetPlayerSegmentsResult : PlayFabResultCommon } - public class GetPlayersInSegmentRequest + public class GetPlayersInSegmentRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for this segment. @@ -1132,7 +1696,7 @@ public class GetPlayersInSegmentResult : PlayFabResultCommon } - public class GetPlayersSegmentsRequest + public class GetPlayersSegmentsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1141,7 +1705,7 @@ public class GetPlayersSegmentsRequest } - public class GetPlayerStatisticDefinitionsRequest + public class GetPlayerStatisticDefinitionsRequest : PlayFabRequestCommon { } @@ -1154,7 +1718,7 @@ public class GetPlayerStatisticDefinitionsResult : PlayFabResultCommon } - public class GetPlayerStatisticVersionsRequest + public class GetPlayerStatisticVersionsRequest : PlayFabRequestCommon { /// <summary> /// unique name of the statistic @@ -1172,7 +1736,7 @@ public class GetPlayerStatisticVersionsResult : PlayFabResultCommon } - public class GetPlayerTagsRequest + public class GetPlayerTagsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1200,7 +1764,7 @@ public class GetPlayerTagsResult : PlayFabResultCommon } - public class GetPublisherDataRequest + public class GetPublisherDataRequest : PlayFabRequestCommon { /// <summary> /// array of keys to get back data from the Publisher data blob, set by the admin tools @@ -1218,7 +1782,7 @@ public class GetPublisherDataResult : PlayFabResultCommon } - public class GetRandomResultTablesRequest : PlayFabResultCommon + public class GetRandomResultTablesRequest : PlayFabRequestCommon { /// <summary> /// catalog version to fetch tables from. Use default catalog version if null @@ -1255,7 +1819,7 @@ public class GetSegmentResult : PlayFabResultCommon } - public class GetServerBuildInfoRequest + public class GetServerBuildInfoRequest : PlayFabRequestCommon { /// <summary> /// unique identifier of the previously uploaded build executable for which information is being requested @@ -1277,7 +1841,6 @@ public class GetServerBuildInfoResult : PlayFabResultCommon, IComparable<GetServ /// <summary> /// array of regions where this build can used, when it is active /// </summary> - [JsonProperty(ItemConverterType = typeof(StringEnumConverter))] [Unordered] public List<Region> ActiveRegions; @@ -1309,7 +1872,6 @@ public class GetServerBuildInfoResult : PlayFabResultCommon, IComparable<GetServ /// <summary> /// the current status of the build validation and processing steps /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public GameBuildStatus? Status; /// <summary> @@ -1326,7 +1888,7 @@ public int CompareTo(GetServerBuildInfoResult other) } - public class GetServerBuildUploadURLRequest + public class GetServerBuildUploadURLRequest : PlayFabRequestCommon { /// <summary> /// unique identifier of the game server build to upload @@ -1344,7 +1906,7 @@ public class GetServerBuildUploadURLResult : PlayFabResultCommon } - public class GetStoreItemsRequest + public class GetStoreItemsRequest : PlayFabRequestCommon { /// <summary> /// catalog version to store items from. Use default catalog version if null @@ -1369,7 +1931,6 @@ public class GetStoreItemsResult : PlayFabResultCommon /// <summary> /// How the store was last updated (Admin or a third party). /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public SourceType? Source; /// <summary> @@ -1389,7 +1950,67 @@ public class GetStoreItemsResult : PlayFabResultCommon } - public class GetTitleDataRequest + public class GetTaskInstanceRequest : PlayFabRequestCommon + { + /// <summary> + /// ID of the requested task instance. + /// </summary> + public string TaskInstanceId; + + } + + public class GetTaskInstancesRequest : PlayFabRequestCommon + { + /// <summary> + /// Name or ID of the task whose instances are being queried. If not specified, return all task instances that satisfy conditions set by other filters. + /// </summary> + public NameIdentifier TaskIdentifier; + + /// <summary> + /// Optional filter for task instances that are of a specific status. + /// </summary> + public TaskInstanceStatus? StatusFilter; + + /// <summary> + /// Optional range-from filter for task instances' StartedAt timestamp. + /// </summary> + public DateTime? StartedAtRangeFrom; + + /// <summary> + /// Optional range-to filter for task instances' StartedAt timestamp. + /// </summary> + public DateTime? StartedAtRangeTo; + + } + + public class GetTaskInstancesResult : PlayFabResultCommon + { + /// <summary> + /// Basic status summaries of the queried task instances. Empty If no task instances meets the filter criteria. To get detailed status summary, use Get*TaskInstance API according to task type (e.g. GetActionsOnPlayersInSegmentTaskInstance). + /// </summary> + public List<TaskInstanceBasicSummary> Summaries; + + } + + public class GetTasksRequest : PlayFabRequestCommon + { + /// <summary> + /// Provide either the task ID or the task name to get a specific task. If not specified, return all defined tasks. + /// </summary> + public NameIdentifier Identifier; + + } + + public class GetTasksResult : PlayFabResultCommon + { + /// <summary> + /// Result tasks. Empty if there is no task found. + /// </summary> + public List<ScheduledTask> Tasks; + + } + + public class GetTitleDataRequest : PlayFabRequestCommon { /// <summary> /// Specific keys to search for in the title data (leave null to get all keys) @@ -1407,7 +2028,7 @@ public class GetTitleDataResult : PlayFabResultCommon } - public class GetUserBansRequest + public class GetUserBansRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1425,7 +2046,7 @@ public class GetUserBansResult : PlayFabResultCommon } - public class GetUserDataRequest + public class GetUserDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1463,7 +2084,7 @@ public class GetUserDataResult : PlayFabResultCommon } - public class GetUserInventoryRequest + public class GetUserInventoryRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1601,7 +2222,7 @@ public int CompareTo(GrantedItemInstance other) } - public class GrantItemsToUsersRequest + public class GrantItemsToUsersRequest : PlayFabRequestCommon { /// <summary> /// Catalog version from which items are to be granted. @@ -1625,7 +2246,7 @@ public class GrantItemsToUsersResult : PlayFabResultCommon } - public class IncrementPlayerStatisticVersionRequest + public class IncrementPlayerStatisticVersionRequest : PlayFabRequestCommon { /// <summary> /// unique name of the statistic @@ -1766,7 +2387,7 @@ public int CompareTo(ItemInstance other) } - public class ListBuildsRequest + public class ListBuildsRequest : PlayFabRequestCommon { } @@ -1780,7 +2401,7 @@ public class ListBuildsResult : PlayFabResultCommon } - public class ListVirtualCurrencyTypesRequest + public class ListVirtualCurrencyTypesRequest : PlayFabRequestCommon { } @@ -1812,7 +2433,23 @@ public enum LoginIdentityProvider Twitch } - public class LookupUserAccountInfoRequest + public class LogStatement + { + /// <summary> + /// 'Debug', 'Info', or 'Error' + /// </summary> + public string Level; + + public string Message; + + /// <summary> + /// Optional object accompanying the message as contextual information + /// </summary> + public object Data; + + } + + public class LookupUserAccountInfoRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1845,7 +2482,7 @@ public class LookupUserAccountInfoResult : PlayFabResultCommon } - public class ModifyMatchmakerGameModesRequest + public class ModifyMatchmakerGameModesRequest : PlayFabRequestCommon { /// <summary> /// previously uploaded build version for which game modes are being specified @@ -1863,7 +2500,7 @@ public class ModifyMatchmakerGameModesResult : PlayFabResultCommon { } - public class ModifyServerBuildRequest + public class ModifyServerBuildRequest : PlayFabRequestCommon { /// <summary> /// unique identifier of the previously uploaded build executable to be updated @@ -1878,7 +2515,6 @@ public class ModifyServerBuildRequest /// <summary> /// array of regions where this build can used, when it is active /// </summary> - [JsonProperty(ItemConverterType = typeof(StringEnumConverter))] public List<Region> ActiveRegions; /// <summary> @@ -1918,7 +2554,6 @@ public class ModifyServerBuildResult : PlayFabResultCommon /// <summary> /// array of regions where this build can used, when it is active /// </summary> - [JsonProperty(ItemConverterType = typeof(StringEnumConverter))] public List<Region> ActiveRegions; /// <summary> @@ -1959,7 +2594,6 @@ public class ModifyServerBuildResult : PlayFabResultCommon /// <summary> /// the current status of the build validation and processing steps /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public GameBuildStatus? Status; } @@ -1988,12 +2622,22 @@ public class ModifyUserVirtualCurrencyResult : PlayFabResultCommon } + /// <summary> + /// Identifier by either name or ID. Note that a name may change due to renaming, or reused after being deleted. ID is immutable and unique. + /// </summary> + public class NameIdentifier + { + public string Name; + + public string Id; + + } + public class PlayerLinkedAccount { /// <summary> /// Authentication platform /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public LoginIdentityProvider? Platform; /// <summary> @@ -2013,6 +2657,35 @@ public class PlayerLinkedAccount } + public class PlayerLocation + { + /// <summary> + /// The two-character continent code for this location + /// </summary> + public ContinentCode ContinentCode; + + /// <summary> + /// The two-character ISO 3166-1 country code for the country associated with the location + /// </summary> + public CountryCode CountryCode; + + /// <summary> + /// City of the player's geographic location. + /// </summary> + public string City; + + /// <summary> + /// Latitude coordinate of the player's geographic location. + /// </summary> + public double? Latitude; + + /// <summary> + /// Longitude coordinate of the player's geographic location. + /// </summary> + public double? Longitude; + + } + public class PlayerProfile { /// <summary> @@ -2038,7 +2711,6 @@ public class PlayerProfile /// <summary> /// Player account origination /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public LoginIdentityProvider? Origination; /// <summary> @@ -2076,6 +2748,11 @@ public class PlayerProfile /// </summary> public List<string> Tags; + /// <summary> + /// Dictionary of player's locations by type. + /// </summary> + public Dictionary<string,PlayerLocation> Locations; + /// <summary> /// Dictionary of player's virtual currency balances /// </summary> @@ -2142,13 +2819,11 @@ public class PlayerStatisticDefinition /// <summary> /// interval at which the values of the statistic for all players are reset automatically /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public StatisticResetIntervalOption? VersionChangeInterval; /// <summary> /// the aggregation method to use in updating the statistic (defaults to last) /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public StatisticAggregationMethod? AggregationMethod; } @@ -2188,7 +2863,6 @@ public class PlayerStatisticVersion /// <summary> /// status of the process of saving player statistic values of the previous version to a downloadable archive /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public StatisticVersionArchivalStatus? ArchivalStatus; /// <summary> @@ -2210,7 +2884,6 @@ public class PushNotificationRegistration /// <summary> /// Push notification platform /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public PushNotificationPlatform? Platform; /// <summary> @@ -2220,7 +2893,7 @@ public class PushNotificationRegistration } - public class RandomResultTable : PlayFabResultCommon + public class RandomResultTable { /// <summary> /// Unique name for this drop table @@ -2234,7 +2907,7 @@ public class RandomResultTable : PlayFabResultCommon } - public class RandomResultTableListing : PlayFabResultCommon + public class RandomResultTableListing { /// <summary> /// Catalog version this table is associated with @@ -2253,7 +2926,7 @@ public class RandomResultTableListing : PlayFabResultCommon } - public class RefundPurchaseRequest + public class RefundPurchaseRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2293,7 +2966,7 @@ public enum Region Australia } - public class RemovePlayerTagRequest + public class RemovePlayerTagRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2311,7 +2984,7 @@ public class RemovePlayerTagResult : PlayFabResultCommon { } - public class RemoveServerBuildRequest + public class RemoveServerBuildRequest : PlayFabRequestCommon { /// <summary> /// unique identifier of the previously uploaded build executable to be removed @@ -2324,7 +2997,7 @@ public class RemoveServerBuildResult : PlayFabResultCommon { } - public class RemoveVirtualCurrencyTypesRequest + public class RemoveVirtualCurrencyTypesRequest : PlayFabRequestCommon { /// <summary> /// List of virtual currencies to delete @@ -2333,7 +3006,7 @@ public class RemoveVirtualCurrencyTypesRequest } - public class ResetCharacterStatisticsRequest + public class ResetCharacterStatisticsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2351,7 +3024,7 @@ public class ResetCharacterStatisticsResult : PlayFabResultCommon { } - public class ResetUsersRequest + public class ResetUsersRequest : PlayFabRequestCommon { /// <summary> /// Array of users to reset @@ -2360,7 +3033,7 @@ public class ResetUsersRequest } - public class ResetUserStatisticsRequest + public class ResetUserStatisticsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2381,7 +3054,7 @@ public enum ResolutionOutcome Manual } - public class ResolvePurchaseDisputeRequest + public class ResolvePurchaseDisputeRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2401,7 +3074,6 @@ public class ResolvePurchaseDisputeRequest /// <summary> /// Enum for the desired purchase result state after notifying the payment provider. Valid values are Revoke, Reinstate and Manual. Manual will cause no change to the order state. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public ResolutionOutcome Outcome; } @@ -2415,12 +3087,11 @@ public class ResolvePurchaseDisputeResponse : PlayFabResultCommon } - public class ResultTableNode : PlayFabResultCommon + public class ResultTableNode { /// <summary> /// Whether this entry in the table is an item or a link to another table /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public ResultTableNodeType ResultItemType; /// <summary> @@ -2442,7 +3113,7 @@ public enum ResultTableNodeType TableId } - public class RevokeAllBansForUserRequest + public class RevokeAllBansForUserRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2460,7 +3131,7 @@ public class RevokeAllBansForUserResult : PlayFabResultCommon } - public class RevokeBansRequest + public class RevokeBansRequest : PlayFabRequestCommon { /// <summary> /// Ids of the bans to be revoked. Maximum 100. @@ -2478,7 +3149,7 @@ public class RevokeBansResult : PlayFabResultCommon } - public class RevokeInventoryItemRequest + public class RevokeInventoryItemRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2501,7 +3172,100 @@ public class RevokeInventoryResult : PlayFabResultCommon { } - public class SendAccountRecoveryEmailRequest + public class RunTaskRequest : PlayFabRequestCommon + { + /// <summary> + /// Provide either the task ID or the task name to run a task. + /// </summary> + public NameIdentifier Identifier; + + } + + public class RunTaskResult : PlayFabResultCommon + { + /// <summary> + /// ID of the task instance that is started. This can be used in Get*TaskInstance (e.g. GetCloudScriptTaskInstance) API call to retrieve status for the task instance. + /// </summary> + public string TaskInstanceId; + + } + + public class ScheduledTask + { + /// <summary> + /// ID of the task + /// </summary> + public string TaskId; + + /// <summary> + /// Name of the task. This is a unique identifier for tasks in the title. + /// </summary> + public string Name; + + /// <summary> + /// Description the task + /// </summary> + public string Description; + + /// <summary> + /// Cron expression for the run schedule of the task. The expression should be in UTC. + /// </summary> + public string Schedule; + + /// <summary> + /// Whether the schedule is active. Inactive schedule will not trigger task execution. + /// </summary> + public bool IsActive; + + /// <summary> + /// Task type. + /// </summary> + public ScheduledTaskType? Type; + + /// <summary> + /// Task parameter. Different types of task have different parameter structure. See each task type's create API documentation for the details. + /// </summary> + public object Parameter; + + /// <summary> + /// UTC time of last run + /// </summary> + public DateTime? LastRunTime; + + /// <summary> + /// UTC time of next run + /// </summary> + public DateTime? NextRunTime; + + } + + + public enum ScheduledTaskType + { + CloudScript, + ActionsOnPlayerSegment + } + + public class ScriptExecutionError + { + /// <summary> + /// Error code, such as CloudScriptNotFound, JavascriptException, CloudScriptFunctionArgumentSizeExceeded, CloudScriptAPIRequestCountExceeded, CloudScriptAPIRequestError, or CloudScriptHTTPRequestError + /// </summary> + public string Error; + + /// <summary> + /// Details about the error + /// </summary> + public string Message; + + /// <summary> + /// Point during the execution of the script at which the error occurred, if any + /// </summary> + public string StackTrace; + + } + + public class SendAccountRecoveryEmailRequest : PlayFabRequestCommon { /// <summary> /// User email address attached to their account @@ -2514,7 +3278,7 @@ public class SendAccountRecoveryEmailResult : PlayFabResultCommon { } - public class SetPublishedRevisionRequest + public class SetPublishedRevisionRequest : PlayFabRequestCommon { /// <summary> /// Version number @@ -2532,7 +3296,7 @@ public class SetPublishedRevisionResult : PlayFabResultCommon { } - public class SetPublisherDataRequest + public class SetPublisherDataRequest : PlayFabRequestCommon { /// <summary> /// key we want to set a value on (note, this is additive - will only replace an existing key's value if they are the same name.) Keys are trimmed of whitespace. Keys may not begin with the '!' character. @@ -2550,7 +3314,7 @@ public class SetPublisherDataResult : PlayFabResultCommon { } - public class SetTitleDataRequest + public class SetTitleDataRequest : PlayFabRequestCommon { /// <summary> /// key we want to set a value on (note, this is additive - will only replace an existing key's value if they are the same name.) Keys are trimmed of whitespace. Keys may not begin with the '!' character. @@ -2568,7 +3332,7 @@ public class SetTitleDataResult : PlayFabResultCommon { } - public class SetupPushNotificationRequest + public class SetupPushNotificationRequest : PlayFabRequestCommon { /// <summary> /// name of the application sending the message (application names must be made up of only uppercase and lowercase ASCII letters, numbers, underscores, hyphens, and periods, and must be between 1 and 256 characters long) @@ -2706,7 +3470,7 @@ public class StoreMarketingModel } - public class SubtractUserVirtualCurrencyRequest + public class SubtractUserVirtualCurrencyRequest : PlayFabRequestCommon { /// <summary> /// PlayFab unique identifier of the user whose virtual currency balance is to be decreased. @@ -2725,6 +3489,66 @@ public class SubtractUserVirtualCurrencyRequest } + public class TaskInstanceBasicSummary + { + /// <summary> + /// ID of the task instance. + /// </summary> + public string TaskInstanceId; + + /// <summary> + /// Identifier of the task this instance belongs to. + /// </summary> + public NameIdentifier TaskIdentifier; + + /// <summary> + /// UTC timestamp when the task started. + /// </summary> + public DateTime StartedAt; + + /// <summary> + /// UTC timestamp when the task completed. + /// </summary> + public DateTime? CompletedAt; + + /// <summary> + /// Current status of the task instance. + /// </summary> + public TaskInstanceStatus? Status; + + /// <summary> + /// Progress represented as percentage. + /// </summary> + public double? PercentComplete; + + /// <summary> + /// Estimated time remaining in seconds. + /// </summary> + public double? EstimatedSecondsRemaining; + + /// <summary> + /// If manually scheduled, ID of user who scheduled the task. + /// </summary> + public string ScheduledByUserId; + + /// <summary> + /// Type of the task. + /// </summary> + public ScheduledTaskType? Type; + + } + + + public enum TaskInstanceStatus + { + Succeeded, + Starting, + InProgress, + Failed, + Aborted, + Pending + } + public enum TitleActivationStatus { @@ -2738,7 +3562,7 @@ public enum TitleActivationStatus /// <summary> /// Represents a single update ban request. /// </summary> - public class UpdateBanRequest + public class UpdateBanRequest : PlayFabRequestCommon { /// <summary> /// The id of the ban to be updated. @@ -2777,7 +3601,7 @@ public class UpdateBanRequest } - public class UpdateBansRequest + public class UpdateBansRequest : PlayFabRequestCommon { /// <summary> /// List of bans to be updated. Maximum 100. @@ -2795,7 +3619,7 @@ public class UpdateBansResult : PlayFabResultCommon } - public class UpdateCatalogItemsRequest + public class UpdateCatalogItemsRequest : PlayFabRequestCommon { /// <summary> /// Which catalog is being updated. If null, uses the default catalog. @@ -2818,7 +3642,7 @@ public class UpdateCatalogItemsResult : PlayFabResultCommon { } - public class UpdateCloudScriptRequest + public class UpdateCloudScriptRequest : PlayFabRequestCommon { /// <summary> /// List of Cloud Script files to upload to create the new revision. Must have at least one file. @@ -2851,7 +3675,7 @@ public class UpdateCloudScriptResult : PlayFabResultCommon } - public class UpdatePlayerStatisticDefinitionRequest + public class UpdatePlayerStatisticDefinitionRequest : PlayFabRequestCommon { /// <summary> /// unique name of the statistic @@ -2861,13 +3685,11 @@ public class UpdatePlayerStatisticDefinitionRequest /// <summary> /// interval at which the values of the statistic for all players are reset (changes are effective at the next occurance of the new interval boundary) /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public StatisticResetIntervalOption? VersionChangeInterval; /// <summary> /// the aggregation method to use in updating the statistic (defaults to last) /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public StatisticAggregationMethod? AggregationMethod; } @@ -2881,7 +3703,7 @@ public class UpdatePlayerStatisticDefinitionResult : PlayFabResultCommon } - public class UpdateRandomResultTablesRequest : PlayFabResultCommon + public class UpdateRandomResultTablesRequest : PlayFabRequestCommon { /// <summary> /// which catalog is being updated. If null, update the current default catalog version @@ -2899,7 +3721,7 @@ public class UpdateRandomResultTablesResult : PlayFabResultCommon { } - public class UpdateStoreItemsRequest + public class UpdateStoreItemsRequest : PlayFabRequestCommon { /// <summary> /// Catalog version of the store to update. If null, uses the default catalog. @@ -2927,7 +3749,46 @@ public class UpdateStoreItemsResult : PlayFabResultCommon { } - public class UpdateUserDataRequest + public class UpdateTaskRequest : PlayFabRequestCommon + { + /// <summary> + /// Specify either the task ID or the name of the task to be updated. + /// </summary> + public NameIdentifier Identifier; + + /// <summary> + /// Name of the task. This is a unique identifier for tasks in the title. + /// </summary> + public string Name; + + /// <summary> + /// Description the task + /// </summary> + public string Description; + + /// <summary> + /// Cron expression for the run schedule of the task. The expression should be in UTC. + /// </summary> + public string Schedule; + + /// <summary> + /// Whether the schedule is active. Inactive schedule will not trigger task execution. + /// </summary> + public bool IsActive; + + /// <summary> + /// Task type. + /// </summary> + public ScheduledTaskType Type; + + /// <summary> + /// Parameter object specific to the task type. See each task type's create API documentation for details. + /// </summary> + public object Parameter; + + } + + public class UpdateUserDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2947,7 +3808,6 @@ public class UpdateUserDataRequest /// <summary> /// Permission to be applied to all user data keys written in this request. Defaults to "private" if not set. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -2961,7 +3821,7 @@ public class UpdateUserDataResult : PlayFabResultCommon } - public class UpdateUserInternalDataRequest + public class UpdateUserInternalDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2980,7 +3840,7 @@ public class UpdateUserInternalDataRequest } - public class UpdateUserTitleDisplayNameRequest + public class UpdateUserTitleDisplayNameRequest : PlayFabRequestCommon { /// <summary> /// PlayFab unique identifier of the user whose title specific display name is to be changed @@ -3145,7 +4005,6 @@ public class UserDataRecord /// <summary> /// Indicates whether this data can be read by all users (public) or only the user (private). This is used for GetUserData requests being made by one player about another player. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -3280,13 +4139,11 @@ public class UserSteamInfo /// <summary> /// currency type set in the user Steam account /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Currency? SteamCurrency; /// <summary> /// what stage of game ownership the user is listed as being in, from Steam /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public TitleActivationStatus? SteamActivationStatus; } @@ -3301,7 +4158,6 @@ public class UserTitleInfo /// <summary> /// source by which the user first joined the game, if known /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserOrigination? Origination; /// <summary> diff --git a/PlayFabSDK/source/PlayFabClientAPI.cs b/PlayFabSDK/source/PlayFabClientAPI.cs index f1137e40..f354fa7e 100644 --- a/PlayFabSDK/source/PlayFabClientAPI.cs +++ b/PlayFabSDK/source/PlayFabClientAPI.cs @@ -1,13 +1,11 @@ -using Newtonsoft.Json; -using PlayFab.Internal; using PlayFab.ClientModels; +using PlayFab.Internal; +using PlayFab.Json; using System; -using System.IO; using System.Threading.Tasks; namespace PlayFab { - /// <summary> /// APIs which provide the full range of PlayFab features available to the client - authentication, account and data management, inventory, friends, matchmaking, reporting, and platform-specific functionality /// </summary> @@ -16,3067 +14,2825 @@ public class PlayFabClientAPI /// <summary> /// Gets a Photon custom authentication token that can be used to securely join the player into a Photon room. See https://api.playfab.com/docs/using-photon-with-playfab/ for more details. /// </summary> - public static async Task<PlayFabResult<GetPhotonAuthenticationTokenResult>> GetPhotonAuthenticationTokenAsync(GetPhotonAuthenticationTokenRequest request) + public static async Task<PlayFabResult<GetPhotonAuthenticationTokenResult>> GetPhotonAuthenticationTokenAsync(GetPhotonAuthenticationTokenRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPhotonAuthenticationToken", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPhotonAuthenticationToken", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPhotonAuthenticationTokenResult> { Error = error, }; + return new PlayFabResult<GetPhotonAuthenticationTokenResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPhotonAuthenticationTokenResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPhotonAuthenticationTokenResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPhotonAuthenticationTokenResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPhotonAuthenticationTokenResult> { Result = result }; + return new PlayFabResult<GetPhotonAuthenticationTokenResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user in using the Android device identifier, returning a session identifier that can subsequently be used for API calls which require an authenticated user /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithAndroidDeviceIDAsync(LoginWithAndroidDeviceIDRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithAndroidDeviceIDAsync(LoginWithAndroidDeviceIDRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithAndroidDeviceID", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithAndroidDeviceID", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user in using a custom unique identifier generated by the title, returning a session identifier that can subsequently be used for API calls which require an authenticated user /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithCustomIDAsync(LoginWithCustomIDRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithCustomIDAsync(LoginWithCustomIDRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithCustomID", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithCustomID", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user into the PlayFab account, returning a session identifier that can subsequently be used for API calls which require an authenticated user /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithEmailAddressAsync(LoginWithEmailAddressRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithEmailAddressAsync(LoginWithEmailAddressRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithEmailAddress", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithEmailAddress", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user in using a Facebook access token, returning a session identifier that can subsequently be used for API calls which require an authenticated user /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithFacebookAsync(LoginWithFacebookRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithFacebookAsync(LoginWithFacebookRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithFacebook", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithFacebook", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user in using an iOS Game Center player identifier, returning a session identifier that can subsequently be used for API calls which require an authenticated user /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithGameCenterAsync(LoginWithGameCenterRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithGameCenterAsync(LoginWithGameCenterRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithGameCenter", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithGameCenter", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user in using a Google account access token(https://developers.google.com/android/reference/com/google/android/gms/auth/GoogleAuthUtil#public-methods), returning a session identifier that can subsequently be used for API calls which require an authenticated user /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithGoogleAccountAsync(LoginWithGoogleAccountRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithGoogleAccountAsync(LoginWithGoogleAccountRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithGoogleAccount", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithGoogleAccount", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user in using the vendor-specific iOS device identifier, returning a session identifier that can subsequently be used for API calls which require an authenticated user /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithIOSDeviceIDAsync(LoginWithIOSDeviceIDRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithIOSDeviceIDAsync(LoginWithIOSDeviceIDRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithIOSDeviceID", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithIOSDeviceID", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user in using a Kongregate player account. /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithKongregateAsync(LoginWithKongregateRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithKongregateAsync(LoginWithKongregateRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithKongregate", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithKongregate", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user into the PlayFab account, returning a session identifier that can subsequently be used for API calls which require an authenticated user. Unlike other login API calls, LoginWithEmailAddress does not permit the creation of new accounts via the CreateAccountFlag. Email accounts must be created using the RegisterPlayFabUser API or added to existing accounts using AddUsernamePassword. /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithPlayFabAsync(LoginWithPlayFabRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithPlayFabAsync(LoginWithPlayFabRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithPlayFab", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithPlayFab", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user in using a Steam authentication ticket, returning a session identifier that can subsequently be used for API calls which require an authenticated user /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithSteamAsync(LoginWithSteamRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithSteamAsync(LoginWithSteamRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithSteam", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithSteam", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Signs the user in using a Twitch access token. /// </summary> - public static async Task<PlayFabResult<LoginResult>> LoginWithTwitchAsync(LoginWithTwitchRequest request) + public static async Task<PlayFabResult<LoginResult>> LoginWithTwitchAsync(LoginWithTwitchRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LoginWithTwitch", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/LoginWithTwitch", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LoginResult> { Error = error, }; + return new PlayFabResult<LoginResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LoginResult>>(new JsonTextReader(new StringReader(resultRawJson))); - - LoginResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LoginResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<LoginResult> { Result = result }; + return new PlayFabResult<LoginResult> { Result = result, CustomData = customData }; } /// <summary> /// Registers a new Playfab user account, returning a session identifier that can subsequently be used for API calls which require an authenticated user. You must supply either a username or an email address. /// </summary> - public static async Task<PlayFabResult<RegisterPlayFabUserResult>> RegisterPlayFabUserAsync(RegisterPlayFabUserRequest request) + public static async Task<PlayFabResult<RegisterPlayFabUserResult>> RegisterPlayFabUserAsync(RegisterPlayFabUserRequest request, object customData = null) { request.TitleId = PlayFabSettings.TitleId ?? request.TitleId; if(request.TitleId == null) throw new Exception ("Must be have PlayFabSettings.TitleId set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/RegisterPlayFabUser", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/RegisterPlayFabUser", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RegisterPlayFabUserResult> { Error = error, }; + return new PlayFabResult<RegisterPlayFabUserResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RegisterPlayFabUserResult>>(new JsonTextReader(new StringReader(resultRawJson))); - RegisterPlayFabUserResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RegisterPlayFabUserResult>>(resultRawJson); + var result = resultData.data; _authKey = result.SessionTicket ?? _authKey; await MultiStepClientLogin(result.SettingsForUser.NeedsAttribution); - return new PlayFabResult<RegisterPlayFabUserResult> { Result = result }; + return new PlayFabResult<RegisterPlayFabUserResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the specified generic service identifier to the player's PlayFab account. This is designed to allow for a PlayFab ID lookup of any arbitrary service identifier a title wants to add. This identifier should never be used as authentication credentials, as the intent is that it is easily accessible by other players. /// </summary> - public static async Task<PlayFabResult<AddGenericIDResult>> AddGenericIDAsync(AddGenericIDRequest request) + public static async Task<PlayFabResult<AddGenericIDResult>> AddGenericIDAsync(AddGenericIDRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/AddGenericID", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/AddGenericID", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AddGenericIDResult> { Error = error, }; + return new PlayFabResult<AddGenericIDResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AddGenericIDResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AddGenericIDResult>>(resultRawJson); + var result = resultData.data; - AddGenericIDResult result = resultData.data; - - return new PlayFabResult<AddGenericIDResult> { Result = result }; + return new PlayFabResult<AddGenericIDResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds playfab username/password auth to an existing account created via an anonymous auth method, e.g. automatic device ID login. /// </summary> - public static async Task<PlayFabResult<AddUsernamePasswordResult>> AddUsernamePasswordAsync(AddUsernamePasswordRequest request) + public static async Task<PlayFabResult<AddUsernamePasswordResult>> AddUsernamePasswordAsync(AddUsernamePasswordRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/AddUsernamePassword", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/AddUsernamePassword", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AddUsernamePasswordResult> { Error = error, }; + return new PlayFabResult<AddUsernamePasswordResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AddUsernamePasswordResult>>(new JsonTextReader(new StringReader(resultRawJson))); - AddUsernamePasswordResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AddUsernamePasswordResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AddUsernamePasswordResult> { Result = result }; + return new PlayFabResult<AddUsernamePasswordResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the user's PlayFab account details /// </summary> - public static async Task<PlayFabResult<GetAccountInfoResult>> GetAccountInfoAsync(GetAccountInfoRequest request) + public static async Task<PlayFabResult<GetAccountInfoResult>> GetAccountInfoAsync(GetAccountInfoRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetAccountInfo", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetAccountInfo", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetAccountInfoResult> { Error = error, }; + return new PlayFabResult<GetAccountInfoResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetAccountInfoResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetAccountInfoResult>>(resultRawJson); + var result = resultData.data; - GetAccountInfoResult result = resultData.data; - - return new PlayFabResult<GetAccountInfoResult> { Result = result }; + return new PlayFabResult<GetAccountInfoResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves all of the user's different kinds of info. /// </summary> - public static async Task<PlayFabResult<GetPlayerCombinedInfoResult>> GetPlayerCombinedInfoAsync(GetPlayerCombinedInfoRequest request) + public static async Task<PlayFabResult<GetPlayerCombinedInfoResult>> GetPlayerCombinedInfoAsync(GetPlayerCombinedInfoRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayerCombinedInfo", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayerCombinedInfo", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerCombinedInfoResult> { Error = error, }; + return new PlayFabResult<GetPlayerCombinedInfoResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerCombinedInfoResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerCombinedInfoResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerCombinedInfoResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerCombinedInfoResult> { Result = result }; + return new PlayFabResult<GetPlayerCombinedInfoResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the unique PlayFab identifiers for the given set of Facebook identifiers. /// </summary> - public static async Task<PlayFabResult<GetPlayFabIDsFromFacebookIDsResult>> GetPlayFabIDsFromFacebookIDsAsync(GetPlayFabIDsFromFacebookIDsRequest request) + public static async Task<PlayFabResult<GetPlayFabIDsFromFacebookIDsResult>> GetPlayFabIDsFromFacebookIDsAsync(GetPlayFabIDsFromFacebookIDsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayFabIDsFromFacebookIDs", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayFabIDsFromFacebookIDs", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayFabIDsFromFacebookIDsResult> { Error = error, }; + return new PlayFabResult<GetPlayFabIDsFromFacebookIDsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayFabIDsFromFacebookIDsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayFabIDsFromFacebookIDsResult>>(resultRawJson); + var result = resultData.data; - GetPlayFabIDsFromFacebookIDsResult result = resultData.data; - - return new PlayFabResult<GetPlayFabIDsFromFacebookIDsResult> { Result = result }; + return new PlayFabResult<GetPlayFabIDsFromFacebookIDsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the unique PlayFab identifiers for the given set of Game Center identifiers (referenced in the Game Center Programming Guide as the Player Identifier). /// </summary> - public static async Task<PlayFabResult<GetPlayFabIDsFromGameCenterIDsResult>> GetPlayFabIDsFromGameCenterIDsAsync(GetPlayFabIDsFromGameCenterIDsRequest request) + public static async Task<PlayFabResult<GetPlayFabIDsFromGameCenterIDsResult>> GetPlayFabIDsFromGameCenterIDsAsync(GetPlayFabIDsFromGameCenterIDsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayFabIDsFromGameCenterIDs", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayFabIDsFromGameCenterIDs", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayFabIDsFromGameCenterIDsResult> { Error = error, }; + return new PlayFabResult<GetPlayFabIDsFromGameCenterIDsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayFabIDsFromGameCenterIDsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayFabIDsFromGameCenterIDsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayFabIDsFromGameCenterIDsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayFabIDsFromGameCenterIDsResult> { Result = result }; + return new PlayFabResult<GetPlayFabIDsFromGameCenterIDsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the unique PlayFab identifiers for the given set of generic service identifiers. A generic identifier is the service name plus the service-specific ID for the player, as specified by the title when the generic identifier was added to the player account. /// </summary> - public static async Task<PlayFabResult<GetPlayFabIDsFromGenericIDsResult>> GetPlayFabIDsFromGenericIDsAsync(GetPlayFabIDsFromGenericIDsRequest request) + public static async Task<PlayFabResult<GetPlayFabIDsFromGenericIDsResult>> GetPlayFabIDsFromGenericIDsAsync(GetPlayFabIDsFromGenericIDsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayFabIDsFromGenericIDs", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayFabIDsFromGenericIDs", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayFabIDsFromGenericIDsResult> { Error = error, }; + return new PlayFabResult<GetPlayFabIDsFromGenericIDsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayFabIDsFromGenericIDsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayFabIDsFromGenericIDsResult>>(resultRawJson); + var result = resultData.data; - GetPlayFabIDsFromGenericIDsResult result = resultData.data; - - return new PlayFabResult<GetPlayFabIDsFromGenericIDsResult> { Result = result }; + return new PlayFabResult<GetPlayFabIDsFromGenericIDsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the unique PlayFab identifiers for the given set of Google identifiers. The Google identifiers are the IDs for the user accounts, available as "id" in the Google+ People API calls. /// </summary> - public static async Task<PlayFabResult<GetPlayFabIDsFromGoogleIDsResult>> GetPlayFabIDsFromGoogleIDsAsync(GetPlayFabIDsFromGoogleIDsRequest request) + public static async Task<PlayFabResult<GetPlayFabIDsFromGoogleIDsResult>> GetPlayFabIDsFromGoogleIDsAsync(GetPlayFabIDsFromGoogleIDsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayFabIDsFromGoogleIDs", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayFabIDsFromGoogleIDs", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayFabIDsFromGoogleIDsResult> { Error = error, }; + return new PlayFabResult<GetPlayFabIDsFromGoogleIDsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayFabIDsFromGoogleIDsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayFabIDsFromGoogleIDsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayFabIDsFromGoogleIDsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayFabIDsFromGoogleIDsResult> { Result = result }; + return new PlayFabResult<GetPlayFabIDsFromGoogleIDsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the unique PlayFab identifiers for the given set of Kongregate identifiers. The Kongregate identifiers are the IDs for the user accounts, available as "user_id" from the Kongregate API methods(ex: http://developers.kongregate.com/docs/client/getUserId). /// </summary> - public static async Task<PlayFabResult<GetPlayFabIDsFromKongregateIDsResult>> GetPlayFabIDsFromKongregateIDsAsync(GetPlayFabIDsFromKongregateIDsRequest request) + public static async Task<PlayFabResult<GetPlayFabIDsFromKongregateIDsResult>> GetPlayFabIDsFromKongregateIDsAsync(GetPlayFabIDsFromKongregateIDsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayFabIDsFromKongregateIDs", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayFabIDsFromKongregateIDs", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayFabIDsFromKongregateIDsResult> { Error = error, }; + return new PlayFabResult<GetPlayFabIDsFromKongregateIDsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayFabIDsFromKongregateIDsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayFabIDsFromKongregateIDsResult>>(resultRawJson); + var result = resultData.data; - GetPlayFabIDsFromKongregateIDsResult result = resultData.data; - - return new PlayFabResult<GetPlayFabIDsFromKongregateIDsResult> { Result = result }; + return new PlayFabResult<GetPlayFabIDsFromKongregateIDsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the unique PlayFab identifiers for the given set of Steam identifiers. The Steam identifiers are the profile IDs for the user accounts, available as SteamId in the Steamworks Community API calls. /// </summary> - public static async Task<PlayFabResult<GetPlayFabIDsFromSteamIDsResult>> GetPlayFabIDsFromSteamIDsAsync(GetPlayFabIDsFromSteamIDsRequest request) + public static async Task<PlayFabResult<GetPlayFabIDsFromSteamIDsResult>> GetPlayFabIDsFromSteamIDsAsync(GetPlayFabIDsFromSteamIDsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayFabIDsFromSteamIDs", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayFabIDsFromSteamIDs", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayFabIDsFromSteamIDsResult> { Error = error, }; + return new PlayFabResult<GetPlayFabIDsFromSteamIDsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayFabIDsFromSteamIDsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayFabIDsFromSteamIDsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayFabIDsFromSteamIDsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayFabIDsFromSteamIDsResult> { Result = result }; + return new PlayFabResult<GetPlayFabIDsFromSteamIDsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the unique PlayFab identifiers for the given set of Twitch identifiers. The Twitch identifiers are the IDs for the user accounts, available as "_id" from the Twitch API methods (ex: https://github.com/justintv/Twitch-API/blob/master/v3_resources/users.md#get-usersuser). /// </summary> - public static async Task<PlayFabResult<GetPlayFabIDsFromTwitchIDsResult>> GetPlayFabIDsFromTwitchIDsAsync(GetPlayFabIDsFromTwitchIDsRequest request) + public static async Task<PlayFabResult<GetPlayFabIDsFromTwitchIDsResult>> GetPlayFabIDsFromTwitchIDsAsync(GetPlayFabIDsFromTwitchIDsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayFabIDsFromTwitchIDs", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayFabIDsFromTwitchIDs", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayFabIDsFromTwitchIDsResult> { Error = error, }; + return new PlayFabResult<GetPlayFabIDsFromTwitchIDsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayFabIDsFromTwitchIDsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayFabIDsFromTwitchIDsResult>>(resultRawJson); + var result = resultData.data; - GetPlayFabIDsFromTwitchIDsResult result = resultData.data; - - return new PlayFabResult<GetPlayFabIDsFromTwitchIDsResult> { Result = result }; + return new PlayFabResult<GetPlayFabIDsFromTwitchIDsResult> { Result = result, CustomData = customData }; } /// <summary> /// NOTE: This call will be deprecated soon. For fetching the data for a given user use GetPlayerCombinedInfo. For looking up users from the client api, we are in the process of adding a new api call. Once that call is ready, this one will be deprecated. Retrieves all requested data for a user in one unified request. By default, this API returns all data for the locally signed-in user. The input parameters may be used to limit the data retrieved to any subset of the available data, as well as retrieve the available data for a different user. Note that certain data, including inventory, virtual currency balances, and personally identifying information, may only be retrieved for the locally signed-in user. In the example below, a request is made for the account details, virtual currency balances, and specified user data for the locally signed-in user. /// </summary> [Obsolete("Use 'GetPlayerCombinedInfo' instead", true)] - public static async Task<PlayFabResult<GetUserCombinedInfoResult>> GetUserCombinedInfoAsync(GetUserCombinedInfoRequest request) + public static async Task<PlayFabResult<GetUserCombinedInfoResult>> GetUserCombinedInfoAsync(GetUserCombinedInfoRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetUserCombinedInfo", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetUserCombinedInfo", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserCombinedInfoResult> { Error = error, }; + return new PlayFabResult<GetUserCombinedInfoResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserCombinedInfoResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserCombinedInfoResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserCombinedInfoResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserCombinedInfoResult> { Result = result }; + return new PlayFabResult<GetUserCombinedInfoResult> { Result = result, CustomData = customData }; } /// <summary> /// Links the Android device identifier to the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<LinkAndroidDeviceIDResult>> LinkAndroidDeviceIDAsync(LinkAndroidDeviceIDRequest request) + public static async Task<PlayFabResult<LinkAndroidDeviceIDResult>> LinkAndroidDeviceIDAsync(LinkAndroidDeviceIDRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LinkAndroidDeviceID", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/LinkAndroidDeviceID", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LinkAndroidDeviceIDResult> { Error = error, }; + return new PlayFabResult<LinkAndroidDeviceIDResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LinkAndroidDeviceIDResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LinkAndroidDeviceIDResult>>(resultRawJson); + var result = resultData.data; - LinkAndroidDeviceIDResult result = resultData.data; - - return new PlayFabResult<LinkAndroidDeviceIDResult> { Result = result }; + return new PlayFabResult<LinkAndroidDeviceIDResult> { Result = result, CustomData = customData }; } /// <summary> /// Links the custom identifier, generated by the title, to the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<LinkCustomIDResult>> LinkCustomIDAsync(LinkCustomIDRequest request) + public static async Task<PlayFabResult<LinkCustomIDResult>> LinkCustomIDAsync(LinkCustomIDRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LinkCustomID", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/LinkCustomID", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LinkCustomIDResult> { Error = error, }; + return new PlayFabResult<LinkCustomIDResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LinkCustomIDResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LinkCustomIDResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LinkCustomIDResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<LinkCustomIDResult> { Result = result }; + return new PlayFabResult<LinkCustomIDResult> { Result = result, CustomData = customData }; } /// <summary> /// Links the Facebook account associated with the provided Facebook access token to the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<LinkFacebookAccountResult>> LinkFacebookAccountAsync(LinkFacebookAccountRequest request) + public static async Task<PlayFabResult<LinkFacebookAccountResult>> LinkFacebookAccountAsync(LinkFacebookAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LinkFacebookAccount", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/LinkFacebookAccount", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LinkFacebookAccountResult> { Error = error, }; + return new PlayFabResult<LinkFacebookAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LinkFacebookAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LinkFacebookAccountResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LinkFacebookAccountResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<LinkFacebookAccountResult> { Result = result }; + return new PlayFabResult<LinkFacebookAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Links the Game Center account associated with the provided Game Center ID to the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<LinkGameCenterAccountResult>> LinkGameCenterAccountAsync(LinkGameCenterAccountRequest request) + public static async Task<PlayFabResult<LinkGameCenterAccountResult>> LinkGameCenterAccountAsync(LinkGameCenterAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LinkGameCenterAccount", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/LinkGameCenterAccount", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LinkGameCenterAccountResult> { Error = error, }; + return new PlayFabResult<LinkGameCenterAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LinkGameCenterAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LinkGameCenterAccountResult>>(resultRawJson); + var result = resultData.data; - LinkGameCenterAccountResult result = resultData.data; - - return new PlayFabResult<LinkGameCenterAccountResult> { Result = result }; + return new PlayFabResult<LinkGameCenterAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Links the currently signed-in user account to the Google account specified by the Google account access token (https://developers.google.com/android/reference/com/google/android/gms/auth/GoogleAuthUtil#public-methods). /// </summary> - public static async Task<PlayFabResult<LinkGoogleAccountResult>> LinkGoogleAccountAsync(LinkGoogleAccountRequest request) + public static async Task<PlayFabResult<LinkGoogleAccountResult>> LinkGoogleAccountAsync(LinkGoogleAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LinkGoogleAccount", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/LinkGoogleAccount", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LinkGoogleAccountResult> { Error = error, }; + return new PlayFabResult<LinkGoogleAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LinkGoogleAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LinkGoogleAccountResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LinkGoogleAccountResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<LinkGoogleAccountResult> { Result = result }; + return new PlayFabResult<LinkGoogleAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Links the vendor-specific iOS device identifier to the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<LinkIOSDeviceIDResult>> LinkIOSDeviceIDAsync(LinkIOSDeviceIDRequest request) + public static async Task<PlayFabResult<LinkIOSDeviceIDResult>> LinkIOSDeviceIDAsync(LinkIOSDeviceIDRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LinkIOSDeviceID", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/LinkIOSDeviceID", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LinkIOSDeviceIDResult> { Error = error, }; + return new PlayFabResult<LinkIOSDeviceIDResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LinkIOSDeviceIDResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LinkIOSDeviceIDResult>>(resultRawJson); + var result = resultData.data; - LinkIOSDeviceIDResult result = resultData.data; - - return new PlayFabResult<LinkIOSDeviceIDResult> { Result = result }; + return new PlayFabResult<LinkIOSDeviceIDResult> { Result = result, CustomData = customData }; } /// <summary> /// Links the Kongregate identifier to the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<LinkKongregateAccountResult>> LinkKongregateAsync(LinkKongregateAccountRequest request) + public static async Task<PlayFabResult<LinkKongregateAccountResult>> LinkKongregateAsync(LinkKongregateAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LinkKongregate", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/LinkKongregate", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LinkKongregateAccountResult> { Error = error, }; + return new PlayFabResult<LinkKongregateAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LinkKongregateAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LinkKongregateAccountResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LinkKongregateAccountResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<LinkKongregateAccountResult> { Result = result }; + return new PlayFabResult<LinkKongregateAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Links the Steam account associated with the provided Steam authentication ticket to the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<LinkSteamAccountResult>> LinkSteamAccountAsync(LinkSteamAccountRequest request) + public static async Task<PlayFabResult<LinkSteamAccountResult>> LinkSteamAccountAsync(LinkSteamAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LinkSteamAccount", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/LinkSteamAccount", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LinkSteamAccountResult> { Error = error, }; + return new PlayFabResult<LinkSteamAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LinkSteamAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LinkSteamAccountResult>>(resultRawJson); + var result = resultData.data; - LinkSteamAccountResult result = resultData.data; - - return new PlayFabResult<LinkSteamAccountResult> { Result = result }; + return new PlayFabResult<LinkSteamAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Links the Twitch account associated with the token to the user's PlayFab account. /// </summary> - public static async Task<PlayFabResult<LinkTwitchAccountResult>> LinkTwitchAsync(LinkTwitchAccountRequest request) + public static async Task<PlayFabResult<LinkTwitchAccountResult>> LinkTwitchAsync(LinkTwitchAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/LinkTwitch", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/LinkTwitch", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LinkTwitchAccountResult> { Error = error, }; + return new PlayFabResult<LinkTwitchAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LinkTwitchAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); - LinkTwitchAccountResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LinkTwitchAccountResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<LinkTwitchAccountResult> { Result = result }; + return new PlayFabResult<LinkTwitchAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Removes the specified generic service identifier from the player's PlayFab account. /// </summary> - public static async Task<PlayFabResult<RemoveGenericIDResult>> RemoveGenericIDAsync(RemoveGenericIDRequest request) + public static async Task<PlayFabResult<RemoveGenericIDResult>> RemoveGenericIDAsync(RemoveGenericIDRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/RemoveGenericID", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/RemoveGenericID", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RemoveGenericIDResult> { Error = error, }; + return new PlayFabResult<RemoveGenericIDResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RemoveGenericIDResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RemoveGenericIDResult>>(resultRawJson); + var result = resultData.data; - RemoveGenericIDResult result = resultData.data; - - return new PlayFabResult<RemoveGenericIDResult> { Result = result }; + return new PlayFabResult<RemoveGenericIDResult> { Result = result, CustomData = customData }; } /// <summary> /// Submit a report for another player (due to bad bahavior, etc.), so that customer service representatives for the title can take action concerning potentially toxic players. /// </summary> - public static async Task<PlayFabResult<ReportPlayerClientResult>> ReportPlayerAsync(ReportPlayerClientRequest request) + public static async Task<PlayFabResult<ReportPlayerClientResult>> ReportPlayerAsync(ReportPlayerClientRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/ReportPlayer", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/ReportPlayer", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ReportPlayerClientResult> { Error = error, }; + return new PlayFabResult<ReportPlayerClientResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ReportPlayerClientResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ReportPlayerClientResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ReportPlayerClientResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ReportPlayerClientResult> { Result = result }; + return new PlayFabResult<ReportPlayerClientResult> { Result = result, CustomData = customData }; } /// <summary> /// Forces an email to be sent to the registered email address for the user's account, with a link allowing the user to change the password /// </summary> - public static async Task<PlayFabResult<SendAccountRecoveryEmailResult>> SendAccountRecoveryEmailAsync(SendAccountRecoveryEmailRequest request) + public static async Task<PlayFabResult<SendAccountRecoveryEmailResult>> SendAccountRecoveryEmailAsync(SendAccountRecoveryEmailRequest request, object customData = null) { - object httpResult = await PlayFabHTTP.DoPost("/Client/SendAccountRecoveryEmail", request, null, null); + var httpResult = await PlayFabHttp.DoPost("/Client/SendAccountRecoveryEmail", request, null, null); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SendAccountRecoveryEmailResult> { Error = error, }; + return new PlayFabResult<SendAccountRecoveryEmailResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SendAccountRecoveryEmailResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SendAccountRecoveryEmailResult>>(resultRawJson); + var result = resultData.data; - SendAccountRecoveryEmailResult result = resultData.data; - - return new PlayFabResult<SendAccountRecoveryEmailResult> { Result = result }; + return new PlayFabResult<SendAccountRecoveryEmailResult> { Result = result, CustomData = customData }; } /// <summary> /// Unlinks the related Android device identifier from the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<UnlinkAndroidDeviceIDResult>> UnlinkAndroidDeviceIDAsync(UnlinkAndroidDeviceIDRequest request) + public static async Task<PlayFabResult<UnlinkAndroidDeviceIDResult>> UnlinkAndroidDeviceIDAsync(UnlinkAndroidDeviceIDRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlinkAndroidDeviceID", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlinkAndroidDeviceID", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlinkAndroidDeviceIDResult> { Error = error, }; + return new PlayFabResult<UnlinkAndroidDeviceIDResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlinkAndroidDeviceIDResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UnlinkAndroidDeviceIDResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlinkAndroidDeviceIDResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UnlinkAndroidDeviceIDResult> { Result = result }; + return new PlayFabResult<UnlinkAndroidDeviceIDResult> { Result = result, CustomData = customData }; } /// <summary> /// Unlinks the related custom identifier from the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<UnlinkCustomIDResult>> UnlinkCustomIDAsync(UnlinkCustomIDRequest request) + public static async Task<PlayFabResult<UnlinkCustomIDResult>> UnlinkCustomIDAsync(UnlinkCustomIDRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlinkCustomID", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlinkCustomID", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlinkCustomIDResult> { Error = error, }; + return new PlayFabResult<UnlinkCustomIDResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlinkCustomIDResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlinkCustomIDResult>>(resultRawJson); + var result = resultData.data; - UnlinkCustomIDResult result = resultData.data; - - return new PlayFabResult<UnlinkCustomIDResult> { Result = result }; + return new PlayFabResult<UnlinkCustomIDResult> { Result = result, CustomData = customData }; } /// <summary> /// Unlinks the related Facebook account from the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<UnlinkFacebookAccountResult>> UnlinkFacebookAccountAsync(UnlinkFacebookAccountRequest request) + public static async Task<PlayFabResult<UnlinkFacebookAccountResult>> UnlinkFacebookAccountAsync(UnlinkFacebookAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlinkFacebookAccount", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlinkFacebookAccount", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlinkFacebookAccountResult> { Error = error, }; + return new PlayFabResult<UnlinkFacebookAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlinkFacebookAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UnlinkFacebookAccountResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlinkFacebookAccountResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UnlinkFacebookAccountResult> { Result = result }; + return new PlayFabResult<UnlinkFacebookAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Unlinks the related Game Center account from the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<UnlinkGameCenterAccountResult>> UnlinkGameCenterAccountAsync(UnlinkGameCenterAccountRequest request) + public static async Task<PlayFabResult<UnlinkGameCenterAccountResult>> UnlinkGameCenterAccountAsync(UnlinkGameCenterAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlinkGameCenterAccount", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlinkGameCenterAccount", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlinkGameCenterAccountResult> { Error = error, }; + return new PlayFabResult<UnlinkGameCenterAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlinkGameCenterAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlinkGameCenterAccountResult>>(resultRawJson); + var result = resultData.data; - UnlinkGameCenterAccountResult result = resultData.data; - - return new PlayFabResult<UnlinkGameCenterAccountResult> { Result = result }; + return new PlayFabResult<UnlinkGameCenterAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Unlinks the related Google account from the user's PlayFab account (https://developers.google.com/android/reference/com/google/android/gms/auth/GoogleAuthUtil#public-methods). /// </summary> - public static async Task<PlayFabResult<UnlinkGoogleAccountResult>> UnlinkGoogleAccountAsync(UnlinkGoogleAccountRequest request) + public static async Task<PlayFabResult<UnlinkGoogleAccountResult>> UnlinkGoogleAccountAsync(UnlinkGoogleAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlinkGoogleAccount", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlinkGoogleAccount", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlinkGoogleAccountResult> { Error = error, }; + return new PlayFabResult<UnlinkGoogleAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlinkGoogleAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UnlinkGoogleAccountResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlinkGoogleAccountResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UnlinkGoogleAccountResult> { Result = result }; + return new PlayFabResult<UnlinkGoogleAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Unlinks the related iOS device identifier from the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<UnlinkIOSDeviceIDResult>> UnlinkIOSDeviceIDAsync(UnlinkIOSDeviceIDRequest request) + public static async Task<PlayFabResult<UnlinkIOSDeviceIDResult>> UnlinkIOSDeviceIDAsync(UnlinkIOSDeviceIDRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlinkIOSDeviceID", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlinkIOSDeviceID", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlinkIOSDeviceIDResult> { Error = error, }; + return new PlayFabResult<UnlinkIOSDeviceIDResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlinkIOSDeviceIDResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlinkIOSDeviceIDResult>>(resultRawJson); + var result = resultData.data; - UnlinkIOSDeviceIDResult result = resultData.data; - - return new PlayFabResult<UnlinkIOSDeviceIDResult> { Result = result }; + return new PlayFabResult<UnlinkIOSDeviceIDResult> { Result = result, CustomData = customData }; } /// <summary> /// Unlinks the related Kongregate identifier from the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<UnlinkKongregateAccountResult>> UnlinkKongregateAsync(UnlinkKongregateAccountRequest request) + public static async Task<PlayFabResult<UnlinkKongregateAccountResult>> UnlinkKongregateAsync(UnlinkKongregateAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlinkKongregate", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlinkKongregate", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlinkKongregateAccountResult> { Error = error, }; + return new PlayFabResult<UnlinkKongregateAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlinkKongregateAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UnlinkKongregateAccountResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlinkKongregateAccountResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UnlinkKongregateAccountResult> { Result = result }; + return new PlayFabResult<UnlinkKongregateAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Unlinks the related Steam account from the user's PlayFab account /// </summary> - public static async Task<PlayFabResult<UnlinkSteamAccountResult>> UnlinkSteamAccountAsync(UnlinkSteamAccountRequest request) + public static async Task<PlayFabResult<UnlinkSteamAccountResult>> UnlinkSteamAccountAsync(UnlinkSteamAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlinkSteamAccount", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlinkSteamAccount", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlinkSteamAccountResult> { Error = error, }; + return new PlayFabResult<UnlinkSteamAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlinkSteamAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlinkSteamAccountResult>>(resultRawJson); + var result = resultData.data; - UnlinkSteamAccountResult result = resultData.data; - - return new PlayFabResult<UnlinkSteamAccountResult> { Result = result }; + return new PlayFabResult<UnlinkSteamAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Unlinks the related Twitch account from the user's PlayFab account. /// </summary> - public static async Task<PlayFabResult<UnlinkTwitchAccountResult>> UnlinkTwitchAsync(UnlinkTwitchAccountRequest request) + public static async Task<PlayFabResult<UnlinkTwitchAccountResult>> UnlinkTwitchAsync(UnlinkTwitchAccountRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlinkTwitch", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlinkTwitch", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlinkTwitchAccountResult> { Error = error, }; + return new PlayFabResult<UnlinkTwitchAccountResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlinkTwitchAccountResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UnlinkTwitchAccountResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlinkTwitchAccountResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UnlinkTwitchAccountResult> { Result = result }; + return new PlayFabResult<UnlinkTwitchAccountResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title specific display name for the user /// </summary> - public static async Task<PlayFabResult<UpdateUserTitleDisplayNameResult>> UpdateUserTitleDisplayNameAsync(UpdateUserTitleDisplayNameRequest request) + public static async Task<PlayFabResult<UpdateUserTitleDisplayNameResult>> UpdateUserTitleDisplayNameAsync(UpdateUserTitleDisplayNameRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UpdateUserTitleDisplayName", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UpdateUserTitleDisplayName", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserTitleDisplayNameResult> { Error = error, }; + return new PlayFabResult<UpdateUserTitleDisplayNameResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserTitleDisplayNameResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserTitleDisplayNameResult>>(resultRawJson); + var result = resultData.data; - UpdateUserTitleDisplayNameResult result = resultData.data; - - return new PlayFabResult<UpdateUserTitleDisplayNameResult> { Result = result }; + return new PlayFabResult<UpdateUserTitleDisplayNameResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked friends of the current player for the given statistic, starting from the indicated point in the leaderboard /// </summary> - public static async Task<PlayFabResult<GetLeaderboardResult>> GetFriendLeaderboardAsync(GetFriendLeaderboardRequest request) + public static async Task<PlayFabResult<GetLeaderboardResult>> GetFriendLeaderboardAsync(GetFriendLeaderboardRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetFriendLeaderboard", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetFriendLeaderboard", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetLeaderboardResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetLeaderboardResult> { Result = result }; + return new PlayFabResult<GetLeaderboardResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked friends of the current player for the given statistic, centered on the requested PlayFab user. If PlayFabId is empty or null will return currently logged in user. /// </summary> - public static async Task<PlayFabResult<GetFriendLeaderboardAroundPlayerResult>> GetFriendLeaderboardAroundPlayerAsync(GetFriendLeaderboardAroundPlayerRequest request) + public static async Task<PlayFabResult<GetFriendLeaderboardAroundPlayerResult>> GetFriendLeaderboardAroundPlayerAsync(GetFriendLeaderboardAroundPlayerRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetFriendLeaderboardAroundPlayer", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetFriendLeaderboardAroundPlayer", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetFriendLeaderboardAroundPlayerResult> { Error = error, }; + return new PlayFabResult<GetFriendLeaderboardAroundPlayerResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetFriendLeaderboardAroundPlayerResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetFriendLeaderboardAroundPlayerResult>>(resultRawJson); + var result = resultData.data; - GetFriendLeaderboardAroundPlayerResult result = resultData.data; - - return new PlayFabResult<GetFriendLeaderboardAroundPlayerResult> { Result = result }; + return new PlayFabResult<GetFriendLeaderboardAroundPlayerResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked users for the given statistic, starting from the indicated point in the leaderboard /// </summary> - public static async Task<PlayFabResult<GetLeaderboardResult>> GetLeaderboardAsync(GetLeaderboardRequest request) + public static async Task<PlayFabResult<GetLeaderboardResult>> GetLeaderboardAsync(GetLeaderboardRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetLeaderboard", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetLeaderboard", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetLeaderboardResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetLeaderboardResult> { Result = result }; + return new PlayFabResult<GetLeaderboardResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked users for the given statistic, centered on the requested player. If PlayFabId is empty or null will return currently logged in user. /// </summary> - public static async Task<PlayFabResult<GetLeaderboardAroundPlayerResult>> GetLeaderboardAroundPlayerAsync(GetLeaderboardAroundPlayerRequest request) + public static async Task<PlayFabResult<GetLeaderboardAroundPlayerResult>> GetLeaderboardAroundPlayerAsync(GetLeaderboardAroundPlayerRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetLeaderboardAroundPlayer", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetLeaderboardAroundPlayer", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardAroundPlayerResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardAroundPlayerResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardAroundPlayerResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardAroundPlayerResult>>(resultRawJson); + var result = resultData.data; - GetLeaderboardAroundPlayerResult result = resultData.data; - - return new PlayFabResult<GetLeaderboardAroundPlayerResult> { Result = result }; + return new PlayFabResult<GetLeaderboardAroundPlayerResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the indicated statistics (current version and values for all statistics, if none are specified), for the local player. /// </summary> - public static async Task<PlayFabResult<GetPlayerStatisticsResult>> GetPlayerStatisticsAsync(GetPlayerStatisticsRequest request) + public static async Task<PlayFabResult<GetPlayerStatisticsResult>> GetPlayerStatisticsAsync(GetPlayerStatisticsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayerStatistics", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayerStatistics", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerStatisticsResult> { Error = error, }; + return new PlayFabResult<GetPlayerStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerStatisticsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerStatisticsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerStatisticsResult> { Result = result }; + return new PlayFabResult<GetPlayerStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the information on the available versions of the specified statistic. /// </summary> - public static async Task<PlayFabResult<GetPlayerStatisticVersionsResult>> GetPlayerStatisticVersionsAsync(GetPlayerStatisticVersionsRequest request) + public static async Task<PlayFabResult<GetPlayerStatisticVersionsResult>> GetPlayerStatisticVersionsAsync(GetPlayerStatisticVersionsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayerStatisticVersions", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayerStatisticVersions", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerStatisticVersionsResult> { Error = error, }; + return new PlayFabResult<GetPlayerStatisticVersionsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerStatisticVersionsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerStatisticVersionsResult>>(resultRawJson); + var result = resultData.data; - GetPlayerStatisticVersionsResult result = resultData.data; - - return new PlayFabResult<GetPlayerStatisticVersionsResult> { Result = result }; + return new PlayFabResult<GetPlayerStatisticVersionsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserDataAsync(GetUserDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetUserData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetUserData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the publisher-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherDataAsync(GetUserDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetUserPublisherData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetUserPublisherData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - GetUserDataResult result = resultData.data; - - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the publisher-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherReadOnlyDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherReadOnlyDataAsync(GetUserDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetUserPublisherReadOnlyData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetUserPublisherReadOnlyData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserReadOnlyDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserReadOnlyDataAsync(GetUserDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetUserReadOnlyData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetUserReadOnlyData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - GetUserDataResult result = resultData.data; - - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the values of the specified title-specific statistics for the user. By default, clients are not permitted to update statistics. Developers may override this setting in the Game Manager > Settings > API Features. /// </summary> - public static async Task<PlayFabResult<UpdatePlayerStatisticsResult>> UpdatePlayerStatisticsAsync(UpdatePlayerStatisticsRequest request) + public static async Task<PlayFabResult<UpdatePlayerStatisticsResult>> UpdatePlayerStatisticsAsync(UpdatePlayerStatisticsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UpdatePlayerStatistics", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UpdatePlayerStatistics", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdatePlayerStatisticsResult> { Error = error, }; + return new PlayFabResult<UpdatePlayerStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdatePlayerStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdatePlayerStatisticsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdatePlayerStatisticsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdatePlayerStatisticsResult> { Result = result }; + return new PlayFabResult<UpdatePlayerStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Creates and updates the title-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserDataAsync(UpdateUserDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UpdateUserData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UpdateUserData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Creates and updates the publisher-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherDataAsync(UpdateUserDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UpdateUserPublisherData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UpdateUserPublisherData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - UpdateUserDataResult result = resultData.data; - - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the specified version of the title's catalog of virtual goods, including all defined properties /// </summary> - public static async Task<PlayFabResult<GetCatalogItemsResult>> GetCatalogItemsAsync(GetCatalogItemsRequest request) + public static async Task<PlayFabResult<GetCatalogItemsResult>> GetCatalogItemsAsync(GetCatalogItemsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetCatalogItems", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetCatalogItems", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCatalogItemsResult> { Error = error, }; + return new PlayFabResult<GetCatalogItemsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCatalogItemsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetCatalogItemsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCatalogItemsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetCatalogItemsResult> { Result = result }; + return new PlayFabResult<GetCatalogItemsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the key-value store of custom publisher settings /// </summary> - public static async Task<PlayFabResult<GetPublisherDataResult>> GetPublisherDataAsync(GetPublisherDataRequest request) + public static async Task<PlayFabResult<GetPublisherDataResult>> GetPublisherDataAsync(GetPublisherDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPublisherData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPublisherData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPublisherDataResult> { Error = error, }; + return new PlayFabResult<GetPublisherDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPublisherDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPublisherDataResult>>(resultRawJson); + var result = resultData.data; - GetPublisherDataResult result = resultData.data; - - return new PlayFabResult<GetPublisherDataResult> { Result = result }; + return new PlayFabResult<GetPublisherDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the set of items defined for the specified store, including all prices defined /// </summary> - public static async Task<PlayFabResult<GetStoreItemsResult>> GetStoreItemsAsync(GetStoreItemsRequest request) + public static async Task<PlayFabResult<GetStoreItemsResult>> GetStoreItemsAsync(GetStoreItemsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetStoreItems", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetStoreItems", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetStoreItemsResult> { Error = error, }; + return new PlayFabResult<GetStoreItemsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetStoreItemsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetStoreItemsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetStoreItemsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetStoreItemsResult> { Result = result }; + return new PlayFabResult<GetStoreItemsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the current server time /// </summary> - public static async Task<PlayFabResult<GetTimeResult>> GetTimeAsync(GetTimeRequest request) + public static async Task<PlayFabResult<GetTimeResult>> GetTimeAsync(GetTimeRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetTime", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetTime", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTimeResult> { Error = error, }; + return new PlayFabResult<GetTimeResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTimeResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTimeResult>>(resultRawJson); + var result = resultData.data; - GetTimeResult result = resultData.data; - - return new PlayFabResult<GetTimeResult> { Result = result }; + return new PlayFabResult<GetTimeResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the key-value store of custom title settings /// </summary> - public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleDataAsync(GetTitleDataRequest request) + public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleDataAsync(GetTitleDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetTitleData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetTitleData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTitleDataResult> { Error = error, }; + return new PlayFabResult<GetTitleDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTitleDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetTitleDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTitleDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetTitleDataResult> { Result = result }; + return new PlayFabResult<GetTitleDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title news feed, as configured in the developer portal /// </summary> - public static async Task<PlayFabResult<GetTitleNewsResult>> GetTitleNewsAsync(GetTitleNewsRequest request) + public static async Task<PlayFabResult<GetTitleNewsResult>> GetTitleNewsAsync(GetTitleNewsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetTitleNews", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetTitleNews", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTitleNewsResult> { Error = error, }; + return new PlayFabResult<GetTitleNewsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTitleNewsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTitleNewsResult>>(resultRawJson); + var result = resultData.data; - GetTitleNewsResult result = resultData.data; - - return new PlayFabResult<GetTitleNewsResult> { Result = result }; + return new PlayFabResult<GetTitleNewsResult> { Result = result, CustomData = customData }; } /// <summary> /// Increments the user's balance of the specified virtual currency by the stated amount /// </summary> - public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> AddUserVirtualCurrencyAsync(AddUserVirtualCurrencyRequest request) + public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> AddUserVirtualCurrencyAsync(AddUserVirtualCurrencyRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/AddUserVirtualCurrency", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/AddUserVirtualCurrency", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ModifyUserVirtualCurrencyResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result, CustomData = customData }; } /// <summary> /// Confirms with the payment provider that the purchase was approved (if applicable) and adjusts inventory and virtual currency balances as appropriate /// </summary> - public static async Task<PlayFabResult<ConfirmPurchaseResult>> ConfirmPurchaseAsync(ConfirmPurchaseRequest request) + public static async Task<PlayFabResult<ConfirmPurchaseResult>> ConfirmPurchaseAsync(ConfirmPurchaseRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/ConfirmPurchase", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/ConfirmPurchase", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ConfirmPurchaseResult> { Error = error, }; + return new PlayFabResult<ConfirmPurchaseResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ConfirmPurchaseResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ConfirmPurchaseResult>>(resultRawJson); + var result = resultData.data; - ConfirmPurchaseResult result = resultData.data; - - return new PlayFabResult<ConfirmPurchaseResult> { Result = result }; + return new PlayFabResult<ConfirmPurchaseResult> { Result = result, CustomData = customData }; } /// <summary> /// Consume uses of a consumable item. When all uses are consumed, it will be removed from the player's inventory. /// </summary> - public static async Task<PlayFabResult<ConsumeItemResult>> ConsumeItemAsync(ConsumeItemRequest request) + public static async Task<PlayFabResult<ConsumeItemResult>> ConsumeItemAsync(ConsumeItemRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/ConsumeItem", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/ConsumeItem", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ConsumeItemResult> { Error = error, }; + return new PlayFabResult<ConsumeItemResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ConsumeItemResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ConsumeItemResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ConsumeItemResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ConsumeItemResult> { Result = result }; + return new PlayFabResult<ConsumeItemResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the specified character's current inventory of virtual goods /// </summary> - public static async Task<PlayFabResult<GetCharacterInventoryResult>> GetCharacterInventoryAsync(GetCharacterInventoryRequest request) + public static async Task<PlayFabResult<GetCharacterInventoryResult>> GetCharacterInventoryAsync(GetCharacterInventoryRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetCharacterInventory", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetCharacterInventory", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterInventoryResult> { Error = error, }; + return new PlayFabResult<GetCharacterInventoryResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterInventoryResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterInventoryResult>>(resultRawJson); + var result = resultData.data; - GetCharacterInventoryResult result = resultData.data; - - return new PlayFabResult<GetCharacterInventoryResult> { Result = result }; + return new PlayFabResult<GetCharacterInventoryResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a completed purchase along with its current PlayFab status. /// </summary> - public static async Task<PlayFabResult<GetPurchaseResult>> GetPurchaseAsync(GetPurchaseRequest request) + public static async Task<PlayFabResult<GetPurchaseResult>> GetPurchaseAsync(GetPurchaseRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPurchase", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPurchase", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPurchaseResult> { Error = error, }; + return new PlayFabResult<GetPurchaseResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPurchaseResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPurchaseResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPurchaseResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPurchaseResult> { Result = result }; + return new PlayFabResult<GetPurchaseResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the user's current inventory of virtual goods /// </summary> - public static async Task<PlayFabResult<GetUserInventoryResult>> GetUserInventoryAsync(GetUserInventoryRequest request) + public static async Task<PlayFabResult<GetUserInventoryResult>> GetUserInventoryAsync(GetUserInventoryRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetUserInventory", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetUserInventory", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserInventoryResult> { Error = error, }; + return new PlayFabResult<GetUserInventoryResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserInventoryResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserInventoryResult>>(resultRawJson); + var result = resultData.data; - GetUserInventoryResult result = resultData.data; - - return new PlayFabResult<GetUserInventoryResult> { Result = result }; + return new PlayFabResult<GetUserInventoryResult> { Result = result, CustomData = customData }; } /// <summary> /// Selects a payment option for purchase order created via StartPurchase /// </summary> - public static async Task<PlayFabResult<PayForPurchaseResult>> PayForPurchaseAsync(PayForPurchaseRequest request) + public static async Task<PlayFabResult<PayForPurchaseResult>> PayForPurchaseAsync(PayForPurchaseRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/PayForPurchase", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/PayForPurchase", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<PayForPurchaseResult> { Error = error, }; + return new PlayFabResult<PayForPurchaseResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<PayForPurchaseResult>>(new JsonTextReader(new StringReader(resultRawJson))); - PayForPurchaseResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<PayForPurchaseResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<PayForPurchaseResult> { Result = result }; + return new PlayFabResult<PayForPurchaseResult> { Result = result, CustomData = customData }; } /// <summary> /// Buys a single item with virtual currency. You must specify both the virtual currency to use to purchase, as well as what the client believes the price to be. This lets the server fail the purchase if the price has changed. /// </summary> - public static async Task<PlayFabResult<PurchaseItemResult>> PurchaseItemAsync(PurchaseItemRequest request) + public static async Task<PlayFabResult<PurchaseItemResult>> PurchaseItemAsync(PurchaseItemRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/PurchaseItem", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/PurchaseItem", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<PurchaseItemResult> { Error = error, }; + return new PlayFabResult<PurchaseItemResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<PurchaseItemResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<PurchaseItemResult>>(resultRawJson); + var result = resultData.data; - PurchaseItemResult result = resultData.data; - - return new PlayFabResult<PurchaseItemResult> { Result = result }; + return new PlayFabResult<PurchaseItemResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the virtual goods associated with the coupon to the user's inventory. Coupons can be generated via the Economy->Catalogs tab in the PlayFab Game Manager. /// </summary> - public static async Task<PlayFabResult<RedeemCouponResult>> RedeemCouponAsync(RedeemCouponRequest request) + public static async Task<PlayFabResult<RedeemCouponResult>> RedeemCouponAsync(RedeemCouponRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/RedeemCoupon", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/RedeemCoupon", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RedeemCouponResult> { Error = error, }; + return new PlayFabResult<RedeemCouponResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RedeemCouponResult>>(new JsonTextReader(new StringReader(resultRawJson))); - RedeemCouponResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RedeemCouponResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RedeemCouponResult> { Result = result }; + return new PlayFabResult<RedeemCouponResult> { Result = result, CustomData = customData }; } /// <summary> /// Creates an order for a list of items from the title catalog /// </summary> - public static async Task<PlayFabResult<StartPurchaseResult>> StartPurchaseAsync(StartPurchaseRequest request) + public static async Task<PlayFabResult<StartPurchaseResult>> StartPurchaseAsync(StartPurchaseRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/StartPurchase", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/StartPurchase", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<StartPurchaseResult> { Error = error, }; + return new PlayFabResult<StartPurchaseResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<StartPurchaseResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<StartPurchaseResult>>(resultRawJson); + var result = resultData.data; - StartPurchaseResult result = resultData.data; - - return new PlayFabResult<StartPurchaseResult> { Result = result }; + return new PlayFabResult<StartPurchaseResult> { Result = result, CustomData = customData }; } /// <summary> /// Decrements the user's balance of the specified virtual currency by the stated amount /// </summary> - public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> SubtractUserVirtualCurrencyAsync(SubtractUserVirtualCurrencyRequest request) + public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> SubtractUserVirtualCurrencyAsync(SubtractUserVirtualCurrencyRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/SubtractUserVirtualCurrency", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/SubtractUserVirtualCurrency", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ModifyUserVirtualCurrencyResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result, CustomData = customData }; } /// <summary> /// Opens the specified container, with the specified key (when required), and returns the contents of the opened container. If the container (and key when relevant) are consumable (RemainingUses > 0), their RemainingUses will be decremented, consistent with the operation of ConsumeItem. /// </summary> - public static async Task<PlayFabResult<UnlockContainerItemResult>> UnlockContainerInstanceAsync(UnlockContainerInstanceRequest request) + public static async Task<PlayFabResult<UnlockContainerItemResult>> UnlockContainerInstanceAsync(UnlockContainerInstanceRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlockContainerInstance", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlockContainerInstance", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlockContainerItemResult> { Error = error, }; + return new PlayFabResult<UnlockContainerItemResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlockContainerItemResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlockContainerItemResult>>(resultRawJson); + var result = resultData.data; - UnlockContainerItemResult result = resultData.data; - - return new PlayFabResult<UnlockContainerItemResult> { Result = result }; + return new PlayFabResult<UnlockContainerItemResult> { Result = result, CustomData = customData }; } /// <summary> /// Searches target inventory for an ItemInstance matching the given CatalogItemId, if necessary unlocks it using an appropriate key, and returns the contents of the opened container. If the container (and key when relevant) are consumable (RemainingUses > 0), their RemainingUses will be decremented, consistent with the operation of ConsumeItem. /// </summary> - public static async Task<PlayFabResult<UnlockContainerItemResult>> UnlockContainerItemAsync(UnlockContainerItemRequest request) + public static async Task<PlayFabResult<UnlockContainerItemResult>> UnlockContainerItemAsync(UnlockContainerItemRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UnlockContainerItem", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UnlockContainerItem", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlockContainerItemResult> { Error = error, }; + return new PlayFabResult<UnlockContainerItemResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlockContainerItemResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UnlockContainerItemResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlockContainerItemResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UnlockContainerItemResult> { Result = result }; + return new PlayFabResult<UnlockContainerItemResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the PlayFab user, based upon a match against a supplied unique identifier, to the friend list of the local user. At least one of FriendPlayFabId,FriendUsername,FriendEmail, or FriendTitleDisplayName should be initialized. /// </summary> - public static async Task<PlayFabResult<AddFriendResult>> AddFriendAsync(AddFriendRequest request) + public static async Task<PlayFabResult<AddFriendResult>> AddFriendAsync(AddFriendRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/AddFriend", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/AddFriend", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AddFriendResult> { Error = error, }; + return new PlayFabResult<AddFriendResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AddFriendResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AddFriendResult>>(resultRawJson); + var result = resultData.data; - AddFriendResult result = resultData.data; - - return new PlayFabResult<AddFriendResult> { Result = result }; + return new PlayFabResult<AddFriendResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the current friend list for the local user, constrained to users who have PlayFab accounts. Friends from linked accounts (Facebook, Steam) are also included. You may optionally exclude some linked services' friends. /// </summary> - public static async Task<PlayFabResult<GetFriendsListResult>> GetFriendsListAsync(GetFriendsListRequest request) + public static async Task<PlayFabResult<GetFriendsListResult>> GetFriendsListAsync(GetFriendsListRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetFriendsList", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetFriendsList", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetFriendsListResult> { Error = error, }; + return new PlayFabResult<GetFriendsListResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetFriendsListResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetFriendsListResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetFriendsListResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetFriendsListResult> { Result = result }; + return new PlayFabResult<GetFriendsListResult> { Result = result, CustomData = customData }; } /// <summary> /// Removes a specified user from the friend list of the local user /// </summary> - public static async Task<PlayFabResult<RemoveFriendResult>> RemoveFriendAsync(RemoveFriendRequest request) + public static async Task<PlayFabResult<RemoveFriendResult>> RemoveFriendAsync(RemoveFriendRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/RemoveFriend", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/RemoveFriend", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RemoveFriendResult> { Error = error, }; + return new PlayFabResult<RemoveFriendResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RemoveFriendResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RemoveFriendResult>>(resultRawJson); + var result = resultData.data; - RemoveFriendResult result = resultData.data; - - return new PlayFabResult<RemoveFriendResult> { Result = result }; + return new PlayFabResult<RemoveFriendResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the tag list for a specified user in the friend list of the local user /// </summary> - public static async Task<PlayFabResult<SetFriendTagsResult>> SetFriendTagsAsync(SetFriendTagsRequest request) + public static async Task<PlayFabResult<SetFriendTagsResult>> SetFriendTagsAsync(SetFriendTagsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/SetFriendTags", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/SetFriendTags", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetFriendTagsResult> { Error = error, }; + return new PlayFabResult<SetFriendTagsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetFriendTagsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - SetFriendTagsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetFriendTagsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<SetFriendTagsResult> { Result = result }; + return new PlayFabResult<SetFriendTagsResult> { Result = result, CustomData = customData }; } /// <summary> /// Registers the iOS device to receive push notifications /// </summary> - public static async Task<PlayFabResult<RegisterForIOSPushNotificationResult>> RegisterForIOSPushNotificationAsync(RegisterForIOSPushNotificationRequest request) + public static async Task<PlayFabResult<RegisterForIOSPushNotificationResult>> RegisterForIOSPushNotificationAsync(RegisterForIOSPushNotificationRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/RegisterForIOSPushNotification", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/RegisterForIOSPushNotification", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RegisterForIOSPushNotificationResult> { Error = error, }; + return new PlayFabResult<RegisterForIOSPushNotificationResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RegisterForIOSPushNotificationResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RegisterForIOSPushNotificationResult>>(resultRawJson); + var result = resultData.data; - RegisterForIOSPushNotificationResult result = resultData.data; - - return new PlayFabResult<RegisterForIOSPushNotificationResult> { Result = result }; + return new PlayFabResult<RegisterForIOSPushNotificationResult> { Result = result, CustomData = customData }; } /// <summary> /// Restores all in-app purchases based on the given refresh receipt. /// </summary> - public static async Task<PlayFabResult<RestoreIOSPurchasesResult>> RestoreIOSPurchasesAsync(RestoreIOSPurchasesRequest request) + public static async Task<PlayFabResult<RestoreIOSPurchasesResult>> RestoreIOSPurchasesAsync(RestoreIOSPurchasesRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/RestoreIOSPurchases", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/RestoreIOSPurchases", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RestoreIOSPurchasesResult> { Error = error, }; + return new PlayFabResult<RestoreIOSPurchasesResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RestoreIOSPurchasesResult>>(new JsonTextReader(new StringReader(resultRawJson))); - RestoreIOSPurchasesResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RestoreIOSPurchasesResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RestoreIOSPurchasesResult> { Result = result }; + return new PlayFabResult<RestoreIOSPurchasesResult> { Result = result, CustomData = customData }; } /// <summary> /// Validates with the Apple store that the receipt for an iOS in-app purchase is valid and that it matches the purchased catalog item /// </summary> - public static async Task<PlayFabResult<ValidateIOSReceiptResult>> ValidateIOSReceiptAsync(ValidateIOSReceiptRequest request) + public static async Task<PlayFabResult<ValidateIOSReceiptResult>> ValidateIOSReceiptAsync(ValidateIOSReceiptRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/ValidateIOSReceipt", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/ValidateIOSReceipt", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ValidateIOSReceiptResult> { Error = error, }; + return new PlayFabResult<ValidateIOSReceiptResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ValidateIOSReceiptResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ValidateIOSReceiptResult>>(resultRawJson); + var result = resultData.data; - ValidateIOSReceiptResult result = resultData.data; - - return new PlayFabResult<ValidateIOSReceiptResult> { Result = result }; + return new PlayFabResult<ValidateIOSReceiptResult> { Result = result, CustomData = customData }; } /// <summary> /// Get details about all current running game servers matching the given parameters. /// </summary> - public static async Task<PlayFabResult<CurrentGamesResult>> GetCurrentGamesAsync(CurrentGamesRequest request) + public static async Task<PlayFabResult<CurrentGamesResult>> GetCurrentGamesAsync(CurrentGamesRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetCurrentGames", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetCurrentGames", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<CurrentGamesResult> { Error = error, }; + return new PlayFabResult<CurrentGamesResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<CurrentGamesResult>>(new JsonTextReader(new StringReader(resultRawJson))); - CurrentGamesResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<CurrentGamesResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<CurrentGamesResult> { Result = result }; + return new PlayFabResult<CurrentGamesResult> { Result = result, CustomData = customData }; } /// <summary> /// Get details about the regions hosting game servers matching the given parameters. /// </summary> - public static async Task<PlayFabResult<GameServerRegionsResult>> GetGameServerRegionsAsync(GameServerRegionsRequest request) + public static async Task<PlayFabResult<GameServerRegionsResult>> GetGameServerRegionsAsync(GameServerRegionsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetGameServerRegions", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetGameServerRegions", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GameServerRegionsResult> { Error = error, }; + return new PlayFabResult<GameServerRegionsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GameServerRegionsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GameServerRegionsResult>>(resultRawJson); + var result = resultData.data; - GameServerRegionsResult result = resultData.data; - - return new PlayFabResult<GameServerRegionsResult> { Result = result }; + return new PlayFabResult<GameServerRegionsResult> { Result = result, CustomData = customData }; } /// <summary> /// Attempts to locate a game session matching the given parameters. If the goal is to match the player into a specific active session, only the LobbyId is required. Otherwise, the BuildVersion, GameMode, and Region are all required parameters. Note that parameters specified in the search are required (they are not weighting factors). If a slot is found in a server instance matching the parameters, the slot will be assigned to that player, removing it from the availabe set. In that case, the information on the game session will be returned, otherwise the Status returned will be GameNotFound. Note that EnableQueue is deprecated at this time. /// </summary> - public static async Task<PlayFabResult<MatchmakeResult>> MatchmakeAsync(MatchmakeRequest request) + public static async Task<PlayFabResult<MatchmakeResult>> MatchmakeAsync(MatchmakeRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/Matchmake", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/Matchmake", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<MatchmakeResult> { Error = error, }; + return new PlayFabResult<MatchmakeResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<MatchmakeResult>>(new JsonTextReader(new StringReader(resultRawJson))); - MatchmakeResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<MatchmakeResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<MatchmakeResult> { Result = result }; + return new PlayFabResult<MatchmakeResult> { Result = result, CustomData = customData }; } /// <summary> /// Start a new game server with a given configuration, add the current player and return the connection information. /// </summary> - public static async Task<PlayFabResult<StartGameResult>> StartGameAsync(StartGameRequest request) + public static async Task<PlayFabResult<StartGameResult>> StartGameAsync(StartGameRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/StartGame", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/StartGame", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<StartGameResult> { Error = error, }; + return new PlayFabResult<StartGameResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<StartGameResult>>(new JsonTextReader(new StringReader(resultRawJson))); - StartGameResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<StartGameResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<StartGameResult> { Result = result }; + return new PlayFabResult<StartGameResult> { Result = result, CustomData = customData }; } /// <summary> /// Registers the Android device to receive push notifications /// </summary> - public static async Task<PlayFabResult<AndroidDevicePushNotificationRegistrationResult>> AndroidDevicePushNotificationRegistrationAsync(AndroidDevicePushNotificationRegistrationRequest request) + public static async Task<PlayFabResult<AndroidDevicePushNotificationRegistrationResult>> AndroidDevicePushNotificationRegistrationAsync(AndroidDevicePushNotificationRegistrationRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/AndroidDevicePushNotificationRegistration", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/AndroidDevicePushNotificationRegistration", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AndroidDevicePushNotificationRegistrationResult> { Error = error, }; + return new PlayFabResult<AndroidDevicePushNotificationRegistrationResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AndroidDevicePushNotificationRegistrationResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AndroidDevicePushNotificationRegistrationResult>>(resultRawJson); + var result = resultData.data; - AndroidDevicePushNotificationRegistrationResult result = resultData.data; - - return new PlayFabResult<AndroidDevicePushNotificationRegistrationResult> { Result = result }; + return new PlayFabResult<AndroidDevicePushNotificationRegistrationResult> { Result = result, CustomData = customData }; } /// <summary> /// Validates a Google Play purchase and gives the corresponding item to the player. /// </summary> - public static async Task<PlayFabResult<ValidateGooglePlayPurchaseResult>> ValidateGooglePlayPurchaseAsync(ValidateGooglePlayPurchaseRequest request) + public static async Task<PlayFabResult<ValidateGooglePlayPurchaseResult>> ValidateGooglePlayPurchaseAsync(ValidateGooglePlayPurchaseRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/ValidateGooglePlayPurchase", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/ValidateGooglePlayPurchase", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ValidateGooglePlayPurchaseResult> { Error = error, }; + return new PlayFabResult<ValidateGooglePlayPurchaseResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ValidateGooglePlayPurchaseResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ValidateGooglePlayPurchaseResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ValidateGooglePlayPurchaseResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ValidateGooglePlayPurchaseResult> { Result = result }; + return new PlayFabResult<ValidateGooglePlayPurchaseResult> { Result = result, CustomData = customData }; } /// <summary> /// Writes a character-based event into PlayStream. /// </summary> - public static async Task<PlayFabResult<WriteEventResponse>> WriteCharacterEventAsync(WriteClientCharacterEventRequest request) + public static async Task<PlayFabResult<WriteEventResponse>> WriteCharacterEventAsync(WriteClientCharacterEventRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/WriteCharacterEvent", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/WriteCharacterEvent", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<WriteEventResponse> { Error = error, }; + return new PlayFabResult<WriteEventResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<WriteEventResponse>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<WriteEventResponse>>(resultRawJson); + var result = resultData.data; - WriteEventResponse result = resultData.data; - - return new PlayFabResult<WriteEventResponse> { Result = result }; + return new PlayFabResult<WriteEventResponse> { Result = result, CustomData = customData }; } /// <summary> /// Writes a player-based event into PlayStream. /// </summary> - public static async Task<PlayFabResult<WriteEventResponse>> WritePlayerEventAsync(WriteClientPlayerEventRequest request) + public static async Task<PlayFabResult<WriteEventResponse>> WritePlayerEventAsync(WriteClientPlayerEventRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/WritePlayerEvent", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/WritePlayerEvent", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<WriteEventResponse> { Error = error, }; + return new PlayFabResult<WriteEventResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<WriteEventResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - WriteEventResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<WriteEventResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<WriteEventResponse> { Result = result }; + return new PlayFabResult<WriteEventResponse> { Result = result, CustomData = customData }; } /// <summary> /// Writes a title-based event into PlayStream. /// </summary> - public static async Task<PlayFabResult<WriteEventResponse>> WriteTitleEventAsync(WriteTitleEventRequest request) + public static async Task<PlayFabResult<WriteEventResponse>> WriteTitleEventAsync(WriteTitleEventRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/WriteTitleEvent", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/WriteTitleEvent", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<WriteEventResponse> { Error = error, }; + return new PlayFabResult<WriteEventResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<WriteEventResponse>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<WriteEventResponse>>(resultRawJson); + var result = resultData.data; - WriteEventResponse result = resultData.data; - - return new PlayFabResult<WriteEventResponse> { Result = result }; + return new PlayFabResult<WriteEventResponse> { Result = result, CustomData = customData }; } /// <summary> /// Adds users to the set of those able to update both the shared data, as well as the set of users in the group. Only users in the group can add new members. /// </summary> - public static async Task<PlayFabResult<AddSharedGroupMembersResult>> AddSharedGroupMembersAsync(AddSharedGroupMembersRequest request) + public static async Task<PlayFabResult<AddSharedGroupMembersResult>> AddSharedGroupMembersAsync(AddSharedGroupMembersRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/AddSharedGroupMembers", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/AddSharedGroupMembers", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AddSharedGroupMembersResult> { Error = error, }; + return new PlayFabResult<AddSharedGroupMembersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AddSharedGroupMembersResult>>(new JsonTextReader(new StringReader(resultRawJson))); - AddSharedGroupMembersResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AddSharedGroupMembersResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AddSharedGroupMembersResult> { Result = result }; + return new PlayFabResult<AddSharedGroupMembersResult> { Result = result, CustomData = customData }; } /// <summary> /// Requests the creation of a shared group object, containing key/value pairs which may be updated by all members of the group. Upon creation, the current user will be the only member of the group. /// </summary> - public static async Task<PlayFabResult<CreateSharedGroupResult>> CreateSharedGroupAsync(CreateSharedGroupRequest request) + public static async Task<PlayFabResult<CreateSharedGroupResult>> CreateSharedGroupAsync(CreateSharedGroupRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/CreateSharedGroup", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/CreateSharedGroup", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<CreateSharedGroupResult> { Error = error, }; + return new PlayFabResult<CreateSharedGroupResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<CreateSharedGroupResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<CreateSharedGroupResult>>(resultRawJson); + var result = resultData.data; - CreateSharedGroupResult result = resultData.data; - - return new PlayFabResult<CreateSharedGroupResult> { Result = result }; + return new PlayFabResult<CreateSharedGroupResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves data stored in a shared group object, as well as the list of members in the group. Non-members of the group may use this to retrieve group data, including membership, but they will not receive data for keys marked as private. /// </summary> - public static async Task<PlayFabResult<GetSharedGroupDataResult>> GetSharedGroupDataAsync(GetSharedGroupDataRequest request) + public static async Task<PlayFabResult<GetSharedGroupDataResult>> GetSharedGroupDataAsync(GetSharedGroupDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetSharedGroupData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetSharedGroupData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetSharedGroupDataResult> { Error = error, }; + return new PlayFabResult<GetSharedGroupDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetSharedGroupDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetSharedGroupDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetSharedGroupDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetSharedGroupDataResult> { Result = result }; + return new PlayFabResult<GetSharedGroupDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Removes users from the set of those able to update the shared data and the set of users in the group. Only users in the group can remove members. If as a result of the call, zero users remain with access, the group and its associated data will be deleted. /// </summary> - public static async Task<PlayFabResult<RemoveSharedGroupMembersResult>> RemoveSharedGroupMembersAsync(RemoveSharedGroupMembersRequest request) + public static async Task<PlayFabResult<RemoveSharedGroupMembersResult>> RemoveSharedGroupMembersAsync(RemoveSharedGroupMembersRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/RemoveSharedGroupMembers", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/RemoveSharedGroupMembers", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RemoveSharedGroupMembersResult> { Error = error, }; + return new PlayFabResult<RemoveSharedGroupMembersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RemoveSharedGroupMembersResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RemoveSharedGroupMembersResult>>(resultRawJson); + var result = resultData.data; - RemoveSharedGroupMembersResult result = resultData.data; - - return new PlayFabResult<RemoveSharedGroupMembersResult> { Result = result }; + return new PlayFabResult<RemoveSharedGroupMembersResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds, updates, and removes data keys for a shared group object. If the permission is set to Public, all fields updated or added in this call will be readable by users not in the group. By default, data permissions are set to Private. Regardless of the permission setting, only members of the group can update the data. /// </summary> - public static async Task<PlayFabResult<UpdateSharedGroupDataResult>> UpdateSharedGroupDataAsync(UpdateSharedGroupDataRequest request) + public static async Task<PlayFabResult<UpdateSharedGroupDataResult>> UpdateSharedGroupDataAsync(UpdateSharedGroupDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UpdateSharedGroupData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UpdateSharedGroupData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateSharedGroupDataResult> { Error = error, }; + return new PlayFabResult<UpdateSharedGroupDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateSharedGroupDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateSharedGroupDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateSharedGroupDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateSharedGroupDataResult> { Result = result }; + return new PlayFabResult<UpdateSharedGroupDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Executes a CloudScript function, with the 'currentPlayerId' set to the PlayFab ID of the authenticated player. /// </summary> - public static async Task<PlayFabResult<ExecuteCloudScriptResult>> ExecuteCloudScriptAsync(ExecuteCloudScriptRequest request) + public static async Task<PlayFabResult<ExecuteCloudScriptResult>> ExecuteCloudScriptAsync(ExecuteCloudScriptRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/ExecuteCloudScript", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/ExecuteCloudScript", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ExecuteCloudScriptResult> { Error = error, }; + return new PlayFabResult<ExecuteCloudScriptResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ExecuteCloudScriptResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ExecuteCloudScriptResult>>(resultRawJson); + var result = resultData.data; - ExecuteCloudScriptResult result = resultData.data; - - return new PlayFabResult<ExecuteCloudScriptResult> { Result = result }; + return new PlayFabResult<ExecuteCloudScriptResult> { Result = result, CustomData = customData }; } /// <summary> /// This API retrieves a pre-signed URL for accessing a content file for the title. A subsequent HTTP GET to the returned URL will attempt to download the content. A HEAD query to the returned URL will attempt to retrieve the metadata of the content. Note that a successful result does not guarantee the existence of this content - if it has not been uploaded, the query to retrieve the data will fail. See this post for more information: https://community.playfab.com/hc/en-us/community/posts/205469488-How-to-upload-files-to-PlayFab-s-Content-Service /// </summary> - public static async Task<PlayFabResult<GetContentDownloadUrlResult>> GetContentDownloadUrlAsync(GetContentDownloadUrlRequest request) + public static async Task<PlayFabResult<GetContentDownloadUrlResult>> GetContentDownloadUrlAsync(GetContentDownloadUrlRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetContentDownloadUrl", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetContentDownloadUrl", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetContentDownloadUrlResult> { Error = error, }; + return new PlayFabResult<GetContentDownloadUrlResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetContentDownloadUrlResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetContentDownloadUrlResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetContentDownloadUrlResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetContentDownloadUrlResult> { Result = result }; + return new PlayFabResult<GetContentDownloadUrlResult> { Result = result, CustomData = customData }; } /// <summary> /// Lists all of the characters that belong to a specific user. CharacterIds are not globally unique; characterId must be evaluated with the parent PlayFabId to guarantee uniqueness. /// </summary> - public static async Task<PlayFabResult<ListUsersCharactersResult>> GetAllUsersCharactersAsync(ListUsersCharactersRequest request) + public static async Task<PlayFabResult<ListUsersCharactersResult>> GetAllUsersCharactersAsync(ListUsersCharactersRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetAllUsersCharacters", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetAllUsersCharacters", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ListUsersCharactersResult> { Error = error, }; + return new PlayFabResult<ListUsersCharactersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ListUsersCharactersResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ListUsersCharactersResult>>(resultRawJson); + var result = resultData.data; - ListUsersCharactersResult result = resultData.data; - - return new PlayFabResult<ListUsersCharactersResult> { Result = result }; + return new PlayFabResult<ListUsersCharactersResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked characters for the given statistic, starting from the indicated point in the leaderboard /// </summary> - public static async Task<PlayFabResult<GetCharacterLeaderboardResult>> GetCharacterLeaderboardAsync(GetCharacterLeaderboardRequest request) + public static async Task<PlayFabResult<GetCharacterLeaderboardResult>> GetCharacterLeaderboardAsync(GetCharacterLeaderboardRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetCharacterLeaderboard", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetCharacterLeaderboard", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterLeaderboardResult> { Error = error, }; + return new PlayFabResult<GetCharacterLeaderboardResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterLeaderboardResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetCharacterLeaderboardResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterLeaderboardResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetCharacterLeaderboardResult> { Result = result }; + return new PlayFabResult<GetCharacterLeaderboardResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the details of all title-specific statistics for the user /// </summary> - public static async Task<PlayFabResult<GetCharacterStatisticsResult>> GetCharacterStatisticsAsync(GetCharacterStatisticsRequest request) + public static async Task<PlayFabResult<GetCharacterStatisticsResult>> GetCharacterStatisticsAsync(GetCharacterStatisticsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetCharacterStatistics", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetCharacterStatistics", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterStatisticsResult> { Error = error, }; + return new PlayFabResult<GetCharacterStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterStatisticsResult>>(resultRawJson); + var result = resultData.data; - GetCharacterStatisticsResult result = resultData.data; - - return new PlayFabResult<GetCharacterStatisticsResult> { Result = result }; + return new PlayFabResult<GetCharacterStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked characters for the given statistic, centered on the requested Character ID /// </summary> - public static async Task<PlayFabResult<GetLeaderboardAroundCharacterResult>> GetLeaderboardAroundCharacterAsync(GetLeaderboardAroundCharacterRequest request) + public static async Task<PlayFabResult<GetLeaderboardAroundCharacterResult>> GetLeaderboardAroundCharacterAsync(GetLeaderboardAroundCharacterRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetLeaderboardAroundCharacter", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetLeaderboardAroundCharacter", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardAroundCharacterResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardAroundCharacterResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardAroundCharacterResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetLeaderboardAroundCharacterResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardAroundCharacterResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetLeaderboardAroundCharacterResult> { Result = result }; + return new PlayFabResult<GetLeaderboardAroundCharacterResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of all of the user's characters for the given statistic. /// </summary> - public static async Task<PlayFabResult<GetLeaderboardForUsersCharactersResult>> GetLeaderboardForUserCharactersAsync(GetLeaderboardForUsersCharactersRequest request) + public static async Task<PlayFabResult<GetLeaderboardForUsersCharactersResult>> GetLeaderboardForUserCharactersAsync(GetLeaderboardForUsersCharactersRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetLeaderboardForUserCharacters", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetLeaderboardForUserCharacters", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardForUsersCharactersResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardForUsersCharactersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardForUsersCharactersResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardForUsersCharactersResult>>(resultRawJson); + var result = resultData.data; - GetLeaderboardForUsersCharactersResult result = resultData.data; - - return new PlayFabResult<GetLeaderboardForUsersCharactersResult> { Result = result }; + return new PlayFabResult<GetLeaderboardForUsersCharactersResult> { Result = result, CustomData = customData }; } /// <summary> /// Grants the specified character type to the user. CharacterIds are not globally unique; characterId must be evaluated with the parent PlayFabId to guarantee uniqueness. /// </summary> - public static async Task<PlayFabResult<GrantCharacterToUserResult>> GrantCharacterToUserAsync(GrantCharacterToUserRequest request) + public static async Task<PlayFabResult<GrantCharacterToUserResult>> GrantCharacterToUserAsync(GrantCharacterToUserRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GrantCharacterToUser", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GrantCharacterToUser", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GrantCharacterToUserResult> { Error = error, }; + return new PlayFabResult<GrantCharacterToUserResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GrantCharacterToUserResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GrantCharacterToUserResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GrantCharacterToUserResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GrantCharacterToUserResult> { Result = result }; + return new PlayFabResult<GrantCharacterToUserResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the values of the specified title-specific statistics for the specific character. By default, clients are not permitted to update statistics. Developers may override this setting in the Game Manager > Settings > API Features. /// </summary> - public static async Task<PlayFabResult<UpdateCharacterStatisticsResult>> UpdateCharacterStatisticsAsync(UpdateCharacterStatisticsRequest request) + public static async Task<PlayFabResult<UpdateCharacterStatisticsResult>> UpdateCharacterStatisticsAsync(UpdateCharacterStatisticsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UpdateCharacterStatistics", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UpdateCharacterStatistics", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateCharacterStatisticsResult> { Error = error, }; + return new PlayFabResult<UpdateCharacterStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateCharacterStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateCharacterStatisticsResult>>(resultRawJson); + var result = resultData.data; - UpdateCharacterStatisticsResult result = resultData.data; - - return new PlayFabResult<UpdateCharacterStatisticsResult> { Result = result }; + return new PlayFabResult<UpdateCharacterStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the character which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterDataAsync(GetCharacterDataRequest request) + public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterDataAsync(GetCharacterDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetCharacterData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetCharacterData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterDataResult> { Error = error, }; + return new PlayFabResult<GetCharacterDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetCharacterDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetCharacterDataResult> { Result = result }; + return new PlayFabResult<GetCharacterDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the character which can only be read by the client /// </summary> - public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterReadOnlyDataAsync(GetCharacterDataRequest request) + public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterReadOnlyDataAsync(GetCharacterDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetCharacterReadOnlyData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetCharacterReadOnlyData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterDataResult> { Error = error, }; + return new PlayFabResult<GetCharacterDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterDataResult>>(resultRawJson); + var result = resultData.data; - GetCharacterDataResult result = resultData.data; - - return new PlayFabResult<GetCharacterDataResult> { Result = result }; + return new PlayFabResult<GetCharacterDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Creates and updates the title-specific custom data for the user's character which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<UpdateCharacterDataResult>> UpdateCharacterDataAsync(UpdateCharacterDataRequest request) + public static async Task<PlayFabResult<UpdateCharacterDataResult>> UpdateCharacterDataAsync(UpdateCharacterDataRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/UpdateCharacterData", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/UpdateCharacterData", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateCharacterDataResult> { Error = error, }; + return new PlayFabResult<UpdateCharacterDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateCharacterDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateCharacterDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateCharacterDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateCharacterDataResult> { Result = result }; + return new PlayFabResult<UpdateCharacterDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Validates with Amazon that the receipt for an Amazon App Store in-app purchase is valid and that it matches the purchased catalog item /// </summary> - public static async Task<PlayFabResult<ValidateAmazonReceiptResult>> ValidateAmazonIAPReceiptAsync(ValidateAmazonReceiptRequest request) + public static async Task<PlayFabResult<ValidateAmazonReceiptResult>> ValidateAmazonIAPReceiptAsync(ValidateAmazonReceiptRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/ValidateAmazonIAPReceipt", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/ValidateAmazonIAPReceipt", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ValidateAmazonReceiptResult> { Error = error, }; + return new PlayFabResult<ValidateAmazonReceiptResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ValidateAmazonReceiptResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ValidateAmazonReceiptResult>>(resultRawJson); + var result = resultData.data; - ValidateAmazonReceiptResult result = resultData.data; - - return new PlayFabResult<ValidateAmazonReceiptResult> { Result = result }; + return new PlayFabResult<ValidateAmazonReceiptResult> { Result = result, CustomData = customData }; } /// <summary> /// Accepts an open trade. If the call is successful, the offered and accepted items will be swapped between the two players' inventories. /// </summary> - public static async Task<PlayFabResult<AcceptTradeResponse>> AcceptTradeAsync(AcceptTradeRequest request) + public static async Task<PlayFabResult<AcceptTradeResponse>> AcceptTradeAsync(AcceptTradeRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/AcceptTrade", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/AcceptTrade", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AcceptTradeResponse> { Error = error, }; + return new PlayFabResult<AcceptTradeResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AcceptTradeResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - AcceptTradeResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AcceptTradeResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AcceptTradeResponse> { Result = result }; + return new PlayFabResult<AcceptTradeResponse> { Result = result, CustomData = customData }; } /// <summary> /// Cancels an open trade. /// </summary> - public static async Task<PlayFabResult<CancelTradeResponse>> CancelTradeAsync(CancelTradeRequest request) + public static async Task<PlayFabResult<CancelTradeResponse>> CancelTradeAsync(CancelTradeRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/CancelTrade", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/CancelTrade", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<CancelTradeResponse> { Error = error, }; + return new PlayFabResult<CancelTradeResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<CancelTradeResponse>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<CancelTradeResponse>>(resultRawJson); + var result = resultData.data; - CancelTradeResponse result = resultData.data; - - return new PlayFabResult<CancelTradeResponse> { Result = result }; + return new PlayFabResult<CancelTradeResponse> { Result = result, CustomData = customData }; } /// <summary> /// Gets all trades the player has either opened or accepted, optionally filtered by trade status. /// </summary> - public static async Task<PlayFabResult<GetPlayerTradesResponse>> GetPlayerTradesAsync(GetPlayerTradesRequest request) + public static async Task<PlayFabResult<GetPlayerTradesResponse>> GetPlayerTradesAsync(GetPlayerTradesRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayerTrades", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayerTrades", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerTradesResponse> { Error = error, }; + return new PlayFabResult<GetPlayerTradesResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerTradesResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerTradesResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerTradesResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerTradesResponse> { Result = result }; + return new PlayFabResult<GetPlayerTradesResponse> { Result = result, CustomData = customData }; } /// <summary> /// Gets the current status of an existing trade. /// </summary> - public static async Task<PlayFabResult<GetTradeStatusResponse>> GetTradeStatusAsync(GetTradeStatusRequest request) + public static async Task<PlayFabResult<GetTradeStatusResponse>> GetTradeStatusAsync(GetTradeStatusRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetTradeStatus", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetTradeStatus", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTradeStatusResponse> { Error = error, }; + return new PlayFabResult<GetTradeStatusResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTradeStatusResponse>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTradeStatusResponse>>(resultRawJson); + var result = resultData.data; - GetTradeStatusResponse result = resultData.data; - - return new PlayFabResult<GetTradeStatusResponse> { Result = result }; + return new PlayFabResult<GetTradeStatusResponse> { Result = result, CustomData = customData }; } /// <summary> /// Opens a new outstanding trade. /// </summary> - public static async Task<PlayFabResult<OpenTradeResponse>> OpenTradeAsync(OpenTradeRequest request) + public static async Task<PlayFabResult<OpenTradeResponse>> OpenTradeAsync(OpenTradeRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/OpenTrade", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/OpenTrade", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<OpenTradeResponse> { Error = error, }; + return new PlayFabResult<OpenTradeResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<OpenTradeResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - OpenTradeResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<OpenTradeResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<OpenTradeResponse> { Result = result }; + return new PlayFabResult<OpenTradeResponse> { Result = result, CustomData = customData }; } /// <summary> /// Attributes an install for advertisment. /// </summary> - public static async Task<PlayFabResult<AttributeInstallResult>> AttributeInstallAsync(AttributeInstallRequest request) + public static async Task<PlayFabResult<AttributeInstallResult>> AttributeInstallAsync(AttributeInstallRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/AttributeInstall", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/AttributeInstall", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AttributeInstallResult> { Error = error, }; + return new PlayFabResult<AttributeInstallResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AttributeInstallResult>>(new JsonTextReader(new StringReader(resultRawJson))); - - AttributeInstallResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AttributeInstallResult>>(resultRawJson); + var result = resultData.data; // Modify AdvertisingIdType: Prevents us from sending the id multiple times, and allows automated tests to determine id was sent successfully PlayFabSettings.AdvertisingIdType += "_Successful"; - return new PlayFabResult<AttributeInstallResult> { Result = result }; + return new PlayFabResult<AttributeInstallResult> { Result = result, CustomData = customData }; } /// <summary> /// List all segments that a player currently belongs to at this moment in time. /// </summary> - public static async Task<PlayFabResult<GetPlayerSegmentsResult>> GetPlayerSegmentsAsync(GetPlayerSegmentsRequest request) + public static async Task<PlayFabResult<GetPlayerSegmentsResult>> GetPlayerSegmentsAsync(GetPlayerSegmentsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayerSegments", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayerSegments", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerSegmentsResult> { Error = error, }; + return new PlayFabResult<GetPlayerSegmentsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerSegmentsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerSegmentsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerSegmentsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerSegmentsResult> { Result = result }; + return new PlayFabResult<GetPlayerSegmentsResult> { Result = result, CustomData = customData }; } /// <summary> /// Get all tags with a given Namespace (optional) from a player profile. /// </summary> - public static async Task<PlayFabResult<GetPlayerTagsResult>> GetPlayerTagsAsync(GetPlayerTagsRequest request) + public static async Task<PlayFabResult<GetPlayerTagsResult>> GetPlayerTagsAsync(GetPlayerTagsRequest request, object customData = null) { if (_authKey == null) throw new Exception ("Must be logged in to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Client/GetPlayerTags", request, "X-Authorization", _authKey); + var httpResult = await PlayFabHttp.DoPost("/Client/GetPlayerTags", request, "X-Authorization", _authKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerTagsResult> { Error = error, }; + return new PlayFabResult<GetPlayerTagsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerTagsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerTagsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerTagsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerTagsResult> { Result = result }; + return new PlayFabResult<GetPlayerTagsResult> { Result = result, CustomData = customData }; } - private static string _authKey = null; + private static string _authKey; // Determine if the _authKey is set, without actually making it public public static bool IsClientLoggedIn() @@ -3088,15 +2844,14 @@ private static async Task<PlayFabResult<AttributeInstallResult>> MultiStepClient { if (needsAttribution && !PlayFabSettings.DisableAdvertising && !string.IsNullOrEmpty(PlayFabSettings.AdvertisingIdType) && !string.IsNullOrEmpty(PlayFabSettings.AdvertisingIdValue)) { - AttributeInstallRequest request = new AttributeInstallRequest(); + var request = new AttributeInstallRequest(); if (PlayFabSettings.AdvertisingIdType == PlayFabSettings.AD_TYPE_IDFA) request.Idfa = PlayFabSettings.AdvertisingIdValue; else if (PlayFabSettings.AdvertisingIdType == PlayFabSettings.AD_TYPE_ANDROID_ID) request.Adid = PlayFabSettings.AdvertisingIdValue; else return null; - var output = await AttributeInstallAsync(request); - return output; + return await AttributeInstallAsync(request); } return null; } diff --git a/PlayFabSDK/source/PlayFabClientModels.cs b/PlayFabSDK/source/PlayFabClientModels.cs index 1d6970d7..28fc2e4b 100644 --- a/PlayFabSDK/source/PlayFabClientModels.cs +++ b/PlayFabSDK/source/PlayFabClientModels.cs @@ -1,12 +1,10 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; using PlayFab.Internal; using System; using System.Collections.Generic; namespace PlayFab.ClientModels { - public class AcceptTradeRequest + public class AcceptTradeRequest : PlayFabRequestCommon { /// <summary> /// Player who opened the trade. @@ -34,7 +32,7 @@ public class AcceptTradeResponse : PlayFabResultCommon } - public class AddFriendRequest + public class AddFriendRequest : PlayFabRequestCommon { /// <summary> /// PlayFab identifier of the user to attempt to add to the local user's friend list. @@ -67,7 +65,7 @@ public class AddFriendResult : PlayFabResultCommon } - public class AddGenericIDRequest + public class AddGenericIDRequest : PlayFabRequestCommon { /// <summary> /// Generic service identifier to add to the player account. @@ -80,7 +78,7 @@ public class AddGenericIDResult : PlayFabResultCommon { } - public class AddSharedGroupMembersRequest + public class AddSharedGroupMembersRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group. @@ -98,7 +96,7 @@ public class AddSharedGroupMembersResult : PlayFabResultCommon { } - public class AddUsernamePasswordRequest + public class AddUsernamePasswordRequest : PlayFabRequestCommon { /// <summary> /// PlayFab username for the account (3-20 characters) @@ -126,7 +124,7 @@ public class AddUsernamePasswordResult : PlayFabResultCommon } - public class AddUserVirtualCurrencyRequest + public class AddUserVirtualCurrencyRequest : PlayFabRequestCommon { /// <summary> /// Name of the virtual currency which is to be incremented. @@ -140,7 +138,7 @@ public class AddUserVirtualCurrencyRequest } - public class AndroidDevicePushNotificationRegistrationRequest + public class AndroidDevicePushNotificationRegistrationRequest : PlayFabRequestCommon { /// <summary> /// Registration ID provided by the Google Cloud Messaging service when the title registered to receive push notifications (see the GCM documentation, here: http://developer.android.com/google/gcm/client.html). @@ -163,7 +161,7 @@ public class AndroidDevicePushNotificationRegistrationResult : PlayFabResultComm { } - public class AttributeInstallRequest + public class AttributeInstallRequest : PlayFabRequestCommon { /// <summary> /// The IdentifierForAdvertisers for iOS Devices. @@ -187,7 +185,7 @@ public class AttributeInstallResult : PlayFabResultCommon { } - public class CancelTradeRequest + public class CancelTradeRequest : PlayFabRequestCommon { /// <summary> /// Trade identifier. @@ -341,7 +339,7 @@ public class CatalogItem : IComparable<CatalogItem> public bool IsLimitedEdition; /// <summary> - /// BETA: If IsLImitedEdition is true, then this determines amount of the item initially available. Note that this fieldis ignored if the catalog item already existed in this catalog, or the field is less than 1. + /// If IsLImitedEdition is true, then this determines amount of the item initially available. Note that this fieldis ignored if the catalog item already existed in this catalog, or the field is less than 1. /// </summary> public int InitialLimitedEditionCount; @@ -520,7 +518,7 @@ public class CollectionFilter } - public class ConfirmPurchaseRequest + public class ConfirmPurchaseRequest : PlayFabRequestCommon { /// <summary> /// Purchase order identifier returned from StartPurchase. @@ -548,7 +546,7 @@ public class ConfirmPurchaseResult : PlayFabResultCommon } - public class ConsumeItemRequest + public class ConsumeItemRequest : PlayFabRequestCommon { /// <summary> /// Unique instance identifier of the item to be consumed. @@ -593,7 +591,7 @@ public class Container_Dictionary_String_String } - public class CreateSharedGroupRequest + public class CreateSharedGroupRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group (a random identifier will be assigned, if one is not specified). @@ -778,12 +776,11 @@ public enum Currency ZWD } - public class CurrentGamesRequest + public class CurrentGamesRequest : PlayFabRequestCommon { /// <summary> /// Region to check for Game Server Instances. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Region? Region; /// <summary> @@ -831,7 +828,7 @@ public class EmptyResult : PlayFabResultCommon { } - public class ExecuteCloudScriptRequest + public class ExecuteCloudScriptRequest : PlayFabRequestCommon { /// <summary> /// The name of the CloudScript function to execute @@ -846,7 +843,6 @@ public class ExecuteCloudScriptRequest /// <summary> /// Option for which revision of the CloudScript to execute. 'Latest' executes the most recently created revision, 'Live' executes the current live, published revision, and 'Specific' executes the specified revision. The default value is 'Specific', if the SpeificRevision parameter is specified, otherwise it is 'Live'. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public CloudScriptRevisionOption? RevisionSelection; /// <summary> @@ -986,7 +982,6 @@ public class GameInfo /// <summary> /// region to which this server is associated /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Region? Region; /// <summary> @@ -1027,7 +1022,6 @@ public class GameInfo /// <summary> /// game specific string denoting server configuration /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public GameInstanceState? GameServerState; /// <summary> @@ -1045,6 +1039,16 @@ public class GameInfo /// </summary> public DateTime? LastHeartbeat; + /// <summary> + /// IP address of the server + /// </summary> + public string ServerHostname; + + /// <summary> + /// port number to use for non-http communications with the server + /// </summary> + public int? ServerPort; + } @@ -1054,7 +1058,7 @@ public enum GameInstanceState Closed } - public class GameServerRegionsRequest + public class GameServerRegionsRequest : PlayFabRequestCommon { /// <summary> /// version of game server for which stats are being requested @@ -1105,7 +1109,7 @@ public class GenericServiceId } - public class GetAccountInfoRequest + public class GetAccountInfoRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab identifier of the user whose info is being requested. Optional, defaults to the authenticated user if no other lookup identifier set. @@ -1123,7 +1127,7 @@ public class GetAccountInfoRequest public string Email; /// <summary> - /// Title-specific username for the account to find (if no Email is set). + /// Title-specific username for the account to find (if no Email is set). Note that if the non-unique Title Display Names option is enabled for the title, attempts to look up users by Title Display Name will always return AccountNotFound. /// </summary> public string TitleDisplayName; @@ -1138,7 +1142,7 @@ public class GetAccountInfoResult : PlayFabResultCommon } - public class GetCatalogItemsRequest + public class GetCatalogItemsRequest : PlayFabRequestCommon { /// <summary> /// Which catalog is being requested. If null, uses the default catalog. @@ -1157,7 +1161,7 @@ public class GetCatalogItemsResult : PlayFabResultCommon } - public class GetCharacterDataRequest + public class GetCharacterDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab identifier of the user to load data for. Optional, defaults to yourself if not set. @@ -1200,7 +1204,7 @@ public class GetCharacterDataResult : PlayFabResultCommon } - public class GetCharacterInventoryRequest + public class GetCharacterInventoryRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID for a specific character owned by a user @@ -1239,7 +1243,7 @@ public class GetCharacterInventoryResult : PlayFabResultCommon } - public class GetCharacterLeaderboardRequest + public class GetCharacterLeaderboardRequest : PlayFabRequestCommon { /// <summary> /// Optional character type on which to filter the leaderboard entries. @@ -1272,7 +1276,7 @@ public class GetCharacterLeaderboardResult : PlayFabResultCommon } - public class GetCharacterStatisticsRequest + public class GetCharacterStatisticsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID for a specific character owned by a user @@ -1290,7 +1294,7 @@ public class GetCharacterStatisticsResult : PlayFabResultCommon } - public class GetContentDownloadUrlRequest + public class GetContentDownloadUrlRequest : PlayFabRequestCommon { /// <summary> /// Key of the content item to fetch, usually formatted as a path, e.g. images/a.png @@ -1318,7 +1322,7 @@ public class GetContentDownloadUrlResult : PlayFabResultCommon } - public class GetFriendLeaderboardAroundPlayerRequest + public class GetFriendLeaderboardAroundPlayerRequest : PlayFabRequestCommon { /// <summary> /// Statistic used to rank players for this leaderboard. @@ -1356,7 +1360,7 @@ public class GetFriendLeaderboardAroundPlayerResult : PlayFabResultCommon } - public class GetFriendLeaderboardRequest + public class GetFriendLeaderboardRequest : PlayFabRequestCommon { /// <summary> /// Statistic used to rank friends for this leaderboard. @@ -1385,7 +1389,7 @@ public class GetFriendLeaderboardRequest } - public class GetFriendsListRequest + public class GetFriendsListRequest : PlayFabRequestCommon { /// <summary> /// Indicates whether Steam service friends should be included in the response. Default is true. @@ -1408,7 +1412,7 @@ public class GetFriendsListResult : PlayFabResultCommon } - public class GetLeaderboardAroundCharacterRequest + public class GetLeaderboardAroundCharacterRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title-specific statistic for the leaderboard. @@ -1441,7 +1445,7 @@ public class GetLeaderboardAroundCharacterResult : PlayFabResultCommon } - public class GetLeaderboardAroundPlayerRequest + public class GetLeaderboardAroundPlayerRequest : PlayFabRequestCommon { /// <summary> /// PlayFab unique identifier of the user to center the leaderboard around. If null will center on the logged in user. @@ -1469,7 +1473,7 @@ public class GetLeaderboardAroundPlayerResult : PlayFabResultCommon } - public class GetLeaderboardForUsersCharactersRequest + public class GetLeaderboardForUsersCharactersRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title-specific statistic for the leaderboard. @@ -1492,7 +1496,7 @@ public class GetLeaderboardForUsersCharactersResult : PlayFabResultCommon } - public class GetLeaderboardRequest + public class GetLeaderboardRequest : PlayFabRequestCommon { /// <summary> /// Statistic used to rank players for this leaderboard. @@ -1520,7 +1524,7 @@ public class GetLeaderboardResult : PlayFabResultCommon } - public class GetPhotonAuthenticationTokenRequest + public class GetPhotonAuthenticationTokenRequest : PlayFabRequestCommon { /// <summary> /// The Photon applicationId for the game you wish to log into. @@ -1538,7 +1542,7 @@ public class GetPhotonAuthenticationTokenResult : PlayFabResultCommon } - public class GetPlayerCombinedInfoRequest + public class GetPlayerCombinedInfoRequest : PlayFabRequestCommon { /// <summary> /// PlayFabId of the user whose data will be returned. If not filled included, we return the data for the calling player. @@ -1635,7 +1639,7 @@ public class GetPlayerCombinedInfoResult : PlayFabResultCommon } - public class GetPlayerCombinedInfoResultPayload : PlayFabResultCommon + public class GetPlayerCombinedInfoResultPayload { /// <summary> /// Account information for the user. This is always retrieved. @@ -1700,7 +1704,7 @@ public class GetPlayerCombinedInfoResultPayload : PlayFabResultCommon } - public class GetPlayerSegmentsRequest + public class GetPlayerSegmentsRequest : PlayFabRequestCommon { } @@ -1713,7 +1717,7 @@ public class GetPlayerSegmentsResult : PlayFabResultCommon } - public class GetPlayerStatisticsRequest + public class GetPlayerStatisticsRequest : PlayFabRequestCommon { /// <summary> /// statistics to return (current version will be returned for each) @@ -1736,7 +1740,7 @@ public class GetPlayerStatisticsResult : PlayFabResultCommon } - public class GetPlayerStatisticVersionsRequest + public class GetPlayerStatisticVersionsRequest : PlayFabRequestCommon { /// <summary> /// unique name of the statistic @@ -1754,7 +1758,7 @@ public class GetPlayerStatisticVersionsResult : PlayFabResultCommon } - public class GetPlayerTagsRequest + public class GetPlayerTagsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1782,12 +1786,11 @@ public class GetPlayerTagsResult : PlayFabResultCommon } - public class GetPlayerTradesRequest + public class GetPlayerTradesRequest : PlayFabRequestCommon { /// <summary> /// Returns only trades with the given status. If null, returns all trades. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public TradeStatus? StatusFilter; } @@ -1806,7 +1809,7 @@ public class GetPlayerTradesResponse : PlayFabResultCommon } - public class GetPlayFabIDsFromFacebookIDsRequest + public class GetPlayFabIDsFromFacebookIDsRequest : PlayFabRequestCommon { /// <summary> /// Array of unique Facebook identifiers for which the title needs to get PlayFab identifiers. @@ -1824,7 +1827,7 @@ public class GetPlayFabIDsFromFacebookIDsResult : PlayFabResultCommon } - public class GetPlayFabIDsFromGameCenterIDsRequest + public class GetPlayFabIDsFromGameCenterIDsRequest : PlayFabRequestCommon { /// <summary> /// Array of unique Game Center identifiers (the Player Identifier) for which the title needs to get PlayFab identifiers. @@ -1842,7 +1845,7 @@ public class GetPlayFabIDsFromGameCenterIDsResult : PlayFabResultCommon } - public class GetPlayFabIDsFromGenericIDsRequest + public class GetPlayFabIDsFromGenericIDsRequest : PlayFabRequestCommon { /// <summary> /// Array of unique generic service identifiers for which the title needs to get PlayFab identifiers. Currently limited to a maximum of 10 in a single request. @@ -1860,7 +1863,7 @@ public class GetPlayFabIDsFromGenericIDsResult : PlayFabResultCommon } - public class GetPlayFabIDsFromGoogleIDsRequest + public class GetPlayFabIDsFromGoogleIDsRequest : PlayFabRequestCommon { /// <summary> /// Array of unique Google identifiers (Google+ user IDs) for which the title needs to get PlayFab identifiers. @@ -1878,7 +1881,7 @@ public class GetPlayFabIDsFromGoogleIDsResult : PlayFabResultCommon } - public class GetPlayFabIDsFromKongregateIDsRequest + public class GetPlayFabIDsFromKongregateIDsRequest : PlayFabRequestCommon { /// <summary> /// Array of unique Kongregate identifiers (Kongregate's user_id) for which the title needs to get PlayFab identifiers. @@ -1896,7 +1899,7 @@ public class GetPlayFabIDsFromKongregateIDsResult : PlayFabResultCommon } - public class GetPlayFabIDsFromSteamIDsRequest + public class GetPlayFabIDsFromSteamIDsRequest : PlayFabRequestCommon { /// <summary> /// Array of unique Steam identifiers (Steam profile IDs) for which the title needs to get PlayFab identifiers. @@ -1914,7 +1917,7 @@ public class GetPlayFabIDsFromSteamIDsResult : PlayFabResultCommon } - public class GetPlayFabIDsFromTwitchIDsRequest + public class GetPlayFabIDsFromTwitchIDsRequest : PlayFabRequestCommon { /// <summary> /// Array of unique Twitch identifiers (Twitch's _id) for which the title needs to get PlayFab identifiers. @@ -1932,7 +1935,7 @@ public class GetPlayFabIDsFromTwitchIDsResult : PlayFabResultCommon } - public class GetPublisherDataRequest + public class GetPublisherDataRequest : PlayFabRequestCommon { /// <summary> /// array of keys to get back data from the Publisher data blob, set by the admin tools @@ -1950,7 +1953,7 @@ public class GetPublisherDataResult : PlayFabResultCommon } - public class GetPurchaseRequest + public class GetPurchaseRequest : PlayFabRequestCommon { /// <summary> /// Purchase order identifier. @@ -2012,7 +2015,7 @@ public class GetSegmentResult : PlayFabResultCommon } - public class GetSharedGroupDataRequest + public class GetSharedGroupDataRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group. @@ -2045,7 +2048,7 @@ public class GetSharedGroupDataResult : PlayFabResultCommon } - public class GetStoreItemsRequest + public class GetStoreItemsRequest : PlayFabRequestCommon { /// <summary> /// catalog version to store items from. Use default catalog version if null @@ -2070,7 +2073,6 @@ public class GetStoreItemsResult : PlayFabResultCommon /// <summary> /// How the store was last updated (Admin or a third party). /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public SourceType? Source; /// <summary> @@ -2090,7 +2092,7 @@ public class GetStoreItemsResult : PlayFabResultCommon } - public class GetTimeRequest + public class GetTimeRequest : PlayFabRequestCommon { } @@ -2103,7 +2105,7 @@ public class GetTimeResult : PlayFabResultCommon } - public class GetTitleDataRequest + public class GetTitleDataRequest : PlayFabRequestCommon { /// <summary> /// Specific keys to search for in the title data (leave null to get all keys) @@ -2121,7 +2123,7 @@ public class GetTitleDataResult : PlayFabResultCommon } - public class GetTitleNewsRequest + public class GetTitleNewsRequest : PlayFabRequestCommon { /// <summary> /// Limits the results to the last n entries. Defaults to 10 if not set. @@ -2139,7 +2141,7 @@ public class GetTitleNewsResult : PlayFabResultCommon } - public class GetTradeStatusRequest + public class GetTradeStatusRequest : PlayFabRequestCommon { /// <summary> /// Player who opened trade. @@ -2163,7 +2165,7 @@ public class GetTradeStatusResponse : PlayFabResultCommon } [Obsolete("No longer available", true)] - public class GetUserCombinedInfoRequest + public class GetUserCombinedInfoRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab identifier of the user whose info is being requested. Optional, defaults to the authenticated user if no other lookup identifier set. @@ -2273,7 +2275,7 @@ public class GetUserCombinedInfoResult : PlayFabResultCommon } - public class GetUserDataRequest + public class GetUserDataRequest : PlayFabRequestCommon { /// <summary> /// Specific keys to search for in the custom data. Leave null to get all keys. @@ -2306,7 +2308,7 @@ public class GetUserDataResult : PlayFabResultCommon } - public class GetUserInventoryRequest + public class GetUserInventoryRequest : PlayFabRequestCommon { } @@ -2344,7 +2346,7 @@ public class GooglePlayFabIdPair } - public class GrantCharacterToUserRequest + public class GrantCharacterToUserRequest : PlayFabRequestCommon { /// <summary> /// Catalog version from which items are to be granted. @@ -2471,7 +2473,7 @@ public int CompareTo(ItemInstance other) } - public class ItemPurchaseRequest + public class ItemPurchaseRequest : PlayFabRequestCommon { /// <summary> /// Unique ItemId of the item to purchase. @@ -2509,7 +2511,7 @@ public class KongregatePlayFabIdPair } - public class LinkAndroidDeviceIDRequest + public class LinkAndroidDeviceIDRequest : PlayFabRequestCommon { /// <summary> /// Android device identifier for the user's device. @@ -2537,7 +2539,7 @@ public class LinkAndroidDeviceIDResult : PlayFabResultCommon { } - public class LinkCustomIDRequest + public class LinkCustomIDRequest : PlayFabRequestCommon { /// <summary> /// Custom unique identifier for the user, generated by the title. @@ -2555,7 +2557,7 @@ public class LinkCustomIDResult : PlayFabResultCommon { } - public class LinkFacebookAccountRequest + public class LinkFacebookAccountRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier from Facebook for the user. @@ -2573,7 +2575,7 @@ public class LinkFacebookAccountResult : PlayFabResultCommon { } - public class LinkGameCenterAccountRequest + public class LinkGameCenterAccountRequest : PlayFabRequestCommon { /// <summary> /// Game Center identifier for the player account to be linked. @@ -2591,7 +2593,7 @@ public class LinkGameCenterAccountResult : PlayFabResultCommon { } - public class LinkGoogleAccountRequest + public class LinkGoogleAccountRequest : PlayFabRequestCommon { /// <summary> /// Unique token (https://developers.google.com/android/reference/com/google/android/gms/auth/GoogleAuthUtil#public-methods) from Google Play for the user. @@ -2609,7 +2611,7 @@ public class LinkGoogleAccountResult : PlayFabResultCommon { } - public class LinkIOSDeviceIDRequest + public class LinkIOSDeviceIDRequest : PlayFabRequestCommon { /// <summary> /// Vendor-specific iOS identifier for the user's device. @@ -2637,7 +2639,7 @@ public class LinkIOSDeviceIDResult : PlayFabResultCommon { } - public class LinkKongregateAccountRequest + public class LinkKongregateAccountRequest : PlayFabRequestCommon { /// <summary> /// Numeric user ID assigned by Kongregate @@ -2660,7 +2662,7 @@ public class LinkKongregateAccountResult : PlayFabResultCommon { } - public class LinkSteamAccountRequest + public class LinkSteamAccountRequest : PlayFabRequestCommon { /// <summary> /// Authentication token for the user, returned as a byte array from Steam, and converted to a string (for example, the byte 0x08 should become "08"). @@ -2678,7 +2680,7 @@ public class LinkSteamAccountResult : PlayFabResultCommon { } - public class LinkTwitchAccountRequest + public class LinkTwitchAccountRequest : PlayFabRequestCommon { /// <summary> /// Valid token issued by Twitch @@ -2696,7 +2698,7 @@ public class LinkTwitchAccountResult : PlayFabResultCommon { } - public class ListUsersCharactersRequest + public class ListUsersCharactersRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2748,7 +2750,7 @@ public class LoginResult : PlayFabResultCommon } - public class LoginWithAndroidDeviceIDRequest + public class LoginWithAndroidDeviceIDRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -2782,7 +2784,7 @@ public class LoginWithAndroidDeviceIDRequest } - public class LoginWithCustomIDRequest + public class LoginWithCustomIDRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -2806,7 +2808,7 @@ public class LoginWithCustomIDRequest } - public class LoginWithEmailAddressRequest + public class LoginWithEmailAddressRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -2830,7 +2832,7 @@ public class LoginWithEmailAddressRequest } - public class LoginWithFacebookRequest + public class LoginWithFacebookRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -2854,7 +2856,7 @@ public class LoginWithFacebookRequest } - public class LoginWithGameCenterRequest + public class LoginWithGameCenterRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -2878,7 +2880,7 @@ public class LoginWithGameCenterRequest } - public class LoginWithGoogleAccountRequest + public class LoginWithGoogleAccountRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -2902,7 +2904,7 @@ public class LoginWithGoogleAccountRequest } - public class LoginWithIOSDeviceIDRequest + public class LoginWithIOSDeviceIDRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -2936,7 +2938,7 @@ public class LoginWithIOSDeviceIDRequest } - public class LoginWithKongregateRequest + public class LoginWithKongregateRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -2965,7 +2967,7 @@ public class LoginWithKongregateRequest } - public class LoginWithPlayFabRequest + public class LoginWithPlayFabRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -2989,7 +2991,7 @@ public class LoginWithPlayFabRequest } - public class LoginWithSteamRequest + public class LoginWithSteamRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -3013,7 +3015,7 @@ public class LoginWithSteamRequest } - public class LoginWithTwitchRequest + public class LoginWithTwitchRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -3053,7 +3055,7 @@ public class LogStatement } - public class MatchmakeRequest + public class MatchmakeRequest : PlayFabRequestCommon { /// <summary> /// Build version to match against. [Note: Required if LobbyId is not specified] @@ -3063,7 +3065,6 @@ public class MatchmakeRequest /// <summary> /// Region to match make against. [Note: Required if LobbyId is not specified] /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Region? Region; /// <summary> @@ -3133,7 +3134,6 @@ public class MatchmakeResult : PlayFabResultCommon /// <summary> /// result of match making process /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public MatchmakeStatus? Status; } @@ -3172,7 +3172,7 @@ public class ModifyUserVirtualCurrencyResult : PlayFabResultCommon } - public class OpenTradeRequest + public class OpenTradeRequest : PlayFabRequestCommon { /// <summary> /// Player inventory items offered for trade. If not set, the trade is effectively a gift request @@ -3200,7 +3200,7 @@ public class OpenTradeResponse : PlayFabResultCommon } - public class PayForPurchaseRequest + public class PayForPurchaseRequest : PlayFabRequestCommon { /// <summary> /// Purchase order identifier returned from StartPurchase. @@ -3234,7 +3234,6 @@ public class PayForPurchaseResult : PlayFabResultCommon /// <summary> /// Status of the transaction. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public TransactionStatus? Status; /// <summary> @@ -3361,7 +3360,7 @@ public class PlayerStatisticVersion } - public class PurchaseItemRequest + public class PurchaseItemRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier of the item to purchase. @@ -3404,7 +3403,7 @@ public class PurchaseItemResult : PlayFabResultCommon } - public class RedeemCouponRequest + public class RedeemCouponRequest : PlayFabRequestCommon { /// <summary> /// Generated coupon code to redeem. @@ -3416,6 +3415,11 @@ public class RedeemCouponRequest /// </summary> public string CatalogVersion; + /// <summary> + /// Optional identifier for the Character that should receive the item. If null, item is added to the player + /// </summary> + public string CharacterId; + } public class RedeemCouponResult : PlayFabResultCommon @@ -3444,7 +3448,6 @@ public class RegionInfo /// <summary> /// unique identifier for the region /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Region? Region; /// <summary> @@ -3464,7 +3467,7 @@ public class RegionInfo } - public class RegisterForIOSPushNotificationRequest + public class RegisterForIOSPushNotificationRequest : PlayFabRequestCommon { /// <summary> /// Unique token generated by the Apple Push Notification service when the title registered to receive push notifications. @@ -3487,7 +3490,7 @@ public class RegisterForIOSPushNotificationResult : PlayFabResultCommon { } - public class RegisterPlayFabUserRequest + public class RegisterPlayFabUserRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title, found in the Settings > Game Properties section of the PlayFab developer site when a title has been selected. @@ -3545,7 +3548,7 @@ public class RegisterPlayFabUserResult : PlayFabResultCommon } - public class RemoveFriendRequest + public class RemoveFriendRequest : PlayFabRequestCommon { /// <summary> /// PlayFab identifier of the friend account which is to be removed. @@ -3558,7 +3561,7 @@ public class RemoveFriendResult : PlayFabResultCommon { } - public class RemoveGenericIDRequest + public class RemoveGenericIDRequest : PlayFabRequestCommon { /// <summary> /// Generic service identifier to be removed from the player. @@ -3571,7 +3574,7 @@ public class RemoveGenericIDResult : PlayFabResultCommon { } - public class RemoveSharedGroupMembersRequest + public class RemoveSharedGroupMembersRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group. @@ -3589,7 +3592,7 @@ public class RemoveSharedGroupMembersResult : PlayFabResultCommon { } - public class ReportPlayerClientRequest + public class ReportPlayerClientRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab identifier of the reported player. @@ -3617,7 +3620,7 @@ public class ReportPlayerClientResult : PlayFabResultCommon } - public class RestoreIOSPurchasesRequest + public class RestoreIOSPurchasesRequest : PlayFabRequestCommon { /// <summary> /// Base64 encoded receipt data, passed back by the App Store as a result of a successful purchase. @@ -3649,7 +3652,7 @@ public class ScriptExecutionError } - public class SendAccountRecoveryEmailRequest + public class SendAccountRecoveryEmailRequest : PlayFabRequestCommon { /// <summary> /// User email address attached to their account @@ -3667,7 +3670,7 @@ public class SendAccountRecoveryEmailResult : PlayFabResultCommon { } - public class SetFriendTagsRequest + public class SetFriendTagsRequest : PlayFabRequestCommon { /// <summary> /// PlayFab identifier of the friend account to which the tag(s) should be applied. @@ -3705,7 +3708,6 @@ public class SharedGroupDataRecord /// <summary> /// Indicates whether this data can be read by all users (public) or only members of the group (private). /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -3720,7 +3722,7 @@ public enum SourceType Partner } - public class StartGameRequest + public class StartGameRequest : PlayFabRequestCommon { /// <summary> /// version information for the build of the game server which is to be started @@ -3730,7 +3732,6 @@ public class StartGameRequest /// <summary> /// the region to associate this server with for match filtering /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Region Region; /// <summary> @@ -3789,7 +3790,7 @@ public class StartGameResult : PlayFabResultCommon } - public class StartPurchaseRequest + public class StartPurchaseRequest : PlayFabRequestCommon { /// <summary> /// Catalog version for the items to be purchased. Defaults to most recent catalog. @@ -3959,7 +3960,7 @@ public class StoreMarketingModel } - public class SubtractUserVirtualCurrencyRequest + public class SubtractUserVirtualCurrencyRequest : PlayFabRequestCommon { /// <summary> /// Name of the virtual currency which is to be decremented. @@ -4012,7 +4013,6 @@ public class TradeInfo /// <summary> /// Describes the current state of this trade. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public TradeStatus? Status; /// <summary> @@ -4128,7 +4128,7 @@ public class TwitchPlayFabIdPair } - public class UnlinkAndroidDeviceIDRequest + public class UnlinkAndroidDeviceIDRequest : PlayFabRequestCommon { /// <summary> /// Android device identifier for the user's device. If not specified, the most recently signed in Android Device ID will be used. @@ -4141,7 +4141,7 @@ public class UnlinkAndroidDeviceIDResult : PlayFabResultCommon { } - public class UnlinkCustomIDRequest + public class UnlinkCustomIDRequest : PlayFabRequestCommon { /// <summary> /// Custom unique identifier for the user, generated by the title. If not specified, the most recently signed in Custom ID will be used. @@ -4154,7 +4154,7 @@ public class UnlinkCustomIDResult : PlayFabResultCommon { } - public class UnlinkFacebookAccountRequest + public class UnlinkFacebookAccountRequest : PlayFabRequestCommon { } @@ -4162,7 +4162,7 @@ public class UnlinkFacebookAccountResult : PlayFabResultCommon { } - public class UnlinkGameCenterAccountRequest + public class UnlinkGameCenterAccountRequest : PlayFabRequestCommon { } @@ -4170,7 +4170,7 @@ public class UnlinkGameCenterAccountResult : PlayFabResultCommon { } - public class UnlinkGoogleAccountRequest + public class UnlinkGoogleAccountRequest : PlayFabRequestCommon { } @@ -4178,7 +4178,7 @@ public class UnlinkGoogleAccountResult : PlayFabResultCommon { } - public class UnlinkIOSDeviceIDRequest + public class UnlinkIOSDeviceIDRequest : PlayFabRequestCommon { /// <summary> /// Vendor-specific iOS identifier for the user's device. If not specified, the most recently signed in iOS Device ID will be used. @@ -4191,7 +4191,7 @@ public class UnlinkIOSDeviceIDResult : PlayFabResultCommon { } - public class UnlinkKongregateAccountRequest + public class UnlinkKongregateAccountRequest : PlayFabRequestCommon { } @@ -4199,7 +4199,7 @@ public class UnlinkKongregateAccountResult : PlayFabResultCommon { } - public class UnlinkSteamAccountRequest + public class UnlinkSteamAccountRequest : PlayFabRequestCommon { } @@ -4207,7 +4207,7 @@ public class UnlinkSteamAccountResult : PlayFabResultCommon { } - public class UnlinkTwitchAccountRequest + public class UnlinkTwitchAccountRequest : PlayFabRequestCommon { } @@ -4215,7 +4215,7 @@ public class UnlinkTwitchAccountResult : PlayFabResultCommon { } - public class UnlockContainerInstanceRequest + public class UnlockContainerInstanceRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID for a specific character owned by a user @@ -4239,7 +4239,7 @@ public class UnlockContainerInstanceRequest } - public class UnlockContainerItemRequest + public class UnlockContainerItemRequest : PlayFabRequestCommon { /// <summary> /// Catalog ItemId of the container type to unlock. @@ -4282,7 +4282,7 @@ public class UnlockContainerItemResult : PlayFabResultCommon } - public class UpdateCharacterDataRequest + public class UpdateCharacterDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID for a specific character owned by a user @@ -4302,7 +4302,6 @@ public class UpdateCharacterDataRequest /// <summary> /// Permission to be applied to all user data keys written in this request. Defaults to "private" if not set. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -4316,7 +4315,7 @@ public class UpdateCharacterDataResult : PlayFabResultCommon } - public class UpdateCharacterStatisticsRequest + public class UpdateCharacterStatisticsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID for a specific character owned by a user @@ -4334,7 +4333,7 @@ public class UpdateCharacterStatisticsResult : PlayFabResultCommon { } - public class UpdatePlayerStatisticsRequest + public class UpdatePlayerStatisticsRequest : PlayFabRequestCommon { /// <summary> /// Statistics to be updated with the provided values @@ -4347,7 +4346,7 @@ public class UpdatePlayerStatisticsResult : PlayFabResultCommon { } - public class UpdateSharedGroupDataRequest + public class UpdateSharedGroupDataRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group. @@ -4367,7 +4366,6 @@ public class UpdateSharedGroupDataRequest /// <summary> /// Permission to be applied to all user data keys in this request. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -4376,7 +4374,7 @@ public class UpdateSharedGroupDataResult : PlayFabResultCommon { } - public class UpdateUserDataRequest + public class UpdateUserDataRequest : PlayFabRequestCommon { /// <summary> /// Key-value pairs to be written to the custom data. Note that keys are trimmed of whitespace, are limited in size, and may not begin with a '!' character. @@ -4391,7 +4389,6 @@ public class UpdateUserDataRequest /// <summary> /// Permission to be applied to all user data keys written in this request. Defaults to "private" if not set. This is used for requests by one player for information about another player; those requests will only return Public keys. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -4405,7 +4402,7 @@ public class UpdateUserDataResult : PlayFabResultCommon } - public class UpdateUserTitleDisplayNameRequest + public class UpdateUserTitleDisplayNameRequest : PlayFabRequestCommon { /// <summary> /// New title display name for the user - must be between 3 and 25 characters. @@ -4550,7 +4547,6 @@ public class UserDataRecord /// <summary> /// Indicates whether this data can be read by all users (public) or only the user (private). This is used for GetUserData requests being made by one player about another player. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -4694,13 +4690,11 @@ public class UserSteamInfo /// <summary> /// currency type set in the user Steam account /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Currency? SteamCurrency; /// <summary> /// what stage of game ownership the user is listed as being in, from Steam /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public TitleActivationStatus? SteamActivationStatus; } @@ -4715,7 +4709,6 @@ public class UserTitleInfo /// <summary> /// source by which the user first joined the game, if known /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserOrigination? Origination; /// <summary> @@ -4763,7 +4756,7 @@ public class UserXboxInfo } - public class ValidateAmazonReceiptRequest + public class ValidateAmazonReceiptRequest : PlayFabRequestCommon { /// <summary> /// ReceiptId returned by the Amazon App Store in-app purchase API @@ -4796,7 +4789,7 @@ public class ValidateAmazonReceiptResult : PlayFabResultCommon { } - public class ValidateGooglePlayPurchaseRequest + public class ValidateGooglePlayPurchaseRequest : PlayFabRequestCommon { /// <summary> /// Original JSON string returned by the Google Play IAB API. @@ -4824,7 +4817,7 @@ public class ValidateGooglePlayPurchaseResult : PlayFabResultCommon { } - public class ValidateIOSReceiptRequest + public class ValidateIOSReceiptRequest : PlayFabRequestCommon { /// <summary> /// Base64 encoded receipt data, passed back by the App Store as a result of a successful purchase. @@ -4866,7 +4859,7 @@ public class VirtualCurrencyRechargeTime } - public class WriteClientCharacterEventRequest + public class WriteClientCharacterEventRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID for a specific character owned by a user @@ -4890,7 +4883,7 @@ public class WriteClientCharacterEventRequest } - public class WriteClientPlayerEventRequest + public class WriteClientPlayerEventRequest : PlayFabRequestCommon { /// <summary> /// The name of the event, within the namespace scoped to the title. The naming convention is up to the caller, but it commonly follows the subject_verb_object pattern (e.g. player_logged_in). @@ -4912,13 +4905,13 @@ public class WriteClientPlayerEventRequest public class WriteEventResponse : PlayFabResultCommon { /// <summary> - /// The unique identifier of the event. This can be used to retrieve the event's properties using the GetEvent API. The values of this identifier consist of ASCII characters and are not constrained to any particular format. + /// The unique identifier of the event. The values of this identifier consist of ASCII characters and are not constrained to any particular format. /// </summary> public string EventId; } - public class WriteTitleEventRequest + public class WriteTitleEventRequest : PlayFabRequestCommon { /// <summary> /// The name of the event, within the namespace scoped to the title. The naming convention is up to the caller, but it commonly follows the subject_verb_object pattern (e.g. player_logged_in). diff --git a/PlayFabSDK/source/PlayFabErrors.cs b/PlayFabSDK/source/PlayFabErrors.cs index 20cb9c0d..189cd3ff 100644 --- a/PlayFabSDK/source/PlayFabErrors.cs +++ b/PlayFabSDK/source/PlayFabErrors.cs @@ -1,5 +1,6 @@ using PlayFab.Internal; using System.Collections.Generic; +using System.Text; namespace PlayFab { @@ -259,7 +260,11 @@ public enum PlayFabErrorCode ScheduledTaskCreateConflict = 1255, InvalidScheduledTaskName = 1256, InvalidTaskSchedule = 1257, - SteamNotEnabledForTitle = 1258 + SteamNotEnabledForTitle = 1258, + LimitNotAnUpgradeOption = 1259, + NoSecretKeyEnabledForCloudScript = 1260, + TaskNotFound = 1261, + TaskInstanceNotFound = 1262 } public class PlayFabError @@ -269,12 +274,30 @@ public class PlayFabError public PlayFabErrorCode Error; public string ErrorMessage; public Dictionary<string, string[] > ErrorDetails; + + private static readonly StringBuilder Sb = new StringBuilder(); + public string GenerateErrorReport() + { + Sb.Length = 0; + if (ErrorMessage != null) + Sb.Append(ErrorMessage); + if (ErrorDetails == null) + return Sb.ToString(); + + foreach (var pair in ErrorDetails) + { + foreach (var eachMsg in pair.Value) + Sb.Append(pair.Key).Append(": ").Append(eachMsg); + } + return Sb.ToString(); + } }; public class PlayFabResult<TResult> where TResult : PlayFabResultCommon { public PlayFabError Error; public TResult Result; + public object CustomData; } public delegate void ErrorCallback(PlayFabError error); diff --git a/PlayFabSDK/source/PlayFabFileUtil.cs b/PlayFabSDK/source/PlayFabFileUtil.cs new file mode 100644 index 00000000..598d875f --- /dev/null +++ b/PlayFabSDK/source/PlayFabFileUtil.cs @@ -0,0 +1,71 @@ +#if XAMARIN + +using PlayFab.Json; +using System; +using System.IO; +using System.Text; +using System.Threading.Tasks; + +namespace PlayFab +{ + public static partial class PlayFabUtil + { +#if !NETFX_CORE + [ThreadStatic] + private static StringBuilder _sb; + /// <summary> + /// A threadsafe way to block and load a text file + /// + /// Load a text file, and return the file as text. + /// Used for small (usually json) files. + /// </summary> + public static string ReadAllFileText(string filename) + { + if (!File.Exists(filename)) + return ""; + + if (_sb == null) + _sb = new StringBuilder(); + _sb.Length = 0; + + var fs = new FileStream(filename, FileMode.Open); + var br = new BinaryReader(fs); + while (br.BaseStream.Position != br.BaseStream.Length) + _sb.Append(br.ReadChar()); + + return _sb.ToString(); + } +#else + public static string ReadAllFileText(string filename) + { + var task = ReadAllFileTextAsync(filename); + + var output = ""; + try + { + output = task.Result; + } + catch (AggregateException agEx) + { + foreach (var eachEx in agEx.InnerExceptions) + { + System.Diagnostics.Debug.WriteLine("Each Exception:"); + System.Diagnostics.Debug.WriteLine(eachEx.Message); + } + } + + return output; + } + + public static async Task<string> ReadAllFileTextAsync(string fullpath) + { + var foldername = Path.GetDirectoryName(fullpath); + var filename = Path.GetFileName(fullpath); + var folder = await Windows.Storage.StorageFolder.GetFolderFromPathAsync(foldername); + var file = await folder.GetFileAsync(filename); + return await Windows.Storage.FileIO.ReadTextAsync(file); + } +#endif + } +} +#endif diff --git a/PlayFabSDK/source/PlayFabHttp/IPlayFabHttp.cs b/PlayFabSDK/source/PlayFabHttp/IPlayFabHttp.cs new file mode 100644 index 00000000..a83051f7 --- /dev/null +++ b/PlayFabSDK/source/PlayFabHttp/IPlayFabHttp.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace PlayFab.Internal +{ + public interface IPlayFabHttp + { + Task<object> DoPost(string urlPath, PlayFabRequestCommon request, string authType, string authKey); + } +} diff --git a/PlayFabSDK/source/PlayFabHttp/PlayFabHttp.cs b/PlayFabSDK/source/PlayFabHttp/PlayFabHttp.cs new file mode 100644 index 00000000..b4014a05 --- /dev/null +++ b/PlayFabSDK/source/PlayFabHttp/PlayFabHttp.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace PlayFab.Internal +{ + /// <summary> + /// This is a base-class for all Api-request objects. + /// It is currently unfinished, but we will add result-specific properties, + /// and add template where-conditions to make some code easier to follow + /// </summary> + public class PlayFabRequestCommon + { + } + + /// <summary> + /// This is a base-class for all Api-result objects. + /// It is currently unfinished, but we will add result-specific properties, + /// and add template where-conditions to make some code easier to follow + /// </summary> + public class PlayFabResultCommon + { + } + + public class PlayFabJsonError + { + public int code; + public string status; + public string error; + public int errorCode; + public string errorMessage; + public Dictionary<string, string[]> errorDetails = null; + } + + public class PlayFabJsonSuccess<TResult> where TResult : PlayFabResultCommon + { + public int code; + public string status; + public TResult data; + } + + public static class PlayFabHttp + { + private static IPlayFabHttp _http; + + static PlayFabHttp() + { + var httpInterfaceType = typeof(IPlayFabHttp); + var types = typeof(PlayFabHttp).GetAssembly().GetTypes(); + foreach (var eachType in types) + { + if (httpInterfaceType.IsAssignableFrom(eachType) && !eachType.IsAbstract) + { + _http = (IPlayFabHttp)Activator.CreateInstance(eachType.AsType()); + return; + } + } + throw new Exception("Cannot find a valid IPlayFabHttp type"); + } + + public static async Task<object> DoPost(string urlPath, PlayFabRequestCommon request, string authType, string authKey) + { + if (PlayFabSettings.TitleId == null) + throw new Exception("You must set your titleId before making an api call"); + return await _http.DoPost(urlPath, request, authType, authKey); + } + } +} diff --git a/PlayFabSDK/source/PlayFabHttp/PlayFabSysHttp.cs b/PlayFabSDK/source/PlayFabHttp/PlayFabSysHttp.cs new file mode 100644 index 00000000..6203261d --- /dev/null +++ b/PlayFabSDK/source/PlayFabHttp/PlayFabSysHttp.cs @@ -0,0 +1,107 @@ +#if !NETFX_CORE || !XAMARIN + +using System; +using System.IO; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using PlayFab.Json; + +namespace PlayFab.Internal +{ + public class PlayFabSysHttp : IPlayFabHttp + { + public async Task<object> DoPost(string urlPath, PlayFabRequestCommon request, string authType, string authKey) + { + var fullUrl = PlayFabSettings.GetFullUrl(urlPath); + string bodyString; + + if (request == null) + { + bodyString = "{}"; + } + else + { + bodyString = JsonWrapper.SerializeObject(request); + } + + var client = new HttpClient(); + HttpResponseMessage httpResponse; + string httpResponseString; + using (var postBody = new ByteArrayContent(Encoding.UTF8.GetBytes(bodyString))) + { + postBody.Headers.Add("Content-Type", "application/json"); + if (authType != null) + postBody.Headers.Add(authType, authKey); + postBody.Headers.Add("X-PlayFabSDK", PlayFabSettings.SdkVersionString); + + try + { + httpResponse = await client.PostAsync(fullUrl, postBody); + httpResponseString = await httpResponse.Content.ReadAsStringAsync(); + } + catch (HttpRequestException e) + { + return new PlayFabError + { + Error = PlayFabErrorCode.ConnectionError, + ErrorMessage = e.InnerException.Message + }; + } + catch (Exception e) + { + return new PlayFabError + { + Error = PlayFabErrorCode.ConnectionError, + ErrorMessage = e.Message + }; + } + } + + if (!httpResponse.IsSuccessStatusCode) + { + var error = new PlayFabError(); + + if (string.IsNullOrEmpty(httpResponseString) || httpResponse.StatusCode == System.Net.HttpStatusCode.NotFound) + { + error.HttpCode = (int)httpResponse.StatusCode; + error.HttpStatus = httpResponse.StatusCode.ToString(); + return error; + } + + PlayFabJsonError errorResult; + try + { + errorResult = JsonWrapper.DeserializeObject<PlayFabJsonError>(httpResponseString); + } + catch (Exception e) + { + error.HttpCode = (int)httpResponse.StatusCode; + error.HttpStatus = httpResponse.StatusCode.ToString(); + error.Error = PlayFabErrorCode.JsonParseError; + error.ErrorMessage = e.Message; + return error; + } + + error.HttpCode = errorResult.code; + error.HttpStatus = errorResult.status; + error.Error = (PlayFabErrorCode)errorResult.errorCode; + error.ErrorMessage = errorResult.errorMessage; + error.ErrorDetails = errorResult.errorDetails; + return error; + } + + if (string.IsNullOrEmpty(httpResponseString)) + { + return new PlayFabError + { + Error = PlayFabErrorCode.Unknown, + ErrorMessage = "Internal server error" + }; + } + + return httpResponseString; + } + } +} +#endif diff --git a/PlayFabSDK/source/PlayFabHttp/PlayFabWinHttp.cs b/PlayFabSDK/source/PlayFabHttp/PlayFabWinHttp.cs new file mode 100644 index 00000000..cab057c5 --- /dev/null +++ b/PlayFabSDK/source/PlayFabHttp/PlayFabWinHttp.cs @@ -0,0 +1,96 @@ +#if NETFX_CORE && XAMARIN + +using PlayFab.Json; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Windows.Web.Http; + +namespace PlayFab.Internal +{ + public class PlayFabWinHttp : IPlayFabHttp + { + public async Task<object> DoPost(string urlPath, PlayFabRequestCommon request, string authType, string authKey) + { + var fullUrl = PlayFabSettings.GetFullUrl(urlPath); + string bodyString; + + if (request == null) + { + bodyString = "{}"; + } + else + { + bodyString = JsonWrapper.SerializeObject(request); + } + + var httpClient = new HttpClient(); + var requestMessage = new HttpRequestMessage(HttpMethod.Post, new Uri(fullUrl)); + requestMessage.Content = new HttpStringContent(bodyString, Windows.Storage.Streams.UnicodeEncoding.Utf8, "application/json"); + if (authType != null) + requestMessage.Headers.Add(new KeyValuePair<string, string>(authType, authKey)); + requestMessage.Headers.Add(new KeyValuePair<string, string>("X-PlayFabSDK", PlayFabSettings.SdkVersionString)); + + HttpResponseMessage httpResponse; + string httpResponseString; + try + { + httpResponse = await httpClient.SendRequestAsync(requestMessage); + httpResponseString = await httpResponse.Content.ReadAsStringAsync(); + } + catch (Exception e) + { + return new PlayFabError + { + Error = PlayFabErrorCode.ConnectionError, + ErrorMessage = e.Message + }; + } + + if (!httpResponse.IsSuccessStatusCode) + { + var error = new PlayFabError(); + + if (string.IsNullOrEmpty(httpResponseString) || httpResponse.StatusCode == HttpStatusCode.NotFound) + { + error.HttpCode = (int)httpResponse.StatusCode; + error.HttpStatus = httpResponse.StatusCode.ToString(); + return error; + } + + PlayFabJsonError errorResult; + try + { + errorResult = JsonWrapper.DeserializeObject<PlayFabJsonError>(httpResponseString); + } + catch (Exception e) + { + error.HttpCode = (int)httpResponse.StatusCode; + error.HttpStatus = httpResponse.StatusCode.ToString(); + error.Error = PlayFabErrorCode.JsonParseError; + error.ErrorMessage = e.Message; + return error; + } + + error.HttpCode = errorResult.code; + error.HttpStatus = errorResult.status; + error.Error = (PlayFabErrorCode)errorResult.errorCode; + error.ErrorMessage = errorResult.errorMessage; + error.ErrorDetails = errorResult.errorDetails; + return error; + } + + if (string.IsNullOrEmpty(httpResponseString)) + { + return new PlayFabError + { + Error = PlayFabErrorCode.Unknown, + ErrorMessage = "Internal server error" + }; + } + + return httpResponseString; + } + } +} +#endif diff --git a/PlayFabSDK/source/PlayFabMatchmakerAPI.cs b/PlayFabSDK/source/PlayFabMatchmakerAPI.cs index 1c16e59d..7e2f2d35 100644 --- a/PlayFabSDK/source/PlayFabMatchmakerAPI.cs +++ b/PlayFabSDK/source/PlayFabMatchmakerAPI.cs @@ -1,13 +1,11 @@ -using Newtonsoft.Json; -using PlayFab.Internal; using PlayFab.MatchmakerModels; +using PlayFab.Internal; +using PlayFab.Json; using System; -using System.IO; using System.Threading.Tasks; namespace PlayFab { - /// <summary> /// Enables the use of an external match-making service in conjunction with PlayFab hosted Game Server instances /// </summary> @@ -16,126 +14,116 @@ public class PlayFabMatchmakerAPI /// <summary> /// Validates a user with the PlayFab service /// </summary> - public static async Task<PlayFabResult<AuthUserResponse>> AuthUserAsync(AuthUserRequest request) + public static async Task<PlayFabResult<AuthUserResponse>> AuthUserAsync(AuthUserRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Matchmaker/AuthUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Matchmaker/AuthUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AuthUserResponse> { Error = error, }; + return new PlayFabResult<AuthUserResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AuthUserResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - AuthUserResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AuthUserResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AuthUserResponse> { Result = result }; + return new PlayFabResult<AuthUserResponse> { Result = result, CustomData = customData }; } /// <summary> /// Informs the PlayFab game server hosting service that the indicated user has joined the Game Server Instance specified /// </summary> - public static async Task<PlayFabResult<PlayerJoinedResponse>> PlayerJoinedAsync(PlayerJoinedRequest request) + public static async Task<PlayFabResult<PlayerJoinedResponse>> PlayerJoinedAsync(PlayerJoinedRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Matchmaker/PlayerJoined", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Matchmaker/PlayerJoined", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<PlayerJoinedResponse> { Error = error, }; + return new PlayFabResult<PlayerJoinedResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<PlayerJoinedResponse>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<PlayerJoinedResponse>>(resultRawJson); + var result = resultData.data; - PlayerJoinedResponse result = resultData.data; - - return new PlayFabResult<PlayerJoinedResponse> { Result = result }; + return new PlayFabResult<PlayerJoinedResponse> { Result = result, CustomData = customData }; } /// <summary> /// Informs the PlayFab game server hosting service that the indicated user has left the Game Server Instance specified /// </summary> - public static async Task<PlayFabResult<PlayerLeftResponse>> PlayerLeftAsync(PlayerLeftRequest request) + public static async Task<PlayFabResult<PlayerLeftResponse>> PlayerLeftAsync(PlayerLeftRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Matchmaker/PlayerLeft", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Matchmaker/PlayerLeft", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<PlayerLeftResponse> { Error = error, }; + return new PlayFabResult<PlayerLeftResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<PlayerLeftResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - PlayerLeftResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<PlayerLeftResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<PlayerLeftResponse> { Result = result }; + return new PlayFabResult<PlayerLeftResponse> { Result = result, CustomData = customData }; } /// <summary> /// Instructs the PlayFab game server hosting service to instantiate a new Game Server Instance /// </summary> - public static async Task<PlayFabResult<StartGameResponse>> StartGameAsync(StartGameRequest request) + public static async Task<PlayFabResult<StartGameResponse>> StartGameAsync(StartGameRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Matchmaker/StartGame", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Matchmaker/StartGame", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<StartGameResponse> { Error = error, }; + return new PlayFabResult<StartGameResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<StartGameResponse>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<StartGameResponse>>(resultRawJson); + var result = resultData.data; - StartGameResponse result = resultData.data; - - return new PlayFabResult<StartGameResponse> { Result = result }; + return new PlayFabResult<StartGameResponse> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the relevant details for a specified user, which the external match-making service can then use to compute effective matches /// </summary> - public static async Task<PlayFabResult<UserInfoResponse>> UserInfoAsync(UserInfoRequest request) + public static async Task<PlayFabResult<UserInfoResponse>> UserInfoAsync(UserInfoRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Matchmaker/UserInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Matchmaker/UserInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UserInfoResponse> { Error = error, }; + return new PlayFabResult<UserInfoResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UserInfoResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - UserInfoResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UserInfoResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UserInfoResponse> { Result = result }; + return new PlayFabResult<UserInfoResponse> { Result = result, CustomData = customData }; } } diff --git a/PlayFabSDK/source/PlayFabMatchmakerModels.cs b/PlayFabSDK/source/PlayFabMatchmakerModels.cs index b00aa4f2..23c49f14 100644 --- a/PlayFabSDK/source/PlayFabMatchmakerModels.cs +++ b/PlayFabSDK/source/PlayFabMatchmakerModels.cs @@ -1,12 +1,10 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; using PlayFab.Internal; using System; using System.Collections.Generic; namespace PlayFab.MatchmakerModels { - public class AuthUserRequest + public class AuthUserRequest : PlayFabRequestCommon { /// <summary> /// Session Ticket provided by the client. @@ -29,7 +27,7 @@ public class AuthUserResponse : PlayFabResultCommon } - public class DeregisterGameRequest + public class DeregisterGameRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the Game Server Instance that is being deregistered. @@ -131,7 +129,7 @@ public int CompareTo(ItemInstance other) } - public class PlayerJoinedRequest + public class PlayerJoinedRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier of the Game Server Instance the user is joining. @@ -149,7 +147,7 @@ public class PlayerJoinedResponse : PlayFabResultCommon { } - public class PlayerLeftRequest + public class PlayerLeftRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier of the Game Server Instance the user is leaving. @@ -179,7 +177,7 @@ public enum Region Australia } - public class RegisterGameRequest + public class RegisterGameRequest : PlayFabRequestCommon { /// <summary> /// IP address of the Game Server Instance. @@ -199,7 +197,6 @@ public class RegisterGameRequest /// <summary> /// Region in which the Game Server Instance is running. For matchmaking using non-AWS region names, set this to any AWS region and use Tags (below) to specify your custom region. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Region Region; /// <summary> @@ -223,7 +220,7 @@ public class RegisterGameResponse : PlayFabResultCommon } - public class StartGameRequest + public class StartGameRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier of the previously uploaded build executable which is to be started. @@ -233,7 +230,6 @@ public class StartGameRequest /// <summary> /// Region with which to associate the server, for filtering. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Region Region; /// <summary> @@ -272,7 +268,7 @@ public class StartGameResponse : PlayFabResultCommon } - public class UserInfoRequest + public class UserInfoRequest : PlayFabRequestCommon { /// <summary> /// PlayFab unique identifier of the user whose information is being requested. diff --git a/PlayFabSDK/source/PlayFabServerAPI.cs b/PlayFabSDK/source/PlayFabServerAPI.cs index 50fbabe8..e2edbcc5 100644 --- a/PlayFabSDK/source/PlayFabServerAPI.cs +++ b/PlayFabSDK/source/PlayFabServerAPI.cs @@ -1,13 +1,11 @@ -using Newtonsoft.Json; -using PlayFab.Internal; using PlayFab.ServerModels; +using PlayFab.Internal; +using PlayFab.Json; using System; -using System.IO; using System.Threading.Tasks; namespace PlayFab { - /// <summary> /// Provides functionality to allow external (developer-controlled) servers to interact with user inventories and data in a trusted manner, and to handle matchmaking and client connection orchestration /// </summary> @@ -16,2626 +14,2416 @@ public class PlayFabServerAPI /// <summary> /// Validated a client's session ticket, and if successful, returns details for that user /// </summary> - public static async Task<PlayFabResult<AuthenticateSessionTicketResult>> AuthenticateSessionTicketAsync(AuthenticateSessionTicketRequest request) + public static async Task<PlayFabResult<AuthenticateSessionTicketResult>> AuthenticateSessionTicketAsync(AuthenticateSessionTicketRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/AuthenticateSessionTicket", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/AuthenticateSessionTicket", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AuthenticateSessionTicketResult> { Error = error, }; + return new PlayFabResult<AuthenticateSessionTicketResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AuthenticateSessionTicketResult>>(new JsonTextReader(new StringReader(resultRawJson))); - AuthenticateSessionTicketResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AuthenticateSessionTicketResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AuthenticateSessionTicketResult> { Result = result }; + return new PlayFabResult<AuthenticateSessionTicketResult> { Result = result, CustomData = customData }; } /// <summary> /// Bans users by PlayFab ID with optional IP address, or MAC address for the provided game. /// </summary> - public static async Task<PlayFabResult<BanUsersResult>> BanUsersAsync(BanUsersRequest request) + public static async Task<PlayFabResult<BanUsersResult>> BanUsersAsync(BanUsersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/BanUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/BanUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<BanUsersResult> { Error = error, }; + return new PlayFabResult<BanUsersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<BanUsersResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<BanUsersResult>>(resultRawJson); + var result = resultData.data; - BanUsersResult result = resultData.data; - - return new PlayFabResult<BanUsersResult> { Result = result }; + return new PlayFabResult<BanUsersResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the unique PlayFab identifiers for the given set of Facebook identifiers. /// </summary> - public static async Task<PlayFabResult<GetPlayFabIDsFromFacebookIDsResult>> GetPlayFabIDsFromFacebookIDsAsync(GetPlayFabIDsFromFacebookIDsRequest request) + public static async Task<PlayFabResult<GetPlayFabIDsFromFacebookIDsResult>> GetPlayFabIDsFromFacebookIDsAsync(GetPlayFabIDsFromFacebookIDsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetPlayFabIDsFromFacebookIDs", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetPlayFabIDsFromFacebookIDs", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayFabIDsFromFacebookIDsResult> { Error = error, }; + return new PlayFabResult<GetPlayFabIDsFromFacebookIDsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayFabIDsFromFacebookIDsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayFabIDsFromFacebookIDsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayFabIDsFromFacebookIDsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayFabIDsFromFacebookIDsResult> { Result = result }; + return new PlayFabResult<GetPlayFabIDsFromFacebookIDsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the unique PlayFab identifiers for the given set of Steam identifiers. The Steam identifiers are the profile IDs for the user accounts, available as SteamId in the Steamworks Community API calls. /// </summary> - public static async Task<PlayFabResult<GetPlayFabIDsFromSteamIDsResult>> GetPlayFabIDsFromSteamIDsAsync(GetPlayFabIDsFromSteamIDsRequest request) + public static async Task<PlayFabResult<GetPlayFabIDsFromSteamIDsResult>> GetPlayFabIDsFromSteamIDsAsync(GetPlayFabIDsFromSteamIDsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetPlayFabIDsFromSteamIDs", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetPlayFabIDsFromSteamIDs", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayFabIDsFromSteamIDsResult> { Error = error, }; + return new PlayFabResult<GetPlayFabIDsFromSteamIDsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayFabIDsFromSteamIDsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayFabIDsFromSteamIDsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayFabIDsFromSteamIDsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayFabIDsFromSteamIDsResult> { Result = result }; + return new PlayFabResult<GetPlayFabIDsFromSteamIDsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the relevant details for a specified user /// </summary> - public static async Task<PlayFabResult<GetUserAccountInfoResult>> GetUserAccountInfoAsync(GetUserAccountInfoRequest request) + public static async Task<PlayFabResult<GetUserAccountInfoResult>> GetUserAccountInfoAsync(GetUserAccountInfoRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetUserAccountInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetUserAccountInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserAccountInfoResult> { Error = error, }; + return new PlayFabResult<GetUserAccountInfoResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserAccountInfoResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserAccountInfoResult>>(resultRawJson); + var result = resultData.data; - GetUserAccountInfoResult result = resultData.data; - - return new PlayFabResult<GetUserAccountInfoResult> { Result = result }; + return new PlayFabResult<GetUserAccountInfoResult> { Result = result, CustomData = customData }; } /// <summary> /// Gets all bans for a user. /// </summary> - public static async Task<PlayFabResult<GetUserBansResult>> GetUserBansAsync(GetUserBansRequest request) + public static async Task<PlayFabResult<GetUserBansResult>> GetUserBansAsync(GetUserBansRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetUserBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetUserBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserBansResult> { Error = error, }; + return new PlayFabResult<GetUserBansResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserBansResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserBansResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserBansResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserBansResult> { Result = result }; + return new PlayFabResult<GetUserBansResult> { Result = result, CustomData = customData }; } /// <summary> /// Revoke all active bans for a user. /// </summary> - public static async Task<PlayFabResult<RevokeAllBansForUserResult>> RevokeAllBansForUserAsync(RevokeAllBansForUserRequest request) + public static async Task<PlayFabResult<RevokeAllBansForUserResult>> RevokeAllBansForUserAsync(RevokeAllBansForUserRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RevokeAllBansForUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RevokeAllBansForUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RevokeAllBansForUserResult> { Error = error, }; + return new PlayFabResult<RevokeAllBansForUserResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RevokeAllBansForUserResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RevokeAllBansForUserResult>>(resultRawJson); + var result = resultData.data; - RevokeAllBansForUserResult result = resultData.data; - - return new PlayFabResult<RevokeAllBansForUserResult> { Result = result }; + return new PlayFabResult<RevokeAllBansForUserResult> { Result = result, CustomData = customData }; } /// <summary> /// Revoke all active bans specified with BanId. /// </summary> - public static async Task<PlayFabResult<RevokeBansResult>> RevokeBansAsync(RevokeBansRequest request) + public static async Task<PlayFabResult<RevokeBansResult>> RevokeBansAsync(RevokeBansRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RevokeBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RevokeBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RevokeBansResult> { Error = error, }; + return new PlayFabResult<RevokeBansResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RevokeBansResult>>(new JsonTextReader(new StringReader(resultRawJson))); - RevokeBansResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RevokeBansResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RevokeBansResult> { Result = result }; + return new PlayFabResult<RevokeBansResult> { Result = result, CustomData = customData }; } /// <summary> /// Sends an iOS/Android Push Notification to a specific user, if that user's device has been configured for Push Notifications in PlayFab. If a user has linked both Android and iOS devices, both will be notified. /// </summary> - public static async Task<PlayFabResult<SendPushNotificationResult>> SendPushNotificationAsync(SendPushNotificationRequest request) + public static async Task<PlayFabResult<SendPushNotificationResult>> SendPushNotificationAsync(SendPushNotificationRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/SendPushNotification", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/SendPushNotification", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SendPushNotificationResult> { Error = error, }; + return new PlayFabResult<SendPushNotificationResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SendPushNotificationResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SendPushNotificationResult>>(resultRawJson); + var result = resultData.data; - SendPushNotificationResult result = resultData.data; - - return new PlayFabResult<SendPushNotificationResult> { Result = result }; + return new PlayFabResult<SendPushNotificationResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates information of a list of existing bans specified with Ban Ids. /// </summary> - public static async Task<PlayFabResult<UpdateBansResult>> UpdateBansAsync(UpdateBansRequest request) + public static async Task<PlayFabResult<UpdateBansResult>> UpdateBansAsync(UpdateBansRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateBansResult> { Error = error, }; + return new PlayFabResult<UpdateBansResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateBansResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateBansResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateBansResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateBansResult> { Result = result }; + return new PlayFabResult<UpdateBansResult> { Result = result, CustomData = customData }; } /// <summary> /// Deletes the users for the provided game. Deletes custom data, all account linkages, and statistics. /// </summary> - public static async Task<PlayFabResult<DeleteUsersResult>> DeleteUsersAsync(DeleteUsersRequest request) + public static async Task<PlayFabResult<DeleteUsersResult>> DeleteUsersAsync(DeleteUsersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/DeleteUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/DeleteUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<DeleteUsersResult> { Error = error, }; + return new PlayFabResult<DeleteUsersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<DeleteUsersResult>>(new JsonTextReader(new StringReader(resultRawJson))); - DeleteUsersResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<DeleteUsersResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<DeleteUsersResult> { Result = result }; + return new PlayFabResult<DeleteUsersResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked friends of the given player for the given statistic, starting from the indicated point in the leaderboard /// </summary> - public static async Task<PlayFabResult<GetLeaderboardResult>> GetFriendLeaderboardAsync(GetFriendLeaderboardRequest request) + public static async Task<PlayFabResult<GetLeaderboardResult>> GetFriendLeaderboardAsync(GetFriendLeaderboardRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetFriendLeaderboard", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetFriendLeaderboard", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardResult>>(resultRawJson); + var result = resultData.data; - GetLeaderboardResult result = resultData.data; - - return new PlayFabResult<GetLeaderboardResult> { Result = result }; + return new PlayFabResult<GetLeaderboardResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked users for the given statistic, starting from the indicated point in the leaderboard /// </summary> - public static async Task<PlayFabResult<GetLeaderboardResult>> GetLeaderboardAsync(GetLeaderboardRequest request) + public static async Task<PlayFabResult<GetLeaderboardResult>> GetLeaderboardAsync(GetLeaderboardRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetLeaderboard", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetLeaderboard", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetLeaderboardResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetLeaderboardResult> { Result = result }; + return new PlayFabResult<GetLeaderboardResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked users for the given statistic, centered on the currently signed-in user /// </summary> - public static async Task<PlayFabResult<GetLeaderboardAroundUserResult>> GetLeaderboardAroundUserAsync(GetLeaderboardAroundUserRequest request) + public static async Task<PlayFabResult<GetLeaderboardAroundUserResult>> GetLeaderboardAroundUserAsync(GetLeaderboardAroundUserRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetLeaderboardAroundUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetLeaderboardAroundUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardAroundUserResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardAroundUserResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardAroundUserResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardAroundUserResult>>(resultRawJson); + var result = resultData.data; - GetLeaderboardAroundUserResult result = resultData.data; - - return new PlayFabResult<GetLeaderboardAroundUserResult> { Result = result }; + return new PlayFabResult<GetLeaderboardAroundUserResult> { Result = result, CustomData = customData }; } /// <summary> /// Returns whatever info is requested in the response for the user. Note that PII (like email address, facebook id) may be returned. All parameters default to false. /// </summary> - public static async Task<PlayFabResult<GetPlayerCombinedInfoResult>> GetPlayerCombinedInfoAsync(GetPlayerCombinedInfoRequest request) + public static async Task<PlayFabResult<GetPlayerCombinedInfoResult>> GetPlayerCombinedInfoAsync(GetPlayerCombinedInfoRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetPlayerCombinedInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetPlayerCombinedInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerCombinedInfoResult> { Error = error, }; + return new PlayFabResult<GetPlayerCombinedInfoResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerCombinedInfoResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerCombinedInfoResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerCombinedInfoResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerCombinedInfoResult> { Result = result }; + return new PlayFabResult<GetPlayerCombinedInfoResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the current version and values for the indicated statistics, for the local player. /// </summary> - public static async Task<PlayFabResult<GetPlayerStatisticsResult>> GetPlayerStatisticsAsync(GetPlayerStatisticsRequest request) + public static async Task<PlayFabResult<GetPlayerStatisticsResult>> GetPlayerStatisticsAsync(GetPlayerStatisticsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetPlayerStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetPlayerStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerStatisticsResult> { Error = error, }; + return new PlayFabResult<GetPlayerStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerStatisticsResult>>(resultRawJson); + var result = resultData.data; - GetPlayerStatisticsResult result = resultData.data; - - return new PlayFabResult<GetPlayerStatisticsResult> { Result = result }; + return new PlayFabResult<GetPlayerStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the information on the available versions of the specified statistic. /// </summary> - public static async Task<PlayFabResult<GetPlayerStatisticVersionsResult>> GetPlayerStatisticVersionsAsync(GetPlayerStatisticVersionsRequest request) + public static async Task<PlayFabResult<GetPlayerStatisticVersionsResult>> GetPlayerStatisticVersionsAsync(GetPlayerStatisticVersionsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetPlayerStatisticVersions", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetPlayerStatisticVersions", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerStatisticVersionsResult> { Error = error, }; + return new PlayFabResult<GetPlayerStatisticVersionsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerStatisticVersionsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerStatisticVersionsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerStatisticVersionsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerStatisticVersionsResult> { Result = result }; + return new PlayFabResult<GetPlayerStatisticVersionsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetUserData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetUserData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserInternalDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserInternalDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetUserInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetUserInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - GetUserDataResult result = resultData.data; - - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the publisher-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetUserPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetUserPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the publisher-specific custom data for the user which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherInternalDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherInternalDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetUserPublisherInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetUserPublisherInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the publisher-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherReadOnlyDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherReadOnlyDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetUserPublisherReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetUserPublisherReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - GetUserDataResult result = resultData.data; - - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserReadOnlyDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserReadOnlyDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetUserReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetUserReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the values of the specified title-specific statistics for the user /// </summary> - public static async Task<PlayFabResult<UpdatePlayerStatisticsResult>> UpdatePlayerStatisticsAsync(UpdatePlayerStatisticsRequest request) + public static async Task<PlayFabResult<UpdatePlayerStatisticsResult>> UpdatePlayerStatisticsAsync(UpdatePlayerStatisticsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdatePlayerStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdatePlayerStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdatePlayerStatisticsResult> { Error = error, }; + return new PlayFabResult<UpdatePlayerStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdatePlayerStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdatePlayerStatisticsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdatePlayerStatisticsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdatePlayerStatisticsResult> { Result = result }; + return new PlayFabResult<UpdatePlayerStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserDataAsync(UpdateUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateUserData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateUserData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - UpdateUserDataResult result = resultData.data; - - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title-specific custom data for the user which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserInternalDataAsync(UpdateUserInternalDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserInternalDataAsync(UpdateUserInternalDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateUserInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateUserInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the publisher-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherDataAsync(UpdateUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateUserPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateUserPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - UpdateUserDataResult result = resultData.data; - - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the publisher-specific custom data for the user which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherInternalDataAsync(UpdateUserInternalDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherInternalDataAsync(UpdateUserInternalDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateUserPublisherInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateUserPublisherInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the publisher-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherReadOnlyDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherReadOnlyDataAsync(UpdateUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateUserPublisherReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateUserPublisherReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - UpdateUserDataResult result = resultData.data; - - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserReadOnlyDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserReadOnlyDataAsync(UpdateUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateUserReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateUserReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the specified version of the title's catalog of virtual goods, including all defined properties /// </summary> - public static async Task<PlayFabResult<GetCatalogItemsResult>> GetCatalogItemsAsync(GetCatalogItemsRequest request) + public static async Task<PlayFabResult<GetCatalogItemsResult>> GetCatalogItemsAsync(GetCatalogItemsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetCatalogItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetCatalogItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCatalogItemsResult> { Error = error, }; + return new PlayFabResult<GetCatalogItemsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCatalogItemsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetCatalogItemsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCatalogItemsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetCatalogItemsResult> { Result = result }; + return new PlayFabResult<GetCatalogItemsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the key-value store of custom publisher settings /// </summary> - public static async Task<PlayFabResult<GetPublisherDataResult>> GetPublisherDataAsync(GetPublisherDataRequest request) + public static async Task<PlayFabResult<GetPublisherDataResult>> GetPublisherDataAsync(GetPublisherDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPublisherDataResult> { Error = error, }; + return new PlayFabResult<GetPublisherDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPublisherDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPublisherDataResult>>(resultRawJson); + var result = resultData.data; - GetPublisherDataResult result = resultData.data; - - return new PlayFabResult<GetPublisherDataResult> { Result = result }; + return new PlayFabResult<GetPublisherDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the current server time /// </summary> - public static async Task<PlayFabResult<GetTimeResult>> GetTimeAsync(GetTimeRequest request) + public static async Task<PlayFabResult<GetTimeResult>> GetTimeAsync(GetTimeRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetTime", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetTime", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTimeResult> { Error = error, }; + return new PlayFabResult<GetTimeResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTimeResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetTimeResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTimeResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetTimeResult> { Result = result }; + return new PlayFabResult<GetTimeResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the key-value store of custom title settings /// </summary> - public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleDataAsync(GetTitleDataRequest request) + public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleDataAsync(GetTitleDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetTitleData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetTitleData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTitleDataResult> { Error = error, }; + return new PlayFabResult<GetTitleDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTitleDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTitleDataResult>>(resultRawJson); + var result = resultData.data; - GetTitleDataResult result = resultData.data; - - return new PlayFabResult<GetTitleDataResult> { Result = result }; + return new PlayFabResult<GetTitleDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the key-value store of custom internal title settings /// </summary> - public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleInternalDataAsync(GetTitleDataRequest request) + public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleInternalDataAsync(GetTitleDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetTitleInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetTitleInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTitleDataResult> { Error = error, }; + return new PlayFabResult<GetTitleDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTitleDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetTitleDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTitleDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetTitleDataResult> { Result = result }; + return new PlayFabResult<GetTitleDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title news feed, as configured in the developer portal /// </summary> - public static async Task<PlayFabResult<GetTitleNewsResult>> GetTitleNewsAsync(GetTitleNewsRequest request) + public static async Task<PlayFabResult<GetTitleNewsResult>> GetTitleNewsAsync(GetTitleNewsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetTitleNews", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetTitleNews", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTitleNewsResult> { Error = error, }; + return new PlayFabResult<GetTitleNewsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTitleNewsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTitleNewsResult>>(resultRawJson); + var result = resultData.data; - GetTitleNewsResult result = resultData.data; - - return new PlayFabResult<GetTitleNewsResult> { Result = result }; + return new PlayFabResult<GetTitleNewsResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the key-value store of custom publisher settings /// </summary> - public static async Task<PlayFabResult<SetPublisherDataResult>> SetPublisherDataAsync(SetPublisherDataRequest request) + public static async Task<PlayFabResult<SetPublisherDataResult>> SetPublisherDataAsync(SetPublisherDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/SetPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/SetPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetPublisherDataResult> { Error = error, }; + return new PlayFabResult<SetPublisherDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetPublisherDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - SetPublisherDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetPublisherDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<SetPublisherDataResult> { Result = result }; + return new PlayFabResult<SetPublisherDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the key-value store of custom title settings /// </summary> - public static async Task<PlayFabResult<SetTitleDataResult>> SetTitleDataAsync(SetTitleDataRequest request) + public static async Task<PlayFabResult<SetTitleDataResult>> SetTitleDataAsync(SetTitleDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/SetTitleData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/SetTitleData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetTitleDataResult> { Error = error, }; + return new PlayFabResult<SetTitleDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetTitleDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - SetTitleDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetTitleDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<SetTitleDataResult> { Result = result }; + return new PlayFabResult<SetTitleDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the key-value store of custom title settings /// </summary> - public static async Task<PlayFabResult<SetTitleDataResult>> SetTitleInternalDataAsync(SetTitleDataRequest request) + public static async Task<PlayFabResult<SetTitleDataResult>> SetTitleInternalDataAsync(SetTitleDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/SetTitleInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/SetTitleInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetTitleDataResult> { Error = error, }; + return new PlayFabResult<SetTitleDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetTitleDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetTitleDataResult>>(resultRawJson); + var result = resultData.data; - SetTitleDataResult result = resultData.data; - - return new PlayFabResult<SetTitleDataResult> { Result = result }; + return new PlayFabResult<SetTitleDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Increments the character's balance of the specified virtual currency by the stated amount /// </summary> - public static async Task<PlayFabResult<ModifyCharacterVirtualCurrencyResult>> AddCharacterVirtualCurrencyAsync(AddCharacterVirtualCurrencyRequest request) + public static async Task<PlayFabResult<ModifyCharacterVirtualCurrencyResult>> AddCharacterVirtualCurrencyAsync(AddCharacterVirtualCurrencyRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/AddCharacterVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/AddCharacterVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyCharacterVirtualCurrencyResult> { Error = error, }; + return new PlayFabResult<ModifyCharacterVirtualCurrencyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyCharacterVirtualCurrencyResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ModifyCharacterVirtualCurrencyResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyCharacterVirtualCurrencyResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ModifyCharacterVirtualCurrencyResult> { Result = result }; + return new PlayFabResult<ModifyCharacterVirtualCurrencyResult> { Result = result, CustomData = customData }; } /// <summary> /// Increments the user's balance of the specified virtual currency by the stated amount /// </summary> - public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> AddUserVirtualCurrencyAsync(AddUserVirtualCurrencyRequest request) + public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> AddUserVirtualCurrencyAsync(AddUserVirtualCurrencyRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/AddUserVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/AddUserVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(resultRawJson); + var result = resultData.data; - ModifyUserVirtualCurrencyResult result = resultData.data; - - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result, CustomData = customData }; } /// <summary> /// Consume uses of a consumable item. When all uses are consumed, it will be removed from the player's inventory. /// </summary> - public static async Task<PlayFabResult<ConsumeItemResult>> ConsumeItemAsync(ConsumeItemRequest request) + public static async Task<PlayFabResult<ConsumeItemResult>> ConsumeItemAsync(ConsumeItemRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/ConsumeItem", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/ConsumeItem", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ConsumeItemResult> { Error = error, }; + return new PlayFabResult<ConsumeItemResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ConsumeItemResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ConsumeItemResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ConsumeItemResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ConsumeItemResult> { Result = result }; + return new PlayFabResult<ConsumeItemResult> { Result = result, CustomData = customData }; } /// <summary> /// Returns the result of an evaluation of a Random Result Table - the ItemId from the game Catalog which would have been added to the player inventory, if the Random Result Table were added via a Bundle or a call to UnlockContainer. /// </summary> - public static async Task<PlayFabResult<EvaluateRandomResultTableResult>> EvaluateRandomResultTableAsync(EvaluateRandomResultTableRequest request) + public static async Task<PlayFabResult<EvaluateRandomResultTableResult>> EvaluateRandomResultTableAsync(EvaluateRandomResultTableRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/EvaluateRandomResultTable", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/EvaluateRandomResultTable", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<EvaluateRandomResultTableResult> { Error = error, }; + return new PlayFabResult<EvaluateRandomResultTableResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<EvaluateRandomResultTableResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<EvaluateRandomResultTableResult>>(resultRawJson); + var result = resultData.data; - EvaluateRandomResultTableResult result = resultData.data; - - return new PlayFabResult<EvaluateRandomResultTableResult> { Result = result }; + return new PlayFabResult<EvaluateRandomResultTableResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the specified character's current inventory of virtual goods /// </summary> - public static async Task<PlayFabResult<GetCharacterInventoryResult>> GetCharacterInventoryAsync(GetCharacterInventoryRequest request) + public static async Task<PlayFabResult<GetCharacterInventoryResult>> GetCharacterInventoryAsync(GetCharacterInventoryRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetCharacterInventory", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetCharacterInventory", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterInventoryResult> { Error = error, }; + return new PlayFabResult<GetCharacterInventoryResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterInventoryResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetCharacterInventoryResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterInventoryResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetCharacterInventoryResult> { Result = result }; + return new PlayFabResult<GetCharacterInventoryResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the configuration information for the specified random results tables for the title, including all ItemId values and weights /// </summary> - public static async Task<PlayFabResult<GetRandomResultTablesResult>> GetRandomResultTablesAsync(GetRandomResultTablesRequest request) + public static async Task<PlayFabResult<GetRandomResultTablesResult>> GetRandomResultTablesAsync(GetRandomResultTablesRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetRandomResultTables", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetRandomResultTables", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetRandomResultTablesResult> { Error = error, }; + return new PlayFabResult<GetRandomResultTablesResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetRandomResultTablesResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetRandomResultTablesResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetRandomResultTablesResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetRandomResultTablesResult> { Result = result }; + return new PlayFabResult<GetRandomResultTablesResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the specified user's current inventory of virtual goods /// </summary> - public static async Task<PlayFabResult<GetUserInventoryResult>> GetUserInventoryAsync(GetUserInventoryRequest request) + public static async Task<PlayFabResult<GetUserInventoryResult>> GetUserInventoryAsync(GetUserInventoryRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetUserInventory", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetUserInventory", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserInventoryResult> { Error = error, }; + return new PlayFabResult<GetUserInventoryResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserInventoryResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserInventoryResult>>(resultRawJson); + var result = resultData.data; - GetUserInventoryResult result = resultData.data; - - return new PlayFabResult<GetUserInventoryResult> { Result = result }; + return new PlayFabResult<GetUserInventoryResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the specified items to the specified character's inventory /// </summary> - public static async Task<PlayFabResult<GrantItemsToCharacterResult>> GrantItemsToCharacterAsync(GrantItemsToCharacterRequest request) + public static async Task<PlayFabResult<GrantItemsToCharacterResult>> GrantItemsToCharacterAsync(GrantItemsToCharacterRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GrantItemsToCharacter", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GrantItemsToCharacter", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GrantItemsToCharacterResult> { Error = error, }; + return new PlayFabResult<GrantItemsToCharacterResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GrantItemsToCharacterResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GrantItemsToCharacterResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GrantItemsToCharacterResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GrantItemsToCharacterResult> { Result = result }; + return new PlayFabResult<GrantItemsToCharacterResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the specified items to the specified user's inventory /// </summary> - public static async Task<PlayFabResult<GrantItemsToUserResult>> GrantItemsToUserAsync(GrantItemsToUserRequest request) + public static async Task<PlayFabResult<GrantItemsToUserResult>> GrantItemsToUserAsync(GrantItemsToUserRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GrantItemsToUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GrantItemsToUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GrantItemsToUserResult> { Error = error, }; + return new PlayFabResult<GrantItemsToUserResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GrantItemsToUserResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GrantItemsToUserResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GrantItemsToUserResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GrantItemsToUserResult> { Result = result }; + return new PlayFabResult<GrantItemsToUserResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the specified items to the specified user inventories /// </summary> - public static async Task<PlayFabResult<GrantItemsToUsersResult>> GrantItemsToUsersAsync(GrantItemsToUsersRequest request) + public static async Task<PlayFabResult<GrantItemsToUsersResult>> GrantItemsToUsersAsync(GrantItemsToUsersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GrantItemsToUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GrantItemsToUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GrantItemsToUsersResult> { Error = error, }; + return new PlayFabResult<GrantItemsToUsersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GrantItemsToUsersResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GrantItemsToUsersResult>>(resultRawJson); + var result = resultData.data; - GrantItemsToUsersResult result = resultData.data; - - return new PlayFabResult<GrantItemsToUsersResult> { Result = result }; + return new PlayFabResult<GrantItemsToUsersResult> { Result = result, CustomData = customData }; } /// <summary> /// Modifies the number of remaining uses of a player's inventory item /// </summary> - public static async Task<PlayFabResult<ModifyItemUsesResult>> ModifyItemUsesAsync(ModifyItemUsesRequest request) + public static async Task<PlayFabResult<ModifyItemUsesResult>> ModifyItemUsesAsync(ModifyItemUsesRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/ModifyItemUses", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/ModifyItemUses", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyItemUsesResult> { Error = error, }; + return new PlayFabResult<ModifyItemUsesResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyItemUsesResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ModifyItemUsesResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyItemUsesResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ModifyItemUsesResult> { Result = result }; + return new PlayFabResult<ModifyItemUsesResult> { Result = result, CustomData = customData }; } /// <summary> /// Moves an item from a character's inventory into another of the users's character's inventory. /// </summary> - public static async Task<PlayFabResult<MoveItemToCharacterFromCharacterResult>> MoveItemToCharacterFromCharacterAsync(MoveItemToCharacterFromCharacterRequest request) + public static async Task<PlayFabResult<MoveItemToCharacterFromCharacterResult>> MoveItemToCharacterFromCharacterAsync(MoveItemToCharacterFromCharacterRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/MoveItemToCharacterFromCharacter", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/MoveItemToCharacterFromCharacter", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<MoveItemToCharacterFromCharacterResult> { Error = error, }; + return new PlayFabResult<MoveItemToCharacterFromCharacterResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<MoveItemToCharacterFromCharacterResult>>(new JsonTextReader(new StringReader(resultRawJson))); - MoveItemToCharacterFromCharacterResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<MoveItemToCharacterFromCharacterResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<MoveItemToCharacterFromCharacterResult> { Result = result }; + return new PlayFabResult<MoveItemToCharacterFromCharacterResult> { Result = result, CustomData = customData }; } /// <summary> /// Moves an item from a user's inventory into their character's inventory. /// </summary> - public static async Task<PlayFabResult<MoveItemToCharacterFromUserResult>> MoveItemToCharacterFromUserAsync(MoveItemToCharacterFromUserRequest request) + public static async Task<PlayFabResult<MoveItemToCharacterFromUserResult>> MoveItemToCharacterFromUserAsync(MoveItemToCharacterFromUserRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/MoveItemToCharacterFromUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/MoveItemToCharacterFromUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<MoveItemToCharacterFromUserResult> { Error = error, }; + return new PlayFabResult<MoveItemToCharacterFromUserResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<MoveItemToCharacterFromUserResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<MoveItemToCharacterFromUserResult>>(resultRawJson); + var result = resultData.data; - MoveItemToCharacterFromUserResult result = resultData.data; - - return new PlayFabResult<MoveItemToCharacterFromUserResult> { Result = result }; + return new PlayFabResult<MoveItemToCharacterFromUserResult> { Result = result, CustomData = customData }; } /// <summary> /// Moves an item from a character's inventory into the owning user's inventory. /// </summary> - public static async Task<PlayFabResult<MoveItemToUserFromCharacterResult>> MoveItemToUserFromCharacterAsync(MoveItemToUserFromCharacterRequest request) + public static async Task<PlayFabResult<MoveItemToUserFromCharacterResult>> MoveItemToUserFromCharacterAsync(MoveItemToUserFromCharacterRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/MoveItemToUserFromCharacter", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/MoveItemToUserFromCharacter", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<MoveItemToUserFromCharacterResult> { Error = error, }; + return new PlayFabResult<MoveItemToUserFromCharacterResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<MoveItemToUserFromCharacterResult>>(new JsonTextReader(new StringReader(resultRawJson))); - MoveItemToUserFromCharacterResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<MoveItemToUserFromCharacterResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<MoveItemToUserFromCharacterResult> { Result = result }; + return new PlayFabResult<MoveItemToUserFromCharacterResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the virtual goods associated with the coupon to the user's inventory. Coupons can be generated via the Economy->Catalogs tab in the PlayFab Game Manager. /// </summary> - public static async Task<PlayFabResult<RedeemCouponResult>> RedeemCouponAsync(RedeemCouponRequest request) + public static async Task<PlayFabResult<RedeemCouponResult>> RedeemCouponAsync(RedeemCouponRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RedeemCoupon", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RedeemCoupon", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RedeemCouponResult> { Error = error, }; + return new PlayFabResult<RedeemCouponResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RedeemCouponResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RedeemCouponResult>>(resultRawJson); + var result = resultData.data; - RedeemCouponResult result = resultData.data; - - return new PlayFabResult<RedeemCouponResult> { Result = result }; + return new PlayFabResult<RedeemCouponResult> { Result = result, CustomData = customData }; } /// <summary> /// Submit a report about a player (due to bad bahavior, etc.) on behalf of another player, so that customer service representatives for the title can take action concerning potentially toxic players. /// </summary> - public static async Task<PlayFabResult<ReportPlayerServerResult>> ReportPlayerAsync(ReportPlayerServerRequest request) + public static async Task<PlayFabResult<ReportPlayerServerResult>> ReportPlayerAsync(ReportPlayerServerRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/ReportPlayer", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/ReportPlayer", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ReportPlayerServerResult> { Error = error, }; + return new PlayFabResult<ReportPlayerServerResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ReportPlayerServerResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ReportPlayerServerResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ReportPlayerServerResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ReportPlayerServerResult> { Result = result }; + return new PlayFabResult<ReportPlayerServerResult> { Result = result, CustomData = customData }; } /// <summary> /// Revokes access to an item in a user's inventory /// </summary> - public static async Task<PlayFabResult<RevokeInventoryResult>> RevokeInventoryItemAsync(RevokeInventoryItemRequest request) + public static async Task<PlayFabResult<RevokeInventoryResult>> RevokeInventoryItemAsync(RevokeInventoryItemRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RevokeInventoryItem", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RevokeInventoryItem", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RevokeInventoryResult> { Error = error, }; + return new PlayFabResult<RevokeInventoryResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RevokeInventoryResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RevokeInventoryResult>>(resultRawJson); + var result = resultData.data; - RevokeInventoryResult result = resultData.data; - - return new PlayFabResult<RevokeInventoryResult> { Result = result }; + return new PlayFabResult<RevokeInventoryResult> { Result = result, CustomData = customData }; } /// <summary> /// Decrements the character's balance of the specified virtual currency by the stated amount /// </summary> - public static async Task<PlayFabResult<ModifyCharacterVirtualCurrencyResult>> SubtractCharacterVirtualCurrencyAsync(SubtractCharacterVirtualCurrencyRequest request) + public static async Task<PlayFabResult<ModifyCharacterVirtualCurrencyResult>> SubtractCharacterVirtualCurrencyAsync(SubtractCharacterVirtualCurrencyRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/SubtractCharacterVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/SubtractCharacterVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyCharacterVirtualCurrencyResult> { Error = error, }; + return new PlayFabResult<ModifyCharacterVirtualCurrencyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyCharacterVirtualCurrencyResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ModifyCharacterVirtualCurrencyResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyCharacterVirtualCurrencyResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ModifyCharacterVirtualCurrencyResult> { Result = result }; + return new PlayFabResult<ModifyCharacterVirtualCurrencyResult> { Result = result, CustomData = customData }; } /// <summary> /// Decrements the user's balance of the specified virtual currency by the stated amount /// </summary> - public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> SubtractUserVirtualCurrencyAsync(SubtractUserVirtualCurrencyRequest request) + public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> SubtractUserVirtualCurrencyAsync(SubtractUserVirtualCurrencyRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/SubtractUserVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/SubtractUserVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ModifyUserVirtualCurrencyResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result, CustomData = customData }; } /// <summary> /// Opens a specific container (ContainerItemInstanceId), with a specific key (KeyItemInstanceId, when required), and returns the contents of the opened container. If the container (and key when relevant) are consumable (RemainingUses > 0), their RemainingUses will be decremented, consistent with the operation of ConsumeItem. /// </summary> - public static async Task<PlayFabResult<UnlockContainerItemResult>> UnlockContainerInstanceAsync(UnlockContainerInstanceRequest request) + public static async Task<PlayFabResult<UnlockContainerItemResult>> UnlockContainerInstanceAsync(UnlockContainerInstanceRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UnlockContainerInstance", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UnlockContainerInstance", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlockContainerItemResult> { Error = error, }; + return new PlayFabResult<UnlockContainerItemResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlockContainerItemResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlockContainerItemResult>>(resultRawJson); + var result = resultData.data; - UnlockContainerItemResult result = resultData.data; - - return new PlayFabResult<UnlockContainerItemResult> { Result = result }; + return new PlayFabResult<UnlockContainerItemResult> { Result = result, CustomData = customData }; } /// <summary> /// Searches Player or Character inventory for any ItemInstance matching the given CatalogItemId, if necessary unlocks it using any appropriate key, and returns the contents of the opened container. If the container (and key when relevant) are consumable (RemainingUses > 0), their RemainingUses will be decremented, consistent with the operation of ConsumeItem. /// </summary> - public static async Task<PlayFabResult<UnlockContainerItemResult>> UnlockContainerItemAsync(UnlockContainerItemRequest request) + public static async Task<PlayFabResult<UnlockContainerItemResult>> UnlockContainerItemAsync(UnlockContainerItemRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UnlockContainerItem", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UnlockContainerItem", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlockContainerItemResult> { Error = error, }; + return new PlayFabResult<UnlockContainerItemResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlockContainerItemResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UnlockContainerItemResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlockContainerItemResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UnlockContainerItemResult> { Result = result }; + return new PlayFabResult<UnlockContainerItemResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the key-value pair data tagged to the specified item, which is read-only from the client. /// </summary> - public static async Task<PlayFabResult<EmptyResult>> UpdateUserInventoryItemCustomDataAsync(UpdateUserInventoryItemDataRequest request) + public static async Task<PlayFabResult<EmptyResult>> UpdateUserInventoryItemCustomDataAsync(UpdateUserInventoryItemDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateUserInventoryItemCustomData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateUserInventoryItemCustomData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<EmptyResult> { Error = error, }; + return new PlayFabResult<EmptyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<EmptyResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<EmptyResult>>(resultRawJson); + var result = resultData.data; - EmptyResult result = resultData.data; - - return new PlayFabResult<EmptyResult> { Result = result }; + return new PlayFabResult<EmptyResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the Friend user to the friendlist of the user with PlayFabId. At least one of FriendPlayFabId,FriendUsername,FriendEmail, or FriendTitleDisplayName should be initialized. /// </summary> - public static async Task<PlayFabResult<EmptyResult>> AddFriendAsync(AddFriendRequest request) + public static async Task<PlayFabResult<EmptyResult>> AddFriendAsync(AddFriendRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/AddFriend", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/AddFriend", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<EmptyResult> { Error = error, }; + return new PlayFabResult<EmptyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<EmptyResult>>(new JsonTextReader(new StringReader(resultRawJson))); - EmptyResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<EmptyResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<EmptyResult> { Result = result }; + return new PlayFabResult<EmptyResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the current friends for the user with PlayFabId, constrained to users who have PlayFab accounts. Friends from linked accounts (Facebook, Steam) are also included. You may optionally exclude some linked services' friends. /// </summary> - public static async Task<PlayFabResult<GetFriendsListResult>> GetFriendsListAsync(GetFriendsListRequest request) + public static async Task<PlayFabResult<GetFriendsListResult>> GetFriendsListAsync(GetFriendsListRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetFriendsList", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetFriendsList", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetFriendsListResult> { Error = error, }; + return new PlayFabResult<GetFriendsListResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetFriendsListResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetFriendsListResult>>(resultRawJson); + var result = resultData.data; - GetFriendsListResult result = resultData.data; - - return new PlayFabResult<GetFriendsListResult> { Result = result }; + return new PlayFabResult<GetFriendsListResult> { Result = result, CustomData = customData }; } /// <summary> /// Removes the specified friend from the the user's friend list /// </summary> - public static async Task<PlayFabResult<EmptyResult>> RemoveFriendAsync(RemoveFriendRequest request) + public static async Task<PlayFabResult<EmptyResult>> RemoveFriendAsync(RemoveFriendRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RemoveFriend", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RemoveFriend", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<EmptyResult> { Error = error, }; + return new PlayFabResult<EmptyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<EmptyResult>>(new JsonTextReader(new StringReader(resultRawJson))); - EmptyResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<EmptyResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<EmptyResult> { Result = result }; + return new PlayFabResult<EmptyResult> { Result = result, CustomData = customData }; } /// <summary> /// Inform the matchmaker that a Game Server Instance is removed. /// </summary> - public static async Task<PlayFabResult<DeregisterGameResponse>> DeregisterGameAsync(DeregisterGameRequest request) + public static async Task<PlayFabResult<DeregisterGameResponse>> DeregisterGameAsync(DeregisterGameRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/DeregisterGame", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/DeregisterGame", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<DeregisterGameResponse> { Error = error, }; + return new PlayFabResult<DeregisterGameResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<DeregisterGameResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - DeregisterGameResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<DeregisterGameResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<DeregisterGameResponse> { Result = result }; + return new PlayFabResult<DeregisterGameResponse> { Result = result, CustomData = customData }; } /// <summary> /// Informs the PlayFab match-making service that the user specified has left the Game Server Instance /// </summary> - public static async Task<PlayFabResult<NotifyMatchmakerPlayerLeftResult>> NotifyMatchmakerPlayerLeftAsync(NotifyMatchmakerPlayerLeftRequest request) + public static async Task<PlayFabResult<NotifyMatchmakerPlayerLeftResult>> NotifyMatchmakerPlayerLeftAsync(NotifyMatchmakerPlayerLeftRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/NotifyMatchmakerPlayerLeft", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/NotifyMatchmakerPlayerLeft", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<NotifyMatchmakerPlayerLeftResult> { Error = error, }; + return new PlayFabResult<NotifyMatchmakerPlayerLeftResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<NotifyMatchmakerPlayerLeftResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<NotifyMatchmakerPlayerLeftResult>>(resultRawJson); + var result = resultData.data; - NotifyMatchmakerPlayerLeftResult result = resultData.data; - - return new PlayFabResult<NotifyMatchmakerPlayerLeftResult> { Result = result }; + return new PlayFabResult<NotifyMatchmakerPlayerLeftResult> { Result = result, CustomData = customData }; } /// <summary> /// Validates a Game Server session ticket and returns details about the user /// </summary> - public static async Task<PlayFabResult<RedeemMatchmakerTicketResult>> RedeemMatchmakerTicketAsync(RedeemMatchmakerTicketRequest request) + public static async Task<PlayFabResult<RedeemMatchmakerTicketResult>> RedeemMatchmakerTicketAsync(RedeemMatchmakerTicketRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RedeemMatchmakerTicket", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RedeemMatchmakerTicket", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RedeemMatchmakerTicketResult> { Error = error, }; + return new PlayFabResult<RedeemMatchmakerTicketResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RedeemMatchmakerTicketResult>>(new JsonTextReader(new StringReader(resultRawJson))); - RedeemMatchmakerTicketResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RedeemMatchmakerTicketResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RedeemMatchmakerTicketResult> { Result = result }; + return new PlayFabResult<RedeemMatchmakerTicketResult> { Result = result, CustomData = customData }; } /// <summary> /// Set the state of the indicated Game Server Instance. Also update the heartbeat for the instance. /// </summary> - public static async Task<PlayFabResult<RefreshGameServerInstanceHeartbeatResult>> RefreshGameServerInstanceHeartbeatAsync(RefreshGameServerInstanceHeartbeatRequest request) + public static async Task<PlayFabResult<RefreshGameServerInstanceHeartbeatResult>> RefreshGameServerInstanceHeartbeatAsync(RefreshGameServerInstanceHeartbeatRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RefreshGameServerInstanceHeartbeat", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RefreshGameServerInstanceHeartbeat", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RefreshGameServerInstanceHeartbeatResult> { Error = error, }; + return new PlayFabResult<RefreshGameServerInstanceHeartbeatResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RefreshGameServerInstanceHeartbeatResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RefreshGameServerInstanceHeartbeatResult>>(resultRawJson); + var result = resultData.data; - RefreshGameServerInstanceHeartbeatResult result = resultData.data; - - return new PlayFabResult<RefreshGameServerInstanceHeartbeatResult> { Result = result }; + return new PlayFabResult<RefreshGameServerInstanceHeartbeatResult> { Result = result, CustomData = customData }; } /// <summary> /// Inform the matchmaker that a new Game Server Instance is added. /// </summary> - public static async Task<PlayFabResult<RegisterGameResponse>> RegisterGameAsync(RegisterGameRequest request) + public static async Task<PlayFabResult<RegisterGameResponse>> RegisterGameAsync(RegisterGameRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RegisterGame", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RegisterGame", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RegisterGameResponse> { Error = error, }; + return new PlayFabResult<RegisterGameResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RegisterGameResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - RegisterGameResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RegisterGameResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RegisterGameResponse> { Result = result }; + return new PlayFabResult<RegisterGameResponse> { Result = result, CustomData = customData }; } /// <summary> /// Sets the custom data of the indicated Game Server Instance /// </summary> - public static async Task<PlayFabResult<SetGameServerInstanceDataResult>> SetGameServerInstanceDataAsync(SetGameServerInstanceDataRequest request) + public static async Task<PlayFabResult<SetGameServerInstanceDataResult>> SetGameServerInstanceDataAsync(SetGameServerInstanceDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/SetGameServerInstanceData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/SetGameServerInstanceData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetGameServerInstanceDataResult> { Error = error, }; + return new PlayFabResult<SetGameServerInstanceDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetGameServerInstanceDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetGameServerInstanceDataResult>>(resultRawJson); + var result = resultData.data; - SetGameServerInstanceDataResult result = resultData.data; - - return new PlayFabResult<SetGameServerInstanceDataResult> { Result = result }; + return new PlayFabResult<SetGameServerInstanceDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Set the state of the indicated Game Server Instance. /// </summary> - public static async Task<PlayFabResult<SetGameServerInstanceStateResult>> SetGameServerInstanceStateAsync(SetGameServerInstanceStateRequest request) + public static async Task<PlayFabResult<SetGameServerInstanceStateResult>> SetGameServerInstanceStateAsync(SetGameServerInstanceStateRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/SetGameServerInstanceState", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/SetGameServerInstanceState", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetGameServerInstanceStateResult> { Error = error, }; + return new PlayFabResult<SetGameServerInstanceStateResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetGameServerInstanceStateResult>>(new JsonTextReader(new StringReader(resultRawJson))); - SetGameServerInstanceStateResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetGameServerInstanceStateResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<SetGameServerInstanceStateResult> { Result = result }; + return new PlayFabResult<SetGameServerInstanceStateResult> { Result = result, CustomData = customData }; } /// <summary> /// Set custom tags for the specified Game Server Instance /// </summary> - public static async Task<PlayFabResult<SetGameServerInstanceTagsResult>> SetGameServerInstanceTagsAsync(SetGameServerInstanceTagsRequest request) + public static async Task<PlayFabResult<SetGameServerInstanceTagsResult>> SetGameServerInstanceTagsAsync(SetGameServerInstanceTagsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/SetGameServerInstanceTags", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/SetGameServerInstanceTags", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetGameServerInstanceTagsResult> { Error = error, }; + return new PlayFabResult<SetGameServerInstanceTagsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetGameServerInstanceTagsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - SetGameServerInstanceTagsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetGameServerInstanceTagsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<SetGameServerInstanceTagsResult> { Result = result }; + return new PlayFabResult<SetGameServerInstanceTagsResult> { Result = result, CustomData = customData }; } /// <summary> /// Awards the specified users the specified Steam achievements /// </summary> - public static async Task<PlayFabResult<AwardSteamAchievementResult>> AwardSteamAchievementAsync(AwardSteamAchievementRequest request) + public static async Task<PlayFabResult<AwardSteamAchievementResult>> AwardSteamAchievementAsync(AwardSteamAchievementRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/AwardSteamAchievement", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/AwardSteamAchievement", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AwardSteamAchievementResult> { Error = error, }; + return new PlayFabResult<AwardSteamAchievementResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AwardSteamAchievementResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AwardSteamAchievementResult>>(resultRawJson); + var result = resultData.data; - AwardSteamAchievementResult result = resultData.data; - - return new PlayFabResult<AwardSteamAchievementResult> { Result = result }; + return new PlayFabResult<AwardSteamAchievementResult> { Result = result, CustomData = customData }; } /// <summary> /// Writes a character-based event into PlayStream. /// </summary> - public static async Task<PlayFabResult<WriteEventResponse>> WriteCharacterEventAsync(WriteServerCharacterEventRequest request) + public static async Task<PlayFabResult<WriteEventResponse>> WriteCharacterEventAsync(WriteServerCharacterEventRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/WriteCharacterEvent", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/WriteCharacterEvent", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<WriteEventResponse> { Error = error, }; + return new PlayFabResult<WriteEventResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<WriteEventResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - WriteEventResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<WriteEventResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<WriteEventResponse> { Result = result }; + return new PlayFabResult<WriteEventResponse> { Result = result, CustomData = customData }; } /// <summary> /// Writes a player-based event into PlayStream. /// </summary> - public static async Task<PlayFabResult<WriteEventResponse>> WritePlayerEventAsync(WriteServerPlayerEventRequest request) + public static async Task<PlayFabResult<WriteEventResponse>> WritePlayerEventAsync(WriteServerPlayerEventRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/WritePlayerEvent", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/WritePlayerEvent", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<WriteEventResponse> { Error = error, }; + return new PlayFabResult<WriteEventResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<WriteEventResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - WriteEventResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<WriteEventResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<WriteEventResponse> { Result = result }; + return new PlayFabResult<WriteEventResponse> { Result = result, CustomData = customData }; } /// <summary> /// Writes a title-based event into PlayStream. /// </summary> - public static async Task<PlayFabResult<WriteEventResponse>> WriteTitleEventAsync(WriteTitleEventRequest request) + public static async Task<PlayFabResult<WriteEventResponse>> WriteTitleEventAsync(WriteTitleEventRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/WriteTitleEvent", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/WriteTitleEvent", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<WriteEventResponse> { Error = error, }; + return new PlayFabResult<WriteEventResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<WriteEventResponse>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<WriteEventResponse>>(resultRawJson); + var result = resultData.data; - WriteEventResponse result = resultData.data; - - return new PlayFabResult<WriteEventResponse> { Result = result }; + return new PlayFabResult<WriteEventResponse> { Result = result, CustomData = customData }; } /// <summary> /// Adds users to the set of those able to update both the shared data, as well as the set of users in the group. Only users in the group (and the server) can add new members. /// </summary> - public static async Task<PlayFabResult<AddSharedGroupMembersResult>> AddSharedGroupMembersAsync(AddSharedGroupMembersRequest request) + public static async Task<PlayFabResult<AddSharedGroupMembersResult>> AddSharedGroupMembersAsync(AddSharedGroupMembersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/AddSharedGroupMembers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/AddSharedGroupMembers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AddSharedGroupMembersResult> { Error = error, }; + return new PlayFabResult<AddSharedGroupMembersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AddSharedGroupMembersResult>>(new JsonTextReader(new StringReader(resultRawJson))); - AddSharedGroupMembersResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AddSharedGroupMembersResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AddSharedGroupMembersResult> { Result = result }; + return new PlayFabResult<AddSharedGroupMembersResult> { Result = result, CustomData = customData }; } /// <summary> /// Requests the creation of a shared group object, containing key/value pairs which may be updated by all members of the group. When created by a server, the group will initially have no members. /// </summary> - public static async Task<PlayFabResult<CreateSharedGroupResult>> CreateSharedGroupAsync(CreateSharedGroupRequest request) + public static async Task<PlayFabResult<CreateSharedGroupResult>> CreateSharedGroupAsync(CreateSharedGroupRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/CreateSharedGroup", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/CreateSharedGroup", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<CreateSharedGroupResult> { Error = error, }; + return new PlayFabResult<CreateSharedGroupResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<CreateSharedGroupResult>>(new JsonTextReader(new StringReader(resultRawJson))); - CreateSharedGroupResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<CreateSharedGroupResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<CreateSharedGroupResult> { Result = result }; + return new PlayFabResult<CreateSharedGroupResult> { Result = result, CustomData = customData }; } /// <summary> /// Deletes a shared group, freeing up the shared group ID to be reused for a new group /// </summary> - public static async Task<PlayFabResult<EmptyResult>> DeleteSharedGroupAsync(DeleteSharedGroupRequest request) + public static async Task<PlayFabResult<EmptyResult>> DeleteSharedGroupAsync(DeleteSharedGroupRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/DeleteSharedGroup", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/DeleteSharedGroup", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<EmptyResult> { Error = error, }; + return new PlayFabResult<EmptyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<EmptyResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<EmptyResult>>(resultRawJson); + var result = resultData.data; - EmptyResult result = resultData.data; - - return new PlayFabResult<EmptyResult> { Result = result }; + return new PlayFabResult<EmptyResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves data stored in a shared group object, as well as the list of members in the group. The server can access all public and private group data. /// </summary> - public static async Task<PlayFabResult<GetSharedGroupDataResult>> GetSharedGroupDataAsync(GetSharedGroupDataRequest request) + public static async Task<PlayFabResult<GetSharedGroupDataResult>> GetSharedGroupDataAsync(GetSharedGroupDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetSharedGroupData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetSharedGroupData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetSharedGroupDataResult> { Error = error, }; + return new PlayFabResult<GetSharedGroupDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetSharedGroupDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetSharedGroupDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetSharedGroupDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetSharedGroupDataResult> { Result = result }; + return new PlayFabResult<GetSharedGroupDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Removes users from the set of those able to update the shared data and the set of users in the group. Only users in the group can remove members. If as a result of the call, zero users remain with access, the group and its associated data will be deleted. /// </summary> - public static async Task<PlayFabResult<RemoveSharedGroupMembersResult>> RemoveSharedGroupMembersAsync(RemoveSharedGroupMembersRequest request) + public static async Task<PlayFabResult<RemoveSharedGroupMembersResult>> RemoveSharedGroupMembersAsync(RemoveSharedGroupMembersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RemoveSharedGroupMembers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RemoveSharedGroupMembers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RemoveSharedGroupMembersResult> { Error = error, }; + return new PlayFabResult<RemoveSharedGroupMembersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RemoveSharedGroupMembersResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RemoveSharedGroupMembersResult>>(resultRawJson); + var result = resultData.data; - RemoveSharedGroupMembersResult result = resultData.data; - - return new PlayFabResult<RemoveSharedGroupMembersResult> { Result = result }; + return new PlayFabResult<RemoveSharedGroupMembersResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds, updates, and removes data keys for a shared group object. If the permission is set to Public, all fields updated or added in this call will be readable by users not in the group. By default, data permissions are set to Private. Regardless of the permission setting, only members of the group (and the server) can update the data. /// </summary> - public static async Task<PlayFabResult<UpdateSharedGroupDataResult>> UpdateSharedGroupDataAsync(UpdateSharedGroupDataRequest request) + public static async Task<PlayFabResult<UpdateSharedGroupDataResult>> UpdateSharedGroupDataAsync(UpdateSharedGroupDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateSharedGroupData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateSharedGroupData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateSharedGroupDataResult> { Error = error, }; + return new PlayFabResult<UpdateSharedGroupDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateSharedGroupDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateSharedGroupDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateSharedGroupDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateSharedGroupDataResult> { Result = result }; + return new PlayFabResult<UpdateSharedGroupDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Executes a CloudScript function, with the 'currentPlayerId' variable set to the specified PlayFabId parameter value. /// </summary> - public static async Task<PlayFabResult<ExecuteCloudScriptResult>> ExecuteCloudScriptAsync(ExecuteCloudScriptServerRequest request) + public static async Task<PlayFabResult<ExecuteCloudScriptResult>> ExecuteCloudScriptAsync(ExecuteCloudScriptServerRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/ExecuteCloudScript", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/ExecuteCloudScript", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ExecuteCloudScriptResult> { Error = error, }; + return new PlayFabResult<ExecuteCloudScriptResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ExecuteCloudScriptResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ExecuteCloudScriptResult>>(resultRawJson); + var result = resultData.data; - ExecuteCloudScriptResult result = resultData.data; - - return new PlayFabResult<ExecuteCloudScriptResult> { Result = result }; + return new PlayFabResult<ExecuteCloudScriptResult> { Result = result, CustomData = customData }; } /// <summary> /// This API retrieves a pre-signed URL for accessing a content file for the title. A subsequent HTTP GET to the returned URL will attempt to download the content. A HEAD query to the returned URL will attempt to retrieve the metadata of the content. Note that a successful result does not guarantee the existence of this content - if it has not been uploaded, the query to retrieve the data will fail. See this post for more information: https://community.playfab.com/hc/en-us/community/posts/205469488-How-to-upload-files-to-PlayFab-s-Content-Service /// </summary> - public static async Task<PlayFabResult<GetContentDownloadUrlResult>> GetContentDownloadUrlAsync(GetContentDownloadUrlRequest request) + public static async Task<PlayFabResult<GetContentDownloadUrlResult>> GetContentDownloadUrlAsync(GetContentDownloadUrlRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetContentDownloadUrl", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetContentDownloadUrl", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetContentDownloadUrlResult> { Error = error, }; + return new PlayFabResult<GetContentDownloadUrlResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetContentDownloadUrlResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetContentDownloadUrlResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetContentDownloadUrlResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetContentDownloadUrlResult> { Result = result }; + return new PlayFabResult<GetContentDownloadUrlResult> { Result = result, CustomData = customData }; } /// <summary> /// Deletes the specific character ID from the specified user. /// </summary> - public static async Task<PlayFabResult<DeleteCharacterFromUserResult>> DeleteCharacterFromUserAsync(DeleteCharacterFromUserRequest request) + public static async Task<PlayFabResult<DeleteCharacterFromUserResult>> DeleteCharacterFromUserAsync(DeleteCharacterFromUserRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/DeleteCharacterFromUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/DeleteCharacterFromUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<DeleteCharacterFromUserResult> { Error = error, }; + return new PlayFabResult<DeleteCharacterFromUserResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<DeleteCharacterFromUserResult>>(new JsonTextReader(new StringReader(resultRawJson))); - DeleteCharacterFromUserResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<DeleteCharacterFromUserResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<DeleteCharacterFromUserResult> { Result = result }; + return new PlayFabResult<DeleteCharacterFromUserResult> { Result = result, CustomData = customData }; } /// <summary> /// Lists all of the characters that belong to a specific user. CharacterIds are not globally unique; characterId must be evaluated with the parent PlayFabId to guarantee uniqueness. /// </summary> - public static async Task<PlayFabResult<ListUsersCharactersResult>> GetAllUsersCharactersAsync(ListUsersCharactersRequest request) + public static async Task<PlayFabResult<ListUsersCharactersResult>> GetAllUsersCharactersAsync(ListUsersCharactersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetAllUsersCharacters", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetAllUsersCharacters", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ListUsersCharactersResult> { Error = error, }; + return new PlayFabResult<ListUsersCharactersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ListUsersCharactersResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ListUsersCharactersResult>>(resultRawJson); + var result = resultData.data; - ListUsersCharactersResult result = resultData.data; - - return new PlayFabResult<ListUsersCharactersResult> { Result = result }; + return new PlayFabResult<ListUsersCharactersResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked characters for the given statistic, starting from the indicated point in the leaderboard /// </summary> - public static async Task<PlayFabResult<GetCharacterLeaderboardResult>> GetCharacterLeaderboardAsync(GetCharacterLeaderboardRequest request) + public static async Task<PlayFabResult<GetCharacterLeaderboardResult>> GetCharacterLeaderboardAsync(GetCharacterLeaderboardRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetCharacterLeaderboard", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetCharacterLeaderboard", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterLeaderboardResult> { Error = error, }; + return new PlayFabResult<GetCharacterLeaderboardResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterLeaderboardResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetCharacterLeaderboardResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterLeaderboardResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetCharacterLeaderboardResult> { Result = result }; + return new PlayFabResult<GetCharacterLeaderboardResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the details of all title-specific statistics for the specific character /// </summary> - public static async Task<PlayFabResult<GetCharacterStatisticsResult>> GetCharacterStatisticsAsync(GetCharacterStatisticsRequest request) + public static async Task<PlayFabResult<GetCharacterStatisticsResult>> GetCharacterStatisticsAsync(GetCharacterStatisticsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetCharacterStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetCharacterStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterStatisticsResult> { Error = error, }; + return new PlayFabResult<GetCharacterStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterStatisticsResult>>(resultRawJson); + var result = resultData.data; - GetCharacterStatisticsResult result = resultData.data; - - return new PlayFabResult<GetCharacterStatisticsResult> { Result = result }; + return new PlayFabResult<GetCharacterStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked characters for the given statistic, centered on the requested user /// </summary> - public static async Task<PlayFabResult<GetLeaderboardAroundCharacterResult>> GetLeaderboardAroundCharacterAsync(GetLeaderboardAroundCharacterRequest request) + public static async Task<PlayFabResult<GetLeaderboardAroundCharacterResult>> GetLeaderboardAroundCharacterAsync(GetLeaderboardAroundCharacterRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetLeaderboardAroundCharacter", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetLeaderboardAroundCharacter", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardAroundCharacterResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardAroundCharacterResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardAroundCharacterResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetLeaderboardAroundCharacterResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardAroundCharacterResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetLeaderboardAroundCharacterResult> { Result = result }; + return new PlayFabResult<GetLeaderboardAroundCharacterResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of all of the user's characters for the given statistic. /// </summary> - public static async Task<PlayFabResult<GetLeaderboardForUsersCharactersResult>> GetLeaderboardForUserCharactersAsync(GetLeaderboardForUsersCharactersRequest request) + public static async Task<PlayFabResult<GetLeaderboardForUsersCharactersResult>> GetLeaderboardForUserCharactersAsync(GetLeaderboardForUsersCharactersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetLeaderboardForUserCharacters", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetLeaderboardForUserCharacters", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardForUsersCharactersResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardForUsersCharactersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardForUsersCharactersResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardForUsersCharactersResult>>(resultRawJson); + var result = resultData.data; - GetLeaderboardForUsersCharactersResult result = resultData.data; - - return new PlayFabResult<GetLeaderboardForUsersCharactersResult> { Result = result }; + return new PlayFabResult<GetLeaderboardForUsersCharactersResult> { Result = result, CustomData = customData }; } /// <summary> /// Grants the specified character type to the user. CharacterIds are not globally unique; characterId must be evaluated with the parent PlayFabId to guarantee uniqueness. /// </summary> - public static async Task<PlayFabResult<GrantCharacterToUserResult>> GrantCharacterToUserAsync(GrantCharacterToUserRequest request) + public static async Task<PlayFabResult<GrantCharacterToUserResult>> GrantCharacterToUserAsync(GrantCharacterToUserRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GrantCharacterToUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GrantCharacterToUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GrantCharacterToUserResult> { Error = error, }; + return new PlayFabResult<GrantCharacterToUserResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GrantCharacterToUserResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GrantCharacterToUserResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GrantCharacterToUserResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GrantCharacterToUserResult> { Result = result }; + return new PlayFabResult<GrantCharacterToUserResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the values of the specified title-specific statistics for the specific character /// </summary> - public static async Task<PlayFabResult<UpdateCharacterStatisticsResult>> UpdateCharacterStatisticsAsync(UpdateCharacterStatisticsRequest request) + public static async Task<PlayFabResult<UpdateCharacterStatisticsResult>> UpdateCharacterStatisticsAsync(UpdateCharacterStatisticsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateCharacterStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateCharacterStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateCharacterStatisticsResult> { Error = error, }; + return new PlayFabResult<UpdateCharacterStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateCharacterStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateCharacterStatisticsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateCharacterStatisticsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateCharacterStatisticsResult> { Result = result }; + return new PlayFabResult<UpdateCharacterStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterDataAsync(GetCharacterDataRequest request) + public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterDataAsync(GetCharacterDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetCharacterData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetCharacterData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterDataResult> { Error = error, }; + return new PlayFabResult<GetCharacterDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterDataResult>>(resultRawJson); + var result = resultData.data; - GetCharacterDataResult result = resultData.data; - - return new PlayFabResult<GetCharacterDataResult> { Result = result }; + return new PlayFabResult<GetCharacterDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user's character which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterInternalDataAsync(GetCharacterDataRequest request) + public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterInternalDataAsync(GetCharacterDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetCharacterInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetCharacterInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterDataResult> { Error = error, }; + return new PlayFabResult<GetCharacterDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetCharacterDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetCharacterDataResult> { Result = result }; + return new PlayFabResult<GetCharacterDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user's character which can only be read by the client /// </summary> - public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterReadOnlyDataAsync(GetCharacterDataRequest request) + public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterReadOnlyDataAsync(GetCharacterDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetCharacterReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetCharacterReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterDataResult> { Error = error, }; + return new PlayFabResult<GetCharacterDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterDataResult>>(resultRawJson); + var result = resultData.data; - GetCharacterDataResult result = resultData.data; - - return new PlayFabResult<GetCharacterDataResult> { Result = result }; + return new PlayFabResult<GetCharacterDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title-specific custom data for the user's chjaracter which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<UpdateCharacterDataResult>> UpdateCharacterDataAsync(UpdateCharacterDataRequest request) + public static async Task<PlayFabResult<UpdateCharacterDataResult>> UpdateCharacterDataAsync(UpdateCharacterDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateCharacterData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateCharacterData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateCharacterDataResult> { Error = error, }; + return new PlayFabResult<UpdateCharacterDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateCharacterDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateCharacterDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateCharacterDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateCharacterDataResult> { Result = result }; + return new PlayFabResult<UpdateCharacterDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title-specific custom data for the user's character which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<UpdateCharacterDataResult>> UpdateCharacterInternalDataAsync(UpdateCharacterDataRequest request) + public static async Task<PlayFabResult<UpdateCharacterDataResult>> UpdateCharacterInternalDataAsync(UpdateCharacterDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateCharacterInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateCharacterInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateCharacterDataResult> { Error = error, }; + return new PlayFabResult<UpdateCharacterDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateCharacterDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateCharacterDataResult>>(resultRawJson); + var result = resultData.data; - UpdateCharacterDataResult result = resultData.data; - - return new PlayFabResult<UpdateCharacterDataResult> { Result = result }; + return new PlayFabResult<UpdateCharacterDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title-specific custom data for the user's character which can only be read by the client /// </summary> - public static async Task<PlayFabResult<UpdateCharacterDataResult>> UpdateCharacterReadOnlyDataAsync(UpdateCharacterDataRequest request) + public static async Task<PlayFabResult<UpdateCharacterDataResult>> UpdateCharacterReadOnlyDataAsync(UpdateCharacterDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateCharacterReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateCharacterReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateCharacterDataResult> { Error = error, }; + return new PlayFabResult<UpdateCharacterDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateCharacterDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateCharacterDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateCharacterDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateCharacterDataResult> { Result = result }; + return new PlayFabResult<UpdateCharacterDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds a given tag to a player profile. The tag's namespace is automatically generated based on the source of the tag. /// </summary> - public static async Task<PlayFabResult<AddPlayerTagResult>> AddPlayerTagAsync(AddPlayerTagRequest request) + public static async Task<PlayFabResult<AddPlayerTagResult>> AddPlayerTagAsync(AddPlayerTagRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/AddPlayerTag", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/AddPlayerTag", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AddPlayerTagResult> { Error = error, }; + return new PlayFabResult<AddPlayerTagResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AddPlayerTagResult>>(new JsonTextReader(new StringReader(resultRawJson))); - AddPlayerTagResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AddPlayerTagResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AddPlayerTagResult> { Result = result }; + return new PlayFabResult<AddPlayerTagResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieve a list of all PlayStream actions groups. /// </summary> - public static async Task<PlayFabResult<GetAllActionGroupsResult>> GetAllActionGroupsAsync(GetAllActionGroupsRequest request) + public static async Task<PlayFabResult<GetAllActionGroupsResult>> GetAllActionGroupsAsync(GetAllActionGroupsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetAllActionGroups", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetAllActionGroups", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetAllActionGroupsResult> { Error = error, }; + return new PlayFabResult<GetAllActionGroupsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetAllActionGroupsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetAllActionGroupsResult>>(resultRawJson); + var result = resultData.data; - GetAllActionGroupsResult result = resultData.data; - - return new PlayFabResult<GetAllActionGroupsResult> { Result = result }; + return new PlayFabResult<GetAllActionGroupsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves an array of player segment definitions. Results from this can be used in subsequent API calls such as GetPlayersInSegment which requires a Segment ID. While segment names can change the ID for that segment will not change. /// </summary> - public static async Task<PlayFabResult<GetAllSegmentsResult>> GetAllSegmentsAsync(GetAllSegmentsRequest request) + public static async Task<PlayFabResult<GetAllSegmentsResult>> GetAllSegmentsAsync(GetAllSegmentsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetAllSegments", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetAllSegments", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetAllSegmentsResult> { Error = error, }; + return new PlayFabResult<GetAllSegmentsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetAllSegmentsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetAllSegmentsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetAllSegmentsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetAllSegmentsResult> { Result = result }; + return new PlayFabResult<GetAllSegmentsResult> { Result = result, CustomData = customData }; } /// <summary> /// List all segments that a player currently belongs to at this moment in time. /// </summary> - public static async Task<PlayFabResult<GetPlayerSegmentsResult>> GetPlayerSegmentsAsync(GetPlayersSegmentsRequest request) + public static async Task<PlayFabResult<GetPlayerSegmentsResult>> GetPlayerSegmentsAsync(GetPlayersSegmentsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetPlayerSegments", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetPlayerSegments", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerSegmentsResult> { Error = error, }; + return new PlayFabResult<GetPlayerSegmentsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerSegmentsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerSegmentsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerSegmentsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerSegmentsResult> { Result = result }; + return new PlayFabResult<GetPlayerSegmentsResult> { Result = result, CustomData = customData }; } /// <summary> /// Allows for paging through all players in a given segment. This API creates a snapshot of all player profiles that match the segment definition at the time of its creation and lives through the Total Seconds to Live, refreshing its life span on each subsequent use of the Continuation Token. Profiles that change during the course of paging will not be reflected in the results. AB Test segments are currently not supported by this operation. /// </summary> - public static async Task<PlayFabResult<GetPlayersInSegmentResult>> GetPlayersInSegmentAsync(GetPlayersInSegmentRequest request) + public static async Task<PlayFabResult<GetPlayersInSegmentResult>> GetPlayersInSegmentAsync(GetPlayersInSegmentRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetPlayersInSegment", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetPlayersInSegment", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayersInSegmentResult> { Error = error, }; + return new PlayFabResult<GetPlayersInSegmentResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayersInSegmentResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayersInSegmentResult>>(resultRawJson); + var result = resultData.data; - GetPlayersInSegmentResult result = resultData.data; - - return new PlayFabResult<GetPlayersInSegmentResult> { Result = result }; + return new PlayFabResult<GetPlayersInSegmentResult> { Result = result, CustomData = customData }; } /// <summary> /// Get all tags with a given Namespace (optional) from a player profile. /// </summary> - public static async Task<PlayFabResult<GetPlayerTagsResult>> GetPlayerTagsAsync(GetPlayerTagsRequest request) + public static async Task<PlayFabResult<GetPlayerTagsResult>> GetPlayerTagsAsync(GetPlayerTagsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetPlayerTags", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetPlayerTags", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerTagsResult> { Error = error, }; + return new PlayFabResult<GetPlayerTagsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerTagsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerTagsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerTagsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerTagsResult> { Result = result }; + return new PlayFabResult<GetPlayerTagsResult> { Result = result, CustomData = customData }; } /// <summary> /// Remove a given tag from a player profile. The tag's namespace is automatically generated based on the source of the tag. /// </summary> - public static async Task<PlayFabResult<RemovePlayerTagResult>> RemovePlayerTagAsync(RemovePlayerTagRequest request) + public static async Task<PlayFabResult<RemovePlayerTagResult>> RemovePlayerTagAsync(RemovePlayerTagRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RemovePlayerTag", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RemovePlayerTag", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RemovePlayerTagResult> { Error = error, }; + return new PlayFabResult<RemovePlayerTagResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RemovePlayerTagResult>>(new JsonTextReader(new StringReader(resultRawJson))); - RemovePlayerTagResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RemovePlayerTagResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RemovePlayerTagResult> { Result = result }; + return new PlayFabResult<RemovePlayerTagResult> { Result = result, CustomData = customData }; } } diff --git a/PlayFabSDK/source/PlayFabServerModels.cs b/PlayFabSDK/source/PlayFabServerModels.cs index 76b15e48..8609cc1c 100644 --- a/PlayFabSDK/source/PlayFabServerModels.cs +++ b/PlayFabSDK/source/PlayFabServerModels.cs @@ -1,11 +1,73 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; using PlayFab.Internal; using System; using System.Collections.Generic; namespace PlayFab.ServerModels { + public class ActionsOnPlayersInSegmentTaskSummary + { + /// <summary> + /// ID of the task instance. + /// </summary> + public string TaskInstanceId; + + /// <summary> + /// Identifier of the task this instance belongs to. + /// </summary> + public NameIdentifier TaskIdentifier; + + /// <summary> + /// UTC timestamp when the task started. + /// </summary> + public DateTime StartedAt; + + /// <summary> + /// UTC timestamp when the task completed. + /// </summary> + public DateTime? CompletedAt; + + /// <summary> + /// Current status of the task instance. + /// </summary> + public TaskInstanceStatus? Status; + + /// <summary> + /// Progress represented as percentage. + /// </summary> + public double? PercentComplete; + + /// <summary> + /// Estimated time remaining in seconds. + /// </summary> + public double? EstimatedSecondsRemaining; + + /// <summary> + /// If manually scheduled, ID of user who scheduled the task. + /// </summary> + public string ScheduledByUserId; + + /// <summary> + /// Error message for last processing attempt, if an error occured. + /// </summary> + public string ErrorMessage; + + /// <summary> + /// Flag indicating if the error was fatal, if false job will be retried. + /// </summary> + public bool? ErrorWasFatal; + + /// <summary> + /// Total players in segment when task was started. + /// </summary> + public int? TotalPlayersInSegment; + + /// <summary> + /// Total number of players that have had the actions applied to. + /// </summary> + public int? TotalPlayersProcessed; + + } + public class AdCampaignAttribution { /// <summary> @@ -25,7 +87,7 @@ public class AdCampaignAttribution } - public class AddCharacterVirtualCurrencyRequest + public class AddCharacterVirtualCurrencyRequest : PlayFabRequestCommon { /// <summary> /// PlayFab unique identifier of the user whose virtual currency balance is to be incremented. @@ -49,7 +111,7 @@ public class AddCharacterVirtualCurrencyRequest } - public class AddFriendRequest + public class AddFriendRequest : PlayFabRequestCommon { /// <summary> /// PlayFab identifier of the player to add a new friend. @@ -78,7 +140,7 @@ public class AddFriendRequest } - public class AddPlayerTagRequest + public class AddPlayerTagRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -96,7 +158,7 @@ public class AddPlayerTagResult : PlayFabResultCommon { } - public class AddSharedGroupMembersRequest + public class AddSharedGroupMembersRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group. @@ -114,7 +176,7 @@ public class AddSharedGroupMembersResult : PlayFabResultCommon { } - public class AddUserVirtualCurrencyRequest + public class AddUserVirtualCurrencyRequest : PlayFabRequestCommon { /// <summary> /// PlayFab unique identifier of the user whose virtual currency balance is to be increased. @@ -133,7 +195,7 @@ public class AddUserVirtualCurrencyRequest } - public class AuthenticateSessionTicketRequest + public class AuthenticateSessionTicketRequest : PlayFabRequestCommon { /// <summary> /// Session ticket as issued by a PlayFab client login API. @@ -170,7 +232,7 @@ public class AwardSteamAchievementItem } - public class AwardSteamAchievementRequest + public class AwardSteamAchievementRequest : PlayFabRequestCommon { /// <summary> /// Array of achievements to grant and the users to whom they are to be granted. @@ -238,7 +300,7 @@ public class BanInfo /// <summary> /// Represents a single ban request. /// </summary> - public class BanRequest + public class BanRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -267,7 +329,7 @@ public class BanRequest } - public class BanUsersRequest + public class BanUsersRequest : PlayFabRequestCommon { /// <summary> /// List of ban requests to be applied. Maximum 100. @@ -377,7 +439,7 @@ public class CatalogItem : IComparable<CatalogItem> public bool IsLimitedEdition; /// <summary> - /// BETA: If IsLImitedEdition is true, then this determines amount of the item initially available. Note that this fieldis ignored if the catalog item already existed in this catalog, or the field is less than 1. + /// If IsLImitedEdition is true, then this determines amount of the item initially available. Note that this fieldis ignored if the catalog item already existed in this catalog, or the field is less than 1. /// </summary> public int InitialLimitedEditionCount; @@ -539,7 +601,7 @@ public enum CloudScriptRevisionOption Specific } - public class ConsumeItemRequest + public class ConsumeItemRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -577,7 +639,273 @@ public class ConsumeItemResult : PlayFabResultCommon } - public class CreateSharedGroupRequest + + public enum ContinentCode + { + AF, + AN, + AS, + EU, + NA, + OC, + SA + } + + + public enum CountryCode + { + AF, + AX, + AL, + DZ, + AS, + AD, + AO, + AI, + AQ, + AG, + AR, + AM, + AW, + AU, + AT, + AZ, + BS, + BH, + BD, + BB, + BY, + BE, + BZ, + BJ, + BM, + BT, + BO, + BQ, + BA, + BW, + BV, + BR, + IO, + BN, + BG, + BF, + BI, + KH, + CM, + CA, + CV, + KY, + CF, + TD, + CL, + CN, + CX, + CC, + CO, + KM, + CG, + CD, + CK, + CR, + CI, + HR, + CU, + CW, + CY, + CZ, + DK, + DJ, + DM, + DO, + EC, + EG, + SV, + GQ, + ER, + EE, + ET, + FK, + FO, + FJ, + FI, + FR, + GF, + PF, + TF, + GA, + GM, + GE, + DE, + GH, + GI, + GR, + GL, + GD, + GP, + GU, + GT, + GG, + GN, + GW, + GY, + HT, + HM, + VA, + HN, + HK, + HU, + IS, + IN, + ID, + IR, + IQ, + IE, + IM, + IL, + IT, + JM, + JP, + JE, + JO, + KZ, + KE, + KI, + KP, + KR, + KW, + KG, + LA, + LV, + LB, + LS, + LR, + LY, + LI, + LT, + LU, + MO, + MK, + MG, + MW, + MY, + MV, + ML, + MT, + MH, + MQ, + MR, + MU, + YT, + MX, + FM, + MD, + MC, + MN, + ME, + MS, + MA, + MZ, + MM, + NA, + NR, + NP, + NL, + NC, + NZ, + NI, + NE, + NG, + NU, + NF, + MP, + NO, + OM, + PK, + PW, + PS, + PA, + PG, + PY, + PE, + PH, + PN, + PL, + PT, + PR, + QA, + RE, + RO, + RU, + RW, + BL, + SH, + KN, + LC, + MF, + PM, + VC, + WS, + SM, + ST, + SA, + SN, + RS, + SC, + SL, + SG, + SX, + SK, + SI, + SB, + SO, + ZA, + GS, + SS, + ES, + LK, + SD, + SR, + SJ, + SZ, + SE, + CH, + SY, + TW, + TJ, + TZ, + TH, + TL, + TG, + TK, + TO, + TT, + TN, + TR, + TM, + TC, + TV, + UG, + UA, + AE, + GB, + US, + UM, + UY, + UZ, + VU, + VE, + VN, + VG, + VI, + WF, + EH, + YE, + ZM, + ZW + } + + public class CreateSharedGroupRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group (a random identifier will be assigned, if one is not specified). @@ -762,7 +1090,7 @@ public enum Currency ZWD } - public class DeleteCharacterFromUserRequest + public class DeleteCharacterFromUserRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -785,7 +1113,7 @@ public class DeleteCharacterFromUserResult : PlayFabResultCommon { } - public class DeleteSharedGroupRequest + public class DeleteSharedGroupRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group. @@ -794,7 +1122,7 @@ public class DeleteSharedGroupRequest } - public class DeleteUsersRequest + public class DeleteUsersRequest : PlayFabRequestCommon { /// <summary> /// An array of unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -812,7 +1140,7 @@ public class DeleteUsersResult : PlayFabResultCommon { } - public class DeregisterGameRequest + public class DeregisterGameRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the Game Server Instance that is being deregistered. @@ -829,7 +1157,7 @@ public class EmptyResult : PlayFabResultCommon { } - public class EvaluateRandomResultTableRequest : PlayFabResultCommon + public class EvaluateRandomResultTableRequest : PlayFabRequestCommon { /// <summary> /// The unique identifier of the Random Result Table to use. @@ -900,7 +1228,7 @@ public class ExecuteCloudScriptResult : PlayFabResultCommon } - public class ExecuteCloudScriptServerRequest + public class ExecuteCloudScriptServerRequest : PlayFabRequestCommon { /// <summary> /// The unique user identifier for the player on whose behalf the script is being run @@ -920,7 +1248,6 @@ public class ExecuteCloudScriptServerRequest /// <summary> /// Option for which revision of the CloudScript to execute. 'Latest' executes the most recently created revision, 'Live' executes the current live, published revision, and 'Specific' executes the specified revision. The default value is 'Specific', if the SpeificRevision parameter is specified, otherwise it is 'Live'. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public CloudScriptRevisionOption? RevisionSelection; /// <summary> @@ -1014,7 +1341,7 @@ public class GetActionGroupResult : PlayFabResultCommon } - public class GetAllActionGroupsRequest + public class GetAllActionGroupsRequest : PlayFabRequestCommon { } @@ -1027,7 +1354,7 @@ public class GetAllActionGroupsResult : PlayFabResultCommon } - public class GetAllSegmentsRequest + public class GetAllSegmentsRequest : PlayFabRequestCommon { } @@ -1040,7 +1367,7 @@ public class GetAllSegmentsResult : PlayFabResultCommon } - public class GetCatalogItemsRequest + public class GetCatalogItemsRequest : PlayFabRequestCommon { /// <summary> /// Which catalog is being requested. If null, uses the default catalog. @@ -1059,7 +1386,7 @@ public class GetCatalogItemsResult : PlayFabResultCommon } - public class GetCharacterDataRequest + public class GetCharacterDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1107,7 +1434,7 @@ public class GetCharacterDataResult : PlayFabResultCommon } - public class GetCharacterInventoryRequest + public class GetCharacterInventoryRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1156,7 +1483,7 @@ public class GetCharacterInventoryResult : PlayFabResultCommon } - public class GetCharacterLeaderboardRequest + public class GetCharacterLeaderboardRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID for a specific character owned by a user @@ -1194,7 +1521,7 @@ public class GetCharacterLeaderboardResult : PlayFabResultCommon } - public class GetCharacterStatisticsRequest + public class GetCharacterStatisticsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1227,7 +1554,7 @@ public class GetCharacterStatisticsResult : PlayFabResultCommon } - public class GetContentDownloadUrlRequest + public class GetContentDownloadUrlRequest : PlayFabRequestCommon { /// <summary> /// Key of the content item to fetch, usually formatted as a path, e.g. images/a.png @@ -1255,7 +1582,7 @@ public class GetContentDownloadUrlResult : PlayFabResultCommon } - public class GetFriendLeaderboardRequest + public class GetFriendLeaderboardRequest : PlayFabRequestCommon { /// <summary> /// The player whose friend leaderboard to get @@ -1289,7 +1616,7 @@ public class GetFriendLeaderboardRequest } - public class GetFriendsListRequest + public class GetFriendsListRequest : PlayFabRequestCommon { /// <summary> /// PlayFab identifier of the player whose friend list to get. @@ -1317,7 +1644,7 @@ public class GetFriendsListResult : PlayFabResultCommon } - public class GetLeaderboardAroundCharacterRequest + public class GetLeaderboardAroundCharacterRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title-specific statistic for the leaderboard. @@ -1355,7 +1682,7 @@ public class GetLeaderboardAroundCharacterResult : PlayFabResultCommon } - public class GetLeaderboardAroundUserRequest + public class GetLeaderboardAroundUserRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title-specific statistic for the leaderboard. @@ -1383,7 +1710,7 @@ public class GetLeaderboardAroundUserResult : PlayFabResultCommon } - public class GetLeaderboardForUsersCharactersRequest + public class GetLeaderboardForUsersCharactersRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title-specific statistic for the leaderboard. @@ -1411,7 +1738,7 @@ public class GetLeaderboardForUsersCharactersResult : PlayFabResultCommon } - public class GetLeaderboardRequest + public class GetLeaderboardRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title-specific statistic for the leaderboard. @@ -1439,7 +1766,7 @@ public class GetLeaderboardResult : PlayFabResultCommon } - public class GetPlayerCombinedInfoRequest + public class GetPlayerCombinedInfoRequest : PlayFabRequestCommon { /// <summary> /// PlayFabId of the user whose data will be returned @@ -1536,7 +1863,7 @@ public class GetPlayerCombinedInfoResult : PlayFabResultCommon } - public class GetPlayerCombinedInfoResultPayload : PlayFabResultCommon + public class GetPlayerCombinedInfoResultPayload { /// <summary> /// Account information for the user. This is always retrieved. @@ -1610,7 +1937,7 @@ public class GetPlayerSegmentsResult : PlayFabResultCommon } - public class GetPlayersInSegmentRequest + public class GetPlayersInSegmentRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for this segment. @@ -1653,7 +1980,7 @@ public class GetPlayersInSegmentResult : PlayFabResultCommon } - public class GetPlayersSegmentsRequest + public class GetPlayersSegmentsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1662,7 +1989,7 @@ public class GetPlayersSegmentsRequest } - public class GetPlayerStatisticsRequest + public class GetPlayerStatisticsRequest : PlayFabRequestCommon { /// <summary> /// user for whom statistics are being requested @@ -1695,7 +2022,7 @@ public class GetPlayerStatisticsResult : PlayFabResultCommon } - public class GetPlayerStatisticVersionsRequest + public class GetPlayerStatisticVersionsRequest : PlayFabRequestCommon { /// <summary> /// unique name of the statistic @@ -1713,7 +2040,7 @@ public class GetPlayerStatisticVersionsResult : PlayFabResultCommon } - public class GetPlayerTagsRequest + public class GetPlayerTagsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1741,7 +2068,7 @@ public class GetPlayerTagsResult : PlayFabResultCommon } - public class GetPlayFabIDsFromFacebookIDsRequest + public class GetPlayFabIDsFromFacebookIDsRequest : PlayFabRequestCommon { /// <summary> /// Array of unique Facebook identifiers for which the title needs to get PlayFab identifiers. @@ -1759,7 +2086,7 @@ public class GetPlayFabIDsFromFacebookIDsResult : PlayFabResultCommon } - public class GetPlayFabIDsFromSteamIDsRequest + public class GetPlayFabIDsFromSteamIDsRequest : PlayFabRequestCommon { /// <summary> /// Array of unique Steam identifiers (Steam profile IDs) for which the title needs to get PlayFab identifiers. @@ -1777,7 +2104,7 @@ public class GetPlayFabIDsFromSteamIDsResult : PlayFabResultCommon } - public class GetPublisherDataRequest + public class GetPublisherDataRequest : PlayFabRequestCommon { /// <summary> /// array of keys to get back data from the Publisher data blob, set by the admin tools @@ -1795,7 +2122,7 @@ public class GetPublisherDataResult : PlayFabResultCommon } - public class GetRandomResultTablesRequest : PlayFabResultCommon + public class GetRandomResultTablesRequest : PlayFabRequestCommon { /// <summary> /// Specifies the catalog version that should be used to retrieve the Random Result Tables. If unspecified, uses default/primary catalog. @@ -1837,7 +2164,7 @@ public class GetSegmentResult : PlayFabResultCommon } - public class GetSharedGroupDataRequest + public class GetSharedGroupDataRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group. @@ -1870,7 +2197,7 @@ public class GetSharedGroupDataResult : PlayFabResultCommon } - public class GetTimeRequest + public class GetTimeRequest : PlayFabRequestCommon { } @@ -1883,7 +2210,7 @@ public class GetTimeResult : PlayFabResultCommon } - public class GetTitleDataRequest + public class GetTitleDataRequest : PlayFabRequestCommon { /// <summary> /// Specific keys to search for in the title data (leave null to get all keys) @@ -1901,7 +2228,7 @@ public class GetTitleDataResult : PlayFabResultCommon } - public class GetTitleNewsRequest + public class GetTitleNewsRequest : PlayFabRequestCommon { /// <summary> /// Limits the results to the last n entries. Defaults to 10 if not set. @@ -1919,7 +2246,7 @@ public class GetTitleNewsResult : PlayFabResultCommon } - public class GetUserAccountInfoRequest + public class GetUserAccountInfoRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1937,7 +2264,7 @@ public class GetUserAccountInfoResult : PlayFabResultCommon } - public class GetUserBansRequest + public class GetUserBansRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1955,7 +2282,7 @@ public class GetUserBansResult : PlayFabResultCommon } - public class GetUserDataRequest + public class GetUserDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1993,7 +2320,7 @@ public class GetUserDataResult : PlayFabResultCommon } - public class GetUserInventoryRequest + public class GetUserInventoryRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2027,7 +2354,7 @@ public class GetUserInventoryResult : PlayFabResultCommon } - public class GrantCharacterToUserRequest + public class GrantCharacterToUserRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2159,7 +2486,7 @@ public int CompareTo(GrantedItemInstance other) } - public class GrantItemsToCharacterRequest + public class GrantItemsToCharacterRequest : PlayFabRequestCommon { /// <summary> /// Catalog version from which items are to be granted. @@ -2197,7 +2524,7 @@ public class GrantItemsToCharacterResult : PlayFabResultCommon } - public class GrantItemsToUserRequest + public class GrantItemsToUserRequest : PlayFabRequestCommon { /// <summary> /// Catalog version from which items are to be granted. @@ -2230,7 +2557,7 @@ public class GrantItemsToUserResult : PlayFabResultCommon } - public class GrantItemsToUsersRequest + public class GrantItemsToUsersRequest : PlayFabRequestCommon { /// <summary> /// Catalog version from which items are to be granted. @@ -2377,7 +2704,7 @@ public int CompareTo(ItemInstance other) } - public class ListUsersCharactersRequest + public class ListUsersCharactersRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2443,7 +2770,7 @@ public class ModifyCharacterVirtualCurrencyResult : PlayFabResultCommon } - public class ModifyItemUsesRequest + public class ModifyItemUsesRequest : PlayFabRequestCommon { /// <summary> /// PlayFab unique identifier of the user whose item is being modified. @@ -2500,7 +2827,7 @@ public class ModifyUserVirtualCurrencyResult : PlayFabResultCommon } - public class MoveItemToCharacterFromCharacterRequest + public class MoveItemToCharacterFromCharacterRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2528,7 +2855,7 @@ public class MoveItemToCharacterFromCharacterResult : PlayFabResultCommon { } - public class MoveItemToCharacterFromUserRequest + public class MoveItemToCharacterFromUserRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2551,7 +2878,7 @@ public class MoveItemToCharacterFromUserResult : PlayFabResultCommon { } - public class MoveItemToUserFromCharacterRequest + public class MoveItemToUserFromCharacterRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2574,7 +2901,18 @@ public class MoveItemToUserFromCharacterResult : PlayFabResultCommon { } - public class NotifyMatchmakerPlayerLeftRequest + /// <summary> + /// Identifier by either name or ID. Note that a name may change due to renaming, or reused after being deleted. ID is immutable and unique. + /// </summary> + public class NameIdentifier + { + public string Name; + + public string Id; + + } + + public class NotifyMatchmakerPlayerLeftRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier of the Game Instance the user is leaving. @@ -2593,7 +2931,6 @@ public class NotifyMatchmakerPlayerLeftResult : PlayFabResultCommon /// <summary> /// State of user leaving the Game Server Instance. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public PlayerConnectionState? PlayerState; } @@ -2636,7 +2973,6 @@ public class PlayerLinkedAccount /// <summary> /// Authentication platform /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public LoginIdentityProvider? Platform; /// <summary> @@ -2656,6 +2992,35 @@ public class PlayerLinkedAccount } + public class PlayerLocation + { + /// <summary> + /// The two-character continent code for this location + /// </summary> + public ContinentCode ContinentCode; + + /// <summary> + /// The two-character ISO 3166-1 country code for the country associated with the location + /// </summary> + public CountryCode CountryCode; + + /// <summary> + /// City of the player's geographic location. + /// </summary> + public string City; + + /// <summary> + /// Latitude coordinate of the player's geographic location. + /// </summary> + public double? Latitude; + + /// <summary> + /// Longitude coordinate of the player's geographic location. + /// </summary> + public double? Longitude; + + } + public class PlayerProfile { /// <summary> @@ -2681,7 +3046,6 @@ public class PlayerProfile /// <summary> /// Player account origination /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public LoginIdentityProvider? Origination; /// <summary> @@ -2719,6 +3083,11 @@ public class PlayerProfile /// </summary> public List<string> Tags; + /// <summary> + /// Dictionary of player's locations by type. + /// </summary> + public Dictionary<string,PlayerLocation> Locations; + /// <summary> /// Dictionary of player's virtual currency balances /// </summary> @@ -2816,7 +3185,6 @@ public class PushNotificationRegistration /// <summary> /// Push notification platform /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public PushNotificationPlatform? Platform; /// <summary> @@ -2826,7 +3194,7 @@ public class PushNotificationRegistration } - public class RandomResultTableListing : PlayFabResultCommon + public class RandomResultTableListing { /// <summary> /// Catalog version this table is associated with @@ -2845,7 +3213,7 @@ public class RandomResultTableListing : PlayFabResultCommon } - public class RedeemCouponRequest + public class RedeemCouponRequest : PlayFabRequestCommon { /// <summary> /// Generated coupon code to redeem. @@ -2862,6 +3230,11 @@ public class RedeemCouponRequest /// </summary> public string CatalogVersion; + /// <summary> + /// Optional identifier for the Character that should receive the item. If null, item is added to the player + /// </summary> + public string CharacterId; + } public class RedeemCouponResult : PlayFabResultCommon @@ -2873,7 +3246,7 @@ public class RedeemCouponResult : PlayFabResultCommon } - public class RedeemMatchmakerTicketRequest + public class RedeemMatchmakerTicketRequest : PlayFabRequestCommon { /// <summary> /// Server authorization ticket passed back from a call to Matchmake or StartGame. @@ -2906,7 +3279,7 @@ public class RedeemMatchmakerTicketResult : PlayFabResultCommon } - public class RefreshGameServerInstanceHeartbeatRequest + public class RefreshGameServerInstanceHeartbeatRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier of the Game Server Instance for which the heartbeat is updated. @@ -2931,7 +3304,7 @@ public enum Region Australia } - public class RegisterGameRequest + public class RegisterGameRequest : PlayFabRequestCommon { /// <summary> /// IP address of the Game Server Instance. @@ -2951,7 +3324,6 @@ public class RegisterGameRequest /// <summary> /// Region in which the Game Server Instance is running. For matchmaking using non-AWS region names, set this to any AWS region and use Tags (below) to specify your custom region. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Region Region; /// <summary> @@ -2975,7 +3347,7 @@ public class RegisterGameResponse : PlayFabResultCommon } - public class RemoveFriendRequest + public class RemoveFriendRequest : PlayFabRequestCommon { /// <summary> /// PlayFab identifier of the friend account which is to be removed. @@ -2989,7 +3361,7 @@ public class RemoveFriendRequest } - public class RemovePlayerTagRequest + public class RemovePlayerTagRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3007,7 +3379,7 @@ public class RemovePlayerTagResult : PlayFabResultCommon { } - public class RemoveSharedGroupMembersRequest + public class RemoveSharedGroupMembersRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group. @@ -3025,7 +3397,7 @@ public class RemoveSharedGroupMembersResult : PlayFabResultCommon { } - public class ReportPlayerServerRequest + public class ReportPlayerServerRequest : PlayFabRequestCommon { /// <summary> /// PlayFabId of the reporting player. @@ -3063,12 +3435,11 @@ public class ReportPlayerServerResult : PlayFabResultCommon } - public class ResultTableNode : PlayFabResultCommon + public class ResultTableNode { /// <summary> /// Whether this entry in the table is an item or a link to another table /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public ResultTableNodeType ResultItemType; /// <summary> @@ -3090,7 +3461,7 @@ public enum ResultTableNodeType TableId } - public class RevokeAllBansForUserRequest + public class RevokeAllBansForUserRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3108,7 +3479,7 @@ public class RevokeAllBansForUserResult : PlayFabResultCommon } - public class RevokeBansRequest + public class RevokeBansRequest : PlayFabRequestCommon { /// <summary> /// Ids of the bans to be revoked. Maximum 100. @@ -3126,7 +3497,7 @@ public class RevokeBansResult : PlayFabResultCommon } - public class RevokeInventoryItemRequest + public class RevokeInventoryItemRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3168,7 +3539,7 @@ public class ScriptExecutionError } - public class SendPushNotificationRequest + public class SendPushNotificationRequest : PlayFabRequestCommon { /// <summary> /// PlayFabId of the recipient of the push notification. @@ -3191,7 +3562,7 @@ public class SendPushNotificationResult : PlayFabResultCommon { } - public class SetGameServerInstanceDataRequest + public class SetGameServerInstanceDataRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier of the Game Instance to be updated. @@ -3209,7 +3580,7 @@ public class SetGameServerInstanceDataResult : PlayFabResultCommon { } - public class SetGameServerInstanceStateRequest + public class SetGameServerInstanceStateRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier of the Game Instance to be updated. @@ -3219,7 +3590,6 @@ public class SetGameServerInstanceStateRequest /// <summary> /// State to set for the specified game server instance. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public GameInstanceState State; } @@ -3228,7 +3598,7 @@ public class SetGameServerInstanceStateResult : PlayFabResultCommon { } - public class SetGameServerInstanceTagsRequest + public class SetGameServerInstanceTagsRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier of the Game Server Instance to be updated. @@ -3246,7 +3616,7 @@ public class SetGameServerInstanceTagsResult : PlayFabResultCommon { } - public class SetPublisherDataRequest + public class SetPublisherDataRequest : PlayFabRequestCommon { /// <summary> /// key we want to set a value on (note, this is additive - will only replace an existing key's value if they are the same name.) Keys are trimmed of whitespace. Keys may not begin with the '!' character. @@ -3264,7 +3634,7 @@ public class SetPublisherDataResult : PlayFabResultCommon { } - public class SetTitleDataRequest + public class SetTitleDataRequest : PlayFabRequestCommon { /// <summary> /// key we want to set a value on (note, this is additive - will only replace an existing key's value if they are the same name.) Keys are trimmed of whitespace. Keys may not begin with the '!' character. @@ -3302,7 +3672,6 @@ public class SharedGroupDataRecord /// <summary> /// Indicates whether this data can be read by all users (public) or only members of the group (private). /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -3373,7 +3742,7 @@ public class SteamPlayFabIdPair } - public class SubtractCharacterVirtualCurrencyRequest + public class SubtractCharacterVirtualCurrencyRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3397,7 +3766,7 @@ public class SubtractCharacterVirtualCurrencyRequest } - public class SubtractUserVirtualCurrencyRequest + public class SubtractUserVirtualCurrencyRequest : PlayFabRequestCommon { /// <summary> /// PlayFab unique identifier of the user whose virtual currency balance is to be decreased. @@ -3417,6 +3786,17 @@ public class SubtractUserVirtualCurrencyRequest } + public enum TaskInstanceStatus + { + Succeeded, + Starting, + InProgress, + Failed, + Aborted, + Pending + } + + public enum TitleActivationStatus { None, @@ -3450,7 +3830,7 @@ public class TitleNewsItem } - public class UnlockContainerInstanceRequest + public class UnlockContainerInstanceRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3479,7 +3859,7 @@ public class UnlockContainerInstanceRequest } - public class UnlockContainerItemRequest + public class UnlockContainerItemRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3530,7 +3910,7 @@ public class UnlockContainerItemResult : PlayFabResultCommon /// <summary> /// Represents a single update ban request. /// </summary> - public class UpdateBanRequest + public class UpdateBanRequest : PlayFabRequestCommon { /// <summary> /// The id of the ban to be updated. @@ -3569,7 +3949,7 @@ public class UpdateBanRequest } - public class UpdateBansRequest + public class UpdateBansRequest : PlayFabRequestCommon { /// <summary> /// List of bans to be updated. Maximum 100. @@ -3587,7 +3967,7 @@ public class UpdateBansResult : PlayFabResultCommon } - public class UpdateCharacterDataRequest + public class UpdateCharacterDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3612,7 +3992,6 @@ public class UpdateCharacterDataRequest /// <summary> /// Permission to be applied to all user data keys written in this request. Defaults to "private" if not set. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -3626,7 +4005,7 @@ public class UpdateCharacterDataResult : PlayFabResultCommon } - public class UpdateCharacterStatisticsRequest + public class UpdateCharacterStatisticsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3649,7 +4028,7 @@ public class UpdateCharacterStatisticsResult : PlayFabResultCommon { } - public class UpdatePlayerStatisticsRequest + public class UpdatePlayerStatisticsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3661,13 +4040,18 @@ public class UpdatePlayerStatisticsRequest /// </summary> public List<StatisticUpdate> Statistics; + /// <summary> + /// Indicates whether the statistics provided should be set, regardless of the aggregation method set on the statistic. Default is false. + /// </summary> + public bool? ForceUpdate; + } public class UpdatePlayerStatisticsResult : PlayFabResultCommon { } - public class UpdateSharedGroupDataRequest + public class UpdateSharedGroupDataRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group. @@ -3687,7 +4071,6 @@ public class UpdateSharedGroupDataRequest /// <summary> /// Permission to be applied to all user data keys in this request. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -3696,7 +4079,7 @@ public class UpdateSharedGroupDataResult : PlayFabResultCommon { } - public class UpdateUserDataRequest + public class UpdateUserDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3716,7 +4099,6 @@ public class UpdateUserDataRequest /// <summary> /// Permission to be applied to all user data keys written in this request. Defaults to "private" if not set. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -3730,7 +4112,7 @@ public class UpdateUserDataResult : PlayFabResultCommon } - public class UpdateUserInternalDataRequest + public class UpdateUserInternalDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3749,7 +4131,7 @@ public class UpdateUserInternalDataRequest } - public class UpdateUserInventoryItemDataRequest + public class UpdateUserInventoryItemDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3905,7 +4287,6 @@ public class UserDataRecord /// <summary> /// Indicates whether this data can be read by all users (public) or only the user (private). This is used for GetUserData requests being made by one player about another player. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -4040,13 +4421,11 @@ public class UserSteamInfo /// <summary> /// currency type set in the user Steam account /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Currency? SteamCurrency; /// <summary> /// what stage of game ownership the user is listed as being in, from Steam /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public TitleActivationStatus? SteamActivationStatus; } @@ -4061,7 +4440,6 @@ public class UserTitleInfo /// <summary> /// source by which the user first joined the game, if known /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserOrigination? Origination; /// <summary> @@ -4131,13 +4509,13 @@ public class VirtualCurrencyRechargeTime public class WriteEventResponse : PlayFabResultCommon { /// <summary> - /// The unique identifier of the event. This can be used to retrieve the event's properties using the GetEvent API. The values of this identifier consist of ASCII characters and are not constrained to any particular format. + /// The unique identifier of the event. The values of this identifier consist of ASCII characters and are not constrained to any particular format. /// </summary> public string EventId; } - public class WriteServerCharacterEventRequest + public class WriteServerCharacterEventRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -4166,7 +4544,7 @@ public class WriteServerCharacterEventRequest } - public class WriteServerPlayerEventRequest + public class WriteServerPlayerEventRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -4190,7 +4568,7 @@ public class WriteServerPlayerEventRequest } - public class WriteTitleEventRequest + public class WriteTitleEventRequest : PlayFabRequestCommon { /// <summary> /// The name of the event, within the namespace scoped to the title. The naming convention is up to the caller, but it commonly follows the subject_verb_object pattern (e.g. player_logged_in). diff --git a/PlayFabSDK/source/PlayFabSettings.cs b/PlayFabSDK/source/PlayFabSettings.cs index 49b96d4e..65d72380 100644 --- a/PlayFabSDK/source/PlayFabSettings.cs +++ b/PlayFabSDK/source/PlayFabSettings.cs @@ -1,13 +1,11 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; namespace PlayFab { public class PlayFabSettings { - public const string SdkVersion = "0.40.161017"; + public const string SdkVersion = "1.0.161107"; public const string BuildIdentifier = "jbuild_csharpsdk_1"; - public const string SdkVersionString = "CSharpSDK-0.40.161017"; + public const string SdkVersionString = "CSharpSDK-1.0.161107"; /// <summary> This is for PlayFab internal debugging. Generally you shouldn't touch this </summary> public static bool UseDevelopmentEnvironment = false; @@ -35,7 +33,7 @@ public class PlayFabSettings public static string GetFullUrl(string apiCall) { - string baseUrl = UseDevelopmentEnvironment ? DevelopmentEnvironmentUrl : ProductionEnvironmentUrl; + var baseUrl = UseDevelopmentEnvironment ? DevelopmentEnvironmentUrl : ProductionEnvironmentUrl; if (baseUrl.StartsWith("http")) return baseUrl; return "https://" + TitleId + baseUrl + apiCall; diff --git a/PlayFabSDK/source/PlayFabUtil.cs b/PlayFabSDK/source/PlayFabUtil.cs index e4a9d64b..c28ea6d6 100644 --- a/PlayFabSDK/source/PlayFabUtil.cs +++ b/PlayFabSDK/source/PlayFabUtil.cs @@ -1,7 +1,8 @@ +using PlayFab.Json; using System; +using System.IO; using System.Text; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; +using System.Threading.Tasks; using PlayFab.ClientModels; namespace PlayFab @@ -19,7 +20,7 @@ public Unordered(string sortProperty) } } - public static class PlayFabUtil + public static partial class PlayFabUtil { public static readonly string[] DefaultDateTimeFormats = { // All parseable ISO 8601 formats for DateTime.[Try]ParseExact - Lets us deserialize any legacy timestamps in one of these formats // These are the standard format with ISO 8601 UTC markers (T/Z) @@ -38,32 +39,13 @@ public static class PlayFabUtil }; public const int DEFAULT_UTC_OUTPUT_INDEX = 2; // The default format everybody should use public const int DEFAULT_LOCAL_OUTPUT_INDEX = 7; // The default format if you want to use local time (This doesn't have universal support in all PlayFab code) - public static JsonSerializerSettings JsonSettings = new JsonSerializerSettings - { - NullValueHandling = NullValueHandling.Ignore, - Converters = { new IsoDateTimeConverter { DateTimeFormat = DefaultDateTimeFormats[0] } }, - }; - public static Formatting JsonFormatting = Formatting.None; - private static readonly StringBuilder Sb = new StringBuilder(); public static string GetErrorReport(PlayFabError error) { - if (error == null) - return null; - Sb.Length = 0; - if (error.ErrorMessage != null) - Sb.Append(error.ErrorMessage); - if (error.ErrorDetails == null) - return Sb.ToString(); - - foreach (var pair in error.ErrorDetails) - { - foreach (var eachMsg in pair.Value) - Sb.Append(pair.Key).Append(": ").Append(eachMsg); - } - return Sb.ToString(); + return error?.GenerateErrorReport(); } + private static readonly StringBuilder Sb = new StringBuilder(); public static string GetCloudScriptErrorReport(PlayFabResult<ExecuteCloudScriptResult> result) { if (result.Error != null) @@ -89,28 +71,9 @@ public static string GetCloudScriptErrorReport(PlayFabResult<ExecuteCloudScriptR if (!string.IsNullOrEmpty(eachLog.Message)) Sb.Append(" - ").Append(eachLog.Message); if (eachLog.Data != null) - Sb.Append("\n").Append(JsonConvert.SerializeObject(eachLog.Data, Formatting.Indented)); + Sb.Append("\n").Append(JsonWrapper.SerializeObject(eachLog.Data)); } return Sb.ToString(); } - - public class TimeSpanFloatSeconds : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - var timeSpan = (TimeSpan)value; - serializer.Serialize(writer, timeSpan.TotalSeconds); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - return TimeSpan.FromSeconds(serializer.Deserialize<float>(reader)); - } - - public override bool CanConvert(Type objectType) - { - return objectType == typeof(TimeSpan); - } - } } } diff --git a/PlayFabSDK/source/Uunit/PlayFabApiTest.cs b/PlayFabSDK/source/Uunit/PlayFabApiTest.cs new file mode 100644 index 00000000..14b0a3e3 --- /dev/null +++ b/PlayFabSDK/source/Uunit/PlayFabApiTest.cs @@ -0,0 +1,431 @@ +#if !DISABLE_PLAYFABCLIENT_API + +using PlayFab.ClientModels; +using PlayFab.Internal; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using PlayFab.Json; + +namespace PlayFab.UUnit +{ + /// <summary> + /// A real system would potentially run only the client or server API, and not both. + /// But, they still interact with eachother directly. + /// The tests can't be independent for Client/Server, as the sequence of calls isn't really independent for real-world scenarios. + /// The client logs in, which triggers a server, and then back and forth. + /// For the purpose of testing, they each have pieces of information they share with one another, and that sharing makes various calls possible. + /// </summary> + public class PlayFabApiTest : UUnitTestCase + { + private const string TEST_STAT_NAME = "str"; + private const string TEST_DATA_KEY = "testCounter"; + + private int _testInteger; + + // Functional + private static bool TITLE_INFO_SET = false; + + // Fixed values provided from testInputs + private static string USER_EMAIL; + + // Information fetched by appropriate API calls + public static string PlayFabId; + + // Performance + [ThreadStatic] + private static StringBuilder _sb; + + /// <summary> + /// PlayFab Title cannot be created from SDK tests, so you must provide your titleId to run unit tests. + /// (Also, we don't want lots of excess unused titles) + /// </summary> + public static void SetTitleInfo(Dictionary<string, string> testInputs) + { + string eachValue; + + TITLE_INFO_SET = true; + + // Parse all the inputs + TITLE_INFO_SET &= testInputs.TryGetValue("titleId", out eachValue); + PlayFabSettings.TitleId = eachValue; + + TITLE_INFO_SET &= testInputs.TryGetValue("userEmail", out USER_EMAIL); + + // Verify all the inputs won't cause crashes in the tests + TITLE_INFO_SET &= !string.IsNullOrEmpty(PlayFabSettings.TitleId) + && !string.IsNullOrEmpty(USER_EMAIL); + } + + public override void SetUp(UUnitTestContext testContext) + { + if (!TITLE_INFO_SET) + testContext.Skip(); // We cannot do client tests if the titleId is not given + } + + public override void Tick(UUnitTestContext testContext) + { + // No work needed, async tests will end themselves + } + + public override void TearDown(UUnitTestContext testContext) + { + } + + private static void ContinueWithContext<T>(Task<PlayFabResult<T>> srcTask, UUnitTestContext testContext, Action<PlayFabResult<T>, UUnitTestContext, string> continueAction, bool expectSuccess, string failMessage, bool endTest) where T : PlayFabResultCommon + { + srcTask.ContinueWith(task => + { + var failed = true; + try + { + if (expectSuccess) + { + testContext.NotNull(task.Result, failMessage); + testContext.IsNull(task.Result.Error, PlayFabUtil.GetErrorReport(task.Result.Error)); + testContext.NotNull(task.Result.Result, failMessage); + } + continueAction?.Invoke(task.Result, testContext, failMessage); + failed = false; + } + catch (UUnitSkipException uu) + { + // Silence the assert and ensure the test is marked as complete - The exception is just to halt the test process + testContext.EndTest(UUnitFinishState.SKIPPED, uu.Message); + } + catch (UUnitException uu) + { + // Silence the assert and ensure the test is marked as complete - The exception is just to halt the test process + testContext.EndTest(UUnitFinishState.FAILED, uu.Message + "\n" + uu.StackTrace); + } + catch (Exception e) + { + // Report this exception as an unhandled failure in the test + testContext.EndTest(UUnitFinishState.FAILED, e.ToString()); + } + if (!failed && endTest) + testContext.EndTest(UUnitFinishState.PASSED, null); + } + ); + } + + private static string CompileErrorReport(PlayFabError error) + { + if (_sb == null) + _sb = new StringBuilder(); + _sb.Length = 0; + _sb.Append(error.ErrorMessage); + foreach (var detailPair in error.ErrorDetails) + foreach (var msg in detailPair.Value) + _sb.Append("\n").Append(detailPair.Key).Append(": ").Append(msg); + return _sb.ToString(); + } + + /// <summary> + /// CLIENT API + /// Try to deliberately log in with an inappropriate password, + /// and verify that the error displays as expected. + /// </summary> + [UUnitTest] + public void InvalidLogin(UUnitTestContext testContext) + { + // If the setup failed to log in a user, we need to create one. + var request = new LoginWithEmailAddressRequest + { + TitleId = PlayFabSettings.TitleId, + Email = USER_EMAIL, + Password = "INVALID", + }; + var loginTask = PlayFabClientAPI.LoginWithEmailAddressAsync(request); + ContinueWithContext(loginTask, testContext, InvalidLoginContinued, false, "Login should fail", true); + } + private void InvalidLoginContinued(PlayFabResult<LoginResult> loginResult, UUnitTestContext testContext, string failMessage) + { + testContext.NotNull(loginResult, failMessage); + testContext.IsNull(loginResult.Result, failMessage); + testContext.NotNull(loginResult.Error, failMessage); + testContext.True(loginResult.Error.ErrorMessage.Contains("password"), loginResult.Error.ErrorMessage); + } + + /// <summary> + /// CLIENT API + /// Try to deliberately register a user with an invalid email and password + /// Verify that errorDetails are populated correctly. + /// </summary> + [UUnitTest] + public void InvalidRegistration(UUnitTestContext testContext) + { + var registerRequest = new RegisterPlayFabUserRequest + { + TitleId = PlayFabSettings.TitleId, + Username = "x", + Email = "x", + Password = "x", + }; + var registerTask = PlayFabClientAPI.RegisterPlayFabUserAsync(registerRequest); + ContinueWithContext(registerTask, testContext, InvalidRegistrationContinued, false, "Registration should fail", true); + } + private void InvalidRegistrationContinued(PlayFabResult<RegisterPlayFabUserResult> registerResult, UUnitTestContext testContext, string failMessage) + { + testContext.NotNull(registerResult, failMessage); + testContext.IsNull(registerResult.Result, failMessage); + testContext.NotNull(registerResult.Error, failMessage); + + var expectedEmailMsg = "email address is not valid."; + var expectedPasswordMsg = "password must be between"; + var fullReport = CompileErrorReport(registerResult.Error); + + testContext.True(fullReport.ToLower().Contains(expectedEmailMsg), "Expected an error about bad email address: " + fullReport); + testContext.True(fullReport.ToLower().Contains(expectedPasswordMsg), "Expected an error about bad password: " + fullReport); + } + + /// <summary> + /// CLIENT API + /// Log in or create a user, track their PlayFabId + /// </summary> + [UUnitTest] + public void LoginOrRegister(UUnitTestContext testContext) + { + var loginRequest = new LoginWithCustomIDRequest + { + TitleId = PlayFabSettings.TitleId, + CustomId = PlayFabSettings.BuildIdentifier, + CreateAccount = true + }; + var loginTask = PlayFabClientAPI.LoginWithCustomIDAsync(loginRequest); + ContinueWithContext(loginTask, testContext, LoginOrRegisterContinued, true, "User login failed", true); + } + private void LoginOrRegisterContinued(PlayFabResult<LoginResult> loginResult, UUnitTestContext testContext, string failMessage) + { + PlayFabId = loginResult.Result.PlayFabId; // Needed for subsequent tests + testContext.True(PlayFabClientAPI.IsClientLoggedIn(), "User login failed"); + } + + /// <summary> + /// CLIENT API + /// Test that the login call sequence sends the AdvertisingId when set + /// </summary> + [UUnitTest] + public void LoginWithAdvertisingId(UUnitTestContext testContext) + { + PlayFabSettings.AdvertisingIdType = PlayFabSettings.AD_TYPE_ANDROID_ID; + PlayFabSettings.AdvertisingIdValue = "PlayFabTestId"; + + var loginRequest = new LoginWithCustomIDRequest + { + TitleId = PlayFabSettings.TitleId, + CustomId = PlayFabSettings.BuildIdentifier, + CreateAccount = true + }; + var loginTask = PlayFabClientAPI.LoginWithCustomIDAsync(loginRequest); + ContinueWithContext(loginTask, testContext, LoginWithAdvertisingIdContinued, true, "Login with advertId failed", true); + } + private void LoginWithAdvertisingIdContinued(PlayFabResult<LoginResult> loginResult, UUnitTestContext testContext, string failMessage) + { + PlayFabId = loginResult.Result.PlayFabId; // Needed for subsequent tests + testContext.True(PlayFabClientAPI.IsClientLoggedIn(), "User login failed"); + + testContext.StringEquals(PlayFabSettings.AD_TYPE_ANDROID_ID + "_Successful", PlayFabSettings.AdvertisingIdType); + } + + /// <summary> + /// CLIENT API + /// Test a sequence of calls that modifies saved data, + /// and verifies that the next sequential API call contains updated data. + /// Verify that the data is correctly modified on the next call. + /// Parameter types tested: string, Dictionary>string, string>, DateTime + /// </summary> + [UUnitTest] + public void UserDataApi(UUnitTestContext testContext) + { + var getRequest = new GetUserDataRequest(); + var getDataTask1 = PlayFabClientAPI.GetUserDataAsync(getRequest); + ContinueWithContext(getDataTask1, testContext, UserDataApiContinued1, true, "GetUserData1 call failed", false); + } + private void UserDataApiContinued1(PlayFabResult<GetUserDataResult> getDataResult1, UUnitTestContext testContext, string failMessage) + { + UserDataRecord testCounter; + if (!getDataResult1.Result.Data.TryGetValue(TEST_DATA_KEY, out testCounter)) + testCounter = new UserDataRecord { Value = "0" }; + int.TryParse(testCounter.Value, out _testInteger); + _testInteger = (_testInteger + 1) % 100; // This test is about the expected value changing - but not testing more complicated issues like bounds + + var updateRequest = new UpdateUserDataRequest { Data = new Dictionary<string, string> { { TEST_DATA_KEY, _testInteger.ToString() } } }; + var updateTask = PlayFabClientAPI.UpdateUserDataAsync(updateRequest); + ContinueWithContext(updateTask, testContext, UserDataApiContinued2, true, "UpdateUserData call failed", false); // The update doesn't return anything interesting except versionID. It's better to just re-call GetUserData again below to verify the update + } + private void UserDataApiContinued2(PlayFabResult<UpdateUserDataResult> updateResult, UUnitTestContext testContext, string failMessage) + { + var getRequest = new GetUserDataRequest(); + var getDataTask2 = PlayFabClientAPI.GetUserDataAsync(getRequest); + ContinueWithContext(getDataTask2, testContext, UserDataApiContinued3, true, "GetUserData2 call failed", true); + } + private void UserDataApiContinued3(PlayFabResult<GetUserDataResult> getDataResult2, UUnitTestContext testContext, string failMessage) + { + int testCounterValueActual; + UserDataRecord testCounter; + getDataResult2.Result.Data.TryGetValue(TEST_DATA_KEY, out testCounter); + testContext.NotNull(testCounter, "The updated UserData was not found in the Api results"); + int.TryParse(testCounter.Value, out testCounterValueActual); + testContext.IntEquals(_testInteger, testCounterValueActual); + + var timeUpdated = testCounter.LastUpdated; + var testMin = DateTime.UtcNow - TimeSpan.FromMinutes(5); + var testMax = testMin + TimeSpan.FromMinutes(10); + testContext.True(testMin <= timeUpdated && timeUpdated <= testMax); + } + + /// <summary> + /// CLIENT API + /// Test a sequence of calls that modifies saved data, + /// and verifies that the next sequential API call contains updated data. + /// Verify that the data is saved correctly, and that specific types are tested + /// Parameter types tested: Dictionary>string, int> + /// </summary> + [UUnitTest] + public void PlayerStatisticsApi(UUnitTestContext testContext) + { + var getRequest = new GetPlayerStatisticsRequest(); + var getStatTask1 = PlayFabClientAPI.GetPlayerStatisticsAsync(getRequest); + ContinueWithContext(getStatTask1, testContext, PlayerStatisticsApiContinued1, true, "GetPlayerStatistics1 call failed", false); + } + private void PlayerStatisticsApiContinued1(PlayFabResult<GetPlayerStatisticsResult> getStatResult1, UUnitTestContext testContext, string failMessage) + { + foreach (var eachStat in getStatResult1.Result.Statistics) + if (eachStat.StatisticName == TEST_STAT_NAME) + _testInteger = eachStat.Value; + _testInteger = (_testInteger + 1) % 100; // This test is about the expected value changing (incrementing through from TEST_STAT_BASE to TEST_STAT_BASE * 2 - 1) + + var updateRequest = new UpdatePlayerStatisticsRequest { Statistics = new List<StatisticUpdate> { new StatisticUpdate { StatisticName = TEST_STAT_NAME, Value = _testInteger } } }; + var updateTask = PlayFabClientAPI.UpdatePlayerStatisticsAsync(updateRequest); + ContinueWithContext(updateTask, testContext, PlayerStatisticsApiContinued2, true, "UpdatePlayerStatistics call failed", false); + } + private void PlayerStatisticsApiContinued2(PlayFabResult<UpdatePlayerStatisticsResult> updateResult, UUnitTestContext testContext, string failMessage) + { + var getRequest = new GetPlayerStatisticsRequest(); + var getStatTask2 = PlayFabClientAPI.GetPlayerStatisticsAsync(getRequest); + ContinueWithContext(getStatTask2, testContext, PlayerStatisticsApiContinued3, true, "GetPlayerStatistics2 call failed", true); + } + private void PlayerStatisticsApiContinued3(PlayFabResult<GetPlayerStatisticsResult> getStatResult2, UUnitTestContext testContext, string failMessage) + { + var testStatActual = int.MinValue; + foreach (var eachStat in getStatResult2.Result.Statistics) + if (eachStat.StatisticName == TEST_STAT_NAME) + testStatActual = eachStat.Value; + testContext.IntEquals(_testInteger, testStatActual); + } + + /// <summary> + /// SERVER API + /// Get or create the given test character for the given user + /// Parameter types tested: Contained-Classes, string + /// </summary> + [UUnitTest] + public void UserCharacter(UUnitTestContext testContext) + { + var request = new ListUsersCharactersRequest { PlayFabId = PlayFabId }; + var getCharsTask = PlayFabClientAPI.GetAllUsersCharactersAsync(request); + ContinueWithContext(getCharsTask, testContext, null, true, "Failed to GetChars", true); + } + + /// <summary> + /// CLIENT AND SERVER API + /// Test that leaderboard results can be requested + /// Parameter types tested: List of contained-classes + /// </summary> + [UUnitTest] + public void LeaderBoard(UUnitTestContext testContext) + { + var clientRequest = new GetLeaderboardRequest + { + MaxResultsCount = 3, + StatisticName = TEST_STAT_NAME, + }; + var clientTask = PlayFabClientAPI.GetLeaderboardAsync(clientRequest); + ContinueWithContext(clientTask, testContext, LeaderBoardContinued, true, "Failed to get client leaderboard", true); + } + private void LeaderBoardContinued(PlayFabResult<GetLeaderboardResult> clientResult, UUnitTestContext testContext, string failMessage) + { + testContext.True(clientResult.Result.Leaderboard.Count > 0, "Leaderboard does not contain enough entries."); + } + + /// <summary> + /// CLIENT API + /// Test that AccountInfo can be requested + /// Parameter types tested: List of enum-as-strings converted to list of enums + /// </summary> + [UUnitTest] + public void AccountInfo(UUnitTestContext testContext) + { + var request = new GetAccountInfoRequest { PlayFabId = PlayFabId }; + var accountTask = PlayFabClientAPI.GetAccountInfoAsync(request); + ContinueWithContext(accountTask, testContext, LeaderBoardContinued, true, "Failed to get accountInfo", true); + } + private void LeaderBoardContinued(PlayFabResult<GetAccountInfoResult> accountResult, UUnitTestContext testContext, string failMessage) + { + testContext.True(Enum.IsDefined(typeof(UserOrigination), accountResult.Result.AccountInfo.TitleInfo.Origination.Value), "Origination Enum not valid"); + } + + /// <summary> + /// CLIENT API + /// Test that CloudScript can be properly set up and invoked + /// </summary> + [UUnitTest] + public void CloudScript(UUnitTestContext testContext) + { + var request = new ExecuteCloudScriptRequest { FunctionName = "helloWorld" }; + var cloudTask = PlayFabClientAPI.ExecuteCloudScriptAsync(request); + ContinueWithContext(cloudTask, testContext, CloudScriptContinued, true, "Failed to Execute CloudScript", true); + } + private void CloudScriptContinued(PlayFabResult<ExecuteCloudScriptResult> cloudResult, UUnitTestContext testContext, string failMessage) + { + // Get the helloWorld return message + testContext.NotNull(cloudResult.Result.FunctionResult); + var jobj = (JsonObject)cloudResult.Result.FunctionResult; + var messageValue = jobj["messageValue"] as string; + testContext.StringEquals("Hello " + PlayFabId + "!", messageValue); + } + + /// <summary> + /// CLIENT API + /// Test that CloudScript errors can be deciphered + /// </summary> + [UUnitTest] + public void CloudScriptError(UUnitTestContext testContext) + { + var request = new ExecuteCloudScriptRequest { FunctionName = "throwError" }; + var cloudTask = PlayFabClientAPI.ExecuteCloudScriptAsync(request); + ContinueWithContext(cloudTask, testContext, CloudScriptErrorContinued, true, "Failed to Execute CloudScript", true); + } + private void CloudScriptErrorContinued(PlayFabResult<ExecuteCloudScriptResult> cloudResult, UUnitTestContext testContext, string failMessage) + { + // Get the JavascriptException result + testContext.IsNull(cloudResult.Result.FunctionResult); + testContext.NotNull(cloudResult.Result.Error); + testContext.StringEquals(cloudResult.Result.Error.Error, "JavascriptException"); + } + + /// <summary> + /// CLIENT API + /// Test that the client can publish custom PlayStream events + /// </summary> + [UUnitTest] + public void WriteEvent(UUnitTestContext testContext) + { + var request = new WriteClientPlayerEventRequest + { + EventName = "ForumPostEvent", + Timestamp = DateTime.UtcNow, + Body = new Dictionary<string, object> { + { "Subject", "My First Post" }, + { "Body", "My awesome Post." }, + } + }; + + var writeTask = PlayFabClientAPI.WritePlayerEventAsync(request); + ContinueWithContext(writeTask, testContext, null, true, "PlayStream WriteEvent failed", true); + } + } +} +#endif diff --git a/PlayFabSDK/source/Uunit/UUnitAssertException.cs b/PlayFabSDK/source/Uunit/UUnitAssertException.cs index 94ce32f8..96130a17 100644 --- a/PlayFabSDK/source/Uunit/UUnitAssertException.cs +++ b/PlayFabSDK/source/Uunit/UUnitAssertException.cs @@ -10,34 +10,29 @@ namespace PlayFab.UUnit { + /// <summary> + /// The internal uunit exception base class, which you can use to capture all UUnit exceptions + /// </summary> + public class UUnitException : Exception + { + public UUnitException(string message) : base(message) { } + } + /// <summary> /// Throw this exception, via UUnitAssert utility function, in order to define when a test has been skipped. /// The only information shown will be the "skipped" notification /// </summary> - public class UUnitSkipException : Exception { } + public class UUnitSkipException : UUnitException + { + public UUnitSkipException(string message) : base(message) { } + } - /// <summary> + /// <summary> /// Throw this exception, via UUnitAssert utility functions, in order to define when a test has failed. - /// The traceback and message will automatically be displayed as a failure + /// The traceback and Message will automatically be displayed as a failure /// </summary> - public class UUnitAssertException : Exception + public class UUnitAssertException : UUnitException { - public object expected; - public object received; - public string message; - - public UUnitAssertException(string message) - : base(message) - { - this.message = message; - } - - public UUnitAssertException(object expected, object received, string message) - : base("[UUnit] - Assert Failed - Expected: " + expected + " Received: " + received + "\n\t\t(" + message + ")") - { - this.expected = (expected == null) ? "null" : expected; - this.received = (received == null) ? "null" : received; - this.message = (message == null) ? "" : message; - } + public UUnitAssertException(string message) : base(message) { } } } diff --git a/PlayFabSDK/source/Uunit/UUnitIncrementalTestRunner.cs b/PlayFabSDK/source/Uunit/UUnitIncrementalTestRunner.cs new file mode 100644 index 00000000..7f2d7624 --- /dev/null +++ b/PlayFabSDK/source/Uunit/UUnitIncrementalTestRunner.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +#if !DISABLE_PLAYFABCLIENT_API +using PlayFab.ClientModels; +#endif + +namespace PlayFab.UUnit +{ + public static class UUnitIncrementalTestRunner + { + public static bool SuiteFinished { get; private set; } + public static bool AllTestsPassed { get; private set; } + public static string Summary { get; private set; } + private static UUnitTestSuite _suite; + private static bool _postResultsToCloudscript; +#if !DISABLE_PLAYFABCLIENT_API + private static Action<PlayFabResult<ExecuteCloudScriptResult>> _onComplete; +#endif + + public static void Start(bool postResultsToCloudscript = true, string filter = null, Dictionary<string, string> testInputs = null +#if !DISABLE_PLAYFABCLIENT_API + , Action<PlayFabResult<ExecuteCloudScriptResult>> onComplete = null +#endif + ) + { + // Fall back on hard coded testTitleData if necessary (Put your own data here) + if (testInputs == null) + testInputs = new Dictionary<string, string> { { "titleId", "6195" }, { "userEmail", "paul@playfab.com" } }; +#if !DISABLE_PLAYFABCLIENT_API + PlayFabApiTest.SetTitleInfo(testInputs); +#endif + + SuiteFinished = false; + AllTestsPassed = false; + _postResultsToCloudscript = postResultsToCloudscript; + _suite = new UUnitTestSuite(); + _suite.FindAndAddAllTestCases(typeof(UUnitTestCase), filter); +#if !DISABLE_PLAYFABCLIENT_API + _onComplete = onComplete; +#endif + } + + public static string Tick() + { + if (SuiteFinished) + return Summary; + + SuiteFinished = _suite.TickTestSuite(); + Summary = _suite.GenerateSummary(); + AllTestsPassed = _suite.AllTestsPassed(); + + if (SuiteFinished) + OnSuiteFinish(); + + return Summary; + } + + private static void OnSuiteFinish() + { + if (_postResultsToCloudscript) + PostTestResultsToCloudScript(_suite.GetInternalReport()); + } + + private static void PostTestResultsToCloudScript(TestSuiteReport testReport) + { +#if !DISABLE_PLAYFABCLIENT_API + var request = new ExecuteCloudScriptRequest + { + FunctionName = "SaveTestData", + FunctionParameter = new Dictionary<string, object> { { "customId", PlayFabSettings.BuildIdentifier }, { "testReport", new[] { testReport } } }, + GeneratePlayStreamEvent = true + }; + var saveTask = PlayFabClientAPI.ExecuteCloudScriptAsync(request); + saveTask.ContinueWith(task => + { + if (_onComplete != null) + _onComplete(task.Result); + } + ); +#endif + } + } +} diff --git a/PlayFabSDK/source/Uunit/UUnitTestCase.cs b/PlayFabSDK/source/Uunit/UUnitTestCase.cs index 0ecc07ef..f9287dd1 100644 --- a/PlayFabSDK/source/Uunit/UUnitTestCase.cs +++ b/PlayFabSDK/source/Uunit/UUnitTestCase.cs @@ -7,102 +7,54 @@ */ using System; -using System.Diagnostics; -using System.Reflection; namespace PlayFab.UUnit { public class UUnitTestCase { - private delegate void UUnitTestDelegate(); - private static Type[] EMPTY_PARAMETER_TYPES = new Type[0]; - private static object[] EMPTY_PARAMETERS = new object[0]; - - Stopwatch setUpStopwatch = new Stopwatch(); - Stopwatch tearDownStopwatch = new Stopwatch(); - Stopwatch eachTestStopwatch = new Stopwatch(); - private string testMethodName; - - public void SetTest(string testMethodName) + /// <summary> + /// During testing, this is the first function that will be called for each UUnitTestCase. + /// This is run exactly once for this type. + /// It is not considered part of any test. A failure or exception in this method will halt the test framework. + /// </summary> + public virtual void ClassSetUp() { - this.testMethodName = testMethodName; } - public void Run(UUnitTestResults testResults) + /// <summary> + /// During testing, this will be called once before every test function with the [UUnitTest] attribute + /// This is run once for each test. + /// This is considered part of the active test. A failure or exception in this method will be considered a failure for the active test. + /// </summary> + public virtual void SetUp(UUnitTestContext testContext) { - TestFinishState testFinishState = TestFinishState.FAILED; - string message = null, stacktrace = null; - eachTestStopwatch.Reset(); - setUpStopwatch.Reset(); - tearDownStopwatch.Reset(); - - try - { - testResults.TestStarted(); - - setUpStopwatch.Start(); - SetUp(); - setUpStopwatch.Stop(); - - Type type = this.GetType(); - MethodInfo method = type.GetRuntimeMethod(testMethodName, EMPTY_PARAMETER_TYPES); // Test methods must contain no parameters - UUnitAssert.NotNull(method, "Could not execute: " + testMethodName + ", it's probably not public."); // Limited access to loaded assemblies - eachTestStopwatch.Start(); - ((UUnitTestDelegate)method.CreateDelegate(typeof(UUnitTestDelegate), this))(); // This creates a delegate of the test function, and calls it - testFinishState = TestFinishState.PASSED; - } - catch (UUnitAssertException e) - { - message = e.message; - stacktrace = e.StackTrace; - testFinishState = TestFinishState.FAILED; - } - catch (UUnitSkipException) - { - // message remains null - testFinishState = TestFinishState.SKIPPED; - } - catch (TargetInvocationException e) - { - message = e.InnerException.Message; - stacktrace = e.InnerException.StackTrace; - testFinishState = TestFinishState.FAILED; - } - catch (Exception e) - { - message = e.Message; - stacktrace = e.StackTrace; - testFinishState = TestFinishState.FAILED; - } - finally - { - eachTestStopwatch.Stop(); - - if (testFinishState != TestFinishState.SKIPPED) - { - try - { - tearDownStopwatch.Start(); - TearDown(); - tearDownStopwatch.Stop(); - } - catch (Exception e) - { - message = e.Message; - stacktrace = e.StackTrace; - testFinishState = TestFinishState.FAILED; - } - } - } + } - testResults.TestComplete(testMethodName, testFinishState, eachTestStopwatch.ElapsedMilliseconds, message, stacktrace); + /// <summary> + /// During testing, this will be called every tick that a test is asynchronous. + /// This is run every unity tick until testContext.EndTest() is called, or until the test times out. + /// This is considered part of the active test. A failure or exception in this method will be considered a failure for the active test. + /// </summary> + public virtual void Tick(UUnitTestContext testContext) + { + testContext.Fail(GetType().Name + "." + testContext.Name + ": Async TestCase does not implement Tick(). To fix this error, implement \"" + GetType().Name + ".Tick()\" in your async test, or call testContext.EndTest() in your syncronous test."); } - protected virtual void SetUp() + /// <summary> + /// During testing, this will be called once after every test function with the [UUnitTest] attribute. + /// This is run once for each test. + /// This is considered part of the active test. A failure or exception in this method will be considered a failure for the active test. + /// </summary> + public virtual void TearDown(UUnitTestContext testContext) { } - protected virtual void TearDown() + /// <summary> + /// During testing, this is the last function that will be called for each UUnitTestCase. + /// This is run exactly once for this type. + /// It is not considered part of any test. A failure or exception in this method will halt the test framework. + /// </summary> + public virtual void ClassTearDown() { } } diff --git a/PlayFabSDK/source/Uunit/UUnitTestContext.cs b/PlayFabSDK/source/Uunit/UUnitTestContext.cs new file mode 100644 index 00000000..d9c9aca3 --- /dev/null +++ b/PlayFabSDK/source/Uunit/UUnitTestContext.cs @@ -0,0 +1,254 @@ +/* + * UUnit system from UnityCommunity + * Heavily modified + * 0.4 release by pboechat + * http://wiki.unity3d.com/index.php?title=UUnit + * http://creativecommons.org/licenses/by-sa/3.0/ +*/ + +using System; +using System.Collections.Generic; + +namespace PlayFab.UUnit +{ + public enum UUnitActiveState + { + PENDING, // Not started + ACTIVE, // Currently testing + READY, // An answer is sent by the http thread, but the main thread hasn't finalized the test yet + COMPLETE, // Test is finalized and recorded + ABORTED // todo + }; + + public class UUnitTestContext + { + public const float DefaultFloatPrecision = 0.0001f; + public const double DefaultDoublePrecision = 0.000001; + + public UUnitActiveState ActiveState; + public UUnitFinishState FinishState; + public Action<UUnitTestContext> TestDelegate; + public UUnitTestCase TestInstance; + public DateTime StartTime; + public DateTime EndTime; + public string TestResultMsg; + public string Name; + + public UUnitTestContext(UUnitTestCase testInstance, Action<UUnitTestContext> testDelegate, string name) + { + TestInstance = testInstance; + TestDelegate = testDelegate; + ActiveState = UUnitActiveState.PENDING; + Name = name; + } + + internal void EndTest(UUnitFinishState finishState, string resultMsg) + { + EndTime = DateTime.UtcNow; + TestResultMsg = resultMsg; + FinishState = finishState; + ActiveState = UUnitActiveState.READY; + } + + public void Skip(string message = "") + { + EndTime = DateTime.UtcNow; + EndTest(UUnitFinishState.SKIPPED, message); + throw new UUnitSkipException(message); + } + + public void Fail(string message = null) + { + if (string.IsNullOrEmpty(message)) + message = "fail"; + EndTest(UUnitFinishState.FAILED, message); + throw new UUnitAssertException(message); + } + + public void True(bool boolean, string message = null) + { + if (boolean) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: true, Actual: false"; + Fail(message); + } + + public void False(bool boolean, string message = null) + { + if (!boolean) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: false, Actual: true"; + Fail(message); + } + + public void NotNull(object something, string message = null) + { + if (something != null) + return; // Success + + if (string.IsNullOrEmpty(message)) + message = "Null object"; + Fail(message); + } + + public void IsNull(object something, string message = null) + { + if (something == null) + return; + + if (string.IsNullOrEmpty(message)) + message = "Not null object"; + Fail(message); + } + + public void StringEquals(string wanted, string got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void SbyteEquals(sbyte? wanted, sbyte? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void ByteEquals(byte? wanted, byte? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void ShortEquals(short? wanted, short? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void UshortEquals(ushort? wanted, ushort? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void IntEquals(int? wanted, int? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void UintEquals(uint? wanted, uint? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void LongEquals(long? wanted, long? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void ULongEquals(ulong? wanted, ulong? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void FloatEquals(float? wanted, float? got, float precision = DefaultFloatPrecision, string message = null) + { + if (wanted == null && got == null) + return; + if (wanted != null && got != null && Math.Abs(wanted.Value - got.Value) < precision) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void DoubleEquals(double? wanted, double? got, double precision = DefaultDoublePrecision, string message = null) + { + if (wanted == null && got == null) + return; + if (wanted != null && got != null && Math.Abs(wanted.Value - got.Value) < precision) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void ObjEquals(object wanted, object got, string message = null) + { + if (wanted == null && got == null) + return; + if (wanted != null && got != null && wanted.Equals(got)) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void SequenceEquals<T>(IEnumerable<T> wanted, IEnumerable<T> got, string message = null) + { + var wEnum = wanted.GetEnumerator(); + var gEnum = got.GetEnumerator(); + + bool wNext, gNext; + int count = 0; + while (true) + { + wNext = wEnum.MoveNext(); + gNext = gEnum.MoveNext(); + if (wNext != gNext) + Fail(message); + if (!wNext) + break; + count++; + ObjEquals(wEnum.Current, gEnum.Current, "Element at " + count + ": " + message); + } + } + } +} diff --git a/PlayFabSDK/source/Uunit/UUnitTestReport.cs b/PlayFabSDK/source/Uunit/UUnitTestReport.cs new file mode 100644 index 00000000..65e37236 --- /dev/null +++ b/PlayFabSDK/source/Uunit/UUnitTestReport.cs @@ -0,0 +1,115 @@ +/* + * UUnit system from UnityCommunity + * Heavily modified + * 0.4 release by pboechat + * http://wiki.unity3d.com/index.php?title=UUnit + * http://creativecommons.org/licenses/by-sa/3.0/ +*/ + +using System; +using System.Collections.Generic; + +namespace PlayFab.UUnit +{ + public enum UUnitFinishState + { + PENDING, + PASSED, + FAILED, + SKIPPED, + TIMEDOUT + } + + /// <summary> + /// This is a wrapper around TestSuiteReport with the callbacks that let UUnitTestSuite manipulate/append results, and UUnitTestRunner display them + /// </summary> + public class UUnitTestReport + { + public readonly TestSuiteReport InternalReport = new TestSuiteReport(); + + public UUnitTestReport(string classname) + { + InternalReport.name = classname; + InternalReport.timestamp = DateTime.UtcNow; + } + + public void TestStarted() + { + InternalReport.tests += 1; + } + + public void TestComplete(string testName, UUnitFinishState finishState, long stopwatchMs, string message, string stacktrace) + { + var report = new TestCaseReport + { + message = message, + classname = InternalReport.name, + failureText = finishState.ToString(), + finishState = finishState, + name = testName, + time = TimeSpan.FromMilliseconds(stopwatchMs) + }; + if (InternalReport.testResults == null) + InternalReport.testResults = new List<TestCaseReport>(); + InternalReport.testResults.Add(report); + + switch (finishState) + { + case (UUnitFinishState.PASSED): + InternalReport.passed += 1; break; + case (UUnitFinishState.FAILED): + InternalReport.failures += 1; break; + case (UUnitFinishState.SKIPPED): + InternalReport.skipped += 1; break; + } + + // TODO: Add hooks for SuiteSetUp and SuiteTearDown, so this can be estimated more accurately + InternalReport.time = DateTime.UtcNow - InternalReport.timestamp; // For now, update the duration on every test complete - the last one will be essentially correct + } + + /// <summary> + /// Return that tests were run, and all of them reported FinishState + /// </summary> + public bool AllTestsPassed() + { + return InternalReport.tests > 0 && InternalReport.tests == (InternalReport.passed + InternalReport.skipped) && InternalReport.failures == 0; + } + } + + /// <summary> + /// Data container defining the test-suite data saved to JUnit XML format + /// </summary> + public class TestSuiteReport + { + // Part of the XML spec + public List<TestCaseReport> testResults; + public string name; + public int tests; + public int failures; + public int errors; + public int skipped; + public TimeSpan time; + public DateTime timestamp; + public Dictionary<string, string> properties; + // Useful for debugging but not part of the serialized format + public int passed; // Could be calculated from the others, but sometimes knowing if they don't add up means something + } + + /// <summary> + /// Data container defining the test-case data saved to JUnit XML format + /// </summary> + public class TestCaseReport + { + public string classname; + public string name; + public TimeSpan time; + // Sub-Fields in the XML spec + /// <summary> message is the descriptive text used to debug the test failure </summary> + public string message; + /// <summary> The xml spec allows failureText to be an arbitrary string. When possible it should match FinishState (But not required) </summary> + public string failureText; + public UUnitFinishState finishState; + // Other parameters not part of the xml spec, used for internal debugging + public string stacktrace; + } +} diff --git a/PlayFabSDK/source/Uunit/UUnitTestSuite.cs b/PlayFabSDK/source/Uunit/UUnitTestSuite.cs index b2197856..d5feee87 100644 --- a/PlayFabSDK/source/Uunit/UUnitTestSuite.cs +++ b/PlayFabSDK/source/Uunit/UUnitTestSuite.cs @@ -7,6 +7,7 @@ */ using System; +using System.Text; using System.Collections.Generic; using System.Reflection; @@ -19,95 +20,295 @@ public class UUnitTestAttribute : Attribute public class UUnitTestSuite { - private readonly List<UUnitTestCase> _tests = new List<UUnitTestCase>(); - private int _lastTestIndex = -1; - private readonly UUnitTestResults _testResults; + private const int TIME_ALIGNMENT_WIDTH = 10; + private static readonly TimeSpan TestTimeout = TimeSpan.FromSeconds(15); + private static readonly StringBuilder sb = new StringBuilder(); - public UUnitTestSuite(string classname) + private readonly List<UUnitTestContext> _testContexts = new List<UUnitTestContext>(); + private int _activeIndex = 0; + private readonly UUnitTestReport _testReport = new UUnitTestReport(PlayFabSettings.BuildIdentifier); + private UUnitActiveState _suiteState = UUnitActiveState.PENDING; + private UUnitTestCase activeTestInstance = null; + + public string GenerateSummary() { - _testResults = new UUnitTestResults(classname); + sb.Length = 0; + + DateTime now = DateTime.UtcNow, eachStartTime, eachEndTime; + int finished = 0, passed = 0, failed = 0, skipped = 0; + + foreach (var eachContext in _testContexts) + { + // Count tests + if (eachContext.ActiveState == UUnitActiveState.COMPLETE) + { + finished++; + eachStartTime = eachContext.StartTime; + eachEndTime = eachContext.EndTime; + if (eachContext.FinishState == UUnitFinishState.PASSED) + passed++; + else if (eachContext.FinishState == UUnitFinishState.SKIPPED) + skipped++; + else + failed++; + } + else + { + eachStartTime = eachContext.ActiveState == UUnitActiveState.PENDING ? now : eachContext.StartTime; + eachEndTime = now; + } + + // line for each test report + if (sb.Length != 0) + sb.Append("\n"); + var ms = (eachEndTime - eachStartTime).TotalMilliseconds.ToString("0"); + for (var i = ms.Length; i < TIME_ALIGNMENT_WIDTH; i++) + sb.Append(' '); + sb.Append(ms).Append(" ms - ").Append(eachContext.FinishState); + sb.Append(" - ").Append(eachContext.Name); + if (!string.IsNullOrEmpty(eachContext.TestResultMsg)) + { + sb.Append(" - ").Append(eachContext.TestResultMsg); + // TODO: stacktrace + } + } + + sb.AppendFormat("\nTesting complete: {0}/{1} test run, {2} tests passed, {3} tests failed, {4} tests skipped.", finished, _testContexts.Count, passed, failed, skipped); + + return sb.ToString(); } - public void Add(UUnitTestCase testCase) + public TestSuiteReport GetInternalReport() { - _tests.Add(testCase); + return _testReport.InternalReport; } - public void RunAllTests() + public void FindAndAddAllTestCases(Type parent, string filter = null) { - bool eachResult = false; - while (eachResult == false) - eachResult = RunOneTest(); + if (_suiteState != UUnitActiveState.PENDING) + throw new Exception("Must add all tests before executing tests."); + +#if NETFX_CORE + var eachAssembly = typeof(UUnitTestCase).GetTypeInfo().Assembly; // We can only load assemblies known in advance on WSA +#else + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + foreach (var eachAssembly in assemblies) +#endif + FindAndAddAllTestCases(eachAssembly, parent, filter); } - /// <summary> - /// Run a single test, and return whether the test suite is finished - /// </summary> - /// <returns>True when all _tests are finished</returns> - public bool RunOneTest() + public void FindAndAddAllTestCases(Assembly assembly, Type parent, string filter = null) + { + if (_suiteState != UUnitActiveState.PENDING) + throw new Exception("Must add all tests before executing tests."); + + var types = assembly.GetTypes(); + foreach (var t in types) + if (!t.GetTypeInfo().IsAbstract && t.GetTypeInfo().IsSubclassOf(parent)) + AddTestsForType(t.AsType(), filter); + } + + private void AddTestsForType(Type testCaseType, string filter = null) { - // Abort if we've already finished testing - bool doneTesting = _lastTestIndex >= _tests.Count; - if (doneTesting) return true; + if (_suiteState != UUnitActiveState.PENDING) + throw new Exception("Must add all tests before executing tests."); + + var filterSet = AssembleFilter(filter); + + UUnitTestCase newTestCase = null; + foreach (var constructorInfo in testCaseType.GetTypeInfo().GetConstructors()) + { + try + { + newTestCase = (UUnitTestCase)constructorInfo.Invoke(null); + } + catch (Exception) { } // Ignore it and try the next one + } + if (newTestCase == null) + throw new Exception(testCaseType.Name + " must have a parameter-less constructor."); + + var methods = testCaseType.GetTypeInfo().GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + var attributesList = new List<object>(); + foreach (var methodInfo in methods) + { + attributesList.Clear(); + attributesList.AddRange(methodInfo.GetCustomAttributes(typeof(UUnitTestAttribute), false)); + if (attributesList.Count == 0 || !MatchesFilters(methodInfo.Name, filterSet)) // There can only be 1, and we only care about attribute existence (no data on attribute), and it has to match the filter + continue; + + Action<UUnitTestContext> eachTestDelegate = CreateDelegate<UUnitTestContext>(testCaseType.Name, newTestCase, methodInfo); + if (eachTestDelegate != null) + _testContexts.Add(new UUnitTestContext(newTestCase, eachTestDelegate, methodInfo.Name)); + } + } - _lastTestIndex++; - doneTesting = _lastTestIndex >= _tests.Count; - if (!doneTesting) + private static Action<T> CreateDelegate<T>(string typeName, object instance, MethodInfo methodInfo) + { + Action<T> eachTestDelegate; + try + { + eachTestDelegate = methodInfo.CreateDelegate(typeof(Action<T>), instance) as Action<T>; + } + catch (Exception e) { - _tests[_lastTestIndex].Run(_testResults); + var sb = new StringBuilder(); + sb.Append(typeName).Append(".").Append(methodInfo.Name).Append(" must match the test delegate signature: Action<T>"); + sb.Append("\n").Append(e); + + sb.Append("\nExpected Params: ["); + var actionInfo = typeof(Action<T>).GetMethod("Invoke"); + foreach (var param in actionInfo.GetParameters()) + sb.Append(param.Name).Append(","); + sb.Append("]"); + + sb.Append("\nActual Params: ["); + foreach (var param in methodInfo.GetParameters()) + sb.Append(param.Name).Append(","); + sb.Append("]"); + throw new Exception(sb.ToString()); } - return doneTesting; + return eachTestDelegate; + } + + private HashSet<string> AssembleFilter(string filter) + { + if (string.IsNullOrEmpty(filter)) + return null; + var filterWords = filter.ToLower().Split(new char[] { '\n', ',', ' ' }, StringSplitOptions.RemoveEmptyEntries); + if (filterWords.Length > 0) + return new HashSet<string>(filterWords); + return null; } - public UUnitTestResults GetResults() + private bool MatchesFilters(string name, HashSet<string> filterSet) { - bool doneTesting = _lastTestIndex >= _tests.Count; - return doneTesting ? _testResults : null; // Only return the results when finished + if (filterSet == null) + return true; + var nameLc = name.ToLower(); + foreach (var eachFilter in filterSet) + if (nameLc.Contains(eachFilter)) + return true; + return false; } /// <summary> - /// If using WinStore/WinPhone, you should call via: - /// suite.FindAndAddAllTestCases(typeof(UUnitTestSuite).GetTypeInfo().Assembly, typeof(UUnitTestCase)) - /// If you have full reflection (IE everything else), call via: - /// foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) - /// suite.FindAndAddAllTestCases(assembly, typeof(UUnitTestCase)); - /// Don't add the same assembly/parent multiple times, or it'll repeat the same test multiple times + /// Return that tests were run, and all of them reported success /// </summary> - /// <param name="assembly"></param> - /// <param name="parent"></param> - public void FindAndAddAllTestCases(Assembly assembly, Type parent) + public bool AllTestsPassed() { - foreach (var t in assembly.DefinedTypes) - if (!t.IsAbstract && t.IsSubclassOf(parent)) - AddAll(t); + return _testReport.AllTestsPassed(); } - private void AddAll(TypeInfo testCaseType) + /// <summary> + /// Tick the test suite. + /// This should be called once per Update until it returns true. + /// Once it returns true, testing is complete + /// </summary> + public bool TickTestSuite() { - foreach (MethodInfo m in testCaseType.DeclaredMethods) + if (_suiteState == UUnitActiveState.COMPLETE) + return true; + if (_suiteState == UUnitActiveState.PENDING) + _suiteState = UUnitActiveState.ACTIVE; + + var nextTest = _activeIndex < _testContexts.Count ? _testContexts[_activeIndex] : null; + if (nextTest != null && nextTest.ActiveState == UUnitActiveState.COMPLETE) { - var attributes = m.GetCustomAttributes(typeof(UUnitTestAttribute), false); - foreach (var attr in attributes) - { - var constructors = testCaseType.DeclaredConstructors; - foreach (var constructor in constructors) - { - UUnitTestCase newTestCase = (UUnitTestCase)constructor.Invoke(null); - newTestCase.SetTest(m.Name); - Add(newTestCase); - break; // We only want 1 constructor, if relevant - } - break; // We only want 1 attribute, if relevant - } + _activeIndex++; + nextTest = (_activeIndex >= _testContexts.Count) ? null : _testContexts[_activeIndex]; + } + + if (nextTest != null && nextTest.ActiveState == UUnitActiveState.PENDING) + StartTest(nextTest); + else if (nextTest != null) + TickTest(nextTest); + + var testsDone = _activeIndex >= _testContexts.Count; + if (testsDone && _suiteState == UUnitActiveState.ACTIVE) + { + _suiteState = UUnitActiveState.READY; + ManageInstance(null, activeTestInstance); // Ensure that the final test is cleaned up } + return _suiteState == UUnitActiveState.READY; } /// <summary> - /// Return that _tests were run, and all of them reported success + /// Start a test, track which test is active, and manage timers /// </summary> - public bool AllTestsPassed() + private void StartTest(UUnitTestContext testContext) + { + ManageInstance(testContext.TestInstance, activeTestInstance); + + testContext.StartTime = DateTime.UtcNow; + testContext.ActiveState = UUnitActiveState.ACTIVE; + _testReport.TestStarted(); + + if (testContext.ActiveState == UUnitActiveState.ACTIVE) + Wrap(testContext, testContext.TestInstance.SetUp); + if (testContext.ActiveState == UUnitActiveState.ACTIVE) + Wrap(testContext, testContext.TestDelegate); + // Async tests can't resolve this tick, so just return + } + + /// <summary> + /// Ensure that exceptions in any test-functions are relayed to the testContext as failures + /// </summary> + private void Wrap(UUnitTestContext testContext, Action<UUnitTestContext> testFunc) + { + try + { + testFunc(testContext); + } + catch (UUnitSkipException uu) + { + // Silence the assert and ensure the test is marked as complete - The exception is just to halt the test process + testContext.EndTest(UUnitFinishState.SKIPPED, uu.Message); + } + catch (UUnitException uu) + { + // Silence the assert and ensure the test is marked as complete - The exception is just to halt the test process + testContext.EndTest(UUnitFinishState.FAILED, uu.Message + "\n" + uu.StackTrace); + } + catch (Exception e) + { + // Report this exception as an unhandled failure in the test + testContext.EndTest(UUnitFinishState.FAILED, e.ToString()); + } + } + + /// <summary> + /// Manage the ClassSetUp and ClassTearDown functions for each UUnitTestCase + /// </summary> + private void ManageInstance(UUnitTestCase newtestInstance, UUnitTestCase oldTestInstance) + { + if (ReferenceEquals(newtestInstance, oldTestInstance)) + return; + + if (oldTestInstance != null) + oldTestInstance.ClassTearDown(); + if (newtestInstance != null) + newtestInstance.ClassSetUp(); + activeTestInstance = newtestInstance; + } + + private void TickTest(UUnitTestContext testContext) { - return _testResults.AllTestsPassed(); + var now = DateTime.UtcNow; + var timedOut = (now - testContext.StartTime) > TestTimeout; + if (testContext.ActiveState != UUnitActiveState.READY && !timedOut) // Not finished & not timed out + { + testContext.TestInstance.Tick(testContext); + return; + } + else if (testContext.ActiveState == UUnitActiveState.ACTIVE && timedOut) + { + testContext.EndTest(UUnitFinishState.TIMEDOUT, "Test duration exceeded maxumum"); + } + + testContext.EndTime = now; + testContext.ActiveState = UUnitActiveState.COMPLETE; + Wrap(testContext, testContext.TestInstance.TearDown); + _testReport.TestComplete(testContext.TestDelegate.Target.GetType().Name + "." + testContext.Name, testContext.FinishState, (int)(testContext.EndTime - testContext.StartTime).TotalMilliseconds, testContext.TestResultMsg, null); } } } diff --git a/PlayFabSDK/source/WsaReflectionExtensions.cs b/PlayFabSDK/source/WsaReflectionExtensions.cs new file mode 100644 index 00000000..d4991f22 --- /dev/null +++ b/PlayFabSDK/source/WsaReflectionExtensions.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +#if NETFX_CORE +/// <summary>Specifies flags that control binding and the way in which the search for members and types is conducted by reflection.</summary> +[Flags] +public enum BindingFlags +{ + IgnoreCase = 1, + DeclaredOnly = 2, + Instance = 4, + Static = 8, + Public = 16, + NonPublic = 32, + FlattenHierarchy = 64, +} +#endif + +public static class WsaReflectionExtensions +{ + public static Type AsType(this Type type) + { + return type; + } +#if !NETFX_CORE + public static Delegate CreateDelegate(this MethodInfo methodInfo, Type delegateType, object instance) + { + return Delegate.CreateDelegate(delegateType, instance, methodInfo); + } + public static Assembly GetAssembly(this Type type) + { + return type.Assembly; + } + public static Type GetTypeInfo(this Type type) + { + return type; + } + public static string GetDelegateName(this Delegate delegateInstance) + { + return delegateInstance.Method.Name; + } +#else + public static bool IsAssignableFrom(this Type type, Type other) + { + return type.GetTypeInfo().IsAssignableFrom(other.GetTypeInfo()); + } + public static bool IsAssignableFrom(this Type type, TypeInfo other) + { + return type.GetTypeInfo().IsAssignableFrom(other); + } + public static Assembly GetAssembly(this Type type) + { + return type.GetTypeInfo().Assembly; + } + public static bool IsInstanceOfType(this Type type, object obj) + { + return obj != null && type.GetTypeInfo().IsAssignableFrom(obj.GetType().GetTypeInfo()); + } + public static string GetDelegateName(this Delegate delegateInstance) + { + return delegateInstance.ToString(); + } + public static MethodInfo GetMethod(this Type type, string methodName) + { + return type.GetTypeInfo().GetDeclaredMethod(methodName); + } + public static IEnumerable<FieldInfo> GetFields(this TypeInfo typeInfo) + { + return typeInfo.DeclaredFields; + } + public static TypeInfo GetTypeInfo(this TypeInfo typeInfo) + { + return typeInfo; + } + public static IEnumerable<ConstructorInfo> GetConstructors(this TypeInfo typeInfo) + { + return typeInfo.DeclaredConstructors; + } + public static IEnumerable<MethodInfo> GetMethods(this TypeInfo typeInfo, BindingFlags ignored) + { + return typeInfo.DeclaredMethods; + } + public static IEnumerable<TypeInfo> GetTypes(this Assembly assembly) + { + return assembly.DefinedTypes; + } +#endif +} diff --git a/PlayFabServerSDK/PlayFabSDK.csproj b/PlayFabServerSDK/PlayFabSDK.csproj index ba944702..d02b2e1b 100644 --- a/PlayFabServerSDK/PlayFabSDK.csproj +++ b/PlayFabServerSDK/PlayFabSDK.csproj @@ -21,7 +21,7 @@ <DebugType>full</DebugType> <Optimize>false</Optimize> <OutputPath>bin\Debug\</OutputPath> - <DefineConstants>DEBUG;TRACE</DefineConstants> + <DefineConstants>TRACE;DEBUG;NETFX_CORE;SIMPLE_JSON_TYPEINFO;DISABLE_PLAYFABCLIENT_API</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> </PropertyGroup> @@ -29,11 +29,18 @@ <DebugType>pdbonly</DebugType> <Optimize>true</Optimize> <OutputPath>bin\Release\</OutputPath> - <DefineConstants>TRACE</DefineConstants> + <DefineConstants>TRACE;NETFX_CORE;SIMPLE_JSON_TYPEINFO;DISABLE_PLAYFABCLIENT_API</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> </PropertyGroup> <ItemGroup> + <Compile Include="source\Json\ISerializer.cs" /> + <Compile Include="source\Json\NewtonsoftWrapper.cs" /> + <Compile Include="source\Json\SimpleJson.cs" /> + <Compile Include="source\PlayFabHttp\IPlayFabHttp.cs" /> + <Compile Include="source\PlayFabHttp\PlayFabHttp.cs" /> + <Compile Include="source\PlayFabHttp\PlayFabSysHttp.cs" /> + <Compile Include="source\PlayFabHttp\PlayFabWinHttp.cs" /> <Compile Include="source\PlayFabAdminAPI.cs" /> <Compile Include="source\PlayFabAdminModels.cs" /> <Compile Include="source\PlayFabMatchmakerAPI.cs" /> @@ -41,15 +48,18 @@ <Compile Include="source\PlayFabServerAPI.cs" /> <Compile Include="source\PlayFabServerModels.cs" /> <Compile Include="source\PlayFabErrors.cs" /> - <Compile Include="source\PlayFabHTTP.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="source\PlayFabSettings.cs" /> + <Compile Include="source\PlayFabFileUtil.cs" /> <Compile Include="source\PlayFabUtil.cs" /> - <Compile Include="source\Uunit\UUnitAssert.cs" /> + <Compile Include="source\Uunit\PlayFabApiTest.cs" /> <Compile Include="source\Uunit\UUnitAssertException.cs" /> + <Compile Include="source\Uunit\UUnitIncrementalTestRunner.cs" /> <Compile Include="source\Uunit\UUnitTestCase.cs" /> - <Compile Include="source\Uunit\UUnitTestResult.cs" /> + <Compile Include="source\Uunit\UUnitTestContext.cs" /> + <Compile Include="source\Uunit\UUnitTestReport.cs" /> <Compile Include="source\Uunit\UUnitTestSuite.cs" /> + <Compile Include="source\WsaReflectionExtensions.cs" /> </ItemGroup> <ItemGroup> <Reference Include="Newtonsoft.Json"> diff --git a/PlayFabServerSDK/source/Json/ISerializer.cs b/PlayFabServerSDK/source/Json/ISerializer.cs new file mode 100644 index 00000000..012cd8ab --- /dev/null +++ b/PlayFabServerSDK/source/Json/ISerializer.cs @@ -0,0 +1,155 @@ + +using System; +using System.Globalization; +using System.Reflection; + +namespace PlayFab.Json +{ + public interface ISerializer + { + T DeserializeObject<T>(string json); + T DeserializeObject<T>(string json, object jsonSerializerStrategy); + object DeserializeObject(string json); + + string SerializeObject(object json); + string SerializeObject(object json, object jsonSerializerStrategy); + } + + + public static class JsonWrapper + { + private static ISerializer _instance = new SimpleJsonInstance(); + + /// <summary> + /// Use this property to override the Serialization for the SDK. + /// </summary> + public static ISerializer Instance + { + get { return _instance; } + set { _instance = value; } + } + + public static T DeserializeObject<T>(string json) + { + return _instance.DeserializeObject<T>(json); + } + + public static T DeserializeObject<T>(string json, object jsonSerializerStrategy) + { + return _instance.DeserializeObject<T>(json, jsonSerializerStrategy); + } + + public static object DeserializeObject(string json) + { + return _instance.DeserializeObject(json); + } + + public static string SerializeObject(object json) + { + return _instance.SerializeObject(json); + } + + public static string SerializeObject(object json, object jsonSerializerStrategy) + { + return _instance.SerializeObject(json, jsonSerializerStrategy); + } + } + + public class SimpleJsonInstance : ISerializer + { + public static PlayFabJsonSerializerStrategy ApiSerializerStrategy = new PlayFabJsonSerializerStrategy(); + private static DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind; + public class PlayFabJsonSerializerStrategy : PocoJsonSerializerStrategy + { + /// <summary> + /// Convert the json value into the destination field/property + /// </summary> + public override object DeserializeObject(object value, Type type) + { + var valueStr = value as string; + if (valueStr == null) // For all of our custom conversions, value is a string + return base.DeserializeObject(value, type); + + var underType = Nullable.GetUnderlyingType(type); + if (underType != null) + return DeserializeObject(value, underType); + else if (type.GetTypeInfo().IsEnum) + return Enum.Parse(type, (string)value, true); + else if (type == typeof(DateTime)) + { + DateTime output; + var result = DateTime.TryParseExact(valueStr, PlayFabUtil.DefaultDateTimeFormats, CultureInfo.CurrentCulture, _dateTimeStyles, out output); + if (result) + return output; + } + else if (type == typeof(DateTimeOffset)) + { + DateTimeOffset output; + var result = DateTimeOffset.TryParseExact(valueStr, PlayFabUtil.DefaultDateTimeFormats, CultureInfo.CurrentCulture, _dateTimeStyles, out output); + if (result) + return output; + } + else if (type == typeof(TimeSpan)) + { + double seconds; + if (double.TryParse(valueStr, out seconds)) + return TimeSpan.FromSeconds(seconds); + } + return base.DeserializeObject(value, type); + } + + /// <summary> + /// Set output to a string that represents the input object + /// </summary> + protected override bool TrySerializeKnownTypes(object input, out object output) + { + if (input.GetType().GetTypeInfo().IsEnum) + { + output = input.ToString(); + return true; + } + else if (input is DateTime) + { + output = ((DateTime)input).ToString(PlayFabUtil.DefaultDateTimeFormats[PlayFabUtil.DEFAULT_UTC_OUTPUT_INDEX], CultureInfo.CurrentCulture); + return true; + } + else if (input is DateTimeOffset) + { + output = ((DateTimeOffset)input).ToString(PlayFabUtil.DefaultDateTimeFormats[PlayFabUtil.DEFAULT_UTC_OUTPUT_INDEX], CultureInfo.CurrentCulture); + return true; + } + else if (input is TimeSpan) + { + output = ((TimeSpan)input).TotalSeconds; + return true; + } + return base.TrySerializeKnownTypes(input, out output); + } + } + + public T DeserializeObject<T>(string json) + { + return PlayFabSimpleJson.DeserializeObject<T>(json, ApiSerializerStrategy); + } + + public T DeserializeObject<T>(string json, object jsonSerializerStrategy) + { + return PlayFabSimpleJson.DeserializeObject<T>(json, (IJsonSerializerStrategy)jsonSerializerStrategy); + } + + public object DeserializeObject(string json) + { + return PlayFabSimpleJson.DeserializeObject(json, typeof(object), ApiSerializerStrategy); + } + + public string SerializeObject(object json) + { + return PlayFabSimpleJson.SerializeObject(json, ApiSerializerStrategy); + } + + public string SerializeObject(object json, object jsonSerializerStrategy) + { + return PlayFabSimpleJson.SerializeObject(json, (IJsonSerializerStrategy)jsonSerializerStrategy); + } + } +} diff --git a/PlayFabServerSDK/source/Json/NewtonsoftWrapper.cs b/PlayFabServerSDK/source/Json/NewtonsoftWrapper.cs new file mode 100644 index 00000000..9f1f7007 --- /dev/null +++ b/PlayFabServerSDK/source/Json/NewtonsoftWrapper.cs @@ -0,0 +1,73 @@ +#if USING_NEWTONSOFT +using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.IO; + +namespace PlayFab.Json +{ + public class NewtonsofJsonInstance : ISerializer + { + public static JsonSerializerSettings JsonSettings = new JsonSerializerSettings + { + NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore, + Converters = { new StringEnumConverter(), new TimeSpanFloatSeconds(), new IsoDateTimeConverter { DateTimeFormat = PlayFabUtil.DefaultDateTimeFormats[0] } }, + }; + private static Formatting JsonFormatting = Formatting.None; + + private readonly JsonSerializer _serializer = JsonSerializer.Create(JsonSettings); + + public T DeserializeObject<T>(string json) + { + return _serializer.Deserialize<T>(new JsonTextReader(new StringReader(json))); + } + + public T DeserializeObject<T>(string json, object jsonSerializerStrategy) + { + var customSerializer = JsonSerializer.Create((JsonSerializerSettings)jsonSerializerStrategy); + return customSerializer.Deserialize<T>(new JsonTextReader(new StringReader(json))); + } + + public object DeserializeObject(string json) + { + return _serializer.Deserialize(new JsonTextReader(new StringReader(json))); + } + + public string SerializeObject(object json) + { + var jsonString = new StringWriter(); + var writer = new JsonTextWriter(jsonString) { Formatting = JsonFormatting }; + _serializer.Serialize(writer, json); + return jsonString.ToString(); + } + + public string SerializeObject(object json, object jsonSerializerStrategy) + { + var customSerializer = JsonSerializer.Create((JsonSerializerSettings)jsonSerializerStrategy); + var jsonString = new StringWriter(); + var writer = new JsonTextWriter(jsonString) { Formatting = JsonFormatting }; + customSerializer.Serialize(writer, json); + return jsonString.ToString(); + } + } + + public class TimeSpanFloatSeconds : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var timeSpan = (TimeSpan)value; + serializer.Serialize(writer, timeSpan.TotalSeconds); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + return TimeSpan.FromSeconds(serializer.Deserialize<float>(reader)); + } + + public override bool CanConvert(Type objectType) + { + return objectType == typeof(TimeSpan); + } + } +} +#endif diff --git a/PlayFabServerSDK/source/Json/SimpleJson.cs b/PlayFabServerSDK/source/Json/SimpleJson.cs new file mode 100644 index 00000000..231b4f41 --- /dev/null +++ b/PlayFabServerSDK/source/Json/SimpleJson.cs @@ -0,0 +1,2078 @@ +//----------------------------------------------------------------------- +// <copyright file="SimpleJson.cs" company="The Outercurve Foundation"> +// Copyright (c) 2011, The Outercurve Foundation. +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.opensource.org/licenses/mit-license.php +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// </copyright> +// <author>Nathan Totten (ntotten.com), Jim Zimmerman (jimzimmerman.com) and Prabir Shrestha (prabir.me)</author> +// <website>https://github.com/facebook-csharp-sdk/simple-json</website> +//----------------------------------------------------------------------- + +// VERSION: + +// NOTE: uncomment the following line to make SimpleJson class internal. +//#define SIMPLE_JSON_INTERNAL + +// NOTE: uncomment the following line to make JsonArray and JsonObject class internal. +//#define SIMPLE_JSON_OBJARRAYINTERNAL + +// NOTE: uncomment the following line to enable dynamic support. +//#define SIMPLE_JSON_DYNAMIC + +// NOTE: uncomment the following line to enable DataContract support. +//#define SIMPLE_JSON_DATACONTRACT + +// NOTE: uncomment the following line to enable IReadOnlyCollection<T> and IReadOnlyList<T> support. +//#define SIMPLE_JSON_READONLY_COLLECTIONS + +// original json parsing code from http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html + +#if NETFX_CORE +#define SIMPLE_JSON_TYPEINFO +#endif + +using System; +using System.CodeDom.Compiler; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +#if SIMPLE_JSON_DYNAMIC +using System.Dynamic; +#endif +using System.Globalization; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.Serialization; +using System.Text; + +// ReSharper disable LoopCanBeConvertedToQuery +// ReSharper disable RedundantExplicitArrayCreation +// ReSharper disable SuggestUseVarKeywordEvident +namespace PlayFab.Json +{ + public enum NullValueHandling + { + Include, // Include null values when serializing and deserializing objects + Ignore // Ignore null values when serializing and deserializing objects + } + + /// <summary> + /// Customize the json output of a field or property + /// </summary> + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] + public class JsonProperty : Attribute + { + public string PropertyName = null; + public NullValueHandling NullValueHandling = NullValueHandling.Include; + } + + /// <summary> + /// Represents the json array. + /// </summary> + [GeneratedCode("simple-json", "1.0.0")] + [EditorBrowsable(EditorBrowsableState.Never)] + [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")] +#if SIMPLE_JSON_OBJARRAYINTERNAL + internal +#else + public +#endif + class JsonArray : List<object> + { + /// <summary> + /// Initializes a new instance of the <see cref="JsonArray"/> class. + /// </summary> + public JsonArray() { } + + /// <summary> + /// Initializes a new instance of the <see cref="JsonArray"/> class. + /// </summary> + /// <param name="capacity">The capacity of the json array.</param> + public JsonArray(int capacity) : base(capacity) { } + + /// <summary> + /// The json representation of the array. + /// </summary> + /// <returns>The json representation of the array.</returns> + public override string ToString() + { + return PlayFabSimpleJson.SerializeObject(this) ?? string.Empty; + } + } + + /// <summary> + /// Represents the json object. + /// </summary> + [GeneratedCode("simple-json", "1.0.0")] + [EditorBrowsable(EditorBrowsableState.Never)] + [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")] +#if SIMPLE_JSON_OBJARRAYINTERNAL + internal +#else + public +#endif + class JsonObject : +#if SIMPLE_JSON_DYNAMIC + DynamicObject, +#endif + IDictionary<string, object> + { + private const int DICTIONARY_DEFAULT_SIZE = 16; + /// <summary> + /// The internal member dictionary. + /// </summary> + private readonly Dictionary<string, object> _members; + + /// <summary> + /// Initializes a new instance of <see cref="JsonObject"/>. + /// </summary> + public JsonObject() + { + _members = new Dictionary<string, object>(DICTIONARY_DEFAULT_SIZE); + } + + /// <summary> + /// Initializes a new instance of <see cref="JsonObject"/>. + /// </summary> + /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer`1"/> implementation to use when comparing keys, or null to use the default <see cref="T:System.Collections.Generic.EqualityComparer`1"/> for the type of the key.</param> + public JsonObject(IEqualityComparer<string> comparer) + { + _members = new Dictionary<string, object>(comparer); + } + + /// <summary> + /// Gets the <see cref="System.Object"/> at the specified index. + /// </summary> + /// <value></value> + public object this[int index] + { + get { return GetAtIndex(_members, index); } + } + + internal static object GetAtIndex(IDictionary<string, object> obj, int index) + { + if (obj == null) + throw new ArgumentNullException("obj"); + if (index >= obj.Count) + throw new ArgumentOutOfRangeException("index"); + int i = 0; + foreach (KeyValuePair<string, object> o in obj) + if (i++ == index) return o.Value; + return null; + } + + /// <summary> + /// Adds the specified key. + /// </summary> + /// <param name="key">The key.</param> + /// <param name="value">The value.</param> + public void Add(string key, object value) + { + _members.Add(key, value); + } + + /// <summary> + /// Determines whether the specified key contains key. + /// </summary> + /// <param name="key">The key.</param> + /// <returns> + /// <c>true</c> if the specified key contains key; otherwise, <c>false</c>. + /// </returns> + public bool ContainsKey(string key) + { + return _members.ContainsKey(key); + } + + /// <summary> + /// Gets the keys. + /// </summary> + /// <value>The keys.</value> + public ICollection<string> Keys + { + get { return _members.Keys; } + } + + /// <summary> + /// Removes the specified key. + /// </summary> + /// <param name="key">The key.</param> + /// <returns></returns> + public bool Remove(string key) + { + return _members.Remove(key); + } + + /// <summary> + /// Tries the get value. + /// </summary> + /// <param name="key">The key.</param> + /// <param name="value">The value.</param> + /// <returns></returns> + public bool TryGetValue(string key, out object value) + { + return _members.TryGetValue(key, out value); + } + + /// <summary> + /// Gets the values. + /// </summary> + /// <value>The values.</value> + public ICollection<object> Values + { + get { return _members.Values; } + } + + /// <summary> + /// Gets or sets the <see cref="System.Object"/> with the specified key. + /// </summary> + /// <value></value> + public object this[string key] + { + get { return _members[key]; } + set { _members[key] = value; } + } + + /// <summary> + /// Adds the specified item. + /// </summary> + /// <param name="item">The item.</param> + public void Add(KeyValuePair<string, object> item) + { + _members.Add(item.Key, item.Value); + } + + /// <summary> + /// Clears this instance. + /// </summary> + public void Clear() + { + _members.Clear(); + } + + /// <summary> + /// Determines whether [contains] [the specified item]. + /// </summary> + /// <param name="item">The item.</param> + /// <returns> + /// <c>true</c> if [contains] [the specified item]; otherwise, <c>false</c>. + /// </returns> + public bool Contains(KeyValuePair<string, object> item) + { + return _members.ContainsKey(item.Key) && _members[item.Key] == item.Value; + } + + /// <summary> + /// Copies to. + /// </summary> + /// <param name="array">The array.</param> + /// <param name="arrayIndex">Index of the array.</param> + public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex) + { + if (array == null) throw new ArgumentNullException("array"); + int num = Count; + foreach (KeyValuePair<string, object> kvp in _members) + { + array[arrayIndex++] = kvp; + if (--num <= 0) + return; + } + } + + /// <summary> + /// Gets the count. + /// </summary> + /// <value>The count.</value> + public int Count + { + get { return _members.Count; } + } + + /// <summary> + /// Gets a value indicating whether this instance is read only. + /// </summary> + /// <value> + /// <c>true</c> if this instance is read only; otherwise, <c>false</c>. + /// </value> + public bool IsReadOnly + { + get { return false; } + } + + /// <summary> + /// Removes the specified item. + /// </summary> + /// <param name="item">The item.</param> + /// <returns></returns> + public bool Remove(KeyValuePair<string, object> item) + { + return _members.Remove(item.Key); + } + + /// <summary> + /// Gets the enumerator. + /// </summary> + /// <returns></returns> + public IEnumerator<KeyValuePair<string, object>> GetEnumerator() + { + return _members.GetEnumerator(); + } + + /// <summary> + /// Returns an enumerator that iterates through a collection. + /// </summary> + /// <returns> + /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection. + /// </returns> + IEnumerator IEnumerable.GetEnumerator() + { + return _members.GetEnumerator(); + } + + /// <summary> + /// Returns a json <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>. + /// </summary> + /// <returns> + /// A json <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>. + /// </returns> + public override string ToString() + { + return PlayFabSimpleJson.SerializeObject(_members); + } + +#if SIMPLE_JSON_DYNAMIC + /// <summary> + /// Provides implementation for type conversion operations. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for operations that convert an object from one type to another. + /// </summary> + /// <param name="binder">Provides information about the conversion operation. The binder.Type property provides the type to which the object must be converted. For example, for the statement (String)sampleObject in C# (CType(sampleObject, Type) in Visual Basic), where sampleObject is an instance of the class derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, binder.Type returns the <see cref="T:System.String"/> type. The binder.Explicit property provides information about the kind of conversion that occurs. It returns true for explicit conversion and false for implicit conversion.</param> + /// <param name="result">The result of the type conversion operation.</param> + /// <returns> + /// Alwasy returns true. + /// </returns> + public override bool TryConvert(ConvertBinder binder, out object result) + { + // <pex> + if (binder == null) + throw new ArgumentNullException("binder"); + // </pex> + Type targetType = binder.Type; + + if ((targetType == typeof(IEnumerable)) || + (targetType == typeof(IEnumerable<KeyValuePair<string, object>>)) || + (targetType == typeof(IDictionary<string, object>)) || + (targetType == typeof(IDictionary))) + { + result = this; + return true; + } + + return base.TryConvert(binder, out result); + } + + /// <summary> + /// Provides the implementation for operations that delete an object member. This method is not intended for use in C# or Visual Basic. + /// </summary> + /// <param name="binder">Provides information about the deletion.</param> + /// <returns> + /// Alwasy returns true. + /// </returns> + public override bool TryDeleteMember(DeleteMemberBinder binder) + { + // <pex> + if (binder == null) + throw new ArgumentNullException("binder"); + // </pex> + return _members.Remove(binder.Name); + } + + /// <summary> + /// Provides the implementation for operations that get a value by index. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for indexing operations. + /// </summary> + /// <param name="binder">Provides information about the operation.</param> + /// <param name="indexes">The indexes that are used in the operation. For example, for the sampleObject[3] operation in C# (sampleObject(3) in Visual Basic), where sampleObject is derived from the DynamicObject class, <paramref name="indexes"/> is equal to 3.</param> + /// <param name="result">The result of the index operation.</param> + /// <returns> + /// Alwasy returns true. + /// </returns> + public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) + { + if (indexes == null) throw new ArgumentNullException("indexes"); + if (indexes.Length == 1) + { + result = ((IDictionary<string, object>)this)[(string)indexes[0]]; + return true; + } + result = null; + return true; + } + + /// <summary> + /// Provides the implementation for operations that get member values. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for operations such as getting a value for a property. + /// </summary> + /// <param name="binder">Provides information about the object that called the dynamic operation. The binder.Name property provides the name of the member on which the dynamic operation is performed. For example, for the Console.WriteLine(sampleObject.SampleProperty) statement, where sampleObject is an instance of the class derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, binder.Name returns "SampleProperty". The binder.IgnoreCase property specifies whether the member name is case-sensitive.</param> + /// <param name="result">The result of the get operation. For example, if the method is called for a property, you can assign the property value to <paramref name="result"/>.</param> + /// <returns> + /// Alwasy returns true. + /// </returns> + public override bool TryGetMember(GetMemberBinder binder, out object result) + { + object value; + if (_members.TryGetValue(binder.Name, out value)) + { + result = value; + return true; + } + result = null; + return true; + } + + /// <summary> + /// Provides the implementation for operations that set a value by index. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for operations that access objects by a specified index. + /// </summary> + /// <param name="binder">Provides information about the operation.</param> + /// <param name="indexes">The indexes that are used in the operation. For example, for the sampleObject[3] = 10 operation in C# (sampleObject(3) = 10 in Visual Basic), where sampleObject is derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, <paramref name="indexes"/> is equal to 3.</param> + /// <param name="value">The value to set to the object that has the specified index. For example, for the sampleObject[3] = 10 operation in C# (sampleObject(3) = 10 in Visual Basic), where sampleObject is derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, <paramref name="value"/> is equal to 10.</param> + /// <returns> + /// true if the operation is successful; otherwise, false. If this method returns false, the run-time binder of the language determines the behavior. (In most cases, a language-specific run-time exception is thrown. + /// </returns> + public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value) + { + if (indexes == null) throw new ArgumentNullException("indexes"); + if (indexes.Length == 1) + { + ((IDictionary<string, object>)this)[(string)indexes[0]] = value; + return true; + } + return base.TrySetIndex(binder, indexes, value); + } + + /// <summary> + /// Provides the implementation for operations that set member values. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for operations such as setting a value for a property. + /// </summary> + /// <param name="binder">Provides information about the object that called the dynamic operation. The binder.Name property provides the name of the member to which the value is being assigned. For example, for the statement sampleObject.SampleProperty = "Test", where sampleObject is an instance of the class derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, binder.Name returns "SampleProperty". The binder.IgnoreCase property specifies whether the member name is case-sensitive.</param> + /// <param name="value">The value to set to the member. For example, for sampleObject.SampleProperty = "Test", where sampleObject is an instance of the class derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, the <paramref name="value"/> is "Test".</param> + /// <returns> + /// true if the operation is successful; otherwise, false. If this method returns false, the run-time binder of the language determines the behavior. (In most cases, a language-specific run-time exception is thrown.) + /// </returns> + public override bool TrySetMember(SetMemberBinder binder, object value) + { + // <pex> + if (binder == null) + throw new ArgumentNullException("binder"); + // </pex> + _members[binder.Name] = value; + return true; + } + + /// <summary> + /// Returns the enumeration of all dynamic member names. + /// </summary> + /// <returns> + /// A sequence that contains dynamic member names. + /// </returns> + public override IEnumerable<string> GetDynamicMemberNames() + { + foreach (var key in Keys) + yield return key; + } +#endif + } + + /// <summary> + /// This class encodes and decodes JSON strings. + /// Spec. details, see http://www.json.org/ + /// + /// JSON uses Arrays and Objects. These correspond here to the datatypes JsonArray(IList<object>) and JsonObject(IDictionary<string,object>). + /// All numbers are parsed to doubles. + /// </summary> + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + static class PlayFabSimpleJson + { + private enum TokenType : byte + { + NONE = 0, + CURLY_OPEN = 1, + CURLY_CLOSE = 2, + SQUARED_OPEN = 3, + SQUARED_CLOSE = 4, + COLON = 5, + COMMA = 6, + STRING = 7, + NUMBER = 8, + TRUE = 9, + FALSE = 10, + NULL = 11, + } + private const int BUILDER_INIT = 2000; + + private static readonly char[] EscapeTable; + private static readonly char[] EscapeCharacters = new char[] { '"', '\\', '\b', '\f', '\n', '\r', '\t' }; + // private static readonly string EscapeCharactersString = new string(EscapeCharacters); + internal static readonly List<Type> NumberTypes = new List<Type> { + typeof(bool), typeof(byte), typeof(ushort), typeof(uint), typeof(ulong), typeof(sbyte), typeof(short), typeof(int), typeof(long), typeof(double), typeof(float), typeof(decimal) + }; + + // Performance stuff + [ThreadStatic] + private static StringBuilder _serializeObjectBuilder; + [ThreadStatic] + private static StringBuilder _parseStringBuilder; + + static PlayFabSimpleJson() + { + EscapeTable = new char[93]; + EscapeTable['"'] = '"'; + EscapeTable['\\'] = '\\'; + EscapeTable['\b'] = 'b'; + EscapeTable['\f'] = 'f'; + EscapeTable['\n'] = 'n'; + EscapeTable['\r'] = 'r'; + EscapeTable['\t'] = 't'; + } + + /// <summary> + /// Parses the string json into a value + /// </summary> + /// <param name="json">A JSON string.</param> + /// <returns>An IList<object>, a IDictionary<string,object>, a double, a string, null, true, or false</returns> + public static object DeserializeObject(string json) + { + object obj; + if (TryDeserializeObject(json, out obj)) + return obj; + throw new SerializationException("Invalid JSON string"); + } + + /// <summary> + /// Try parsing the json string into a value. + /// </summary> + /// <param name="json"> + /// A JSON string. + /// </param> + /// <param name="obj"> + /// The object. + /// </param> + /// <returns> + /// Returns true if successfull otherwise false. + /// </returns> + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification = "Need to support .NET 2")] + public static bool TryDeserializeObject(string json, out object obj) + { + bool success = true; + if (json != null) + { + int index = 0; + obj = ParseValue(json, ref index, ref success); + } + else + obj = null; + + return success; + } + + public static object DeserializeObject(string json, Type type, IJsonSerializerStrategy jsonSerializerStrategy) + { + object jsonObject = DeserializeObject(json); + if (type == null || jsonObject != null && ReflectionUtils.IsAssignableFrom(jsonObject.GetType(), type)) + return jsonObject; + return (jsonSerializerStrategy ?? CurrentJsonSerializerStrategy).DeserializeObject(jsonObject, type); + } + + public static object DeserializeObject(string json, Type type) + { + return DeserializeObject(json, type, null); + } + + public static T DeserializeObject<T>(string json, IJsonSerializerStrategy jsonSerializerStrategy) + { + return (T)DeserializeObject(json, typeof(T), jsonSerializerStrategy); + } + + public static T DeserializeObject<T>(string json) + { + return (T)DeserializeObject(json, typeof(T), null); + } + + /// <summary> + /// Converts a IDictionary<string,object> / IList<object> object into a JSON string + /// </summary> + /// <param name="json">A IDictionary<string,object> / IList<object></param> + /// <param name="jsonSerializerStrategy">Serializer strategy to use</param> + /// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns> + public static string SerializeObject(object json, IJsonSerializerStrategy jsonSerializerStrategy = null) + { + if (_serializeObjectBuilder == null) + _serializeObjectBuilder = new StringBuilder(BUILDER_INIT); + _serializeObjectBuilder.Length = 0; + + if (jsonSerializerStrategy == null) + jsonSerializerStrategy = CurrentJsonSerializerStrategy; + + bool success = SerializeValue(jsonSerializerStrategy, json, _serializeObjectBuilder); + return (success ? _serializeObjectBuilder.ToString() : null); + } + + public static string EscapeToJavascriptString(string jsonString) + { + if (string.IsNullOrEmpty(jsonString)) + return jsonString; + + StringBuilder sb = new StringBuilder(); + char c; + + for (int i = 0; i < jsonString.Length;) + { + c = jsonString[i++]; + + if (c == '\\') + { + int remainingLength = jsonString.Length - i; + if (remainingLength >= 2) + { + char lookahead = jsonString[i]; + if (lookahead == '\\') + { + sb.Append('\\'); + ++i; + } + else if (lookahead == '"') + { + sb.Append("\""); + ++i; + } + else if (lookahead == 't') + { + sb.Append('\t'); + ++i; + } + else if (lookahead == 'b') + { + sb.Append('\b'); + ++i; + } + else if (lookahead == 'n') + { + sb.Append('\n'); + ++i; + } + else if (lookahead == 'r') + { + sb.Append('\r'); + ++i; + } + } + } + else + { + sb.Append(c); + } + } + return sb.ToString(); + } + + static IDictionary<string, object> ParseObject(string json, ref int index, ref bool success) + { + IDictionary<string, object> table = new JsonObject(); + TokenType token; + + // { + NextToken(json, ref index); + + bool done = false; + while (!done) + { + token = LookAhead(json, index); + if (token == TokenType.NONE) + { + success = false; + return null; + } + else if (token == TokenType.COMMA) + NextToken(json, ref index); + else if (token == TokenType.CURLY_CLOSE) + { + NextToken(json, ref index); + return table; + } + else + { + // name + string name = ParseString(json, ref index, ref success); + if (!success) + { + success = false; + return null; + } + // : + token = NextToken(json, ref index); + if (token != TokenType.COLON) + { + success = false; + return null; + } + // value + object value = ParseValue(json, ref index, ref success); + if (!success) + { + success = false; + return null; + } + table[name] = value; + } + } + return table; + } + + static JsonArray ParseArray(string json, ref int index, ref bool success) + { + JsonArray array = new JsonArray(); + + // [ + NextToken(json, ref index); + + bool done = false; + while (!done) + { + TokenType token = LookAhead(json, index); + if (token == TokenType.NONE) + { + success = false; + return null; + } + else if (token == TokenType.COMMA) + NextToken(json, ref index); + else if (token == TokenType.SQUARED_CLOSE) + { + NextToken(json, ref index); + break; + } + else + { + object value = ParseValue(json, ref index, ref success); + if (!success) + return null; + array.Add(value); + } + } + return array; + } + + static object ParseValue(string json, ref int index, ref bool success) + { + switch (LookAhead(json, index)) + { + case TokenType.STRING: + return ParseString(json, ref index, ref success); + case TokenType.NUMBER: + return ParseNumber(json, ref index, ref success); + case TokenType.CURLY_OPEN: + return ParseObject(json, ref index, ref success); + case TokenType.SQUARED_OPEN: + return ParseArray(json, ref index, ref success); + case TokenType.TRUE: + NextToken(json, ref index); + return true; + case TokenType.FALSE: + NextToken(json, ref index); + return false; + case TokenType.NULL: + NextToken(json, ref index); + return null; + case TokenType.NONE: + break; + } + success = false; + return null; + } + + static string ParseString(string json, ref int index, ref bool success) + { + if (_parseStringBuilder == null) + _parseStringBuilder = new StringBuilder(BUILDER_INIT); + _parseStringBuilder.Length = 0; + + EatWhitespace(json, ref index); + + // " + char c = json[index++]; + bool complete = false; + while (!complete) + { + if (index == json.Length) + break; + + c = json[index++]; + if (c == '"') + { + complete = true; + break; + } + else if (c == '\\') + { + if (index == json.Length) + break; + c = json[index++]; + if (c == '"') + _parseStringBuilder.Append('"'); + else if (c == '\\') + _parseStringBuilder.Append('\\'); + else if (c == '/') + _parseStringBuilder.Append('/'); + else if (c == 'b') + _parseStringBuilder.Append('\b'); + else if (c == 'f') + _parseStringBuilder.Append('\f'); + else if (c == 'n') + _parseStringBuilder.Append('\n'); + else if (c == 'r') + _parseStringBuilder.Append('\r'); + else if (c == 't') + _parseStringBuilder.Append('\t'); + else if (c == 'u') + { + int remainingLength = json.Length - index; + if (remainingLength >= 4) + { + // parse the 32 bit hex into an integer codepoint + uint codePoint; + if (!(success = UInt32.TryParse(json.Substring(index, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out codePoint))) + return ""; + + // convert the integer codepoint to a unicode char and add to string + if (0xD800 <= codePoint && codePoint <= 0xDBFF) // if high surrogate + { + index += 4; // skip 4 chars + remainingLength = json.Length - index; + if (remainingLength >= 6) + { + uint lowCodePoint; + if (json.Substring(index, 2) == "\\u" && UInt32.TryParse(json.Substring(index + 2, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out lowCodePoint)) + { + if (0xDC00 <= lowCodePoint && lowCodePoint <= 0xDFFF) // if low surrogate + { + _parseStringBuilder.Append((char)codePoint); + _parseStringBuilder.Append((char)lowCodePoint); + index += 6; // skip 6 chars + continue; + } + } + } + success = false; // invalid surrogate pair + return ""; + } + _parseStringBuilder.Append(ConvertFromUtf32((int)codePoint)); + // skip 4 chars + index += 4; + } + else + break; + } + } + else + _parseStringBuilder.Append(c); + } + if (!complete) + { + success = false; + return null; + } + return _parseStringBuilder.ToString(); + } + + private static string ConvertFromUtf32(int utf32) + { + // http://www.java2s.com/Open-Source/CSharp/2.6.4-mono-.net-core/System/System/Char.cs.htm + if (utf32 < 0 || utf32 > 0x10FFFF) + throw new ArgumentOutOfRangeException("utf32", "The argument must be from 0 to 0x10FFFF."); + if (0xD800 <= utf32 && utf32 <= 0xDFFF) + throw new ArgumentOutOfRangeException("utf32", "The argument must not be in surrogate pair range."); + if (utf32 < 0x10000) + return new string((char)utf32, 1); + utf32 -= 0x10000; + return new string(new char[] { (char)((utf32 >> 10) + 0xD800), (char)(utf32 % 0x0400 + 0xDC00) }); + } + + static object ParseNumber(string json, ref int index, ref bool success) + { + EatWhitespace(json, ref index); + int lastIndex = GetLastIndexOfNumber(json, index); + int charLength = (lastIndex - index) + 1; + object returnNumber; + string str = json.Substring(index, charLength); + if (str.IndexOf(".", StringComparison.OrdinalIgnoreCase) != -1 || str.IndexOf("e", StringComparison.OrdinalIgnoreCase) != -1) + { + double number; + success = double.TryParse(json.Substring(index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); + returnNumber = number; + } + else if (str.IndexOf("-", StringComparison.OrdinalIgnoreCase) == -1) + { + ulong number; + success = ulong.TryParse(json.Substring(index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); + returnNumber = number; + } + else + { + long number; + success = long.TryParse(json.Substring(index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); + returnNumber = number; + } + index = lastIndex + 1; + return returnNumber; + } + + static int GetLastIndexOfNumber(string json, int index) + { + int lastIndex; + for (lastIndex = index; lastIndex < json.Length; lastIndex++) + if ("0123456789+-.eE".IndexOf(json[lastIndex]) == -1) break; + return lastIndex - 1; + } + + static void EatWhitespace(string json, ref int index) + { + for (; index < json.Length; index++) + if (" \t\n\r\b\f".IndexOf(json[index]) == -1) break; + } + + static TokenType LookAhead(string json, int index) + { + int saveIndex = index; + return NextToken(json, ref saveIndex); + } + + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + static TokenType NextToken(string json, ref int index) + { + EatWhitespace(json, ref index); + if (index == json.Length) + return TokenType.NONE; + char c = json[index]; + index++; + switch (c) + { + case '{': + return TokenType.CURLY_OPEN; + case '}': + return TokenType.CURLY_CLOSE; + case '[': + return TokenType.SQUARED_OPEN; + case ']': + return TokenType.SQUARED_CLOSE; + case ',': + return TokenType.COMMA; + case '"': + return TokenType.STRING; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + return TokenType.NUMBER; + case ':': + return TokenType.COLON; + } + index--; + int remainingLength = json.Length - index; + // false + if (remainingLength >= 5) + { + if (json[index] == 'f' && json[index + 1] == 'a' && json[index + 2] == 'l' && json[index + 3] == 's' && json[index + 4] == 'e') + { + index += 5; + return TokenType.FALSE; + } + } + // true + if (remainingLength >= 4) + { + if (json[index] == 't' && json[index + 1] == 'r' && json[index + 2] == 'u' && json[index + 3] == 'e') + { + index += 4; + return TokenType.TRUE; + } + } + // null + if (remainingLength >= 4) + { + if (json[index] == 'n' && json[index + 1] == 'u' && json[index + 2] == 'l' && json[index + 3] == 'l') + { + index += 4; + return TokenType.NULL; + } + } + return TokenType.NONE; + } + + static bool SerializeValue(IJsonSerializerStrategy jsonSerializerStrategy, object value, StringBuilder builder) + { + bool success = true; + string stringValue = value as string; + if (value == null) + builder.Append("null"); + else if (stringValue != null) + success = SerializeString(stringValue, builder); + else + { + IDictionary<string, object> dict = value as IDictionary<string, object>; + Type type = value.GetType(); + Type[] genArgs = ReflectionUtils.GetGenericTypeArguments(type); + var isStringKeyDictionary = type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>) && genArgs[0] == typeof(string); + if (isStringKeyDictionary) + { + var strDictValue = value as IDictionary; + success = SerializeObject(jsonSerializerStrategy, strDictValue.Keys, strDictValue.Values, builder); + } + else if (dict != null) + { + success = SerializeObject(jsonSerializerStrategy, dict.Keys, dict.Values, builder); + } + else + { + IDictionary<string, string> stringDictionary = value as IDictionary<string, string>; + if (stringDictionary != null) + { + success = SerializeObject(jsonSerializerStrategy, stringDictionary.Keys, stringDictionary.Values, builder); + } + else + { + IEnumerable enumerableValue = value as IEnumerable; + if (enumerableValue != null) + success = SerializeArray(jsonSerializerStrategy, enumerableValue, builder); + else if (IsNumeric(value)) + success = SerializeNumber(value, builder); + else if (value is bool) + builder.Append((bool)value ? "true" : "false"); + else + { + object serializedObject; + success = jsonSerializerStrategy.TrySerializeNonPrimitiveObject(value, out serializedObject); + if (success) + SerializeValue(jsonSerializerStrategy, serializedObject, builder); + } + } + } + } + return success; + } + + static bool SerializeObject(IJsonSerializerStrategy jsonSerializerStrategy, IEnumerable keys, IEnumerable values, StringBuilder builder) + { + builder.Append("{"); + IEnumerator ke = keys.GetEnumerator(); + IEnumerator ve = values.GetEnumerator(); + bool first = true; + while (ke.MoveNext() && ve.MoveNext()) + { + object key = ke.Current; + object value = ve.Current; + if (!first) + builder.Append(","); + string stringKey = key as string; + if (stringKey != null) + SerializeString(stringKey, builder); + else + if (!SerializeValue(jsonSerializerStrategy, value, builder)) return false; + builder.Append(":"); + if (!SerializeValue(jsonSerializerStrategy, value, builder)) + return false; + first = false; + } + builder.Append("}"); + return true; + } + + static bool SerializeArray(IJsonSerializerStrategy jsonSerializerStrategy, IEnumerable anArray, StringBuilder builder) + { + builder.Append("["); + bool first = true; + foreach (object value in anArray) + { + if (!first) + builder.Append(","); + if (!SerializeValue(jsonSerializerStrategy, value, builder)) + return false; + first = false; + } + builder.Append("]"); + return true; + } + + static bool SerializeString(string aString, StringBuilder builder) + { + // Happy path if there's nothing to be escaped. IndexOfAny is highly optimized (and unmanaged) + if (aString.IndexOfAny(EscapeCharacters) == -1) + { + builder.Append('"'); + builder.Append(aString); + builder.Append('"'); + + return true; + } + + builder.Append('"'); + int safeCharacterCount = 0; + char[] charArray = aString.ToCharArray(); + + for (int i = 0; i < charArray.Length; i++) + { + char c = charArray[i]; + + // Non ascii characters are fine, buffer them up and send them to the builder + // in larger chunks if possible. The escape table is a 1:1 translation table + // with \0 [default(char)] denoting a safe character. + if (c >= EscapeTable.Length || EscapeTable[c] == default(char)) + { + safeCharacterCount++; + } + else + { + if (safeCharacterCount > 0) + { + builder.Append(charArray, i - safeCharacterCount, safeCharacterCount); + safeCharacterCount = 0; + } + + builder.Append('\\'); + builder.Append(EscapeTable[c]); + } + } + + if (safeCharacterCount > 0) + { + builder.Append(charArray, charArray.Length - safeCharacterCount, safeCharacterCount); + } + + builder.Append('"'); + return true; + } + + static bool SerializeNumber(object number, StringBuilder builder) + { + if (number is decimal) + builder.Append(((decimal)number).ToString("R", CultureInfo.InvariantCulture)); + else if (number is double) + builder.Append(((double)number).ToString("R", CultureInfo.InvariantCulture)); + else if (number is float) + builder.Append(((float)number).ToString("R", CultureInfo.InvariantCulture)); + else if (NumberTypes.IndexOf(number.GetType()) != -1) + builder.Append(number); + return true; + } + + /// <summary> + /// Determines if a given object is numeric in any way + /// (can be integer, double, null, etc). + /// </summary> + static bool IsNumeric(object value) + { + if (value is sbyte) return true; + if (value is byte) return true; + if (value is short) return true; + if (value is ushort) return true; + if (value is int) return true; + if (value is uint) return true; + if (value is long) return true; + if (value is ulong) return true; + if (value is float) return true; + if (value is double) return true; + if (value is decimal) return true; + return false; + } + + private static IJsonSerializerStrategy _currentJsonSerializerStrategy; + public static IJsonSerializerStrategy CurrentJsonSerializerStrategy + { + get + { + return _currentJsonSerializerStrategy ?? + (_currentJsonSerializerStrategy = +#if SIMPLE_JSON_DATACONTRACT + DataContractJsonSerializerStrategy +#else + PocoJsonSerializerStrategy +#endif +); + } + set + { + _currentJsonSerializerStrategy = value; + } + } + + private static PocoJsonSerializerStrategy _pocoJsonSerializerStrategy; + [EditorBrowsable(EditorBrowsableState.Advanced)] + public static PocoJsonSerializerStrategy PocoJsonSerializerStrategy + { + get + { + return _pocoJsonSerializerStrategy ?? (_pocoJsonSerializerStrategy = new PocoJsonSerializerStrategy()); + } + } + +#if SIMPLE_JSON_DATACONTRACT + + private static DataContractJsonSerializerStrategy _dataContractJsonSerializerStrategy; + [System.ComponentModel.EditorBrowsable(EditorBrowsableState.Advanced)] + public static DataContractJsonSerializerStrategy DataContractJsonSerializerStrategy + { + get + { + return _dataContractJsonSerializerStrategy ?? (_dataContractJsonSerializerStrategy = new DataContractJsonSerializerStrategy()); + } + } + +#endif + } + + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + interface IJsonSerializerStrategy + { + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification = "Need to support .NET 2")] + bool TrySerializeNonPrimitiveObject(object input, out object output); + object DeserializeObject(object value, Type type); + } + + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + class PocoJsonSerializerStrategy : IJsonSerializerStrategy + { + internal IDictionary<Type, ReflectionUtils.ConstructorDelegate> ConstructorCache; + internal IDictionary<Type, IDictionary<MemberInfo, ReflectionUtils.GetDelegate>> GetCache; + internal IDictionary<Type, IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>>> SetCache; + + internal static readonly Type[] EmptyTypes = new Type[0]; + internal static readonly Type[] ArrayConstructorParameterTypes = new Type[] { typeof(int) }; + + private static readonly string[] Iso8601Format = new string[] + { + @"yyyy-MM-dd\THH:mm:ss.FFFFFFF\Z", + @"yyyy-MM-dd\THH:mm:ss\Z", + @"yyyy-MM-dd\THH:mm:ssK" + }; + + public PocoJsonSerializerStrategy() + { + ConstructorCache = new ReflectionUtils.ThreadSafeDictionary<Type, ReflectionUtils.ConstructorDelegate>(ContructorDelegateFactory); + GetCache = new ReflectionUtils.ThreadSafeDictionary<Type, IDictionary<MemberInfo, ReflectionUtils.GetDelegate>>(GetterValueFactory); + SetCache = new ReflectionUtils.ThreadSafeDictionary<Type, IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>>>(SetterValueFactory); + } + + protected virtual string MapClrMemberNameToJsonFieldName(MemberInfo memberInfo) + { + // TODO: Optimize and/or cache + foreach (JsonProperty eachAttr in memberInfo.GetCustomAttributes(typeof(JsonProperty), true)) + if (!string.IsNullOrEmpty(eachAttr.PropertyName)) + return eachAttr.PropertyName; + return memberInfo.Name; + } + + protected virtual void MapClrMemberNameToJsonFieldName(MemberInfo memberInfo, out string jsonName, out JsonProperty jsonProp) + { + jsonName = memberInfo.Name; + jsonProp = null; + // TODO: Optimize and/or cache + foreach (JsonProperty eachAttr in memberInfo.GetCustomAttributes(typeof(JsonProperty), true)) + { + jsonProp = eachAttr; + if (!string.IsNullOrEmpty(eachAttr.PropertyName)) + jsonName = eachAttr.PropertyName; + } + } + + internal virtual ReflectionUtils.ConstructorDelegate ContructorDelegateFactory(Type key) + { + return ReflectionUtils.GetContructor(key, key.IsArray ? ArrayConstructorParameterTypes : EmptyTypes); + } + + internal virtual IDictionary<MemberInfo, ReflectionUtils.GetDelegate> GetterValueFactory(Type type) + { + IDictionary<MemberInfo, ReflectionUtils.GetDelegate> result = new Dictionary<MemberInfo, ReflectionUtils.GetDelegate>(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanRead) + { + MethodInfo getMethod = ReflectionUtils.GetGetterMethodInfo(propertyInfo); + if (getMethod.IsStatic || !getMethod.IsPublic) + continue; + result[propertyInfo] = ReflectionUtils.GetGetMethod(propertyInfo); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (fieldInfo.IsStatic || !fieldInfo.IsPublic) + continue; + result[fieldInfo] = ReflectionUtils.GetGetMethod(fieldInfo); + } + return result; + } + + internal virtual IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>> SetterValueFactory(Type type) + { + IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>> result = new Dictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>>(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanWrite) + { + MethodInfo setMethod = ReflectionUtils.GetSetterMethodInfo(propertyInfo); + if (setMethod.IsStatic || !setMethod.IsPublic) + continue; + result[MapClrMemberNameToJsonFieldName(propertyInfo)] = new KeyValuePair<Type, ReflectionUtils.SetDelegate>(propertyInfo.PropertyType, ReflectionUtils.GetSetMethod(propertyInfo)); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (fieldInfo.IsInitOnly || fieldInfo.IsStatic || !fieldInfo.IsPublic) + continue; + result[MapClrMemberNameToJsonFieldName(fieldInfo)] = new KeyValuePair<Type, ReflectionUtils.SetDelegate>(fieldInfo.FieldType, ReflectionUtils.GetSetMethod(fieldInfo)); + } + return result; + } + + public virtual bool TrySerializeNonPrimitiveObject(object input, out object output) + { + return TrySerializeKnownTypes(input, out output) || TrySerializeUnknownTypes(input, out output); + } + + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + public virtual object DeserializeObject(object value, Type type) + { + if (type == null) throw new ArgumentNullException("type"); + if (value != null && type.IsInstanceOfType(value)) return value; + + string str = value as string; + if (type == typeof(Guid) && string.IsNullOrEmpty(str)) + return default(Guid); + + if (value == null) + return null; + + object obj = null; + + if (str != null) + { + if (str.Length != 0) // We know it can't be null now. + { + if (type == typeof(DateTime) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(DateTime))) + return DateTime.ParseExact(str, Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal); + if (type == typeof(DateTimeOffset) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(DateTimeOffset))) + return DateTimeOffset.ParseExact(str, Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal); + if (type == typeof(Guid) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid))) + return new Guid(str); + if (type == typeof(Uri)) + { + bool isValid = Uri.IsWellFormedUriString(str, UriKind.RelativeOrAbsolute); + + Uri result; + if (isValid && Uri.TryCreate(str, UriKind.RelativeOrAbsolute, out result)) + return result; + + return null; + } + + if (type == typeof(string)) + return str; + + return Convert.ChangeType(str, type, CultureInfo.InvariantCulture); + } + else + { + if (type == typeof(Guid)) + obj = default(Guid); + else if (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid)) + obj = null; + else + obj = str; + } + // Empty string case + if (!ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid)) + return str; + } + else if (value is bool) + return value; + + bool valueIsLong = value is long; + bool valueIsUlong = value is ulong; + bool valueIsDouble = value is double; + Type nullableType = Nullable.GetUnderlyingType(type); + if (nullableType != null && PlayFabSimpleJson.NumberTypes.IndexOf(nullableType) != -1) + type = nullableType; // Just use the regular type for the conversion + bool isNumberType = PlayFabSimpleJson.NumberTypes.IndexOf(type) != -1; + bool isEnumType = type.GetTypeInfo().IsEnum; + if ((valueIsLong && type == typeof(long)) || (valueIsUlong && type == typeof(ulong)) || (valueIsDouble && type == typeof(double))) + return value; + if ((valueIsLong || valueIsUlong || valueIsDouble) && isEnumType) + return Enum.ToObject(type, Convert.ChangeType(value, Enum.GetUnderlyingType(type), CultureInfo.InvariantCulture)); + if ((valueIsLong || valueIsUlong || valueIsDouble) && isNumberType) + return Convert.ChangeType(value, type, CultureInfo.InvariantCulture); + + IDictionary<string, object> objects = value as IDictionary<string, object>; + if (objects != null) + { + IDictionary<string, object> jsonObject = objects; + + if (ReflectionUtils.IsTypeDictionary(type)) + { + // if dictionary then + Type[] types = ReflectionUtils.GetGenericTypeArguments(type); + Type keyType = types[0]; + Type valueType = types[1]; + + Type genericType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType); + + IDictionary dict = (IDictionary)ConstructorCache[genericType](); + + foreach (KeyValuePair<string, object> kvp in jsonObject) + dict.Add(kvp.Key, DeserializeObject(kvp.Value, valueType)); + + obj = dict; + } + else + { + if (type == typeof(object)) + obj = value; + else + { + obj = ConstructorCache[type](); + foreach (KeyValuePair<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>> setter in SetCache[type]) + { + object jsonValue; + if (jsonObject.TryGetValue(setter.Key, out jsonValue)) + { + jsonValue = DeserializeObject(jsonValue, setter.Value.Key); + setter.Value.Value(obj, jsonValue); + } + } + } + } + } + else + { + IList<object> valueAsList = value as IList<object>; + if (valueAsList != null) + { + IList<object> jsonObject = valueAsList; + IList list = null; + + if (type.IsArray) + { + list = (IList)ConstructorCache[type](jsonObject.Count); + int i = 0; + foreach (object o in jsonObject) + list[i++] = DeserializeObject(o, type.GetElementType()); + } + else if (ReflectionUtils.IsTypeGenericeCollectionInterface(type) || ReflectionUtils.IsAssignableFrom(typeof(IList), type) || type == typeof(object)) + { + Type innerType = ReflectionUtils.GetGenericListElementType(type); + ReflectionUtils.ConstructorDelegate ctrDelegate = null; + if (type != typeof(object)) + ctrDelegate = ConstructorCache[type]; + if (ctrDelegate == null) + ctrDelegate = ConstructorCache[typeof(List<>).MakeGenericType(innerType)]; + list = (IList)ctrDelegate(); + foreach (object o in jsonObject) + list.Add(DeserializeObject(o, innerType)); + } + obj = list; + } + return obj; + } + if (ReflectionUtils.IsNullableType(type)) + return ReflectionUtils.ToNullableType(obj, type); + return obj; + } + + protected virtual object SerializeEnum(Enum p) + { + return Convert.ToDouble(p, CultureInfo.InvariantCulture); + } + + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification = "Need to support .NET 2")] + protected virtual bool TrySerializeKnownTypes(object input, out object output) + { + bool returnValue = true; + if (input is DateTime) + output = ((DateTime)input).ToUniversalTime().ToString(Iso8601Format[0], CultureInfo.InvariantCulture); + else if (input is DateTimeOffset) + output = ((DateTimeOffset)input).ToUniversalTime().ToString(Iso8601Format[0], CultureInfo.InvariantCulture); + else if (input is Guid) + output = ((Guid)input).ToString("D"); + else if (input is Uri) + output = input.ToString(); + else + { + Enum inputEnum = input as Enum; + if (inputEnum != null) + output = SerializeEnum(inputEnum); + else + { + returnValue = false; + output = null; + } + } + return returnValue; + } + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification = "Need to support .NET 2")] + protected virtual bool TrySerializeUnknownTypes(object input, out object output) + { + if (input == null) throw new ArgumentNullException("input"); + output = null; + Type type = input.GetType(); + if (type.FullName == null) + return false; + IDictionary<string, object> obj = new JsonObject(); + IDictionary<MemberInfo, ReflectionUtils.GetDelegate> getters = GetCache[type]; + foreach (KeyValuePair<MemberInfo, ReflectionUtils.GetDelegate> getter in getters) + { + if (getter.Value == null) + continue; + string jsonKey; + JsonProperty jsonProp; + MapClrMemberNameToJsonFieldName(getter.Key, out jsonKey, out jsonProp); + if (obj.ContainsKey(jsonKey)) + throw new Exception("The given key is defined multiple times in the same type: " + input.GetType().Name + "." + jsonKey); + object value = getter.Value(input); + if (jsonProp == null || jsonProp.NullValueHandling == NullValueHandling.Include || value != null) + obj.Add(jsonKey, value); + } + output = obj; + return true; + } + } + +#if SIMPLE_JSON_DATACONTRACT + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + class DataContractJsonSerializerStrategy : PocoJsonSerializerStrategy + { + public DataContractJsonSerializerStrategy() + { + GetCache = new ReflectionUtils.ThreadSafeDictionary<Type, IDictionary<string, ReflectionUtils.GetDelegate>>(GetterValueFactory); + SetCache = new ReflectionUtils.ThreadSafeDictionary<Type, IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>>>(SetterValueFactory); + } + + internal override IDictionary<string, ReflectionUtils.GetDelegate> GetterValueFactory(Type type) + { + bool hasDataContract = ReflectionUtils.GetAttribute(type, typeof(DataContractAttribute)) != null; + if (!hasDataContract) + return base.GetterValueFactory(type); + string jsonKey; + IDictionary<string, ReflectionUtils.GetDelegate> result = new Dictionary<string, ReflectionUtils.GetDelegate>(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanRead) + { + MethodInfo getMethod = ReflectionUtils.GetGetterMethodInfo(propertyInfo); + if (!getMethod.IsStatic && CanAdd(propertyInfo, out jsonKey)) + result[jsonKey] = ReflectionUtils.GetGetMethod(propertyInfo); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (!fieldInfo.IsStatic && CanAdd(fieldInfo, out jsonKey)) + result[jsonKey] = ReflectionUtils.GetGetMethod(fieldInfo); + } + return result; + } + + internal override IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>> SetterValueFactory(Type type) + { + bool hasDataContract = ReflectionUtils.GetAttribute(type, typeof(DataContractAttribute)) != null; + if (!hasDataContract) + return base.SetterValueFactory(type); + string jsonKey; + IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>> result = new Dictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>>(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanWrite) + { + MethodInfo setMethod = ReflectionUtils.GetSetterMethodInfo(propertyInfo); + if (!setMethod.IsStatic && CanAdd(propertyInfo, out jsonKey)) + result[jsonKey] = new KeyValuePair<Type, ReflectionUtils.SetDelegate>(propertyInfo.PropertyType, ReflectionUtils.GetSetMethod(propertyInfo)); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (!fieldInfo.IsInitOnly && !fieldInfo.IsStatic && CanAdd(fieldInfo, out jsonKey)) + result[jsonKey] = new KeyValuePair<Type, ReflectionUtils.SetDelegate>(fieldInfo.FieldType, ReflectionUtils.GetSetMethod(fieldInfo)); + } + // todo implement sorting for DATACONTRACT. + return result; + } + + private static bool CanAdd(MemberInfo info, out string jsonKey) + { + jsonKey = null; + if (ReflectionUtils.GetAttribute(info, typeof(IgnoreDataMemberAttribute)) != null) + return false; + DataMemberAttribute dataMemberAttribute = (DataMemberAttribute)ReflectionUtils.GetAttribute(info, typeof(DataMemberAttribute)); + if (dataMemberAttribute == null) + return false; + jsonKey = string.IsNullOrEmpty(dataMemberAttribute.Name) ? info.Name : dataMemberAttribute.Name; + return true; + } + } + +#endif + + // This class is meant to be copied into other libraries. So we want to exclude it from Code Analysis rules + // that might be in place in the target project. + [GeneratedCode("reflection-utils", "1.0.0")] +#if SIMPLE_JSON_REFLECTION_UTILS_PUBLIC + public +#else + internal +#endif + class ReflectionUtils + { + private static readonly object[] EmptyObjects = new object[0]; + + public delegate object GetDelegate(object source); + public delegate void SetDelegate(object source, object value); + public delegate object ConstructorDelegate(params object[] args); + + public delegate TValue ThreadSafeDictionaryValueFactory<TKey, TValue>(TKey key); + + [ThreadStatic] + private static object[] _1ObjArray; + +#if SIMPLE_JSON_TYPEINFO + public static TypeInfo GetTypeInfo(Type type) + { + return type.GetTypeInfo(); + } +#else + public static Type GetTypeInfo(Type type) + { + return type; + } +#endif + + public static Attribute GetAttribute(MemberInfo info, Type type) + { +#if SIMPLE_JSON_TYPEINFO + if (info == null || type == null || !info.IsDefined(type)) + return null; + return info.GetCustomAttribute(type); +#else + if (info == null || type == null || !Attribute.IsDefined(info, type)) + return null; + return Attribute.GetCustomAttribute(info, type); +#endif + } + + public static Type GetGenericListElementType(Type type) + { + if (type == typeof(object)) + return type; + + IEnumerable<Type> interfaces; +#if SIMPLE_JSON_TYPEINFO + interfaces = type.GetTypeInfo().ImplementedInterfaces; +#else + interfaces = type.GetInterfaces(); +#endif + foreach (Type implementedInterface in interfaces) + { + if (IsTypeGeneric(implementedInterface) && + implementedInterface.GetGenericTypeDefinition() == typeof(IList<>)) + { + return GetGenericTypeArguments(implementedInterface)[0]; + } + } + return GetGenericTypeArguments(type)[0]; + } + + public static Attribute GetAttribute(Type objectType, Type attributeType) + { + +#if SIMPLE_JSON_TYPEINFO + if (objectType == null || attributeType == null || !objectType.GetTypeInfo().IsDefined(attributeType)) + return null; + return objectType.GetTypeInfo().GetCustomAttribute(attributeType); +#else + if (objectType == null || attributeType == null || !Attribute.IsDefined(objectType, attributeType)) + return null; + return Attribute.GetCustomAttribute(objectType, attributeType); +#endif + } + + public static Type[] GetGenericTypeArguments(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetTypeInfo().GenericTypeArguments; +#else + return type.GetGenericArguments(); +#endif + } + + public static bool IsTypeGeneric(Type type) + { + return GetTypeInfo(type).IsGenericType; + } + + public static bool IsTypeGenericeCollectionInterface(Type type) + { + if (!IsTypeGeneric(type)) + return false; + + Type genericDefinition = type.GetGenericTypeDefinition(); + + return (genericDefinition == typeof(IList<>) + || genericDefinition == typeof(ICollection<>) + || genericDefinition == typeof(IEnumerable<>) +#if SIMPLE_JSON_READONLY_COLLECTIONS + || genericDefinition == typeof(IReadOnlyCollection<>) + || genericDefinition == typeof(IReadOnlyList<>) +#endif +); + } + + public static bool IsAssignableFrom(Type type1, Type type2) + { + return GetTypeInfo(type1).IsAssignableFrom(GetTypeInfo(type2)); + } + + public static bool IsTypeDictionary(Type type) + { +#if SIMPLE_JSON_TYPEINFO + if (typeof(IDictionary<,>).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo())) + return true; +#else + if (typeof(System.Collections.IDictionary).IsAssignableFrom(type)) + return true; +#endif + if (!GetTypeInfo(type).IsGenericType) + return false; + + Type genericDefinition = type.GetGenericTypeDefinition(); + return genericDefinition == typeof(IDictionary<,>) || genericDefinition == typeof(Dictionary<,>); + } + + public static bool IsNullableType(Type type) + { + return GetTypeInfo(type).IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); + } + + public static object ToNullableType(object obj, Type nullableType) + { + return obj == null ? null : Convert.ChangeType(obj, Nullable.GetUnderlyingType(nullableType), CultureInfo.InvariantCulture); + } + + public static bool IsValueType(Type type) + { + return GetTypeInfo(type).IsValueType; + } + + public static IEnumerable<ConstructorInfo> GetConstructors(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetTypeInfo().DeclaredConstructors; +#else + return type.GetConstructors(); +#endif + } + + public static ConstructorInfo GetConstructorInfo(Type type, params Type[] argsType) + { + IEnumerable<ConstructorInfo> constructorInfos = GetConstructors(type); + int i; + bool matches; + foreach (ConstructorInfo constructorInfo in constructorInfos) + { + ParameterInfo[] parameters = constructorInfo.GetParameters(); + if (argsType.Length != parameters.Length) + continue; + + i = 0; + matches = true; + foreach (ParameterInfo parameterInfo in constructorInfo.GetParameters()) + { + if (parameterInfo.ParameterType != argsType[i]) + { + matches = false; + break; + } + } + + if (matches) + return constructorInfo; + } + + return null; + } + + public static IEnumerable<PropertyInfo> GetProperties(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetRuntimeProperties(); +#else + return type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); +#endif + } + + public static IEnumerable<FieldInfo> GetFields(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetRuntimeFields(); +#else + return type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); +#endif + } + + public static MethodInfo GetGetterMethodInfo(PropertyInfo propertyInfo) + { +#if SIMPLE_JSON_TYPEINFO + return propertyInfo.GetMethod; +#else + return propertyInfo.GetGetMethod(true); +#endif + } + + public static MethodInfo GetSetterMethodInfo(PropertyInfo propertyInfo) + { +#if SIMPLE_JSON_TYPEINFO + return propertyInfo.SetMethod; +#else + return propertyInfo.GetSetMethod(true); +#endif + } + + public static ConstructorDelegate GetContructor(ConstructorInfo constructorInfo) + { + return GetConstructorByReflection(constructorInfo); + } + + public static ConstructorDelegate GetContructor(Type type, params Type[] argsType) + { + return GetConstructorByReflection(type, argsType); + } + + public static ConstructorDelegate GetConstructorByReflection(ConstructorInfo constructorInfo) + { + return delegate (object[] args) + { + var x = constructorInfo; + return x.Invoke(args); + }; + } + + public static ConstructorDelegate GetConstructorByReflection(Type type, params Type[] argsType) + { + ConstructorInfo constructorInfo = GetConstructorInfo(type, argsType); + return constructorInfo == null ? null : GetConstructorByReflection(constructorInfo); + } + + public static GetDelegate GetGetMethod(PropertyInfo propertyInfo) + { + return GetGetMethodByReflection(propertyInfo); + } + + public static GetDelegate GetGetMethod(FieldInfo fieldInfo) + { + return GetGetMethodByReflection(fieldInfo); + } + + public static GetDelegate GetGetMethodByReflection(PropertyInfo propertyInfo) + { + MethodInfo methodInfo = GetGetterMethodInfo(propertyInfo); + return delegate (object source) { return methodInfo.Invoke(source, EmptyObjects); }; + } + + public static GetDelegate GetGetMethodByReflection(FieldInfo fieldInfo) + { + return delegate (object source) { return fieldInfo.GetValue(source); }; + } + + public static SetDelegate GetSetMethod(PropertyInfo propertyInfo) + { + return GetSetMethodByReflection(propertyInfo); + } + + public static SetDelegate GetSetMethod(FieldInfo fieldInfo) + { + return GetSetMethodByReflection(fieldInfo); + } + + public static SetDelegate GetSetMethodByReflection(PropertyInfo propertyInfo) + { + MethodInfo methodInfo = GetSetterMethodInfo(propertyInfo); + return delegate (object source, object value) + { + if (_1ObjArray == null) + _1ObjArray = new object[1]; + _1ObjArray[0] = value; + methodInfo.Invoke(source, _1ObjArray); + }; + } + + public static SetDelegate GetSetMethodByReflection(FieldInfo fieldInfo) + { + return delegate (object source, object value) { fieldInfo.SetValue(source, value); }; + } + + public sealed class ThreadSafeDictionary<TKey, TValue> : IDictionary<TKey, TValue> + { + private readonly object _lock = new object(); + private readonly ThreadSafeDictionaryValueFactory<TKey, TValue> _valueFactory; + private Dictionary<TKey, TValue> _dictionary; + + public ThreadSafeDictionary(ThreadSafeDictionaryValueFactory<TKey, TValue> valueFactory) + { + _valueFactory = valueFactory; + } + + private TValue Get(TKey key) + { + if (_dictionary == null) + return AddValue(key); + TValue value; + if (!_dictionary.TryGetValue(key, out value)) + return AddValue(key); + return value; + } + + private TValue AddValue(TKey key) + { + TValue value = _valueFactory(key); + lock (_lock) + { + if (_dictionary == null) + { + _dictionary = new Dictionary<TKey, TValue>(); + _dictionary[key] = value; + } + else + { + TValue val; + if (_dictionary.TryGetValue(key, out val)) + return val; + Dictionary<TKey, TValue> dict = new Dictionary<TKey, TValue>(_dictionary); + dict[key] = value; + _dictionary = dict; + } + } + return value; + } + + public void Add(TKey key, TValue value) + { + throw new NotImplementedException(); + } + + public bool ContainsKey(TKey key) + { + return _dictionary.ContainsKey(key); + } + + public ICollection<TKey> Keys + { + get { return _dictionary.Keys; } + } + + public bool Remove(TKey key) + { + throw new NotImplementedException(); + } + + public bool TryGetValue(TKey key, out TValue value) + { + value = this[key]; + return true; + } + + public ICollection<TValue> Values + { + get { return _dictionary.Values; } + } + + public TValue this[TKey key] + { + get { return Get(key); } + set { throw new NotImplementedException(); } + } + + public void Add(KeyValuePair<TKey, TValue> item) + { + throw new NotImplementedException(); + } + + public void Clear() + { + throw new NotImplementedException(); + } + + public bool Contains(KeyValuePair<TKey, TValue> item) + { + throw new NotImplementedException(); + } + + public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) + { + throw new NotImplementedException(); + } + + public int Count + { + get { return _dictionary.Count; } + } + + public bool IsReadOnly + { + get { throw new NotImplementedException(); } + } + + public bool Remove(KeyValuePair<TKey, TValue> item) + { + throw new NotImplementedException(); + } + + public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() + { + return _dictionary.GetEnumerator(); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return _dictionary.GetEnumerator(); + } + } + } +} + +// ReSharper restore LoopCanBeConvertedToQuery +// ReSharper restore RedundantExplicitArrayCreation +// ReSharper restore SuggestUseVarKeywordEvident diff --git a/PlayFabServerSDK/source/PlayFabAdminAPI.cs b/PlayFabServerSDK/source/PlayFabAdminAPI.cs index ce48141c..f65ba2a4 100644 --- a/PlayFabServerSDK/source/PlayFabAdminAPI.cs +++ b/PlayFabServerSDK/source/PlayFabAdminAPI.cs @@ -1,13 +1,11 @@ -using Newtonsoft.Json; -using PlayFab.Internal; using PlayFab.AdminModels; +using PlayFab.Internal; +using PlayFab.Json; using System; -using System.IO; using System.Threading.Tasks; namespace PlayFab { - /// <summary> /// APIs for managing title configurations, uploaded Game Server code executables, and user data /// </summary> @@ -16,2001 +14,2071 @@ public class PlayFabAdminAPI /// <summary> /// Bans users by PlayFab ID with optional IP address, or MAC address for the provided game. /// </summary> - public static async Task<PlayFabResult<BanUsersResult>> BanUsersAsync(BanUsersRequest request) + public static async Task<PlayFabResult<BanUsersResult>> BanUsersAsync(BanUsersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/BanUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/BanUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<BanUsersResult> { Error = error, }; + return new PlayFabResult<BanUsersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<BanUsersResult>>(new JsonTextReader(new StringReader(resultRawJson))); - BanUsersResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<BanUsersResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<BanUsersResult> { Result = result }; + return new PlayFabResult<BanUsersResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the relevant details for a specified user, based upon a match against a supplied unique identifier /// </summary> - public static async Task<PlayFabResult<LookupUserAccountInfoResult>> GetUserAccountInfoAsync(LookupUserAccountInfoRequest request) + public static async Task<PlayFabResult<LookupUserAccountInfoResult>> GetUserAccountInfoAsync(LookupUserAccountInfoRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetUserAccountInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetUserAccountInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<LookupUserAccountInfoResult> { Error = error, }; + return new PlayFabResult<LookupUserAccountInfoResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<LookupUserAccountInfoResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<LookupUserAccountInfoResult>>(resultRawJson); + var result = resultData.data; - LookupUserAccountInfoResult result = resultData.data; - - return new PlayFabResult<LookupUserAccountInfoResult> { Result = result }; + return new PlayFabResult<LookupUserAccountInfoResult> { Result = result, CustomData = customData }; } /// <summary> /// Gets all bans for a user. /// </summary> - public static async Task<PlayFabResult<GetUserBansResult>> GetUserBansAsync(GetUserBansRequest request) + public static async Task<PlayFabResult<GetUserBansResult>> GetUserBansAsync(GetUserBansRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetUserBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetUserBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserBansResult> { Error = error, }; + return new PlayFabResult<GetUserBansResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserBansResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserBansResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserBansResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserBansResult> { Result = result }; + return new PlayFabResult<GetUserBansResult> { Result = result, CustomData = customData }; } /// <summary> /// Resets all title-specific information about a particular account, including user data, virtual currency balances, inventory, purchase history, and statistics /// </summary> - public static async Task<PlayFabResult<BlankResult>> ResetUsersAsync(ResetUsersRequest request) + public static async Task<PlayFabResult<BlankResult>> ResetUsersAsync(ResetUsersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/ResetUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/ResetUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<BlankResult> { Error = error, }; + return new PlayFabResult<BlankResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<BlankResult>>(new JsonTextReader(new StringReader(resultRawJson))); - BlankResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<BlankResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<BlankResult> { Result = result }; + return new PlayFabResult<BlankResult> { Result = result, CustomData = customData }; } /// <summary> /// Revoke all active bans for a user. /// </summary> - public static async Task<PlayFabResult<RevokeAllBansForUserResult>> RevokeAllBansForUserAsync(RevokeAllBansForUserRequest request) + public static async Task<PlayFabResult<RevokeAllBansForUserResult>> RevokeAllBansForUserAsync(RevokeAllBansForUserRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/RevokeAllBansForUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/RevokeAllBansForUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RevokeAllBansForUserResult> { Error = error, }; + return new PlayFabResult<RevokeAllBansForUserResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RevokeAllBansForUserResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RevokeAllBansForUserResult>>(resultRawJson); + var result = resultData.data; - RevokeAllBansForUserResult result = resultData.data; - - return new PlayFabResult<RevokeAllBansForUserResult> { Result = result }; + return new PlayFabResult<RevokeAllBansForUserResult> { Result = result, CustomData = customData }; } /// <summary> /// Revoke all active bans specified with BanId. /// </summary> - public static async Task<PlayFabResult<RevokeBansResult>> RevokeBansAsync(RevokeBansRequest request) + public static async Task<PlayFabResult<RevokeBansResult>> RevokeBansAsync(RevokeBansRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/RevokeBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/RevokeBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RevokeBansResult> { Error = error, }; + return new PlayFabResult<RevokeBansResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RevokeBansResult>>(new JsonTextReader(new StringReader(resultRawJson))); - RevokeBansResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RevokeBansResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RevokeBansResult> { Result = result }; + return new PlayFabResult<RevokeBansResult> { Result = result, CustomData = customData }; } /// <summary> /// Forces an email to be sent to the registered email address for the specified account, with a link allowing the user to change the password /// </summary> - public static async Task<PlayFabResult<SendAccountRecoveryEmailResult>> SendAccountRecoveryEmailAsync(SendAccountRecoveryEmailRequest request) + public static async Task<PlayFabResult<SendAccountRecoveryEmailResult>> SendAccountRecoveryEmailAsync(SendAccountRecoveryEmailRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/SendAccountRecoveryEmail", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/SendAccountRecoveryEmail", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SendAccountRecoveryEmailResult> { Error = error, }; + return new PlayFabResult<SendAccountRecoveryEmailResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SendAccountRecoveryEmailResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SendAccountRecoveryEmailResult>>(resultRawJson); + var result = resultData.data; - SendAccountRecoveryEmailResult result = resultData.data; - - return new PlayFabResult<SendAccountRecoveryEmailResult> { Result = result }; + return new PlayFabResult<SendAccountRecoveryEmailResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates information of a list of existing bans specified with Ban Ids. /// </summary> - public static async Task<PlayFabResult<UpdateBansResult>> UpdateBansAsync(UpdateBansRequest request) + public static async Task<PlayFabResult<UpdateBansResult>> UpdateBansAsync(UpdateBansRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateBansResult> { Error = error, }; + return new PlayFabResult<UpdateBansResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateBansResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateBansResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateBansResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateBansResult> { Result = result }; + return new PlayFabResult<UpdateBansResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title specific display name for a user /// </summary> - public static async Task<PlayFabResult<UpdateUserTitleDisplayNameResult>> UpdateUserTitleDisplayNameAsync(UpdateUserTitleDisplayNameRequest request) + public static async Task<PlayFabResult<UpdateUserTitleDisplayNameResult>> UpdateUserTitleDisplayNameAsync(UpdateUserTitleDisplayNameRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateUserTitleDisplayName", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateUserTitleDisplayName", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserTitleDisplayNameResult> { Error = error, }; + return new PlayFabResult<UpdateUserTitleDisplayNameResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserTitleDisplayNameResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserTitleDisplayNameResult>>(resultRawJson); + var result = resultData.data; - UpdateUserTitleDisplayNameResult result = resultData.data; - - return new PlayFabResult<UpdateUserTitleDisplayNameResult> { Result = result }; + return new PlayFabResult<UpdateUserTitleDisplayNameResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds a new player statistic configuration to the title, optionally allowing the developer to specify a reset interval and an aggregation method. /// </summary> - public static async Task<PlayFabResult<CreatePlayerStatisticDefinitionResult>> CreatePlayerStatisticDefinitionAsync(CreatePlayerStatisticDefinitionRequest request) + public static async Task<PlayFabResult<CreatePlayerStatisticDefinitionResult>> CreatePlayerStatisticDefinitionAsync(CreatePlayerStatisticDefinitionRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/CreatePlayerStatisticDefinition", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/CreatePlayerStatisticDefinition", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<CreatePlayerStatisticDefinitionResult> { Error = error, }; + return new PlayFabResult<CreatePlayerStatisticDefinitionResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<CreatePlayerStatisticDefinitionResult>>(new JsonTextReader(new StringReader(resultRawJson))); - CreatePlayerStatisticDefinitionResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<CreatePlayerStatisticDefinitionResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<CreatePlayerStatisticDefinitionResult> { Result = result }; + return new PlayFabResult<CreatePlayerStatisticDefinitionResult> { Result = result, CustomData = customData }; } /// <summary> /// Deletes the users for the provided game. Deletes custom data, all account linkages, and statistics. This method does not remove the player's event history, login history, inventory items, nor virtual currencies. /// </summary> - public static async Task<PlayFabResult<DeleteUsersResult>> DeleteUsersAsync(DeleteUsersRequest request) + public static async Task<PlayFabResult<DeleteUsersResult>> DeleteUsersAsync(DeleteUsersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/DeleteUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/DeleteUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<DeleteUsersResult> { Error = error, }; + return new PlayFabResult<DeleteUsersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<DeleteUsersResult>>(new JsonTextReader(new StringReader(resultRawJson))); - DeleteUsersResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<DeleteUsersResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<DeleteUsersResult> { Result = result }; + return new PlayFabResult<DeleteUsersResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a download URL for the requested report /// </summary> - public static async Task<PlayFabResult<GetDataReportResult>> GetDataReportAsync(GetDataReportRequest request) + public static async Task<PlayFabResult<GetDataReportResult>> GetDataReportAsync(GetDataReportRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetDataReport", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetDataReport", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetDataReportResult> { Error = error, }; + return new PlayFabResult<GetDataReportResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetDataReportResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetDataReportResult>>(resultRawJson); + var result = resultData.data; - GetDataReportResult result = resultData.data; - - return new PlayFabResult<GetDataReportResult> { Result = result }; + return new PlayFabResult<GetDataReportResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the configuration information for all player statistics defined in the title, regardless of whether they have a reset interval. /// </summary> - public static async Task<PlayFabResult<GetPlayerStatisticDefinitionsResult>> GetPlayerStatisticDefinitionsAsync(GetPlayerStatisticDefinitionsRequest request) + public static async Task<PlayFabResult<GetPlayerStatisticDefinitionsResult>> GetPlayerStatisticDefinitionsAsync(GetPlayerStatisticDefinitionsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetPlayerStatisticDefinitions", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetPlayerStatisticDefinitions", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerStatisticDefinitionsResult> { Error = error, }; + return new PlayFabResult<GetPlayerStatisticDefinitionsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerStatisticDefinitionsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerStatisticDefinitionsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerStatisticDefinitionsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerStatisticDefinitionsResult> { Result = result }; + return new PlayFabResult<GetPlayerStatisticDefinitionsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the information on the available versions of the specified statistic. /// </summary> - public static async Task<PlayFabResult<GetPlayerStatisticVersionsResult>> GetPlayerStatisticVersionsAsync(GetPlayerStatisticVersionsRequest request) + public static async Task<PlayFabResult<GetPlayerStatisticVersionsResult>> GetPlayerStatisticVersionsAsync(GetPlayerStatisticVersionsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetPlayerStatisticVersions", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetPlayerStatisticVersions", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerStatisticVersionsResult> { Error = error, }; + return new PlayFabResult<GetPlayerStatisticVersionsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerStatisticVersionsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerStatisticVersionsResult>>(resultRawJson); + var result = resultData.data; - GetPlayerStatisticVersionsResult result = resultData.data; - - return new PlayFabResult<GetPlayerStatisticVersionsResult> { Result = result }; + return new PlayFabResult<GetPlayerStatisticVersionsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetUserData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetUserData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserInternalDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserInternalDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetUserInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetUserInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - GetUserDataResult result = resultData.data; - - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the publisher-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetUserPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetUserPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the publisher-specific custom data for the user which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherInternalDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherInternalDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetUserPublisherInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetUserPublisherInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the publisher-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherReadOnlyDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherReadOnlyDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetUserPublisherReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetUserPublisherReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - GetUserDataResult result = resultData.data; - - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserReadOnlyDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserReadOnlyDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetUserReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetUserReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Resets the indicated statistic, removing all player entries for it and backing up the old values. /// </summary> - public static async Task<PlayFabResult<IncrementPlayerStatisticVersionResult>> IncrementPlayerStatisticVersionAsync(IncrementPlayerStatisticVersionRequest request) + public static async Task<PlayFabResult<IncrementPlayerStatisticVersionResult>> IncrementPlayerStatisticVersionAsync(IncrementPlayerStatisticVersionRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/IncrementPlayerStatisticVersion", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/IncrementPlayerStatisticVersion", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<IncrementPlayerStatisticVersionResult> { Error = error, }; + return new PlayFabResult<IncrementPlayerStatisticVersionResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<IncrementPlayerStatisticVersionResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<IncrementPlayerStatisticVersionResult>>(resultRawJson); + var result = resultData.data; - IncrementPlayerStatisticVersionResult result = resultData.data; - - return new PlayFabResult<IncrementPlayerStatisticVersionResult> { Result = result }; + return new PlayFabResult<IncrementPlayerStatisticVersionResult> { Result = result, CustomData = customData }; } /// <summary> /// Attempts to process an order refund through the original real money payment provider. /// </summary> - public static async Task<PlayFabResult<RefundPurchaseResponse>> RefundPurchaseAsync(RefundPurchaseRequest request) + public static async Task<PlayFabResult<RefundPurchaseResponse>> RefundPurchaseAsync(RefundPurchaseRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/RefundPurchase", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/RefundPurchase", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RefundPurchaseResponse> { Error = error, }; + return new PlayFabResult<RefundPurchaseResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RefundPurchaseResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - RefundPurchaseResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RefundPurchaseResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RefundPurchaseResponse> { Result = result }; + return new PlayFabResult<RefundPurchaseResponse> { Result = result, CustomData = customData }; } /// <summary> /// Completely removes all statistics for the specified user, for the current game /// </summary> - public static async Task<PlayFabResult<ResetUserStatisticsResult>> ResetUserStatisticsAsync(ResetUserStatisticsRequest request) + public static async Task<PlayFabResult<ResetUserStatisticsResult>> ResetUserStatisticsAsync(ResetUserStatisticsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/ResetUserStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/ResetUserStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ResetUserStatisticsResult> { Error = error, }; + return new PlayFabResult<ResetUserStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ResetUserStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ResetUserStatisticsResult>>(resultRawJson); + var result = resultData.data; - ResetUserStatisticsResult result = resultData.data; - - return new PlayFabResult<ResetUserStatisticsResult> { Result = result }; + return new PlayFabResult<ResetUserStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Attempts to resolve a dispute with the original order's payment provider. /// </summary> - public static async Task<PlayFabResult<ResolvePurchaseDisputeResponse>> ResolvePurchaseDisputeAsync(ResolvePurchaseDisputeRequest request) + public static async Task<PlayFabResult<ResolvePurchaseDisputeResponse>> ResolvePurchaseDisputeAsync(ResolvePurchaseDisputeRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/ResolvePurchaseDispute", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/ResolvePurchaseDispute", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ResolvePurchaseDisputeResponse> { Error = error, }; + return new PlayFabResult<ResolvePurchaseDisputeResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ResolvePurchaseDisputeResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - ResolvePurchaseDisputeResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ResolvePurchaseDisputeResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ResolvePurchaseDisputeResponse> { Result = result }; + return new PlayFabResult<ResolvePurchaseDisputeResponse> { Result = result, CustomData = customData }; } /// <summary> /// Updates a player statistic configuration for the title, optionally allowing the developer to specify a reset interval. /// </summary> - public static async Task<PlayFabResult<UpdatePlayerStatisticDefinitionResult>> UpdatePlayerStatisticDefinitionAsync(UpdatePlayerStatisticDefinitionRequest request) + public static async Task<PlayFabResult<UpdatePlayerStatisticDefinitionResult>> UpdatePlayerStatisticDefinitionAsync(UpdatePlayerStatisticDefinitionRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdatePlayerStatisticDefinition", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdatePlayerStatisticDefinition", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdatePlayerStatisticDefinitionResult> { Error = error, }; + return new PlayFabResult<UpdatePlayerStatisticDefinitionResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdatePlayerStatisticDefinitionResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdatePlayerStatisticDefinitionResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdatePlayerStatisticDefinitionResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdatePlayerStatisticDefinitionResult> { Result = result }; + return new PlayFabResult<UpdatePlayerStatisticDefinitionResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserDataAsync(UpdateUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateUserData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateUserData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - UpdateUserDataResult result = resultData.data; - - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title-specific custom data for the user which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserInternalDataAsync(UpdateUserInternalDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserInternalDataAsync(UpdateUserInternalDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateUserInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateUserInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the publisher-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherDataAsync(UpdateUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateUserPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateUserPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - UpdateUserDataResult result = resultData.data; - - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the publisher-specific custom data for the user which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherInternalDataAsync(UpdateUserInternalDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherInternalDataAsync(UpdateUserInternalDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateUserPublisherInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateUserPublisherInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the publisher-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherReadOnlyDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherReadOnlyDataAsync(UpdateUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateUserPublisherReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateUserPublisherReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - UpdateUserDataResult result = resultData.data; - - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserReadOnlyDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserReadOnlyDataAsync(UpdateUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateUserReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateUserReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds a new news item to the title's news feed /// </summary> - public static async Task<PlayFabResult<AddNewsResult>> AddNewsAsync(AddNewsRequest request) + public static async Task<PlayFabResult<AddNewsResult>> AddNewsAsync(AddNewsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/AddNews", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/AddNews", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AddNewsResult> { Error = error, }; + return new PlayFabResult<AddNewsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AddNewsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - AddNewsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AddNewsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AddNewsResult> { Result = result }; + return new PlayFabResult<AddNewsResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds one or more virtual currencies to the set defined for the title. Virtual Currencies have a maximum value of 2,147,483,647 when granted to a player. Any value over that will be discarded. /// </summary> - public static async Task<PlayFabResult<BlankResult>> AddVirtualCurrencyTypesAsync(AddVirtualCurrencyTypesRequest request) + public static async Task<PlayFabResult<BlankResult>> AddVirtualCurrencyTypesAsync(AddVirtualCurrencyTypesRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/AddVirtualCurrencyTypes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/AddVirtualCurrencyTypes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<BlankResult> { Error = error, }; + return new PlayFabResult<BlankResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<BlankResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<BlankResult>>(resultRawJson); + var result = resultData.data; - BlankResult result = resultData.data; - - return new PlayFabResult<BlankResult> { Result = result }; + return new PlayFabResult<BlankResult> { Result = result, CustomData = customData }; } /// <summary> /// Deletes an existing virtual item store /// </summary> - public static async Task<PlayFabResult<DeleteStoreResult>> DeleteStoreAsync(DeleteStoreRequest request) + public static async Task<PlayFabResult<DeleteStoreResult>> DeleteStoreAsync(DeleteStoreRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/DeleteStore", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/DeleteStore", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<DeleteStoreResult> { Error = error, }; + return new PlayFabResult<DeleteStoreResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<DeleteStoreResult>>(new JsonTextReader(new StringReader(resultRawJson))); - DeleteStoreResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<DeleteStoreResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<DeleteStoreResult> { Result = result }; + return new PlayFabResult<DeleteStoreResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the specified version of the title's catalog of virtual goods, including all defined properties /// </summary> - public static async Task<PlayFabResult<GetCatalogItemsResult>> GetCatalogItemsAsync(GetCatalogItemsRequest request) + public static async Task<PlayFabResult<GetCatalogItemsResult>> GetCatalogItemsAsync(GetCatalogItemsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetCatalogItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetCatalogItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCatalogItemsResult> { Error = error, }; + return new PlayFabResult<GetCatalogItemsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCatalogItemsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCatalogItemsResult>>(resultRawJson); + var result = resultData.data; - GetCatalogItemsResult result = resultData.data; - - return new PlayFabResult<GetCatalogItemsResult> { Result = result }; + return new PlayFabResult<GetCatalogItemsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the key-value store of custom publisher settings /// </summary> - public static async Task<PlayFabResult<GetPublisherDataResult>> GetPublisherDataAsync(GetPublisherDataRequest request) + public static async Task<PlayFabResult<GetPublisherDataResult>> GetPublisherDataAsync(GetPublisherDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPublisherDataResult> { Error = error, }; + return new PlayFabResult<GetPublisherDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPublisherDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPublisherDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPublisherDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPublisherDataResult> { Result = result }; + return new PlayFabResult<GetPublisherDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the random drop table configuration for the title /// </summary> - public static async Task<PlayFabResult<GetRandomResultTablesResult>> GetRandomResultTablesAsync(GetRandomResultTablesRequest request) + public static async Task<PlayFabResult<GetRandomResultTablesResult>> GetRandomResultTablesAsync(GetRandomResultTablesRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetRandomResultTables", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetRandomResultTables", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetRandomResultTablesResult> { Error = error, }; + return new PlayFabResult<GetRandomResultTablesResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetRandomResultTablesResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetRandomResultTablesResult>>(resultRawJson); + var result = resultData.data; - GetRandomResultTablesResult result = resultData.data; - - return new PlayFabResult<GetRandomResultTablesResult> { Result = result }; + return new PlayFabResult<GetRandomResultTablesResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the set of items defined for the specified store, including all prices defined /// </summary> - public static async Task<PlayFabResult<GetStoreItemsResult>> GetStoreItemsAsync(GetStoreItemsRequest request) + public static async Task<PlayFabResult<GetStoreItemsResult>> GetStoreItemsAsync(GetStoreItemsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetStoreItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetStoreItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetStoreItemsResult> { Error = error, }; + return new PlayFabResult<GetStoreItemsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetStoreItemsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetStoreItemsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetStoreItemsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetStoreItemsResult> { Result = result }; + return new PlayFabResult<GetStoreItemsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the key-value store of custom title settings which can be read by the client /// </summary> - public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleDataAsync(GetTitleDataRequest request) + public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleDataAsync(GetTitleDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetTitleData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetTitleData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTitleDataResult> { Error = error, }; + return new PlayFabResult<GetTitleDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTitleDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetTitleDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTitleDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetTitleDataResult> { Result = result }; + return new PlayFabResult<GetTitleDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the key-value store of custom title settings which cannot be read by the client /// </summary> - public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleInternalDataAsync(GetTitleDataRequest request) + public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleInternalDataAsync(GetTitleDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetTitleInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetTitleInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTitleDataResult> { Error = error, }; + return new PlayFabResult<GetTitleDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTitleDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTitleDataResult>>(resultRawJson); + var result = resultData.data; - GetTitleDataResult result = resultData.data; - - return new PlayFabResult<GetTitleDataResult> { Result = result }; + return new PlayFabResult<GetTitleDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retuns the list of all defined virtual currencies for the title /// </summary> - public static async Task<PlayFabResult<ListVirtualCurrencyTypesResult>> ListVirtualCurrencyTypesAsync(ListVirtualCurrencyTypesRequest request) + public static async Task<PlayFabResult<ListVirtualCurrencyTypesResult>> ListVirtualCurrencyTypesAsync(ListVirtualCurrencyTypesRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/ListVirtualCurrencyTypes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/ListVirtualCurrencyTypes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ListVirtualCurrencyTypesResult> { Error = error, }; + return new PlayFabResult<ListVirtualCurrencyTypesResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ListVirtualCurrencyTypesResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ListVirtualCurrencyTypesResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ListVirtualCurrencyTypesResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ListVirtualCurrencyTypesResult> { Result = result }; + return new PlayFabResult<ListVirtualCurrencyTypesResult> { Result = result, CustomData = customData }; } /// <summary> /// Removes one or more virtual currencies from the set defined for the title. /// </summary> - public static async Task<PlayFabResult<BlankResult>> RemoveVirtualCurrencyTypesAsync(RemoveVirtualCurrencyTypesRequest request) + public static async Task<PlayFabResult<BlankResult>> RemoveVirtualCurrencyTypesAsync(RemoveVirtualCurrencyTypesRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/RemoveVirtualCurrencyTypes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/RemoveVirtualCurrencyTypes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<BlankResult> { Error = error, }; + return new PlayFabResult<BlankResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<BlankResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<BlankResult>>(resultRawJson); + var result = resultData.data; - BlankResult result = resultData.data; - - return new PlayFabResult<BlankResult> { Result = result }; + return new PlayFabResult<BlankResult> { Result = result, CustomData = customData }; } /// <summary> /// Creates the catalog configuration of all virtual goods for the specified catalog version /// </summary> - public static async Task<PlayFabResult<UpdateCatalogItemsResult>> SetCatalogItemsAsync(UpdateCatalogItemsRequest request) + public static async Task<PlayFabResult<UpdateCatalogItemsResult>> SetCatalogItemsAsync(UpdateCatalogItemsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/SetCatalogItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/SetCatalogItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateCatalogItemsResult> { Error = error, }; + return new PlayFabResult<UpdateCatalogItemsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateCatalogItemsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateCatalogItemsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateCatalogItemsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateCatalogItemsResult> { Result = result }; + return new PlayFabResult<UpdateCatalogItemsResult> { Result = result, CustomData = customData }; } /// <summary> /// Sets all the items in one virtual store /// </summary> - public static async Task<PlayFabResult<UpdateStoreItemsResult>> SetStoreItemsAsync(UpdateStoreItemsRequest request) + public static async Task<PlayFabResult<UpdateStoreItemsResult>> SetStoreItemsAsync(UpdateStoreItemsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/SetStoreItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/SetStoreItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateStoreItemsResult> { Error = error, }; + return new PlayFabResult<UpdateStoreItemsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateStoreItemsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateStoreItemsResult>>(resultRawJson); + var result = resultData.data; - UpdateStoreItemsResult result = resultData.data; - - return new PlayFabResult<UpdateStoreItemsResult> { Result = result }; + return new PlayFabResult<UpdateStoreItemsResult> { Result = result, CustomData = customData }; } /// <summary> /// Creates and updates the key-value store of custom title settings which can be read by the client /// </summary> - public static async Task<PlayFabResult<SetTitleDataResult>> SetTitleDataAsync(SetTitleDataRequest request) + public static async Task<PlayFabResult<SetTitleDataResult>> SetTitleDataAsync(SetTitleDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/SetTitleData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/SetTitleData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetTitleDataResult> { Error = error, }; + return new PlayFabResult<SetTitleDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetTitleDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - SetTitleDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetTitleDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<SetTitleDataResult> { Result = result }; + return new PlayFabResult<SetTitleDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the key-value store of custom title settings which cannot be read by the client /// </summary> - public static async Task<PlayFabResult<SetTitleDataResult>> SetTitleInternalDataAsync(SetTitleDataRequest request) + public static async Task<PlayFabResult<SetTitleDataResult>> SetTitleInternalDataAsync(SetTitleDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/SetTitleInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/SetTitleInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetTitleDataResult> { Error = error, }; + return new PlayFabResult<SetTitleDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetTitleDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - SetTitleDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetTitleDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<SetTitleDataResult> { Result = result }; + return new PlayFabResult<SetTitleDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Sets the Amazon Resource Name (ARN) for iOS and Android push notifications. Documentation on the exact restrictions can be found at: http://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html. Currently, Amazon device Messaging is not supported. /// </summary> - public static async Task<PlayFabResult<SetupPushNotificationResult>> SetupPushNotificationAsync(SetupPushNotificationRequest request) + public static async Task<PlayFabResult<SetupPushNotificationResult>> SetupPushNotificationAsync(SetupPushNotificationRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/SetupPushNotification", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/SetupPushNotification", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetupPushNotificationResult> { Error = error, }; + return new PlayFabResult<SetupPushNotificationResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetupPushNotificationResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetupPushNotificationResult>>(resultRawJson); + var result = resultData.data; - SetupPushNotificationResult result = resultData.data; - - return new PlayFabResult<SetupPushNotificationResult> { Result = result }; + return new PlayFabResult<SetupPushNotificationResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the catalog configuration for virtual goods in the specified catalog version /// </summary> - public static async Task<PlayFabResult<UpdateCatalogItemsResult>> UpdateCatalogItemsAsync(UpdateCatalogItemsRequest request) + public static async Task<PlayFabResult<UpdateCatalogItemsResult>> UpdateCatalogItemsAsync(UpdateCatalogItemsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateCatalogItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateCatalogItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateCatalogItemsResult> { Error = error, }; + return new PlayFabResult<UpdateCatalogItemsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateCatalogItemsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateCatalogItemsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateCatalogItemsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateCatalogItemsResult> { Result = result }; + return new PlayFabResult<UpdateCatalogItemsResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the random drop table configuration for the title /// </summary> - public static async Task<PlayFabResult<UpdateRandomResultTablesResult>> UpdateRandomResultTablesAsync(UpdateRandomResultTablesRequest request) + public static async Task<PlayFabResult<UpdateRandomResultTablesResult>> UpdateRandomResultTablesAsync(UpdateRandomResultTablesRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateRandomResultTables", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateRandomResultTables", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateRandomResultTablesResult> { Error = error, }; + return new PlayFabResult<UpdateRandomResultTablesResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateRandomResultTablesResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateRandomResultTablesResult>>(resultRawJson); + var result = resultData.data; - UpdateRandomResultTablesResult result = resultData.data; - - return new PlayFabResult<UpdateRandomResultTablesResult> { Result = result }; + return new PlayFabResult<UpdateRandomResultTablesResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates an existing virtual item store with new or modified items /// </summary> - public static async Task<PlayFabResult<UpdateStoreItemsResult>> UpdateStoreItemsAsync(UpdateStoreItemsRequest request) + public static async Task<PlayFabResult<UpdateStoreItemsResult>> UpdateStoreItemsAsync(UpdateStoreItemsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateStoreItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateStoreItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateStoreItemsResult> { Error = error, }; + return new PlayFabResult<UpdateStoreItemsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateStoreItemsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateStoreItemsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateStoreItemsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateStoreItemsResult> { Result = result }; + return new PlayFabResult<UpdateStoreItemsResult> { Result = result, CustomData = customData }; } /// <summary> /// Increments the specified virtual currency by the stated amount /// </summary> - public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> AddUserVirtualCurrencyAsync(AddUserVirtualCurrencyRequest request) + public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> AddUserVirtualCurrencyAsync(AddUserVirtualCurrencyRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/AddUserVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/AddUserVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(resultRawJson); + var result = resultData.data; - ModifyUserVirtualCurrencyResult result = resultData.data; - - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the specified user's current inventory of virtual goods /// </summary> - public static async Task<PlayFabResult<GetUserInventoryResult>> GetUserInventoryAsync(GetUserInventoryRequest request) + public static async Task<PlayFabResult<GetUserInventoryResult>> GetUserInventoryAsync(GetUserInventoryRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetUserInventory", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetUserInventory", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserInventoryResult> { Error = error, }; + return new PlayFabResult<GetUserInventoryResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserInventoryResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserInventoryResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserInventoryResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserInventoryResult> { Result = result }; + return new PlayFabResult<GetUserInventoryResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the specified items to the specified user inventories /// </summary> - public static async Task<PlayFabResult<GrantItemsToUsersResult>> GrantItemsToUsersAsync(GrantItemsToUsersRequest request) + public static async Task<PlayFabResult<GrantItemsToUsersResult>> GrantItemsToUsersAsync(GrantItemsToUsersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GrantItemsToUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GrantItemsToUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GrantItemsToUsersResult> { Error = error, }; + return new PlayFabResult<GrantItemsToUsersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GrantItemsToUsersResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GrantItemsToUsersResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GrantItemsToUsersResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GrantItemsToUsersResult> { Result = result }; + return new PlayFabResult<GrantItemsToUsersResult> { Result = result, CustomData = customData }; } /// <summary> /// Revokes access to an item in a user's inventory /// </summary> - public static async Task<PlayFabResult<RevokeInventoryResult>> RevokeInventoryItemAsync(RevokeInventoryItemRequest request) + public static async Task<PlayFabResult<RevokeInventoryResult>> RevokeInventoryItemAsync(RevokeInventoryItemRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/RevokeInventoryItem", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/RevokeInventoryItem", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RevokeInventoryResult> { Error = error, }; + return new PlayFabResult<RevokeInventoryResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RevokeInventoryResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RevokeInventoryResult>>(resultRawJson); + var result = resultData.data; - RevokeInventoryResult result = resultData.data; - - return new PlayFabResult<RevokeInventoryResult> { Result = result }; + return new PlayFabResult<RevokeInventoryResult> { Result = result, CustomData = customData }; } /// <summary> /// Decrements the specified virtual currency by the stated amount /// </summary> - public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> SubtractUserVirtualCurrencyAsync(SubtractUserVirtualCurrencyRequest request) + public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> SubtractUserVirtualCurrencyAsync(SubtractUserVirtualCurrencyRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/SubtractUserVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/SubtractUserVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ModifyUserVirtualCurrencyResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the details for a specific completed session, including links to standard out and standard error logs /// </summary> - public static async Task<PlayFabResult<GetMatchmakerGameInfoResult>> GetMatchmakerGameInfoAsync(GetMatchmakerGameInfoRequest request) + public static async Task<PlayFabResult<GetMatchmakerGameInfoResult>> GetMatchmakerGameInfoAsync(GetMatchmakerGameInfoRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetMatchmakerGameInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetMatchmakerGameInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetMatchmakerGameInfoResult> { Error = error, }; + return new PlayFabResult<GetMatchmakerGameInfoResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetMatchmakerGameInfoResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetMatchmakerGameInfoResult>>(resultRawJson); + var result = resultData.data; - GetMatchmakerGameInfoResult result = resultData.data; - - return new PlayFabResult<GetMatchmakerGameInfoResult> { Result = result }; + return new PlayFabResult<GetMatchmakerGameInfoResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the details of defined game modes for the specified game server executable /// </summary> - public static async Task<PlayFabResult<GetMatchmakerGameModesResult>> GetMatchmakerGameModesAsync(GetMatchmakerGameModesRequest request) + public static async Task<PlayFabResult<GetMatchmakerGameModesResult>> GetMatchmakerGameModesAsync(GetMatchmakerGameModesRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetMatchmakerGameModes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetMatchmakerGameModes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetMatchmakerGameModesResult> { Error = error, }; + return new PlayFabResult<GetMatchmakerGameModesResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetMatchmakerGameModesResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetMatchmakerGameModesResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetMatchmakerGameModesResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetMatchmakerGameModesResult> { Result = result }; + return new PlayFabResult<GetMatchmakerGameModesResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the game server mode details for the specified game server executable /// </summary> - public static async Task<PlayFabResult<ModifyMatchmakerGameModesResult>> ModifyMatchmakerGameModesAsync(ModifyMatchmakerGameModesRequest request) + public static async Task<PlayFabResult<ModifyMatchmakerGameModesResult>> ModifyMatchmakerGameModesAsync(ModifyMatchmakerGameModesRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/ModifyMatchmakerGameModes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/ModifyMatchmakerGameModes", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyMatchmakerGameModesResult> { Error = error, }; + return new PlayFabResult<ModifyMatchmakerGameModesResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyMatchmakerGameModesResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyMatchmakerGameModesResult>>(resultRawJson); + var result = resultData.data; - ModifyMatchmakerGameModesResult result = resultData.data; - - return new PlayFabResult<ModifyMatchmakerGameModesResult> { Result = result }; + return new PlayFabResult<ModifyMatchmakerGameModesResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the game server executable specified (previously uploaded - see GetServerBuildUploadUrl) to the set of those a client is permitted to request in a call to StartGame /// </summary> - public static async Task<PlayFabResult<AddServerBuildResult>> AddServerBuildAsync(AddServerBuildRequest request) + public static async Task<PlayFabResult<AddServerBuildResult>> AddServerBuildAsync(AddServerBuildRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/AddServerBuild", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/AddServerBuild", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AddServerBuildResult> { Error = error, }; + return new PlayFabResult<AddServerBuildResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AddServerBuildResult>>(new JsonTextReader(new StringReader(resultRawJson))); - AddServerBuildResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AddServerBuildResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AddServerBuildResult> { Result = result }; + return new PlayFabResult<AddServerBuildResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the build details for the specified game server executable /// </summary> - public static async Task<PlayFabResult<GetServerBuildInfoResult>> GetServerBuildInfoAsync(GetServerBuildInfoRequest request) + public static async Task<PlayFabResult<GetServerBuildInfoResult>> GetServerBuildInfoAsync(GetServerBuildInfoRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetServerBuildInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetServerBuildInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetServerBuildInfoResult> { Error = error, }; + return new PlayFabResult<GetServerBuildInfoResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetServerBuildInfoResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetServerBuildInfoResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetServerBuildInfoResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetServerBuildInfoResult> { Result = result }; + return new PlayFabResult<GetServerBuildInfoResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the pre-authorized URL for uploading a game server package containing a build (does not enable the build for use - see AddServerBuild) /// </summary> - public static async Task<PlayFabResult<GetServerBuildUploadURLResult>> GetServerBuildUploadUrlAsync(GetServerBuildUploadURLRequest request) + public static async Task<PlayFabResult<GetServerBuildUploadURLResult>> GetServerBuildUploadUrlAsync(GetServerBuildUploadURLRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetServerBuildUploadUrl", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetServerBuildUploadUrl", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetServerBuildUploadURLResult> { Error = error, }; + return new PlayFabResult<GetServerBuildUploadURLResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetServerBuildUploadURLResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetServerBuildUploadURLResult>>(resultRawJson); + var result = resultData.data; - GetServerBuildUploadURLResult result = resultData.data; - - return new PlayFabResult<GetServerBuildUploadURLResult> { Result = result }; + return new PlayFabResult<GetServerBuildUploadURLResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the build details for all game server executables which are currently defined for the title /// </summary> - public static async Task<PlayFabResult<ListBuildsResult>> ListServerBuildsAsync(ListBuildsRequest request) + public static async Task<PlayFabResult<ListBuildsResult>> ListServerBuildsAsync(ListBuildsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/ListServerBuilds", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/ListServerBuilds", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ListBuildsResult> { Error = error, }; + return new PlayFabResult<ListBuildsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ListBuildsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ListBuildsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ListBuildsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ListBuildsResult> { Result = result }; + return new PlayFabResult<ListBuildsResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the build details for the specified game server executable /// </summary> - public static async Task<PlayFabResult<ModifyServerBuildResult>> ModifyServerBuildAsync(ModifyServerBuildRequest request) + public static async Task<PlayFabResult<ModifyServerBuildResult>> ModifyServerBuildAsync(ModifyServerBuildRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/ModifyServerBuild", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/ModifyServerBuild", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyServerBuildResult> { Error = error, }; + return new PlayFabResult<ModifyServerBuildResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyServerBuildResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyServerBuildResult>>(resultRawJson); + var result = resultData.data; - ModifyServerBuildResult result = resultData.data; - - return new PlayFabResult<ModifyServerBuildResult> { Result = result }; + return new PlayFabResult<ModifyServerBuildResult> { Result = result, CustomData = customData }; } /// <summary> /// Removes the game server executable specified from the set of those a client is permitted to request in a call to StartGame /// </summary> - public static async Task<PlayFabResult<RemoveServerBuildResult>> RemoveServerBuildAsync(RemoveServerBuildRequest request) + public static async Task<PlayFabResult<RemoveServerBuildResult>> RemoveServerBuildAsync(RemoveServerBuildRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/RemoveServerBuild", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/RemoveServerBuild", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RemoveServerBuildResult> { Error = error, }; + return new PlayFabResult<RemoveServerBuildResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RemoveServerBuildResult>>(new JsonTextReader(new StringReader(resultRawJson))); - RemoveServerBuildResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RemoveServerBuildResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RemoveServerBuildResult> { Result = result }; + return new PlayFabResult<RemoveServerBuildResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the key-value store of custom publisher settings /// </summary> - public static async Task<PlayFabResult<SetPublisherDataResult>> SetPublisherDataAsync(SetPublisherDataRequest request) + public static async Task<PlayFabResult<SetPublisherDataResult>> SetPublisherDataAsync(SetPublisherDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/SetPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/SetPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetPublisherDataResult> { Error = error, }; + return new PlayFabResult<SetPublisherDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetPublisherDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetPublisherDataResult>>(resultRawJson); + var result = resultData.data; - SetPublisherDataResult result = resultData.data; - - return new PlayFabResult<SetPublisherDataResult> { Result = result }; + return new PlayFabResult<SetPublisherDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Gets the contents and information of a specific Cloud Script revision. /// </summary> - public static async Task<PlayFabResult<GetCloudScriptRevisionResult>> GetCloudScriptRevisionAsync(GetCloudScriptRevisionRequest request) + public static async Task<PlayFabResult<GetCloudScriptRevisionResult>> GetCloudScriptRevisionAsync(GetCloudScriptRevisionRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetCloudScriptRevision", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetCloudScriptRevision", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCloudScriptRevisionResult> { Error = error, }; + return new PlayFabResult<GetCloudScriptRevisionResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCloudScriptRevisionResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetCloudScriptRevisionResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCloudScriptRevisionResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetCloudScriptRevisionResult> { Result = result }; + return new PlayFabResult<GetCloudScriptRevisionResult> { Result = result, CustomData = customData }; } /// <summary> /// Lists all the current cloud script versions. For each version, information about the current published and latest revisions is also listed. /// </summary> - public static async Task<PlayFabResult<GetCloudScriptVersionsResult>> GetCloudScriptVersionsAsync(GetCloudScriptVersionsRequest request) + public static async Task<PlayFabResult<GetCloudScriptVersionsResult>> GetCloudScriptVersionsAsync(GetCloudScriptVersionsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetCloudScriptVersions", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetCloudScriptVersions", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCloudScriptVersionsResult> { Error = error, }; + return new PlayFabResult<GetCloudScriptVersionsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCloudScriptVersionsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetCloudScriptVersionsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCloudScriptVersionsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetCloudScriptVersionsResult> { Result = result }; + return new PlayFabResult<GetCloudScriptVersionsResult> { Result = result, CustomData = customData }; } /// <summary> /// Sets the currently published revision of a title Cloud Script /// </summary> - public static async Task<PlayFabResult<SetPublishedRevisionResult>> SetPublishedRevisionAsync(SetPublishedRevisionRequest request) + public static async Task<PlayFabResult<SetPublishedRevisionResult>> SetPublishedRevisionAsync(SetPublishedRevisionRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/SetPublishedRevision", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/SetPublishedRevision", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetPublishedRevisionResult> { Error = error, }; + return new PlayFabResult<SetPublishedRevisionResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetPublishedRevisionResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetPublishedRevisionResult>>(resultRawJson); + var result = resultData.data; - SetPublishedRevisionResult result = resultData.data; - - return new PlayFabResult<SetPublishedRevisionResult> { Result = result }; + return new PlayFabResult<SetPublishedRevisionResult> { Result = result, CustomData = customData }; } /// <summary> /// Creates a new Cloud Script revision and uploads source code to it. Note that at this time, only one file should be submitted in the revision. /// </summary> - public static async Task<PlayFabResult<UpdateCloudScriptResult>> UpdateCloudScriptAsync(UpdateCloudScriptRequest request) + public static async Task<PlayFabResult<UpdateCloudScriptResult>> UpdateCloudScriptAsync(UpdateCloudScriptRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/UpdateCloudScript", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateCloudScript", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateCloudScriptResult> { Error = error, }; + return new PlayFabResult<UpdateCloudScriptResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateCloudScriptResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateCloudScriptResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateCloudScriptResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateCloudScriptResult> { Result = result }; + return new PlayFabResult<UpdateCloudScriptResult> { Result = result, CustomData = customData }; } /// <summary> /// Delete a content file from the title /// </summary> - public static async Task<PlayFabResult<BlankResult>> DeleteContentAsync(DeleteContentRequest request) + public static async Task<PlayFabResult<BlankResult>> DeleteContentAsync(DeleteContentRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/DeleteContent", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/DeleteContent", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<BlankResult> { Error = error, }; + return new PlayFabResult<BlankResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<BlankResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<BlankResult>>(resultRawJson); + var result = resultData.data; - BlankResult result = resultData.data; - - return new PlayFabResult<BlankResult> { Result = result }; + return new PlayFabResult<BlankResult> { Result = result, CustomData = customData }; } /// <summary> /// List all contents of the title and get statistics such as size /// </summary> - public static async Task<PlayFabResult<GetContentListResult>> GetContentListAsync(GetContentListRequest request) + public static async Task<PlayFabResult<GetContentListResult>> GetContentListAsync(GetContentListRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetContentList", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetContentList", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetContentListResult> { Error = error, }; + return new PlayFabResult<GetContentListResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetContentListResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetContentListResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetContentListResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetContentListResult> { Result = result }; + return new PlayFabResult<GetContentListResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the pre-signed URL for uploading a content file. A subsequent HTTP PUT to the returned URL uploads the content. /// </summary> - public static async Task<PlayFabResult<GetContentUploadUrlResult>> GetContentUploadUrlAsync(GetContentUploadUrlRequest request) + public static async Task<PlayFabResult<GetContentUploadUrlResult>> GetContentUploadUrlAsync(GetContentUploadUrlRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetContentUploadUrl", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetContentUploadUrl", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetContentUploadUrlResult> { Error = error, }; + return new PlayFabResult<GetContentUploadUrlResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetContentUploadUrlResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetContentUploadUrlResult>>(resultRawJson); + var result = resultData.data; - GetContentUploadUrlResult result = resultData.data; - - return new PlayFabResult<GetContentUploadUrlResult> { Result = result }; + return new PlayFabResult<GetContentUploadUrlResult> { Result = result, CustomData = customData }; } /// <summary> /// Completely removes all statistics for the specified character, for the current game /// </summary> - public static async Task<PlayFabResult<ResetCharacterStatisticsResult>> ResetCharacterStatisticsAsync(ResetCharacterStatisticsRequest request) + public static async Task<PlayFabResult<ResetCharacterStatisticsResult>> ResetCharacterStatisticsAsync(ResetCharacterStatisticsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/ResetCharacterStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/ResetCharacterStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ResetCharacterStatisticsResult> { Error = error, }; + return new PlayFabResult<ResetCharacterStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ResetCharacterStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ResetCharacterStatisticsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ResetCharacterStatisticsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ResetCharacterStatisticsResult> { Result = result }; + return new PlayFabResult<ResetCharacterStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds a given tag to a player profile. The tag's namespace is automatically generated based on the source of the tag. /// </summary> - public static async Task<PlayFabResult<AddPlayerTagResult>> AddPlayerTagAsync(AddPlayerTagRequest request) + public static async Task<PlayFabResult<AddPlayerTagResult>> AddPlayerTagAsync(AddPlayerTagRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/AddPlayerTag", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/AddPlayerTag", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AddPlayerTagResult> { Error = error, }; + return new PlayFabResult<AddPlayerTagResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AddPlayerTagResult>>(new JsonTextReader(new StringReader(resultRawJson))); - AddPlayerTagResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AddPlayerTagResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AddPlayerTagResult> { Result = result }; + return new PlayFabResult<AddPlayerTagResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieve a list of all PlayStream actions groups. /// </summary> - public static async Task<PlayFabResult<GetAllActionGroupsResult>> GetAllActionGroupsAsync(GetAllActionGroupsRequest request) + public static async Task<PlayFabResult<GetAllActionGroupsResult>> GetAllActionGroupsAsync(GetAllActionGroupsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetAllActionGroups", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetAllActionGroups", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetAllActionGroupsResult> { Error = error, }; + return new PlayFabResult<GetAllActionGroupsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetAllActionGroupsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetAllActionGroupsResult>>(resultRawJson); + var result = resultData.data; - GetAllActionGroupsResult result = resultData.data; - - return new PlayFabResult<GetAllActionGroupsResult> { Result = result }; + return new PlayFabResult<GetAllActionGroupsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves an array of player segment definitions. Results from this can be used in subsequent API calls such as GetPlayersInSegment which requires a Segment ID. While segment names can change the ID for that segment will not change. /// </summary> - public static async Task<PlayFabResult<GetAllSegmentsResult>> GetAllSegmentsAsync(GetAllSegmentsRequest request) + public static async Task<PlayFabResult<GetAllSegmentsResult>> GetAllSegmentsAsync(GetAllSegmentsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetAllSegments", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetAllSegments", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetAllSegmentsResult> { Error = error, }; + return new PlayFabResult<GetAllSegmentsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetAllSegmentsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetAllSegmentsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetAllSegmentsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetAllSegmentsResult> { Result = result }; + return new PlayFabResult<GetAllSegmentsResult> { Result = result, CustomData = customData }; } /// <summary> /// List all segments that a player currently belongs to at this moment in time. /// </summary> - public static async Task<PlayFabResult<GetPlayerSegmentsResult>> GetPlayerSegmentsAsync(GetPlayersSegmentsRequest request) + public static async Task<PlayFabResult<GetPlayerSegmentsResult>> GetPlayerSegmentsAsync(GetPlayersSegmentsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetPlayerSegments", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetPlayerSegments", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerSegmentsResult> { Error = error, }; + return new PlayFabResult<GetPlayerSegmentsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerSegmentsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerSegmentsResult>>(resultRawJson); + var result = resultData.data; - GetPlayerSegmentsResult result = resultData.data; - - return new PlayFabResult<GetPlayerSegmentsResult> { Result = result }; + return new PlayFabResult<GetPlayerSegmentsResult> { Result = result, CustomData = customData }; } /// <summary> /// Allows for paging through all players in a given segment. This API creates a snapshot of all player profiles that match the segment definition at the time of its creation and lives through the Total Seconds to Live, refreshing its life span on each subsequent use of the Continuation Token. Profiles that change during the course of paging will not be reflected in the results. AB Test segments are currently not supported by this operation. /// </summary> - public static async Task<PlayFabResult<GetPlayersInSegmentResult>> GetPlayersInSegmentAsync(GetPlayersInSegmentRequest request) + public static async Task<PlayFabResult<GetPlayersInSegmentResult>> GetPlayersInSegmentAsync(GetPlayersInSegmentRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetPlayersInSegment", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetPlayersInSegment", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayersInSegmentResult> { Error = error, }; + return new PlayFabResult<GetPlayersInSegmentResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayersInSegmentResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayersInSegmentResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayersInSegmentResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayersInSegmentResult> { Result = result }; + return new PlayFabResult<GetPlayersInSegmentResult> { Result = result, CustomData = customData }; } /// <summary> /// Get all tags with a given Namespace (optional) from a player profile. /// </summary> - public static async Task<PlayFabResult<GetPlayerTagsResult>> GetPlayerTagsAsync(GetPlayerTagsRequest request) + public static async Task<PlayFabResult<GetPlayerTagsResult>> GetPlayerTagsAsync(GetPlayerTagsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/GetPlayerTags", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/GetPlayerTags", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerTagsResult> { Error = error, }; + return new PlayFabResult<GetPlayerTagsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerTagsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerTagsResult>>(resultRawJson); + var result = resultData.data; - GetPlayerTagsResult result = resultData.data; - - return new PlayFabResult<GetPlayerTagsResult> { Result = result }; + return new PlayFabResult<GetPlayerTagsResult> { Result = result, CustomData = customData }; } /// <summary> /// Remove a given tag from a player profile. The tag's namespace is automatically generated based on the source of the tag. /// </summary> - public static async Task<PlayFabResult<RemovePlayerTagResult>> RemovePlayerTagAsync(RemovePlayerTagRequest request) + public static async Task<PlayFabResult<RemovePlayerTagResult>> RemovePlayerTagAsync(RemovePlayerTagRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Admin/RemovePlayerTag", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Admin/RemovePlayerTag", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RemovePlayerTagResult> { Error = error, }; + return new PlayFabResult<RemovePlayerTagResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RemovePlayerTagResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RemovePlayerTagResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<RemovePlayerTagResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Abort an ongoing task instance. + /// </summary> + public static async Task<PlayFabResult<EmptyResult>> AbortTaskInstanceAsync(AbortTaskInstanceRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/AbortTaskInstance", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<EmptyResult> { Error = error, CustomData = customData }; + } + + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<EmptyResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<EmptyResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Create an ActionsOnPlayersInSegment task, which iterates through all players in a segment to execute action. + /// </summary> + public static async Task<PlayFabResult<CreateTaskResult>> CreateActionsOnPlayersInSegmentTaskAsync(CreateActionsOnPlayerSegmentTaskRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/CreateActionsOnPlayersInSegmentTask", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<CreateTaskResult> { Error = error, CustomData = customData }; + } + + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<CreateTaskResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<CreateTaskResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Create a CloudScript task, which can run a CloudScript on a schedule. + /// </summary> + public static async Task<PlayFabResult<CreateTaskResult>> CreateCloudScriptTaskAsync(CreateCloudScriptTaskRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/CreateCloudScriptTask", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<CreateTaskResult> { Error = error, CustomData = customData }; + } + + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<CreateTaskResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<CreateTaskResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Delete a task. + /// </summary> + public static async Task<PlayFabResult<EmptyResult>> DeleteTaskAsync(DeleteTaskRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/DeleteTask", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<EmptyResult> { Error = error, CustomData = customData }; + } + + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<EmptyResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<EmptyResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Get information about a ActionsOnPlayersInSegment task instance. + /// </summary> + public static async Task<PlayFabResult<GetActionsOnPlayersInSegmentTaskInstanceResult>> GetActionsOnPlayersInSegmentTaskInstanceAsync(GetTaskInstanceRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/GetActionsOnPlayersInSegmentTaskInstance", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<GetActionsOnPlayersInSegmentTaskInstanceResult> { Error = error, CustomData = customData }; + } + + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetActionsOnPlayersInSegmentTaskInstanceResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<GetActionsOnPlayersInSegmentTaskInstanceResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Get detail information about a CloudScript task instance. + /// </summary> + public static async Task<PlayFabResult<GetCloudScriptTaskInstanceResult>> GetCloudScriptTaskInstanceAsync(GetTaskInstanceRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/GetCloudScriptTaskInstance", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<GetCloudScriptTaskInstanceResult> { Error = error, CustomData = customData }; + } + + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCloudScriptTaskInstanceResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<GetCloudScriptTaskInstanceResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Query for task instances by task, status, or time range. + /// </summary> + public static async Task<PlayFabResult<GetTaskInstancesResult>> GetTaskInstancesAsync(GetTaskInstancesRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/GetTaskInstances", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<GetTaskInstancesResult> { Error = error, CustomData = customData }; + } + + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTaskInstancesResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<GetTaskInstancesResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Get definition information on a specified task or all tasks within a title. + /// </summary> + public static async Task<PlayFabResult<GetTasksResult>> GetTasksAsync(GetTasksRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/GetTasks", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<GetTasksResult> { Error = error, CustomData = customData }; + } + + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTasksResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<GetTasksResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Run a task immediately regardless of its schedule. + /// </summary> + public static async Task<PlayFabResult<RunTaskResult>> RunTaskAsync(RunTaskRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/RunTask", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<RunTaskResult> { Error = error, CustomData = customData }; + } + + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RunTaskResult>>(resultRawJson); + var result = resultData.data; + + return new PlayFabResult<RunTaskResult> { Result = result, CustomData = customData }; + } + + /// <summary> + /// Update an existing task. + /// </summary> + public static async Task<PlayFabResult<EmptyResult>> UpdateTaskAsync(UpdateTaskRequest request, object customData = null) + { + if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); + + var httpResult = await PlayFabHttp.DoPost("/Admin/UpdateTask", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + if(httpResult is PlayFabError) + { + var error = (PlayFabError)httpResult; + if (PlayFabSettings.GlobalErrorHandler != null) + PlayFabSettings.GlobalErrorHandler(error); + return new PlayFabResult<EmptyResult> { Error = error, CustomData = customData }; + } - RemovePlayerTagResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<EmptyResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RemovePlayerTagResult> { Result = result }; + return new PlayFabResult<EmptyResult> { Result = result, CustomData = customData }; } } diff --git a/PlayFabServerSDK/source/PlayFabAdminModels.cs b/PlayFabServerSDK/source/PlayFabAdminModels.cs index ac3abeb9..1fbe81f8 100644 --- a/PlayFabServerSDK/source/PlayFabAdminModels.cs +++ b/PlayFabServerSDK/source/PlayFabAdminModels.cs @@ -1,11 +1,96 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; using PlayFab.Internal; using System; using System.Collections.Generic; namespace PlayFab.AdminModels { + public class AbortTaskInstanceRequest : PlayFabRequestCommon + { + /// <summary> + /// ID of a task instance that is being aborted. + /// </summary> + public string TaskInstanceId; + + } + + public class ActionsOnPlayersInSegmentTaskParameter + { + /// <summary> + /// ID of the segment to perform actions on. + /// </summary> + public string SegmentId; + + /// <summary> + /// ID of the action to perform on each player in segment. + /// </summary> + public string ActionId; + + } + + public class ActionsOnPlayersInSegmentTaskSummary + { + /// <summary> + /// ID of the task instance. + /// </summary> + public string TaskInstanceId; + + /// <summary> + /// Identifier of the task this instance belongs to. + /// </summary> + public NameIdentifier TaskIdentifier; + + /// <summary> + /// UTC timestamp when the task started. + /// </summary> + public DateTime StartedAt; + + /// <summary> + /// UTC timestamp when the task completed. + /// </summary> + public DateTime? CompletedAt; + + /// <summary> + /// Current status of the task instance. + /// </summary> + public TaskInstanceStatus? Status; + + /// <summary> + /// Progress represented as percentage. + /// </summary> + public double? PercentComplete; + + /// <summary> + /// Estimated time remaining in seconds. + /// </summary> + public double? EstimatedSecondsRemaining; + + /// <summary> + /// If manually scheduled, ID of user who scheduled the task. + /// </summary> + public string ScheduledByUserId; + + /// <summary> + /// Error message for last processing attempt, if an error occured. + /// </summary> + public string ErrorMessage; + + /// <summary> + /// Flag indicating if the error was fatal, if false job will be retried. + /// </summary> + public bool? ErrorWasFatal; + + /// <summary> + /// Total players in segment when task was started. + /// </summary> + public int? TotalPlayersInSegment; + + /// <summary> + /// Total number of players that have had the actions applied to. + /// </summary> + public int? TotalPlayersProcessed; + + } + public class AdCampaignAttribution { /// <summary> @@ -25,7 +110,7 @@ public class AdCampaignAttribution } - public class AddNewsRequest + public class AddNewsRequest : PlayFabRequestCommon { /// <summary> /// Time this news was published. If not set, defaults to now. @@ -53,7 +138,7 @@ public class AddNewsResult : PlayFabResultCommon } - public class AddPlayerTagRequest + public class AddPlayerTagRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -71,7 +156,7 @@ public class AddPlayerTagResult : PlayFabResultCommon { } - public class AddServerBuildRequest + public class AddServerBuildRequest : PlayFabRequestCommon { /// <summary> /// unique identifier for the build executable @@ -91,7 +176,6 @@ public class AddServerBuildRequest /// <summary> /// server host regions in which this build should be running and available /// </summary> - [JsonProperty(ItemConverterType = typeof(StringEnumConverter))] public List<Region> ActiveRegions; /// <summary> @@ -121,7 +205,6 @@ public class AddServerBuildResult : PlayFabResultCommon /// <summary> /// array of regions where this build can used, when it is active /// </summary> - [JsonProperty(ItemConverterType = typeof(StringEnumConverter))] public List<Region> ActiveRegions; /// <summary> @@ -162,12 +245,11 @@ public class AddServerBuildResult : PlayFabResultCommon /// <summary> /// the current status of the build validation and processing steps /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public GameBuildStatus? Status; } - public class AddUserVirtualCurrencyRequest + public class AddUserVirtualCurrencyRequest : PlayFabRequestCommon { /// <summary> /// PlayFab unique identifier of the user whose virtual currency balance is to be increased. @@ -186,7 +268,7 @@ public class AddUserVirtualCurrencyRequest } - public class AddVirtualCurrencyTypesRequest + public class AddVirtualCurrencyTypesRequest : PlayFabRequestCommon { /// <summary> /// List of virtual currencies and their initial deposits (the amount a user is granted when signing in for the first time) to the title @@ -245,7 +327,7 @@ public class BanInfo /// <summary> /// Represents a single ban request. /// </summary> - public class BanRequest + public class BanRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -274,7 +356,7 @@ public class BanRequest } - public class BanUsersRequest + public class BanUsersRequest : PlayFabRequestCommon { /// <summary> /// List of ban requests to be applied. Maximum 100. @@ -388,7 +470,7 @@ public class CatalogItem : IComparable<CatalogItem> public bool IsLimitedEdition; /// <summary> - /// BETA: If IsLImitedEdition is true, then this determines amount of the item initially available. Note that this fieldis ignored if the catalog item already existed in this catalog, or the field is less than 1. + /// If IsLImitedEdition is true, then this determines amount of the item initially available. Note that this fieldis ignored if the catalog item already existed in this catalog, or the field is less than 1. /// </summary> public int InitialLimitedEditionCount; @@ -484,6 +566,69 @@ public class CloudScriptFile } + public class CloudScriptTaskParameter + { + /// <summary> + /// Name of the CloudScript function to execute. + /// </summary> + public string FunctionName; + + /// <summary> + /// Argument to pass to the CloudScript function. + /// </summary> + public object Argument; + + } + + public class CloudScriptTaskSummary + { + /// <summary> + /// ID of the task instance. + /// </summary> + public string TaskInstanceId; + + /// <summary> + /// Identifier of the task this instance belongs to. + /// </summary> + public NameIdentifier TaskIdentifier; + + /// <summary> + /// UTC timestamp when the task started. + /// </summary> + public DateTime StartedAt; + + /// <summary> + /// UTC timestamp when the task completed. + /// </summary> + public DateTime? CompletedAt; + + /// <summary> + /// Current status of the task instance. + /// </summary> + public TaskInstanceStatus? Status; + + /// <summary> + /// Progress represented as percentage. + /// </summary> + public double? PercentComplete; + + /// <summary> + /// Estimated time remaining in seconds. + /// </summary> + public double? EstimatedSecondsRemaining; + + /// <summary> + /// If manually scheduled, ID of user who scheduled the task. + /// </summary> + public string ScheduledByUserId; + + /// <summary> + /// Result of CloudScript execution + /// </summary> + public ExecuteCloudScriptResult Result; + + } + public class CloudScriptVersionStatus { /// <summary> @@ -522,7 +667,331 @@ public class ContentInfo } - public class CreatePlayerStatisticDefinitionRequest + + public enum ContinentCode + { + AF, + AN, + AS, + EU, + NA, + OC, + SA + } + + + public enum CountryCode + { + AF, + AX, + AL, + DZ, + AS, + AD, + AO, + AI, + AQ, + AG, + AR, + AM, + AW, + AU, + AT, + AZ, + BS, + BH, + BD, + BB, + BY, + BE, + BZ, + BJ, + BM, + BT, + BO, + BQ, + BA, + BW, + BV, + BR, + IO, + BN, + BG, + BF, + BI, + KH, + CM, + CA, + CV, + KY, + CF, + TD, + CL, + CN, + CX, + CC, + CO, + KM, + CG, + CD, + CK, + CR, + CI, + HR, + CU, + CW, + CY, + CZ, + DK, + DJ, + DM, + DO, + EC, + EG, + SV, + GQ, + ER, + EE, + ET, + FK, + FO, + FJ, + FI, + FR, + GF, + PF, + TF, + GA, + GM, + GE, + DE, + GH, + GI, + GR, + GL, + GD, + GP, + GU, + GT, + GG, + GN, + GW, + GY, + HT, + HM, + VA, + HN, + HK, + HU, + IS, + IN, + ID, + IR, + IQ, + IE, + IM, + IL, + IT, + JM, + JP, + JE, + JO, + KZ, + KE, + KI, + KP, + KR, + KW, + KG, + LA, + LV, + LB, + LS, + LR, + LY, + LI, + LT, + LU, + MO, + MK, + MG, + MW, + MY, + MV, + ML, + MT, + MH, + MQ, + MR, + MU, + YT, + MX, + FM, + MD, + MC, + MN, + ME, + MS, + MA, + MZ, + MM, + NA, + NR, + NP, + NL, + NC, + NZ, + NI, + NE, + NG, + NU, + NF, + MP, + NO, + OM, + PK, + PW, + PS, + PA, + PG, + PY, + PE, + PH, + PN, + PL, + PT, + PR, + QA, + RE, + RO, + RU, + RW, + BL, + SH, + KN, + LC, + MF, + PM, + VC, + WS, + SM, + ST, + SA, + SN, + RS, + SC, + SL, + SG, + SX, + SK, + SI, + SB, + SO, + ZA, + GS, + SS, + ES, + LK, + SD, + SR, + SJ, + SZ, + SE, + CH, + SY, + TW, + TJ, + TZ, + TH, + TL, + TG, + TK, + TO, + TT, + TN, + TR, + TM, + TC, + TV, + UG, + UA, + AE, + GB, + US, + UM, + UY, + UZ, + VU, + VE, + VN, + VG, + VI, + WF, + EH, + YE, + ZM, + ZW + } + + public class CreateActionsOnPlayerSegmentTaskRequest : PlayFabRequestCommon + { + /// <summary> + /// Name of the task. This is a unique identifier for tasks in the title. + /// </summary> + public string Name; + + /// <summary> + /// Description the task + /// </summary> + public string Description; + + /// <summary> + /// Cron expression for the run schedule of the task. The expression should be in UTC. + /// </summary> + public string Schedule; + + /// <summary> + /// Whether the schedule is active. Inactive schedule will not trigger task execution. + /// </summary> + public bool IsActive; + + /// <summary> + /// Task details related to segment and action + /// </summary> + public ActionsOnPlayersInSegmentTaskParameter Parameter; + + } + + public class CreateCloudScriptTaskRequest : PlayFabRequestCommon + { + /// <summary> + /// Name of the task. This is a unique identifier for tasks in the title. + /// </summary> + public string Name; + + /// <summary> + /// Description the task + /// </summary> + public string Description; + + /// <summary> + /// Cron expression for the run schedule of the task. The expression should be in UTC. + /// </summary> + public string Schedule; + + /// <summary> + /// Whether the schedule is active. Inactive schedule will not trigger task execution. + /// </summary> + public bool IsActive; + + /// <summary> + /// Task details related to CloudScript + /// </summary> + public CloudScriptTaskParameter Parameter; + + } + + public class CreatePlayerStatisticDefinitionRequest : PlayFabRequestCommon { /// <summary> /// unique name of the statistic @@ -532,13 +1001,11 @@ public class CreatePlayerStatisticDefinitionRequest /// <summary> /// interval at which the values of the statistic for all players are reset (resets begin at the next interval boundary) /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public StatisticResetIntervalOption? VersionChangeInterval; /// <summary> /// the aggregation method to use in updating the statistic (defaults to last) /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public StatisticAggregationMethod? AggregationMethod; } @@ -552,6 +1019,15 @@ public class CreatePlayerStatisticDefinitionResult : PlayFabResultCommon } + public class CreateTaskResult : PlayFabResultCommon + { + /// <summary> + /// ID of the task + /// </summary> + public string TaskId; + + } + public enum Currency { @@ -719,7 +1195,7 @@ public enum Currency ZWD } - public class DeleteContentRequest + public class DeleteContentRequest : PlayFabRequestCommon { /// <summary> /// Key of the content item to be deleted @@ -728,7 +1204,7 @@ public class DeleteContentRequest } - public class DeleteStoreRequest + public class DeleteStoreRequest : PlayFabRequestCommon { /// <summary> /// catalog version of the store to delete. If null, uses the default catalog. @@ -746,7 +1222,16 @@ public class DeleteStoreResult : PlayFabResultCommon { } - public class DeleteUsersRequest + public class DeleteTaskRequest : PlayFabRequestCommon + { + /// <summary> + /// Specify either the task ID or the name of task to be deleted. + /// </summary> + public NameIdentifier Identifier; + + } + + public class DeleteUsersRequest : PlayFabRequestCommon { /// <summary> /// An array of unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -764,6 +1249,58 @@ public class DeleteUsersResult : PlayFabResultCommon { } + public class EmptyResult : PlayFabResultCommon + { + } + + public class ExecuteCloudScriptResult : PlayFabResultCommon + { + /// <summary> + /// The name of the function that executed + /// </summary> + public string FunctionName; + + /// <summary> + /// The revision of the CloudScript that executed + /// </summary> + public int Revision; + + /// <summary> + /// The object returned from the CloudScript function, if any + /// </summary> + public object FunctionResult; + + /// <summary> + /// Entries logged during the function execution. These include both entries logged in the function code using log.info() and log.error() and error entries for API and HTTP request failures. + /// </summary> + public List<LogStatement> Logs; + + public double ExecutionTimeSeconds; + + /// <summary> + /// Processor time consumed while executing the function. This does not include time spent waiting on API calls or HTTP requests. + /// </summary> + public double ProcessorTimeSeconds; + + public uint MemoryConsumedBytes; + + /// <summary> + /// Number of PlayFab API requests issued by the CloudScript function + /// </summary> + public int APIRequestsIssued; + + /// <summary> + /// Number of external HTTP requests issued by the CloudScript function + /// </summary> + public int HttpRequestsIssued; + + /// <summary> + /// Information about the error, if any, that occured during execution + /// </summary> + public ScriptExecutionError Error; + + } + public enum GameBuildStatus { @@ -812,7 +1349,21 @@ public class GetActionGroupResult : PlayFabResultCommon } - public class GetAllActionGroupsRequest + public class GetActionsOnPlayersInSegmentTaskInstanceResult : PlayFabResultCommon + { + /// <summary> + /// Status summary of the actions-on-players-in-segment task instance + /// </summary> + public ActionsOnPlayersInSegmentTaskSummary Summary; + + /// <summary> + /// Parameter of this task instance + /// </summary> + public ActionsOnPlayersInSegmentTaskParameter Parameter; + + } + + public class GetAllActionGroupsRequest : PlayFabRequestCommon { } @@ -825,7 +1376,7 @@ public class GetAllActionGroupsResult : PlayFabResultCommon } - public class GetAllSegmentsRequest + public class GetAllSegmentsRequest : PlayFabRequestCommon { } @@ -838,7 +1389,7 @@ public class GetAllSegmentsResult : PlayFabResultCommon } - public class GetCatalogItemsRequest + public class GetCatalogItemsRequest : PlayFabRequestCommon { /// <summary> /// Which catalog is being requested. If null, uses the default catalog. @@ -857,7 +1408,7 @@ public class GetCatalogItemsResult : PlayFabResultCommon } - public class GetCloudScriptRevisionRequest + public class GetCloudScriptRevisionRequest : PlayFabRequestCommon { /// <summary> /// Version number. If left null, defaults to the latest version @@ -900,7 +1451,21 @@ public class GetCloudScriptRevisionResult : PlayFabResultCommon } - public class GetCloudScriptVersionsRequest + public class GetCloudScriptTaskInstanceResult : PlayFabResultCommon + { + /// <summary> + /// Status summary of the CloudScript task instance + /// </summary> + public CloudScriptTaskSummary Summary; + + /// <summary> + /// Parameter of this task instance + /// </summary> + public CloudScriptTaskParameter Parameter; + + } + + public class GetCloudScriptVersionsRequest : PlayFabRequestCommon { } @@ -913,7 +1478,7 @@ public class GetCloudScriptVersionsResult : PlayFabResultCommon } - public class GetContentListRequest + public class GetContentListRequest : PlayFabRequestCommon { /// <summary> /// Limits the response to keys that begin with the specified prefix. You can use prefixes to list contents under a folder, or for a specified version, etc. @@ -941,7 +1506,7 @@ public class GetContentListResult : PlayFabResultCommon } - public class GetContentUploadUrlRequest + public class GetContentUploadUrlRequest : PlayFabRequestCommon { /// <summary> /// Key of the content item to upload, usually formatted as a path, e.g. images/a.png @@ -964,7 +1529,7 @@ public class GetContentUploadUrlResult : PlayFabResultCommon } - public class GetDataReportRequest + public class GetDataReportRequest : PlayFabRequestCommon { /// <summary> /// Report name @@ -997,7 +1562,7 @@ public class GetDataReportResult : PlayFabResultCommon } - public class GetMatchmakerGameInfoRequest + public class GetMatchmakerGameInfoRequest : PlayFabRequestCommon { /// <summary> /// unique identifier of the lobby for which info is being requested @@ -1041,7 +1606,6 @@ public class GetMatchmakerGameInfoResult : PlayFabResultCommon /// <summary> /// region in which the Game Server Instance is running /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Region? Region; /// <summary> @@ -1062,7 +1626,7 @@ public class GetMatchmakerGameInfoResult : PlayFabResultCommon } - public class GetMatchmakerGameModesRequest + public class GetMatchmakerGameModesRequest : PlayFabRequestCommon { /// <summary> /// previously uploaded build version for which game modes are being requested @@ -1089,7 +1653,7 @@ public class GetPlayerSegmentsResult : PlayFabResultCommon } - public class GetPlayersInSegmentRequest + public class GetPlayersInSegmentRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for this segment. @@ -1132,7 +1696,7 @@ public class GetPlayersInSegmentResult : PlayFabResultCommon } - public class GetPlayersSegmentsRequest + public class GetPlayersSegmentsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1141,7 +1705,7 @@ public class GetPlayersSegmentsRequest } - public class GetPlayerStatisticDefinitionsRequest + public class GetPlayerStatisticDefinitionsRequest : PlayFabRequestCommon { } @@ -1154,7 +1718,7 @@ public class GetPlayerStatisticDefinitionsResult : PlayFabResultCommon } - public class GetPlayerStatisticVersionsRequest + public class GetPlayerStatisticVersionsRequest : PlayFabRequestCommon { /// <summary> /// unique name of the statistic @@ -1172,7 +1736,7 @@ public class GetPlayerStatisticVersionsResult : PlayFabResultCommon } - public class GetPlayerTagsRequest + public class GetPlayerTagsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1200,7 +1764,7 @@ public class GetPlayerTagsResult : PlayFabResultCommon } - public class GetPublisherDataRequest + public class GetPublisherDataRequest : PlayFabRequestCommon { /// <summary> /// array of keys to get back data from the Publisher data blob, set by the admin tools @@ -1218,7 +1782,7 @@ public class GetPublisherDataResult : PlayFabResultCommon } - public class GetRandomResultTablesRequest : PlayFabResultCommon + public class GetRandomResultTablesRequest : PlayFabRequestCommon { /// <summary> /// catalog version to fetch tables from. Use default catalog version if null @@ -1255,7 +1819,7 @@ public class GetSegmentResult : PlayFabResultCommon } - public class GetServerBuildInfoRequest + public class GetServerBuildInfoRequest : PlayFabRequestCommon { /// <summary> /// unique identifier of the previously uploaded build executable for which information is being requested @@ -1277,7 +1841,6 @@ public class GetServerBuildInfoResult : PlayFabResultCommon, IComparable<GetServ /// <summary> /// array of regions where this build can used, when it is active /// </summary> - [JsonProperty(ItemConverterType = typeof(StringEnumConverter))] [Unordered] public List<Region> ActiveRegions; @@ -1309,7 +1872,6 @@ public class GetServerBuildInfoResult : PlayFabResultCommon, IComparable<GetServ /// <summary> /// the current status of the build validation and processing steps /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public GameBuildStatus? Status; /// <summary> @@ -1326,7 +1888,7 @@ public int CompareTo(GetServerBuildInfoResult other) } - public class GetServerBuildUploadURLRequest + public class GetServerBuildUploadURLRequest : PlayFabRequestCommon { /// <summary> /// unique identifier of the game server build to upload @@ -1344,7 +1906,7 @@ public class GetServerBuildUploadURLResult : PlayFabResultCommon } - public class GetStoreItemsRequest + public class GetStoreItemsRequest : PlayFabRequestCommon { /// <summary> /// catalog version to store items from. Use default catalog version if null @@ -1369,7 +1931,6 @@ public class GetStoreItemsResult : PlayFabResultCommon /// <summary> /// How the store was last updated (Admin or a third party). /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public SourceType? Source; /// <summary> @@ -1389,7 +1950,67 @@ public class GetStoreItemsResult : PlayFabResultCommon } - public class GetTitleDataRequest + public class GetTaskInstanceRequest : PlayFabRequestCommon + { + /// <summary> + /// ID of the requested task instance. + /// </summary> + public string TaskInstanceId; + + } + + public class GetTaskInstancesRequest : PlayFabRequestCommon + { + /// <summary> + /// Name or ID of the task whose instances are being queried. If not specified, return all task instances that satisfy conditions set by other filters. + /// </summary> + public NameIdentifier TaskIdentifier; + + /// <summary> + /// Optional filter for task instances that are of a specific status. + /// </summary> + public TaskInstanceStatus? StatusFilter; + + /// <summary> + /// Optional range-from filter for task instances' StartedAt timestamp. + /// </summary> + public DateTime? StartedAtRangeFrom; + + /// <summary> + /// Optional range-to filter for task instances' StartedAt timestamp. + /// </summary> + public DateTime? StartedAtRangeTo; + + } + + public class GetTaskInstancesResult : PlayFabResultCommon + { + /// <summary> + /// Basic status summaries of the queried task instances. Empty If no task instances meets the filter criteria. To get detailed status summary, use Get*TaskInstance API according to task type (e.g. GetActionsOnPlayersInSegmentTaskInstance). + /// </summary> + public List<TaskInstanceBasicSummary> Summaries; + + } + + public class GetTasksRequest : PlayFabRequestCommon + { + /// <summary> + /// Provide either the task ID or the task name to get a specific task. If not specified, return all defined tasks. + /// </summary> + public NameIdentifier Identifier; + + } + + public class GetTasksResult : PlayFabResultCommon + { + /// <summary> + /// Result tasks. Empty if there is no task found. + /// </summary> + public List<ScheduledTask> Tasks; + + } + + public class GetTitleDataRequest : PlayFabRequestCommon { /// <summary> /// Specific keys to search for in the title data (leave null to get all keys) @@ -1407,7 +2028,7 @@ public class GetTitleDataResult : PlayFabResultCommon } - public class GetUserBansRequest + public class GetUserBansRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1425,7 +2046,7 @@ public class GetUserBansResult : PlayFabResultCommon } - public class GetUserDataRequest + public class GetUserDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1463,7 +2084,7 @@ public class GetUserDataResult : PlayFabResultCommon } - public class GetUserInventoryRequest + public class GetUserInventoryRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1601,7 +2222,7 @@ public int CompareTo(GrantedItemInstance other) } - public class GrantItemsToUsersRequest + public class GrantItemsToUsersRequest : PlayFabRequestCommon { /// <summary> /// Catalog version from which items are to be granted. @@ -1625,7 +2246,7 @@ public class GrantItemsToUsersResult : PlayFabResultCommon } - public class IncrementPlayerStatisticVersionRequest + public class IncrementPlayerStatisticVersionRequest : PlayFabRequestCommon { /// <summary> /// unique name of the statistic @@ -1766,7 +2387,7 @@ public int CompareTo(ItemInstance other) } - public class ListBuildsRequest + public class ListBuildsRequest : PlayFabRequestCommon { } @@ -1780,7 +2401,7 @@ public class ListBuildsResult : PlayFabResultCommon } - public class ListVirtualCurrencyTypesRequest + public class ListVirtualCurrencyTypesRequest : PlayFabRequestCommon { } @@ -1812,7 +2433,23 @@ public enum LoginIdentityProvider Twitch } - public class LookupUserAccountInfoRequest + public class LogStatement + { + /// <summary> + /// 'Debug', 'Info', or 'Error' + /// </summary> + public string Level; + + public string Message; + + /// <summary> + /// Optional object accompanying the message as contextual information + /// </summary> + public object Data; + + } + + public class LookupUserAccountInfoRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1845,7 +2482,7 @@ public class LookupUserAccountInfoResult : PlayFabResultCommon } - public class ModifyMatchmakerGameModesRequest + public class ModifyMatchmakerGameModesRequest : PlayFabRequestCommon { /// <summary> /// previously uploaded build version for which game modes are being specified @@ -1863,7 +2500,7 @@ public class ModifyMatchmakerGameModesResult : PlayFabResultCommon { } - public class ModifyServerBuildRequest + public class ModifyServerBuildRequest : PlayFabRequestCommon { /// <summary> /// unique identifier of the previously uploaded build executable to be updated @@ -1878,7 +2515,6 @@ public class ModifyServerBuildRequest /// <summary> /// array of regions where this build can used, when it is active /// </summary> - [JsonProperty(ItemConverterType = typeof(StringEnumConverter))] public List<Region> ActiveRegions; /// <summary> @@ -1918,7 +2554,6 @@ public class ModifyServerBuildResult : PlayFabResultCommon /// <summary> /// array of regions where this build can used, when it is active /// </summary> - [JsonProperty(ItemConverterType = typeof(StringEnumConverter))] public List<Region> ActiveRegions; /// <summary> @@ -1959,7 +2594,6 @@ public class ModifyServerBuildResult : PlayFabResultCommon /// <summary> /// the current status of the build validation and processing steps /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public GameBuildStatus? Status; } @@ -1988,12 +2622,22 @@ public class ModifyUserVirtualCurrencyResult : PlayFabResultCommon } + /// <summary> + /// Identifier by either name or ID. Note that a name may change due to renaming, or reused after being deleted. ID is immutable and unique. + /// </summary> + public class NameIdentifier + { + public string Name; + + public string Id; + + } + public class PlayerLinkedAccount { /// <summary> /// Authentication platform /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public LoginIdentityProvider? Platform; /// <summary> @@ -2013,6 +2657,35 @@ public class PlayerLinkedAccount } + public class PlayerLocation + { + /// <summary> + /// The two-character continent code for this location + /// </summary> + public ContinentCode ContinentCode; + + /// <summary> + /// The two-character ISO 3166-1 country code for the country associated with the location + /// </summary> + public CountryCode CountryCode; + + /// <summary> + /// City of the player's geographic location. + /// </summary> + public string City; + + /// <summary> + /// Latitude coordinate of the player's geographic location. + /// </summary> + public double? Latitude; + + /// <summary> + /// Longitude coordinate of the player's geographic location. + /// </summary> + public double? Longitude; + + } + public class PlayerProfile { /// <summary> @@ -2038,7 +2711,6 @@ public class PlayerProfile /// <summary> /// Player account origination /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public LoginIdentityProvider? Origination; /// <summary> @@ -2076,6 +2748,11 @@ public class PlayerProfile /// </summary> public List<string> Tags; + /// <summary> + /// Dictionary of player's locations by type. + /// </summary> + public Dictionary<string,PlayerLocation> Locations; + /// <summary> /// Dictionary of player's virtual currency balances /// </summary> @@ -2142,13 +2819,11 @@ public class PlayerStatisticDefinition /// <summary> /// interval at which the values of the statistic for all players are reset automatically /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public StatisticResetIntervalOption? VersionChangeInterval; /// <summary> /// the aggregation method to use in updating the statistic (defaults to last) /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public StatisticAggregationMethod? AggregationMethod; } @@ -2188,7 +2863,6 @@ public class PlayerStatisticVersion /// <summary> /// status of the process of saving player statistic values of the previous version to a downloadable archive /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public StatisticVersionArchivalStatus? ArchivalStatus; /// <summary> @@ -2210,7 +2884,6 @@ public class PushNotificationRegistration /// <summary> /// Push notification platform /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public PushNotificationPlatform? Platform; /// <summary> @@ -2220,7 +2893,7 @@ public class PushNotificationRegistration } - public class RandomResultTable : PlayFabResultCommon + public class RandomResultTable { /// <summary> /// Unique name for this drop table @@ -2234,7 +2907,7 @@ public class RandomResultTable : PlayFabResultCommon } - public class RandomResultTableListing : PlayFabResultCommon + public class RandomResultTableListing { /// <summary> /// Catalog version this table is associated with @@ -2253,7 +2926,7 @@ public class RandomResultTableListing : PlayFabResultCommon } - public class RefundPurchaseRequest + public class RefundPurchaseRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2293,7 +2966,7 @@ public enum Region Australia } - public class RemovePlayerTagRequest + public class RemovePlayerTagRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2311,7 +2984,7 @@ public class RemovePlayerTagResult : PlayFabResultCommon { } - public class RemoveServerBuildRequest + public class RemoveServerBuildRequest : PlayFabRequestCommon { /// <summary> /// unique identifier of the previously uploaded build executable to be removed @@ -2324,7 +2997,7 @@ public class RemoveServerBuildResult : PlayFabResultCommon { } - public class RemoveVirtualCurrencyTypesRequest + public class RemoveVirtualCurrencyTypesRequest : PlayFabRequestCommon { /// <summary> /// List of virtual currencies to delete @@ -2333,7 +3006,7 @@ public class RemoveVirtualCurrencyTypesRequest } - public class ResetCharacterStatisticsRequest + public class ResetCharacterStatisticsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2351,7 +3024,7 @@ public class ResetCharacterStatisticsResult : PlayFabResultCommon { } - public class ResetUsersRequest + public class ResetUsersRequest : PlayFabRequestCommon { /// <summary> /// Array of users to reset @@ -2360,7 +3033,7 @@ public class ResetUsersRequest } - public class ResetUserStatisticsRequest + public class ResetUserStatisticsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2381,7 +3054,7 @@ public enum ResolutionOutcome Manual } - public class ResolvePurchaseDisputeRequest + public class ResolvePurchaseDisputeRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2401,7 +3074,6 @@ public class ResolvePurchaseDisputeRequest /// <summary> /// Enum for the desired purchase result state after notifying the payment provider. Valid values are Revoke, Reinstate and Manual. Manual will cause no change to the order state. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public ResolutionOutcome Outcome; } @@ -2415,12 +3087,11 @@ public class ResolvePurchaseDisputeResponse : PlayFabResultCommon } - public class ResultTableNode : PlayFabResultCommon + public class ResultTableNode { /// <summary> /// Whether this entry in the table is an item or a link to another table /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public ResultTableNodeType ResultItemType; /// <summary> @@ -2442,7 +3113,7 @@ public enum ResultTableNodeType TableId } - public class RevokeAllBansForUserRequest + public class RevokeAllBansForUserRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2460,7 +3131,7 @@ public class RevokeAllBansForUserResult : PlayFabResultCommon } - public class RevokeBansRequest + public class RevokeBansRequest : PlayFabRequestCommon { /// <summary> /// Ids of the bans to be revoked. Maximum 100. @@ -2478,7 +3149,7 @@ public class RevokeBansResult : PlayFabResultCommon } - public class RevokeInventoryItemRequest + public class RevokeInventoryItemRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2501,7 +3172,100 @@ public class RevokeInventoryResult : PlayFabResultCommon { } - public class SendAccountRecoveryEmailRequest + public class RunTaskRequest : PlayFabRequestCommon + { + /// <summary> + /// Provide either the task ID or the task name to run a task. + /// </summary> + public NameIdentifier Identifier; + + } + + public class RunTaskResult : PlayFabResultCommon + { + /// <summary> + /// ID of the task instance that is started. This can be used in Get*TaskInstance (e.g. GetCloudScriptTaskInstance) API call to retrieve status for the task instance. + /// </summary> + public string TaskInstanceId; + + } + + public class ScheduledTask + { + /// <summary> + /// ID of the task + /// </summary> + public string TaskId; + + /// <summary> + /// Name of the task. This is a unique identifier for tasks in the title. + /// </summary> + public string Name; + + /// <summary> + /// Description the task + /// </summary> + public string Description; + + /// <summary> + /// Cron expression for the run schedule of the task. The expression should be in UTC. + /// </summary> + public string Schedule; + + /// <summary> + /// Whether the schedule is active. Inactive schedule will not trigger task execution. + /// </summary> + public bool IsActive; + + /// <summary> + /// Task type. + /// </summary> + public ScheduledTaskType? Type; + + /// <summary> + /// Task parameter. Different types of task have different parameter structure. See each task type's create API documentation for the details. + /// </summary> + public object Parameter; + + /// <summary> + /// UTC time of last run + /// </summary> + public DateTime? LastRunTime; + + /// <summary> + /// UTC time of next run + /// </summary> + public DateTime? NextRunTime; + + } + + + public enum ScheduledTaskType + { + CloudScript, + ActionsOnPlayerSegment + } + + public class ScriptExecutionError + { + /// <summary> + /// Error code, such as CloudScriptNotFound, JavascriptException, CloudScriptFunctionArgumentSizeExceeded, CloudScriptAPIRequestCountExceeded, CloudScriptAPIRequestError, or CloudScriptHTTPRequestError + /// </summary> + public string Error; + + /// <summary> + /// Details about the error + /// </summary> + public string Message; + + /// <summary> + /// Point during the execution of the script at which the error occurred, if any + /// </summary> + public string StackTrace; + + } + + public class SendAccountRecoveryEmailRequest : PlayFabRequestCommon { /// <summary> /// User email address attached to their account @@ -2514,7 +3278,7 @@ public class SendAccountRecoveryEmailResult : PlayFabResultCommon { } - public class SetPublishedRevisionRequest + public class SetPublishedRevisionRequest : PlayFabRequestCommon { /// <summary> /// Version number @@ -2532,7 +3296,7 @@ public class SetPublishedRevisionResult : PlayFabResultCommon { } - public class SetPublisherDataRequest + public class SetPublisherDataRequest : PlayFabRequestCommon { /// <summary> /// key we want to set a value on (note, this is additive - will only replace an existing key's value if they are the same name.) Keys are trimmed of whitespace. Keys may not begin with the '!' character. @@ -2550,7 +3314,7 @@ public class SetPublisherDataResult : PlayFabResultCommon { } - public class SetTitleDataRequest + public class SetTitleDataRequest : PlayFabRequestCommon { /// <summary> /// key we want to set a value on (note, this is additive - will only replace an existing key's value if they are the same name.) Keys are trimmed of whitespace. Keys may not begin with the '!' character. @@ -2568,7 +3332,7 @@ public class SetTitleDataResult : PlayFabResultCommon { } - public class SetupPushNotificationRequest + public class SetupPushNotificationRequest : PlayFabRequestCommon { /// <summary> /// name of the application sending the message (application names must be made up of only uppercase and lowercase ASCII letters, numbers, underscores, hyphens, and periods, and must be between 1 and 256 characters long) @@ -2706,7 +3470,7 @@ public class StoreMarketingModel } - public class SubtractUserVirtualCurrencyRequest + public class SubtractUserVirtualCurrencyRequest : PlayFabRequestCommon { /// <summary> /// PlayFab unique identifier of the user whose virtual currency balance is to be decreased. @@ -2725,6 +3489,66 @@ public class SubtractUserVirtualCurrencyRequest } + public class TaskInstanceBasicSummary + { + /// <summary> + /// ID of the task instance. + /// </summary> + public string TaskInstanceId; + + /// <summary> + /// Identifier of the task this instance belongs to. + /// </summary> + public NameIdentifier TaskIdentifier; + + /// <summary> + /// UTC timestamp when the task started. + /// </summary> + public DateTime StartedAt; + + /// <summary> + /// UTC timestamp when the task completed. + /// </summary> + public DateTime? CompletedAt; + + /// <summary> + /// Current status of the task instance. + /// </summary> + public TaskInstanceStatus? Status; + + /// <summary> + /// Progress represented as percentage. + /// </summary> + public double? PercentComplete; + + /// <summary> + /// Estimated time remaining in seconds. + /// </summary> + public double? EstimatedSecondsRemaining; + + /// <summary> + /// If manually scheduled, ID of user who scheduled the task. + /// </summary> + public string ScheduledByUserId; + + /// <summary> + /// Type of the task. + /// </summary> + public ScheduledTaskType? Type; + + } + + + public enum TaskInstanceStatus + { + Succeeded, + Starting, + InProgress, + Failed, + Aborted, + Pending + } + public enum TitleActivationStatus { @@ -2738,7 +3562,7 @@ public enum TitleActivationStatus /// <summary> /// Represents a single update ban request. /// </summary> - public class UpdateBanRequest + public class UpdateBanRequest : PlayFabRequestCommon { /// <summary> /// The id of the ban to be updated. @@ -2777,7 +3601,7 @@ public class UpdateBanRequest } - public class UpdateBansRequest + public class UpdateBansRequest : PlayFabRequestCommon { /// <summary> /// List of bans to be updated. Maximum 100. @@ -2795,7 +3619,7 @@ public class UpdateBansResult : PlayFabResultCommon } - public class UpdateCatalogItemsRequest + public class UpdateCatalogItemsRequest : PlayFabRequestCommon { /// <summary> /// Which catalog is being updated. If null, uses the default catalog. @@ -2818,7 +3642,7 @@ public class UpdateCatalogItemsResult : PlayFabResultCommon { } - public class UpdateCloudScriptRequest + public class UpdateCloudScriptRequest : PlayFabRequestCommon { /// <summary> /// List of Cloud Script files to upload to create the new revision. Must have at least one file. @@ -2851,7 +3675,7 @@ public class UpdateCloudScriptResult : PlayFabResultCommon } - public class UpdatePlayerStatisticDefinitionRequest + public class UpdatePlayerStatisticDefinitionRequest : PlayFabRequestCommon { /// <summary> /// unique name of the statistic @@ -2861,13 +3685,11 @@ public class UpdatePlayerStatisticDefinitionRequest /// <summary> /// interval at which the values of the statistic for all players are reset (changes are effective at the next occurance of the new interval boundary) /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public StatisticResetIntervalOption? VersionChangeInterval; /// <summary> /// the aggregation method to use in updating the statistic (defaults to last) /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public StatisticAggregationMethod? AggregationMethod; } @@ -2881,7 +3703,7 @@ public class UpdatePlayerStatisticDefinitionResult : PlayFabResultCommon } - public class UpdateRandomResultTablesRequest : PlayFabResultCommon + public class UpdateRandomResultTablesRequest : PlayFabRequestCommon { /// <summary> /// which catalog is being updated. If null, update the current default catalog version @@ -2899,7 +3721,7 @@ public class UpdateRandomResultTablesResult : PlayFabResultCommon { } - public class UpdateStoreItemsRequest + public class UpdateStoreItemsRequest : PlayFabRequestCommon { /// <summary> /// Catalog version of the store to update. If null, uses the default catalog. @@ -2927,7 +3749,46 @@ public class UpdateStoreItemsResult : PlayFabResultCommon { } - public class UpdateUserDataRequest + public class UpdateTaskRequest : PlayFabRequestCommon + { + /// <summary> + /// Specify either the task ID or the name of the task to be updated. + /// </summary> + public NameIdentifier Identifier; + + /// <summary> + /// Name of the task. This is a unique identifier for tasks in the title. + /// </summary> + public string Name; + + /// <summary> + /// Description the task + /// </summary> + public string Description; + + /// <summary> + /// Cron expression for the run schedule of the task. The expression should be in UTC. + /// </summary> + public string Schedule; + + /// <summary> + /// Whether the schedule is active. Inactive schedule will not trigger task execution. + /// </summary> + public bool IsActive; + + /// <summary> + /// Task type. + /// </summary> + public ScheduledTaskType Type; + + /// <summary> + /// Parameter object specific to the task type. See each task type's create API documentation for details. + /// </summary> + public object Parameter; + + } + + public class UpdateUserDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2947,7 +3808,6 @@ public class UpdateUserDataRequest /// <summary> /// Permission to be applied to all user data keys written in this request. Defaults to "private" if not set. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -2961,7 +3821,7 @@ public class UpdateUserDataResult : PlayFabResultCommon } - public class UpdateUserInternalDataRequest + public class UpdateUserInternalDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2980,7 +3840,7 @@ public class UpdateUserInternalDataRequest } - public class UpdateUserTitleDisplayNameRequest + public class UpdateUserTitleDisplayNameRequest : PlayFabRequestCommon { /// <summary> /// PlayFab unique identifier of the user whose title specific display name is to be changed @@ -3145,7 +4005,6 @@ public class UserDataRecord /// <summary> /// Indicates whether this data can be read by all users (public) or only the user (private). This is used for GetUserData requests being made by one player about another player. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -3280,13 +4139,11 @@ public class UserSteamInfo /// <summary> /// currency type set in the user Steam account /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Currency? SteamCurrency; /// <summary> /// what stage of game ownership the user is listed as being in, from Steam /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public TitleActivationStatus? SteamActivationStatus; } @@ -3301,7 +4158,6 @@ public class UserTitleInfo /// <summary> /// source by which the user first joined the game, if known /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserOrigination? Origination; /// <summary> diff --git a/PlayFabServerSDK/source/PlayFabErrors.cs b/PlayFabServerSDK/source/PlayFabErrors.cs index 20cb9c0d..189cd3ff 100644 --- a/PlayFabServerSDK/source/PlayFabErrors.cs +++ b/PlayFabServerSDK/source/PlayFabErrors.cs @@ -1,5 +1,6 @@ using PlayFab.Internal; using System.Collections.Generic; +using System.Text; namespace PlayFab { @@ -259,7 +260,11 @@ public enum PlayFabErrorCode ScheduledTaskCreateConflict = 1255, InvalidScheduledTaskName = 1256, InvalidTaskSchedule = 1257, - SteamNotEnabledForTitle = 1258 + SteamNotEnabledForTitle = 1258, + LimitNotAnUpgradeOption = 1259, + NoSecretKeyEnabledForCloudScript = 1260, + TaskNotFound = 1261, + TaskInstanceNotFound = 1262 } public class PlayFabError @@ -269,12 +274,30 @@ public class PlayFabError public PlayFabErrorCode Error; public string ErrorMessage; public Dictionary<string, string[] > ErrorDetails; + + private static readonly StringBuilder Sb = new StringBuilder(); + public string GenerateErrorReport() + { + Sb.Length = 0; + if (ErrorMessage != null) + Sb.Append(ErrorMessage); + if (ErrorDetails == null) + return Sb.ToString(); + + foreach (var pair in ErrorDetails) + { + foreach (var eachMsg in pair.Value) + Sb.Append(pair.Key).Append(": ").Append(eachMsg); + } + return Sb.ToString(); + } }; public class PlayFabResult<TResult> where TResult : PlayFabResultCommon { public PlayFabError Error; public TResult Result; + public object CustomData; } public delegate void ErrorCallback(PlayFabError error); diff --git a/PlayFabServerSDK/source/PlayFabFileUtil.cs b/PlayFabServerSDK/source/PlayFabFileUtil.cs new file mode 100644 index 00000000..598d875f --- /dev/null +++ b/PlayFabServerSDK/source/PlayFabFileUtil.cs @@ -0,0 +1,71 @@ +#if XAMARIN + +using PlayFab.Json; +using System; +using System.IO; +using System.Text; +using System.Threading.Tasks; + +namespace PlayFab +{ + public static partial class PlayFabUtil + { +#if !NETFX_CORE + [ThreadStatic] + private static StringBuilder _sb; + /// <summary> + /// A threadsafe way to block and load a text file + /// + /// Load a text file, and return the file as text. + /// Used for small (usually json) files. + /// </summary> + public static string ReadAllFileText(string filename) + { + if (!File.Exists(filename)) + return ""; + + if (_sb == null) + _sb = new StringBuilder(); + _sb.Length = 0; + + var fs = new FileStream(filename, FileMode.Open); + var br = new BinaryReader(fs); + while (br.BaseStream.Position != br.BaseStream.Length) + _sb.Append(br.ReadChar()); + + return _sb.ToString(); + } +#else + public static string ReadAllFileText(string filename) + { + var task = ReadAllFileTextAsync(filename); + + var output = ""; + try + { + output = task.Result; + } + catch (AggregateException agEx) + { + foreach (var eachEx in agEx.InnerExceptions) + { + System.Diagnostics.Debug.WriteLine("Each Exception:"); + System.Diagnostics.Debug.WriteLine(eachEx.Message); + } + } + + return output; + } + + public static async Task<string> ReadAllFileTextAsync(string fullpath) + { + var foldername = Path.GetDirectoryName(fullpath); + var filename = Path.GetFileName(fullpath); + var folder = await Windows.Storage.StorageFolder.GetFolderFromPathAsync(foldername); + var file = await folder.GetFileAsync(filename); + return await Windows.Storage.FileIO.ReadTextAsync(file); + } +#endif + } +} +#endif diff --git a/PlayFabServerSDK/source/PlayFabHttp/IPlayFabHttp.cs b/PlayFabServerSDK/source/PlayFabHttp/IPlayFabHttp.cs new file mode 100644 index 00000000..a83051f7 --- /dev/null +++ b/PlayFabServerSDK/source/PlayFabHttp/IPlayFabHttp.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace PlayFab.Internal +{ + public interface IPlayFabHttp + { + Task<object> DoPost(string urlPath, PlayFabRequestCommon request, string authType, string authKey); + } +} diff --git a/PlayFabServerSDK/source/PlayFabHttp/PlayFabHttp.cs b/PlayFabServerSDK/source/PlayFabHttp/PlayFabHttp.cs new file mode 100644 index 00000000..b4014a05 --- /dev/null +++ b/PlayFabServerSDK/source/PlayFabHttp/PlayFabHttp.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace PlayFab.Internal +{ + /// <summary> + /// This is a base-class for all Api-request objects. + /// It is currently unfinished, but we will add result-specific properties, + /// and add template where-conditions to make some code easier to follow + /// </summary> + public class PlayFabRequestCommon + { + } + + /// <summary> + /// This is a base-class for all Api-result objects. + /// It is currently unfinished, but we will add result-specific properties, + /// and add template where-conditions to make some code easier to follow + /// </summary> + public class PlayFabResultCommon + { + } + + public class PlayFabJsonError + { + public int code; + public string status; + public string error; + public int errorCode; + public string errorMessage; + public Dictionary<string, string[]> errorDetails = null; + } + + public class PlayFabJsonSuccess<TResult> where TResult : PlayFabResultCommon + { + public int code; + public string status; + public TResult data; + } + + public static class PlayFabHttp + { + private static IPlayFabHttp _http; + + static PlayFabHttp() + { + var httpInterfaceType = typeof(IPlayFabHttp); + var types = typeof(PlayFabHttp).GetAssembly().GetTypes(); + foreach (var eachType in types) + { + if (httpInterfaceType.IsAssignableFrom(eachType) && !eachType.IsAbstract) + { + _http = (IPlayFabHttp)Activator.CreateInstance(eachType.AsType()); + return; + } + } + throw new Exception("Cannot find a valid IPlayFabHttp type"); + } + + public static async Task<object> DoPost(string urlPath, PlayFabRequestCommon request, string authType, string authKey) + { + if (PlayFabSettings.TitleId == null) + throw new Exception("You must set your titleId before making an api call"); + return await _http.DoPost(urlPath, request, authType, authKey); + } + } +} diff --git a/PlayFabServerSDK/source/PlayFabHttp/PlayFabSysHttp.cs b/PlayFabServerSDK/source/PlayFabHttp/PlayFabSysHttp.cs new file mode 100644 index 00000000..6203261d --- /dev/null +++ b/PlayFabServerSDK/source/PlayFabHttp/PlayFabSysHttp.cs @@ -0,0 +1,107 @@ +#if !NETFX_CORE || !XAMARIN + +using System; +using System.IO; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using PlayFab.Json; + +namespace PlayFab.Internal +{ + public class PlayFabSysHttp : IPlayFabHttp + { + public async Task<object> DoPost(string urlPath, PlayFabRequestCommon request, string authType, string authKey) + { + var fullUrl = PlayFabSettings.GetFullUrl(urlPath); + string bodyString; + + if (request == null) + { + bodyString = "{}"; + } + else + { + bodyString = JsonWrapper.SerializeObject(request); + } + + var client = new HttpClient(); + HttpResponseMessage httpResponse; + string httpResponseString; + using (var postBody = new ByteArrayContent(Encoding.UTF8.GetBytes(bodyString))) + { + postBody.Headers.Add("Content-Type", "application/json"); + if (authType != null) + postBody.Headers.Add(authType, authKey); + postBody.Headers.Add("X-PlayFabSDK", PlayFabSettings.SdkVersionString); + + try + { + httpResponse = await client.PostAsync(fullUrl, postBody); + httpResponseString = await httpResponse.Content.ReadAsStringAsync(); + } + catch (HttpRequestException e) + { + return new PlayFabError + { + Error = PlayFabErrorCode.ConnectionError, + ErrorMessage = e.InnerException.Message + }; + } + catch (Exception e) + { + return new PlayFabError + { + Error = PlayFabErrorCode.ConnectionError, + ErrorMessage = e.Message + }; + } + } + + if (!httpResponse.IsSuccessStatusCode) + { + var error = new PlayFabError(); + + if (string.IsNullOrEmpty(httpResponseString) || httpResponse.StatusCode == System.Net.HttpStatusCode.NotFound) + { + error.HttpCode = (int)httpResponse.StatusCode; + error.HttpStatus = httpResponse.StatusCode.ToString(); + return error; + } + + PlayFabJsonError errorResult; + try + { + errorResult = JsonWrapper.DeserializeObject<PlayFabJsonError>(httpResponseString); + } + catch (Exception e) + { + error.HttpCode = (int)httpResponse.StatusCode; + error.HttpStatus = httpResponse.StatusCode.ToString(); + error.Error = PlayFabErrorCode.JsonParseError; + error.ErrorMessage = e.Message; + return error; + } + + error.HttpCode = errorResult.code; + error.HttpStatus = errorResult.status; + error.Error = (PlayFabErrorCode)errorResult.errorCode; + error.ErrorMessage = errorResult.errorMessage; + error.ErrorDetails = errorResult.errorDetails; + return error; + } + + if (string.IsNullOrEmpty(httpResponseString)) + { + return new PlayFabError + { + Error = PlayFabErrorCode.Unknown, + ErrorMessage = "Internal server error" + }; + } + + return httpResponseString; + } + } +} +#endif diff --git a/PlayFabServerSDK/source/PlayFabHttp/PlayFabWinHttp.cs b/PlayFabServerSDK/source/PlayFabHttp/PlayFabWinHttp.cs new file mode 100644 index 00000000..cab057c5 --- /dev/null +++ b/PlayFabServerSDK/source/PlayFabHttp/PlayFabWinHttp.cs @@ -0,0 +1,96 @@ +#if NETFX_CORE && XAMARIN + +using PlayFab.Json; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Windows.Web.Http; + +namespace PlayFab.Internal +{ + public class PlayFabWinHttp : IPlayFabHttp + { + public async Task<object> DoPost(string urlPath, PlayFabRequestCommon request, string authType, string authKey) + { + var fullUrl = PlayFabSettings.GetFullUrl(urlPath); + string bodyString; + + if (request == null) + { + bodyString = "{}"; + } + else + { + bodyString = JsonWrapper.SerializeObject(request); + } + + var httpClient = new HttpClient(); + var requestMessage = new HttpRequestMessage(HttpMethod.Post, new Uri(fullUrl)); + requestMessage.Content = new HttpStringContent(bodyString, Windows.Storage.Streams.UnicodeEncoding.Utf8, "application/json"); + if (authType != null) + requestMessage.Headers.Add(new KeyValuePair<string, string>(authType, authKey)); + requestMessage.Headers.Add(new KeyValuePair<string, string>("X-PlayFabSDK", PlayFabSettings.SdkVersionString)); + + HttpResponseMessage httpResponse; + string httpResponseString; + try + { + httpResponse = await httpClient.SendRequestAsync(requestMessage); + httpResponseString = await httpResponse.Content.ReadAsStringAsync(); + } + catch (Exception e) + { + return new PlayFabError + { + Error = PlayFabErrorCode.ConnectionError, + ErrorMessage = e.Message + }; + } + + if (!httpResponse.IsSuccessStatusCode) + { + var error = new PlayFabError(); + + if (string.IsNullOrEmpty(httpResponseString) || httpResponse.StatusCode == HttpStatusCode.NotFound) + { + error.HttpCode = (int)httpResponse.StatusCode; + error.HttpStatus = httpResponse.StatusCode.ToString(); + return error; + } + + PlayFabJsonError errorResult; + try + { + errorResult = JsonWrapper.DeserializeObject<PlayFabJsonError>(httpResponseString); + } + catch (Exception e) + { + error.HttpCode = (int)httpResponse.StatusCode; + error.HttpStatus = httpResponse.StatusCode.ToString(); + error.Error = PlayFabErrorCode.JsonParseError; + error.ErrorMessage = e.Message; + return error; + } + + error.HttpCode = errorResult.code; + error.HttpStatus = errorResult.status; + error.Error = (PlayFabErrorCode)errorResult.errorCode; + error.ErrorMessage = errorResult.errorMessage; + error.ErrorDetails = errorResult.errorDetails; + return error; + } + + if (string.IsNullOrEmpty(httpResponseString)) + { + return new PlayFabError + { + Error = PlayFabErrorCode.Unknown, + ErrorMessage = "Internal server error" + }; + } + + return httpResponseString; + } + } +} +#endif diff --git a/PlayFabServerSDK/source/PlayFabMatchmakerAPI.cs b/PlayFabServerSDK/source/PlayFabMatchmakerAPI.cs index 1c16e59d..7e2f2d35 100644 --- a/PlayFabServerSDK/source/PlayFabMatchmakerAPI.cs +++ b/PlayFabServerSDK/source/PlayFabMatchmakerAPI.cs @@ -1,13 +1,11 @@ -using Newtonsoft.Json; -using PlayFab.Internal; using PlayFab.MatchmakerModels; +using PlayFab.Internal; +using PlayFab.Json; using System; -using System.IO; using System.Threading.Tasks; namespace PlayFab { - /// <summary> /// Enables the use of an external match-making service in conjunction with PlayFab hosted Game Server instances /// </summary> @@ -16,126 +14,116 @@ public class PlayFabMatchmakerAPI /// <summary> /// Validates a user with the PlayFab service /// </summary> - public static async Task<PlayFabResult<AuthUserResponse>> AuthUserAsync(AuthUserRequest request) + public static async Task<PlayFabResult<AuthUserResponse>> AuthUserAsync(AuthUserRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Matchmaker/AuthUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Matchmaker/AuthUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AuthUserResponse> { Error = error, }; + return new PlayFabResult<AuthUserResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AuthUserResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - AuthUserResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AuthUserResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AuthUserResponse> { Result = result }; + return new PlayFabResult<AuthUserResponse> { Result = result, CustomData = customData }; } /// <summary> /// Informs the PlayFab game server hosting service that the indicated user has joined the Game Server Instance specified /// </summary> - public static async Task<PlayFabResult<PlayerJoinedResponse>> PlayerJoinedAsync(PlayerJoinedRequest request) + public static async Task<PlayFabResult<PlayerJoinedResponse>> PlayerJoinedAsync(PlayerJoinedRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Matchmaker/PlayerJoined", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Matchmaker/PlayerJoined", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<PlayerJoinedResponse> { Error = error, }; + return new PlayFabResult<PlayerJoinedResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<PlayerJoinedResponse>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<PlayerJoinedResponse>>(resultRawJson); + var result = resultData.data; - PlayerJoinedResponse result = resultData.data; - - return new PlayFabResult<PlayerJoinedResponse> { Result = result }; + return new PlayFabResult<PlayerJoinedResponse> { Result = result, CustomData = customData }; } /// <summary> /// Informs the PlayFab game server hosting service that the indicated user has left the Game Server Instance specified /// </summary> - public static async Task<PlayFabResult<PlayerLeftResponse>> PlayerLeftAsync(PlayerLeftRequest request) + public static async Task<PlayFabResult<PlayerLeftResponse>> PlayerLeftAsync(PlayerLeftRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Matchmaker/PlayerLeft", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Matchmaker/PlayerLeft", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<PlayerLeftResponse> { Error = error, }; + return new PlayFabResult<PlayerLeftResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<PlayerLeftResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - PlayerLeftResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<PlayerLeftResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<PlayerLeftResponse> { Result = result }; + return new PlayFabResult<PlayerLeftResponse> { Result = result, CustomData = customData }; } /// <summary> /// Instructs the PlayFab game server hosting service to instantiate a new Game Server Instance /// </summary> - public static async Task<PlayFabResult<StartGameResponse>> StartGameAsync(StartGameRequest request) + public static async Task<PlayFabResult<StartGameResponse>> StartGameAsync(StartGameRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Matchmaker/StartGame", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Matchmaker/StartGame", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<StartGameResponse> { Error = error, }; + return new PlayFabResult<StartGameResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<StartGameResponse>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<StartGameResponse>>(resultRawJson); + var result = resultData.data; - StartGameResponse result = resultData.data; - - return new PlayFabResult<StartGameResponse> { Result = result }; + return new PlayFabResult<StartGameResponse> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the relevant details for a specified user, which the external match-making service can then use to compute effective matches /// </summary> - public static async Task<PlayFabResult<UserInfoResponse>> UserInfoAsync(UserInfoRequest request) + public static async Task<PlayFabResult<UserInfoResponse>> UserInfoAsync(UserInfoRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Matchmaker/UserInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Matchmaker/UserInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UserInfoResponse> { Error = error, }; + return new PlayFabResult<UserInfoResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UserInfoResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - UserInfoResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UserInfoResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UserInfoResponse> { Result = result }; + return new PlayFabResult<UserInfoResponse> { Result = result, CustomData = customData }; } } diff --git a/PlayFabServerSDK/source/PlayFabMatchmakerModels.cs b/PlayFabServerSDK/source/PlayFabMatchmakerModels.cs index b00aa4f2..23c49f14 100644 --- a/PlayFabServerSDK/source/PlayFabMatchmakerModels.cs +++ b/PlayFabServerSDK/source/PlayFabMatchmakerModels.cs @@ -1,12 +1,10 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; using PlayFab.Internal; using System; using System.Collections.Generic; namespace PlayFab.MatchmakerModels { - public class AuthUserRequest + public class AuthUserRequest : PlayFabRequestCommon { /// <summary> /// Session Ticket provided by the client. @@ -29,7 +27,7 @@ public class AuthUserResponse : PlayFabResultCommon } - public class DeregisterGameRequest + public class DeregisterGameRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the Game Server Instance that is being deregistered. @@ -131,7 +129,7 @@ public int CompareTo(ItemInstance other) } - public class PlayerJoinedRequest + public class PlayerJoinedRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier of the Game Server Instance the user is joining. @@ -149,7 +147,7 @@ public class PlayerJoinedResponse : PlayFabResultCommon { } - public class PlayerLeftRequest + public class PlayerLeftRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier of the Game Server Instance the user is leaving. @@ -179,7 +177,7 @@ public enum Region Australia } - public class RegisterGameRequest + public class RegisterGameRequest : PlayFabRequestCommon { /// <summary> /// IP address of the Game Server Instance. @@ -199,7 +197,6 @@ public class RegisterGameRequest /// <summary> /// Region in which the Game Server Instance is running. For matchmaking using non-AWS region names, set this to any AWS region and use Tags (below) to specify your custom region. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Region Region; /// <summary> @@ -223,7 +220,7 @@ public class RegisterGameResponse : PlayFabResultCommon } - public class StartGameRequest + public class StartGameRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier of the previously uploaded build executable which is to be started. @@ -233,7 +230,6 @@ public class StartGameRequest /// <summary> /// Region with which to associate the server, for filtering. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Region Region; /// <summary> @@ -272,7 +268,7 @@ public class StartGameResponse : PlayFabResultCommon } - public class UserInfoRequest + public class UserInfoRequest : PlayFabRequestCommon { /// <summary> /// PlayFab unique identifier of the user whose information is being requested. diff --git a/PlayFabServerSDK/source/PlayFabServerAPI.cs b/PlayFabServerSDK/source/PlayFabServerAPI.cs index 50fbabe8..e2edbcc5 100644 --- a/PlayFabServerSDK/source/PlayFabServerAPI.cs +++ b/PlayFabServerSDK/source/PlayFabServerAPI.cs @@ -1,13 +1,11 @@ -using Newtonsoft.Json; -using PlayFab.Internal; using PlayFab.ServerModels; +using PlayFab.Internal; +using PlayFab.Json; using System; -using System.IO; using System.Threading.Tasks; namespace PlayFab { - /// <summary> /// Provides functionality to allow external (developer-controlled) servers to interact with user inventories and data in a trusted manner, and to handle matchmaking and client connection orchestration /// </summary> @@ -16,2626 +14,2416 @@ public class PlayFabServerAPI /// <summary> /// Validated a client's session ticket, and if successful, returns details for that user /// </summary> - public static async Task<PlayFabResult<AuthenticateSessionTicketResult>> AuthenticateSessionTicketAsync(AuthenticateSessionTicketRequest request) + public static async Task<PlayFabResult<AuthenticateSessionTicketResult>> AuthenticateSessionTicketAsync(AuthenticateSessionTicketRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/AuthenticateSessionTicket", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/AuthenticateSessionTicket", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AuthenticateSessionTicketResult> { Error = error, }; + return new PlayFabResult<AuthenticateSessionTicketResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AuthenticateSessionTicketResult>>(new JsonTextReader(new StringReader(resultRawJson))); - AuthenticateSessionTicketResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AuthenticateSessionTicketResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AuthenticateSessionTicketResult> { Result = result }; + return new PlayFabResult<AuthenticateSessionTicketResult> { Result = result, CustomData = customData }; } /// <summary> /// Bans users by PlayFab ID with optional IP address, or MAC address for the provided game. /// </summary> - public static async Task<PlayFabResult<BanUsersResult>> BanUsersAsync(BanUsersRequest request) + public static async Task<PlayFabResult<BanUsersResult>> BanUsersAsync(BanUsersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/BanUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/BanUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<BanUsersResult> { Error = error, }; + return new PlayFabResult<BanUsersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<BanUsersResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<BanUsersResult>>(resultRawJson); + var result = resultData.data; - BanUsersResult result = resultData.data; - - return new PlayFabResult<BanUsersResult> { Result = result }; + return new PlayFabResult<BanUsersResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the unique PlayFab identifiers for the given set of Facebook identifiers. /// </summary> - public static async Task<PlayFabResult<GetPlayFabIDsFromFacebookIDsResult>> GetPlayFabIDsFromFacebookIDsAsync(GetPlayFabIDsFromFacebookIDsRequest request) + public static async Task<PlayFabResult<GetPlayFabIDsFromFacebookIDsResult>> GetPlayFabIDsFromFacebookIDsAsync(GetPlayFabIDsFromFacebookIDsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetPlayFabIDsFromFacebookIDs", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetPlayFabIDsFromFacebookIDs", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayFabIDsFromFacebookIDsResult> { Error = error, }; + return new PlayFabResult<GetPlayFabIDsFromFacebookIDsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayFabIDsFromFacebookIDsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayFabIDsFromFacebookIDsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayFabIDsFromFacebookIDsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayFabIDsFromFacebookIDsResult> { Result = result }; + return new PlayFabResult<GetPlayFabIDsFromFacebookIDsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the unique PlayFab identifiers for the given set of Steam identifiers. The Steam identifiers are the profile IDs for the user accounts, available as SteamId in the Steamworks Community API calls. /// </summary> - public static async Task<PlayFabResult<GetPlayFabIDsFromSteamIDsResult>> GetPlayFabIDsFromSteamIDsAsync(GetPlayFabIDsFromSteamIDsRequest request) + public static async Task<PlayFabResult<GetPlayFabIDsFromSteamIDsResult>> GetPlayFabIDsFromSteamIDsAsync(GetPlayFabIDsFromSteamIDsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetPlayFabIDsFromSteamIDs", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetPlayFabIDsFromSteamIDs", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayFabIDsFromSteamIDsResult> { Error = error, }; + return new PlayFabResult<GetPlayFabIDsFromSteamIDsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayFabIDsFromSteamIDsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayFabIDsFromSteamIDsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayFabIDsFromSteamIDsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayFabIDsFromSteamIDsResult> { Result = result }; + return new PlayFabResult<GetPlayFabIDsFromSteamIDsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the relevant details for a specified user /// </summary> - public static async Task<PlayFabResult<GetUserAccountInfoResult>> GetUserAccountInfoAsync(GetUserAccountInfoRequest request) + public static async Task<PlayFabResult<GetUserAccountInfoResult>> GetUserAccountInfoAsync(GetUserAccountInfoRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetUserAccountInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetUserAccountInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserAccountInfoResult> { Error = error, }; + return new PlayFabResult<GetUserAccountInfoResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserAccountInfoResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserAccountInfoResult>>(resultRawJson); + var result = resultData.data; - GetUserAccountInfoResult result = resultData.data; - - return new PlayFabResult<GetUserAccountInfoResult> { Result = result }; + return new PlayFabResult<GetUserAccountInfoResult> { Result = result, CustomData = customData }; } /// <summary> /// Gets all bans for a user. /// </summary> - public static async Task<PlayFabResult<GetUserBansResult>> GetUserBansAsync(GetUserBansRequest request) + public static async Task<PlayFabResult<GetUserBansResult>> GetUserBansAsync(GetUserBansRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetUserBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetUserBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserBansResult> { Error = error, }; + return new PlayFabResult<GetUserBansResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserBansResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserBansResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserBansResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserBansResult> { Result = result }; + return new PlayFabResult<GetUserBansResult> { Result = result, CustomData = customData }; } /// <summary> /// Revoke all active bans for a user. /// </summary> - public static async Task<PlayFabResult<RevokeAllBansForUserResult>> RevokeAllBansForUserAsync(RevokeAllBansForUserRequest request) + public static async Task<PlayFabResult<RevokeAllBansForUserResult>> RevokeAllBansForUserAsync(RevokeAllBansForUserRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RevokeAllBansForUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RevokeAllBansForUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RevokeAllBansForUserResult> { Error = error, }; + return new PlayFabResult<RevokeAllBansForUserResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RevokeAllBansForUserResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RevokeAllBansForUserResult>>(resultRawJson); + var result = resultData.data; - RevokeAllBansForUserResult result = resultData.data; - - return new PlayFabResult<RevokeAllBansForUserResult> { Result = result }; + return new PlayFabResult<RevokeAllBansForUserResult> { Result = result, CustomData = customData }; } /// <summary> /// Revoke all active bans specified with BanId. /// </summary> - public static async Task<PlayFabResult<RevokeBansResult>> RevokeBansAsync(RevokeBansRequest request) + public static async Task<PlayFabResult<RevokeBansResult>> RevokeBansAsync(RevokeBansRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RevokeBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RevokeBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RevokeBansResult> { Error = error, }; + return new PlayFabResult<RevokeBansResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RevokeBansResult>>(new JsonTextReader(new StringReader(resultRawJson))); - RevokeBansResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RevokeBansResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RevokeBansResult> { Result = result }; + return new PlayFabResult<RevokeBansResult> { Result = result, CustomData = customData }; } /// <summary> /// Sends an iOS/Android Push Notification to a specific user, if that user's device has been configured for Push Notifications in PlayFab. If a user has linked both Android and iOS devices, both will be notified. /// </summary> - public static async Task<PlayFabResult<SendPushNotificationResult>> SendPushNotificationAsync(SendPushNotificationRequest request) + public static async Task<PlayFabResult<SendPushNotificationResult>> SendPushNotificationAsync(SendPushNotificationRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/SendPushNotification", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/SendPushNotification", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SendPushNotificationResult> { Error = error, }; + return new PlayFabResult<SendPushNotificationResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SendPushNotificationResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SendPushNotificationResult>>(resultRawJson); + var result = resultData.data; - SendPushNotificationResult result = resultData.data; - - return new PlayFabResult<SendPushNotificationResult> { Result = result }; + return new PlayFabResult<SendPushNotificationResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates information of a list of existing bans specified with Ban Ids. /// </summary> - public static async Task<PlayFabResult<UpdateBansResult>> UpdateBansAsync(UpdateBansRequest request) + public static async Task<PlayFabResult<UpdateBansResult>> UpdateBansAsync(UpdateBansRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateBans", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateBansResult> { Error = error, }; + return new PlayFabResult<UpdateBansResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateBansResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateBansResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateBansResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateBansResult> { Result = result }; + return new PlayFabResult<UpdateBansResult> { Result = result, CustomData = customData }; } /// <summary> /// Deletes the users for the provided game. Deletes custom data, all account linkages, and statistics. /// </summary> - public static async Task<PlayFabResult<DeleteUsersResult>> DeleteUsersAsync(DeleteUsersRequest request) + public static async Task<PlayFabResult<DeleteUsersResult>> DeleteUsersAsync(DeleteUsersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/DeleteUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/DeleteUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<DeleteUsersResult> { Error = error, }; + return new PlayFabResult<DeleteUsersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<DeleteUsersResult>>(new JsonTextReader(new StringReader(resultRawJson))); - DeleteUsersResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<DeleteUsersResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<DeleteUsersResult> { Result = result }; + return new PlayFabResult<DeleteUsersResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked friends of the given player for the given statistic, starting from the indicated point in the leaderboard /// </summary> - public static async Task<PlayFabResult<GetLeaderboardResult>> GetFriendLeaderboardAsync(GetFriendLeaderboardRequest request) + public static async Task<PlayFabResult<GetLeaderboardResult>> GetFriendLeaderboardAsync(GetFriendLeaderboardRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetFriendLeaderboard", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetFriendLeaderboard", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardResult>>(resultRawJson); + var result = resultData.data; - GetLeaderboardResult result = resultData.data; - - return new PlayFabResult<GetLeaderboardResult> { Result = result }; + return new PlayFabResult<GetLeaderboardResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked users for the given statistic, starting from the indicated point in the leaderboard /// </summary> - public static async Task<PlayFabResult<GetLeaderboardResult>> GetLeaderboardAsync(GetLeaderboardRequest request) + public static async Task<PlayFabResult<GetLeaderboardResult>> GetLeaderboardAsync(GetLeaderboardRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetLeaderboard", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetLeaderboard", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetLeaderboardResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetLeaderboardResult> { Result = result }; + return new PlayFabResult<GetLeaderboardResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked users for the given statistic, centered on the currently signed-in user /// </summary> - public static async Task<PlayFabResult<GetLeaderboardAroundUserResult>> GetLeaderboardAroundUserAsync(GetLeaderboardAroundUserRequest request) + public static async Task<PlayFabResult<GetLeaderboardAroundUserResult>> GetLeaderboardAroundUserAsync(GetLeaderboardAroundUserRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetLeaderboardAroundUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetLeaderboardAroundUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardAroundUserResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardAroundUserResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardAroundUserResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardAroundUserResult>>(resultRawJson); + var result = resultData.data; - GetLeaderboardAroundUserResult result = resultData.data; - - return new PlayFabResult<GetLeaderboardAroundUserResult> { Result = result }; + return new PlayFabResult<GetLeaderboardAroundUserResult> { Result = result, CustomData = customData }; } /// <summary> /// Returns whatever info is requested in the response for the user. Note that PII (like email address, facebook id) may be returned. All parameters default to false. /// </summary> - public static async Task<PlayFabResult<GetPlayerCombinedInfoResult>> GetPlayerCombinedInfoAsync(GetPlayerCombinedInfoRequest request) + public static async Task<PlayFabResult<GetPlayerCombinedInfoResult>> GetPlayerCombinedInfoAsync(GetPlayerCombinedInfoRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetPlayerCombinedInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetPlayerCombinedInfo", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerCombinedInfoResult> { Error = error, }; + return new PlayFabResult<GetPlayerCombinedInfoResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerCombinedInfoResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerCombinedInfoResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerCombinedInfoResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerCombinedInfoResult> { Result = result }; + return new PlayFabResult<GetPlayerCombinedInfoResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the current version and values for the indicated statistics, for the local player. /// </summary> - public static async Task<PlayFabResult<GetPlayerStatisticsResult>> GetPlayerStatisticsAsync(GetPlayerStatisticsRequest request) + public static async Task<PlayFabResult<GetPlayerStatisticsResult>> GetPlayerStatisticsAsync(GetPlayerStatisticsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetPlayerStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetPlayerStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerStatisticsResult> { Error = error, }; + return new PlayFabResult<GetPlayerStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerStatisticsResult>>(resultRawJson); + var result = resultData.data; - GetPlayerStatisticsResult result = resultData.data; - - return new PlayFabResult<GetPlayerStatisticsResult> { Result = result }; + return new PlayFabResult<GetPlayerStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the information on the available versions of the specified statistic. /// </summary> - public static async Task<PlayFabResult<GetPlayerStatisticVersionsResult>> GetPlayerStatisticVersionsAsync(GetPlayerStatisticVersionsRequest request) + public static async Task<PlayFabResult<GetPlayerStatisticVersionsResult>> GetPlayerStatisticVersionsAsync(GetPlayerStatisticVersionsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetPlayerStatisticVersions", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetPlayerStatisticVersions", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerStatisticVersionsResult> { Error = error, }; + return new PlayFabResult<GetPlayerStatisticVersionsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerStatisticVersionsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerStatisticVersionsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerStatisticVersionsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerStatisticVersionsResult> { Result = result }; + return new PlayFabResult<GetPlayerStatisticVersionsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetUserData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetUserData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserInternalDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserInternalDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetUserInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetUserInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - GetUserDataResult result = resultData.data; - - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the publisher-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetUserPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetUserPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the publisher-specific custom data for the user which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherInternalDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherInternalDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetUserPublisherInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetUserPublisherInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the publisher-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherReadOnlyDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserPublisherReadOnlyDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetUserPublisherReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetUserPublisherReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - GetUserDataResult result = resultData.data; - - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<GetUserDataResult>> GetUserReadOnlyDataAsync(GetUserDataRequest request) + public static async Task<PlayFabResult<GetUserDataResult>> GetUserReadOnlyDataAsync(GetUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetUserReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetUserReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserDataResult> { Error = error, }; + return new PlayFabResult<GetUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetUserDataResult> { Result = result }; + return new PlayFabResult<GetUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the values of the specified title-specific statistics for the user /// </summary> - public static async Task<PlayFabResult<UpdatePlayerStatisticsResult>> UpdatePlayerStatisticsAsync(UpdatePlayerStatisticsRequest request) + public static async Task<PlayFabResult<UpdatePlayerStatisticsResult>> UpdatePlayerStatisticsAsync(UpdatePlayerStatisticsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdatePlayerStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdatePlayerStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdatePlayerStatisticsResult> { Error = error, }; + return new PlayFabResult<UpdatePlayerStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdatePlayerStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdatePlayerStatisticsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdatePlayerStatisticsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdatePlayerStatisticsResult> { Result = result }; + return new PlayFabResult<UpdatePlayerStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserDataAsync(UpdateUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateUserData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateUserData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - UpdateUserDataResult result = resultData.data; - - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title-specific custom data for the user which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserInternalDataAsync(UpdateUserInternalDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserInternalDataAsync(UpdateUserInternalDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateUserInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateUserInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the publisher-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherDataAsync(UpdateUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateUserPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateUserPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - UpdateUserDataResult result = resultData.data; - - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the publisher-specific custom data for the user which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherInternalDataAsync(UpdateUserInternalDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherInternalDataAsync(UpdateUserInternalDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateUserPublisherInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateUserPublisherInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the publisher-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherReadOnlyDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserPublisherReadOnlyDataAsync(UpdateUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateUserPublisherReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateUserPublisherReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - UpdateUserDataResult result = resultData.data; - - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title-specific custom data for the user which can only be read by the client /// </summary> - public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserReadOnlyDataAsync(UpdateUserDataRequest request) + public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserReadOnlyDataAsync(UpdateUserDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateUserReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateUserReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateUserDataResult> { Error = error, }; + return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateUserDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateUserDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateUserDataResult> { Result = result }; + return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the specified version of the title's catalog of virtual goods, including all defined properties /// </summary> - public static async Task<PlayFabResult<GetCatalogItemsResult>> GetCatalogItemsAsync(GetCatalogItemsRequest request) + public static async Task<PlayFabResult<GetCatalogItemsResult>> GetCatalogItemsAsync(GetCatalogItemsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetCatalogItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetCatalogItems", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCatalogItemsResult> { Error = error, }; + return new PlayFabResult<GetCatalogItemsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCatalogItemsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetCatalogItemsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCatalogItemsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetCatalogItemsResult> { Result = result }; + return new PlayFabResult<GetCatalogItemsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the key-value store of custom publisher settings /// </summary> - public static async Task<PlayFabResult<GetPublisherDataResult>> GetPublisherDataAsync(GetPublisherDataRequest request) + public static async Task<PlayFabResult<GetPublisherDataResult>> GetPublisherDataAsync(GetPublisherDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPublisherDataResult> { Error = error, }; + return new PlayFabResult<GetPublisherDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPublisherDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPublisherDataResult>>(resultRawJson); + var result = resultData.data; - GetPublisherDataResult result = resultData.data; - - return new PlayFabResult<GetPublisherDataResult> { Result = result }; + return new PlayFabResult<GetPublisherDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the current server time /// </summary> - public static async Task<PlayFabResult<GetTimeResult>> GetTimeAsync(GetTimeRequest request) + public static async Task<PlayFabResult<GetTimeResult>> GetTimeAsync(GetTimeRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetTime", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetTime", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTimeResult> { Error = error, }; + return new PlayFabResult<GetTimeResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTimeResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetTimeResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTimeResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetTimeResult> { Result = result }; + return new PlayFabResult<GetTimeResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the key-value store of custom title settings /// </summary> - public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleDataAsync(GetTitleDataRequest request) + public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleDataAsync(GetTitleDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetTitleData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetTitleData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTitleDataResult> { Error = error, }; + return new PlayFabResult<GetTitleDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTitleDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTitleDataResult>>(resultRawJson); + var result = resultData.data; - GetTitleDataResult result = resultData.data; - - return new PlayFabResult<GetTitleDataResult> { Result = result }; + return new PlayFabResult<GetTitleDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the key-value store of custom internal title settings /// </summary> - public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleInternalDataAsync(GetTitleDataRequest request) + public static async Task<PlayFabResult<GetTitleDataResult>> GetTitleInternalDataAsync(GetTitleDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetTitleInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetTitleInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTitleDataResult> { Error = error, }; + return new PlayFabResult<GetTitleDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTitleDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetTitleDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTitleDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetTitleDataResult> { Result = result }; + return new PlayFabResult<GetTitleDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title news feed, as configured in the developer portal /// </summary> - public static async Task<PlayFabResult<GetTitleNewsResult>> GetTitleNewsAsync(GetTitleNewsRequest request) + public static async Task<PlayFabResult<GetTitleNewsResult>> GetTitleNewsAsync(GetTitleNewsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetTitleNews", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetTitleNews", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetTitleNewsResult> { Error = error, }; + return new PlayFabResult<GetTitleNewsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetTitleNewsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetTitleNewsResult>>(resultRawJson); + var result = resultData.data; - GetTitleNewsResult result = resultData.data; - - return new PlayFabResult<GetTitleNewsResult> { Result = result }; + return new PlayFabResult<GetTitleNewsResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the key-value store of custom publisher settings /// </summary> - public static async Task<PlayFabResult<SetPublisherDataResult>> SetPublisherDataAsync(SetPublisherDataRequest request) + public static async Task<PlayFabResult<SetPublisherDataResult>> SetPublisherDataAsync(SetPublisherDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/SetPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/SetPublisherData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetPublisherDataResult> { Error = error, }; + return new PlayFabResult<SetPublisherDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetPublisherDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - SetPublisherDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetPublisherDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<SetPublisherDataResult> { Result = result }; + return new PlayFabResult<SetPublisherDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the key-value store of custom title settings /// </summary> - public static async Task<PlayFabResult<SetTitleDataResult>> SetTitleDataAsync(SetTitleDataRequest request) + public static async Task<PlayFabResult<SetTitleDataResult>> SetTitleDataAsync(SetTitleDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/SetTitleData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/SetTitleData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetTitleDataResult> { Error = error, }; + return new PlayFabResult<SetTitleDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetTitleDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - SetTitleDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetTitleDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<SetTitleDataResult> { Result = result }; + return new PlayFabResult<SetTitleDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the key-value store of custom title settings /// </summary> - public static async Task<PlayFabResult<SetTitleDataResult>> SetTitleInternalDataAsync(SetTitleDataRequest request) + public static async Task<PlayFabResult<SetTitleDataResult>> SetTitleInternalDataAsync(SetTitleDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/SetTitleInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/SetTitleInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetTitleDataResult> { Error = error, }; + return new PlayFabResult<SetTitleDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetTitleDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetTitleDataResult>>(resultRawJson); + var result = resultData.data; - SetTitleDataResult result = resultData.data; - - return new PlayFabResult<SetTitleDataResult> { Result = result }; + return new PlayFabResult<SetTitleDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Increments the character's balance of the specified virtual currency by the stated amount /// </summary> - public static async Task<PlayFabResult<ModifyCharacterVirtualCurrencyResult>> AddCharacterVirtualCurrencyAsync(AddCharacterVirtualCurrencyRequest request) + public static async Task<PlayFabResult<ModifyCharacterVirtualCurrencyResult>> AddCharacterVirtualCurrencyAsync(AddCharacterVirtualCurrencyRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/AddCharacterVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/AddCharacterVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyCharacterVirtualCurrencyResult> { Error = error, }; + return new PlayFabResult<ModifyCharacterVirtualCurrencyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyCharacterVirtualCurrencyResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ModifyCharacterVirtualCurrencyResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyCharacterVirtualCurrencyResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ModifyCharacterVirtualCurrencyResult> { Result = result }; + return new PlayFabResult<ModifyCharacterVirtualCurrencyResult> { Result = result, CustomData = customData }; } /// <summary> /// Increments the user's balance of the specified virtual currency by the stated amount /// </summary> - public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> AddUserVirtualCurrencyAsync(AddUserVirtualCurrencyRequest request) + public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> AddUserVirtualCurrencyAsync(AddUserVirtualCurrencyRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/AddUserVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/AddUserVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(resultRawJson); + var result = resultData.data; - ModifyUserVirtualCurrencyResult result = resultData.data; - - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result, CustomData = customData }; } /// <summary> /// Consume uses of a consumable item. When all uses are consumed, it will be removed from the player's inventory. /// </summary> - public static async Task<PlayFabResult<ConsumeItemResult>> ConsumeItemAsync(ConsumeItemRequest request) + public static async Task<PlayFabResult<ConsumeItemResult>> ConsumeItemAsync(ConsumeItemRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/ConsumeItem", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/ConsumeItem", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ConsumeItemResult> { Error = error, }; + return new PlayFabResult<ConsumeItemResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ConsumeItemResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ConsumeItemResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ConsumeItemResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ConsumeItemResult> { Result = result }; + return new PlayFabResult<ConsumeItemResult> { Result = result, CustomData = customData }; } /// <summary> /// Returns the result of an evaluation of a Random Result Table - the ItemId from the game Catalog which would have been added to the player inventory, if the Random Result Table were added via a Bundle or a call to UnlockContainer. /// </summary> - public static async Task<PlayFabResult<EvaluateRandomResultTableResult>> EvaluateRandomResultTableAsync(EvaluateRandomResultTableRequest request) + public static async Task<PlayFabResult<EvaluateRandomResultTableResult>> EvaluateRandomResultTableAsync(EvaluateRandomResultTableRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/EvaluateRandomResultTable", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/EvaluateRandomResultTable", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<EvaluateRandomResultTableResult> { Error = error, }; + return new PlayFabResult<EvaluateRandomResultTableResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<EvaluateRandomResultTableResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<EvaluateRandomResultTableResult>>(resultRawJson); + var result = resultData.data; - EvaluateRandomResultTableResult result = resultData.data; - - return new PlayFabResult<EvaluateRandomResultTableResult> { Result = result }; + return new PlayFabResult<EvaluateRandomResultTableResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the specified character's current inventory of virtual goods /// </summary> - public static async Task<PlayFabResult<GetCharacterInventoryResult>> GetCharacterInventoryAsync(GetCharacterInventoryRequest request) + public static async Task<PlayFabResult<GetCharacterInventoryResult>> GetCharacterInventoryAsync(GetCharacterInventoryRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetCharacterInventory", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetCharacterInventory", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterInventoryResult> { Error = error, }; + return new PlayFabResult<GetCharacterInventoryResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterInventoryResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetCharacterInventoryResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterInventoryResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetCharacterInventoryResult> { Result = result }; + return new PlayFabResult<GetCharacterInventoryResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the configuration information for the specified random results tables for the title, including all ItemId values and weights /// </summary> - public static async Task<PlayFabResult<GetRandomResultTablesResult>> GetRandomResultTablesAsync(GetRandomResultTablesRequest request) + public static async Task<PlayFabResult<GetRandomResultTablesResult>> GetRandomResultTablesAsync(GetRandomResultTablesRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetRandomResultTables", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetRandomResultTables", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetRandomResultTablesResult> { Error = error, }; + return new PlayFabResult<GetRandomResultTablesResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetRandomResultTablesResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetRandomResultTablesResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetRandomResultTablesResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetRandomResultTablesResult> { Result = result }; + return new PlayFabResult<GetRandomResultTablesResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the specified user's current inventory of virtual goods /// </summary> - public static async Task<PlayFabResult<GetUserInventoryResult>> GetUserInventoryAsync(GetUserInventoryRequest request) + public static async Task<PlayFabResult<GetUserInventoryResult>> GetUserInventoryAsync(GetUserInventoryRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetUserInventory", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetUserInventory", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetUserInventoryResult> { Error = error, }; + return new PlayFabResult<GetUserInventoryResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetUserInventoryResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetUserInventoryResult>>(resultRawJson); + var result = resultData.data; - GetUserInventoryResult result = resultData.data; - - return new PlayFabResult<GetUserInventoryResult> { Result = result }; + return new PlayFabResult<GetUserInventoryResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the specified items to the specified character's inventory /// </summary> - public static async Task<PlayFabResult<GrantItemsToCharacterResult>> GrantItemsToCharacterAsync(GrantItemsToCharacterRequest request) + public static async Task<PlayFabResult<GrantItemsToCharacterResult>> GrantItemsToCharacterAsync(GrantItemsToCharacterRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GrantItemsToCharacter", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GrantItemsToCharacter", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GrantItemsToCharacterResult> { Error = error, }; + return new PlayFabResult<GrantItemsToCharacterResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GrantItemsToCharacterResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GrantItemsToCharacterResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GrantItemsToCharacterResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GrantItemsToCharacterResult> { Result = result }; + return new PlayFabResult<GrantItemsToCharacterResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the specified items to the specified user's inventory /// </summary> - public static async Task<PlayFabResult<GrantItemsToUserResult>> GrantItemsToUserAsync(GrantItemsToUserRequest request) + public static async Task<PlayFabResult<GrantItemsToUserResult>> GrantItemsToUserAsync(GrantItemsToUserRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GrantItemsToUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GrantItemsToUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GrantItemsToUserResult> { Error = error, }; + return new PlayFabResult<GrantItemsToUserResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GrantItemsToUserResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GrantItemsToUserResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GrantItemsToUserResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GrantItemsToUserResult> { Result = result }; + return new PlayFabResult<GrantItemsToUserResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the specified items to the specified user inventories /// </summary> - public static async Task<PlayFabResult<GrantItemsToUsersResult>> GrantItemsToUsersAsync(GrantItemsToUsersRequest request) + public static async Task<PlayFabResult<GrantItemsToUsersResult>> GrantItemsToUsersAsync(GrantItemsToUsersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GrantItemsToUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GrantItemsToUsers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GrantItemsToUsersResult> { Error = error, }; + return new PlayFabResult<GrantItemsToUsersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GrantItemsToUsersResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GrantItemsToUsersResult>>(resultRawJson); + var result = resultData.data; - GrantItemsToUsersResult result = resultData.data; - - return new PlayFabResult<GrantItemsToUsersResult> { Result = result }; + return new PlayFabResult<GrantItemsToUsersResult> { Result = result, CustomData = customData }; } /// <summary> /// Modifies the number of remaining uses of a player's inventory item /// </summary> - public static async Task<PlayFabResult<ModifyItemUsesResult>> ModifyItemUsesAsync(ModifyItemUsesRequest request) + public static async Task<PlayFabResult<ModifyItemUsesResult>> ModifyItemUsesAsync(ModifyItemUsesRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/ModifyItemUses", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/ModifyItemUses", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyItemUsesResult> { Error = error, }; + return new PlayFabResult<ModifyItemUsesResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyItemUsesResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ModifyItemUsesResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyItemUsesResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ModifyItemUsesResult> { Result = result }; + return new PlayFabResult<ModifyItemUsesResult> { Result = result, CustomData = customData }; } /// <summary> /// Moves an item from a character's inventory into another of the users's character's inventory. /// </summary> - public static async Task<PlayFabResult<MoveItemToCharacterFromCharacterResult>> MoveItemToCharacterFromCharacterAsync(MoveItemToCharacterFromCharacterRequest request) + public static async Task<PlayFabResult<MoveItemToCharacterFromCharacterResult>> MoveItemToCharacterFromCharacterAsync(MoveItemToCharacterFromCharacterRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/MoveItemToCharacterFromCharacter", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/MoveItemToCharacterFromCharacter", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<MoveItemToCharacterFromCharacterResult> { Error = error, }; + return new PlayFabResult<MoveItemToCharacterFromCharacterResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<MoveItemToCharacterFromCharacterResult>>(new JsonTextReader(new StringReader(resultRawJson))); - MoveItemToCharacterFromCharacterResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<MoveItemToCharacterFromCharacterResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<MoveItemToCharacterFromCharacterResult> { Result = result }; + return new PlayFabResult<MoveItemToCharacterFromCharacterResult> { Result = result, CustomData = customData }; } /// <summary> /// Moves an item from a user's inventory into their character's inventory. /// </summary> - public static async Task<PlayFabResult<MoveItemToCharacterFromUserResult>> MoveItemToCharacterFromUserAsync(MoveItemToCharacterFromUserRequest request) + public static async Task<PlayFabResult<MoveItemToCharacterFromUserResult>> MoveItemToCharacterFromUserAsync(MoveItemToCharacterFromUserRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/MoveItemToCharacterFromUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/MoveItemToCharacterFromUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<MoveItemToCharacterFromUserResult> { Error = error, }; + return new PlayFabResult<MoveItemToCharacterFromUserResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<MoveItemToCharacterFromUserResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<MoveItemToCharacterFromUserResult>>(resultRawJson); + var result = resultData.data; - MoveItemToCharacterFromUserResult result = resultData.data; - - return new PlayFabResult<MoveItemToCharacterFromUserResult> { Result = result }; + return new PlayFabResult<MoveItemToCharacterFromUserResult> { Result = result, CustomData = customData }; } /// <summary> /// Moves an item from a character's inventory into the owning user's inventory. /// </summary> - public static async Task<PlayFabResult<MoveItemToUserFromCharacterResult>> MoveItemToUserFromCharacterAsync(MoveItemToUserFromCharacterRequest request) + public static async Task<PlayFabResult<MoveItemToUserFromCharacterResult>> MoveItemToUserFromCharacterAsync(MoveItemToUserFromCharacterRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/MoveItemToUserFromCharacter", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/MoveItemToUserFromCharacter", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<MoveItemToUserFromCharacterResult> { Error = error, }; + return new PlayFabResult<MoveItemToUserFromCharacterResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<MoveItemToUserFromCharacterResult>>(new JsonTextReader(new StringReader(resultRawJson))); - MoveItemToUserFromCharacterResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<MoveItemToUserFromCharacterResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<MoveItemToUserFromCharacterResult> { Result = result }; + return new PlayFabResult<MoveItemToUserFromCharacterResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the virtual goods associated with the coupon to the user's inventory. Coupons can be generated via the Economy->Catalogs tab in the PlayFab Game Manager. /// </summary> - public static async Task<PlayFabResult<RedeemCouponResult>> RedeemCouponAsync(RedeemCouponRequest request) + public static async Task<PlayFabResult<RedeemCouponResult>> RedeemCouponAsync(RedeemCouponRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RedeemCoupon", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RedeemCoupon", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RedeemCouponResult> { Error = error, }; + return new PlayFabResult<RedeemCouponResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RedeemCouponResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RedeemCouponResult>>(resultRawJson); + var result = resultData.data; - RedeemCouponResult result = resultData.data; - - return new PlayFabResult<RedeemCouponResult> { Result = result }; + return new PlayFabResult<RedeemCouponResult> { Result = result, CustomData = customData }; } /// <summary> /// Submit a report about a player (due to bad bahavior, etc.) on behalf of another player, so that customer service representatives for the title can take action concerning potentially toxic players. /// </summary> - public static async Task<PlayFabResult<ReportPlayerServerResult>> ReportPlayerAsync(ReportPlayerServerRequest request) + public static async Task<PlayFabResult<ReportPlayerServerResult>> ReportPlayerAsync(ReportPlayerServerRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/ReportPlayer", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/ReportPlayer", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ReportPlayerServerResult> { Error = error, }; + return new PlayFabResult<ReportPlayerServerResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ReportPlayerServerResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ReportPlayerServerResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ReportPlayerServerResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ReportPlayerServerResult> { Result = result }; + return new PlayFabResult<ReportPlayerServerResult> { Result = result, CustomData = customData }; } /// <summary> /// Revokes access to an item in a user's inventory /// </summary> - public static async Task<PlayFabResult<RevokeInventoryResult>> RevokeInventoryItemAsync(RevokeInventoryItemRequest request) + public static async Task<PlayFabResult<RevokeInventoryResult>> RevokeInventoryItemAsync(RevokeInventoryItemRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RevokeInventoryItem", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RevokeInventoryItem", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RevokeInventoryResult> { Error = error, }; + return new PlayFabResult<RevokeInventoryResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RevokeInventoryResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RevokeInventoryResult>>(resultRawJson); + var result = resultData.data; - RevokeInventoryResult result = resultData.data; - - return new PlayFabResult<RevokeInventoryResult> { Result = result }; + return new PlayFabResult<RevokeInventoryResult> { Result = result, CustomData = customData }; } /// <summary> /// Decrements the character's balance of the specified virtual currency by the stated amount /// </summary> - public static async Task<PlayFabResult<ModifyCharacterVirtualCurrencyResult>> SubtractCharacterVirtualCurrencyAsync(SubtractCharacterVirtualCurrencyRequest request) + public static async Task<PlayFabResult<ModifyCharacterVirtualCurrencyResult>> SubtractCharacterVirtualCurrencyAsync(SubtractCharacterVirtualCurrencyRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/SubtractCharacterVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/SubtractCharacterVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyCharacterVirtualCurrencyResult> { Error = error, }; + return new PlayFabResult<ModifyCharacterVirtualCurrencyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyCharacterVirtualCurrencyResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ModifyCharacterVirtualCurrencyResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyCharacterVirtualCurrencyResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ModifyCharacterVirtualCurrencyResult> { Result = result }; + return new PlayFabResult<ModifyCharacterVirtualCurrencyResult> { Result = result, CustomData = customData }; } /// <summary> /// Decrements the user's balance of the specified virtual currency by the stated amount /// </summary> - public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> SubtractUserVirtualCurrencyAsync(SubtractUserVirtualCurrencyRequest request) + public static async Task<PlayFabResult<ModifyUserVirtualCurrencyResult>> SubtractUserVirtualCurrencyAsync(SubtractUserVirtualCurrencyRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/SubtractUserVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/SubtractUserVirtualCurrency", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(new JsonTextReader(new StringReader(resultRawJson))); - ModifyUserVirtualCurrencyResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ModifyUserVirtualCurrencyResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result }; + return new PlayFabResult<ModifyUserVirtualCurrencyResult> { Result = result, CustomData = customData }; } /// <summary> /// Opens a specific container (ContainerItemInstanceId), with a specific key (KeyItemInstanceId, when required), and returns the contents of the opened container. If the container (and key when relevant) are consumable (RemainingUses > 0), their RemainingUses will be decremented, consistent with the operation of ConsumeItem. /// </summary> - public static async Task<PlayFabResult<UnlockContainerItemResult>> UnlockContainerInstanceAsync(UnlockContainerInstanceRequest request) + public static async Task<PlayFabResult<UnlockContainerItemResult>> UnlockContainerInstanceAsync(UnlockContainerInstanceRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UnlockContainerInstance", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UnlockContainerInstance", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlockContainerItemResult> { Error = error, }; + return new PlayFabResult<UnlockContainerItemResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlockContainerItemResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlockContainerItemResult>>(resultRawJson); + var result = resultData.data; - UnlockContainerItemResult result = resultData.data; - - return new PlayFabResult<UnlockContainerItemResult> { Result = result }; + return new PlayFabResult<UnlockContainerItemResult> { Result = result, CustomData = customData }; } /// <summary> /// Searches Player or Character inventory for any ItemInstance matching the given CatalogItemId, if necessary unlocks it using any appropriate key, and returns the contents of the opened container. If the container (and key when relevant) are consumable (RemainingUses > 0), their RemainingUses will be decremented, consistent with the operation of ConsumeItem. /// </summary> - public static async Task<PlayFabResult<UnlockContainerItemResult>> UnlockContainerItemAsync(UnlockContainerItemRequest request) + public static async Task<PlayFabResult<UnlockContainerItemResult>> UnlockContainerItemAsync(UnlockContainerItemRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UnlockContainerItem", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UnlockContainerItem", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UnlockContainerItemResult> { Error = error, }; + return new PlayFabResult<UnlockContainerItemResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UnlockContainerItemResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UnlockContainerItemResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UnlockContainerItemResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UnlockContainerItemResult> { Result = result }; + return new PlayFabResult<UnlockContainerItemResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the key-value pair data tagged to the specified item, which is read-only from the client. /// </summary> - public static async Task<PlayFabResult<EmptyResult>> UpdateUserInventoryItemCustomDataAsync(UpdateUserInventoryItemDataRequest request) + public static async Task<PlayFabResult<EmptyResult>> UpdateUserInventoryItemCustomDataAsync(UpdateUserInventoryItemDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateUserInventoryItemCustomData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateUserInventoryItemCustomData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<EmptyResult> { Error = error, }; + return new PlayFabResult<EmptyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<EmptyResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<EmptyResult>>(resultRawJson); + var result = resultData.data; - EmptyResult result = resultData.data; - - return new PlayFabResult<EmptyResult> { Result = result }; + return new PlayFabResult<EmptyResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds the Friend user to the friendlist of the user with PlayFabId. At least one of FriendPlayFabId,FriendUsername,FriendEmail, or FriendTitleDisplayName should be initialized. /// </summary> - public static async Task<PlayFabResult<EmptyResult>> AddFriendAsync(AddFriendRequest request) + public static async Task<PlayFabResult<EmptyResult>> AddFriendAsync(AddFriendRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/AddFriend", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/AddFriend", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<EmptyResult> { Error = error, }; + return new PlayFabResult<EmptyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<EmptyResult>>(new JsonTextReader(new StringReader(resultRawJson))); - EmptyResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<EmptyResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<EmptyResult> { Result = result }; + return new PlayFabResult<EmptyResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the current friends for the user with PlayFabId, constrained to users who have PlayFab accounts. Friends from linked accounts (Facebook, Steam) are also included. You may optionally exclude some linked services' friends. /// </summary> - public static async Task<PlayFabResult<GetFriendsListResult>> GetFriendsListAsync(GetFriendsListRequest request) + public static async Task<PlayFabResult<GetFriendsListResult>> GetFriendsListAsync(GetFriendsListRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetFriendsList", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetFriendsList", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetFriendsListResult> { Error = error, }; + return new PlayFabResult<GetFriendsListResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetFriendsListResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetFriendsListResult>>(resultRawJson); + var result = resultData.data; - GetFriendsListResult result = resultData.data; - - return new PlayFabResult<GetFriendsListResult> { Result = result }; + return new PlayFabResult<GetFriendsListResult> { Result = result, CustomData = customData }; } /// <summary> /// Removes the specified friend from the the user's friend list /// </summary> - public static async Task<PlayFabResult<EmptyResult>> RemoveFriendAsync(RemoveFriendRequest request) + public static async Task<PlayFabResult<EmptyResult>> RemoveFriendAsync(RemoveFriendRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RemoveFriend", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RemoveFriend", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<EmptyResult> { Error = error, }; + return new PlayFabResult<EmptyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<EmptyResult>>(new JsonTextReader(new StringReader(resultRawJson))); - EmptyResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<EmptyResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<EmptyResult> { Result = result }; + return new PlayFabResult<EmptyResult> { Result = result, CustomData = customData }; } /// <summary> /// Inform the matchmaker that a Game Server Instance is removed. /// </summary> - public static async Task<PlayFabResult<DeregisterGameResponse>> DeregisterGameAsync(DeregisterGameRequest request) + public static async Task<PlayFabResult<DeregisterGameResponse>> DeregisterGameAsync(DeregisterGameRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/DeregisterGame", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/DeregisterGame", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<DeregisterGameResponse> { Error = error, }; + return new PlayFabResult<DeregisterGameResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<DeregisterGameResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - DeregisterGameResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<DeregisterGameResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<DeregisterGameResponse> { Result = result }; + return new PlayFabResult<DeregisterGameResponse> { Result = result, CustomData = customData }; } /// <summary> /// Informs the PlayFab match-making service that the user specified has left the Game Server Instance /// </summary> - public static async Task<PlayFabResult<NotifyMatchmakerPlayerLeftResult>> NotifyMatchmakerPlayerLeftAsync(NotifyMatchmakerPlayerLeftRequest request) + public static async Task<PlayFabResult<NotifyMatchmakerPlayerLeftResult>> NotifyMatchmakerPlayerLeftAsync(NotifyMatchmakerPlayerLeftRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/NotifyMatchmakerPlayerLeft", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/NotifyMatchmakerPlayerLeft", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<NotifyMatchmakerPlayerLeftResult> { Error = error, }; + return new PlayFabResult<NotifyMatchmakerPlayerLeftResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<NotifyMatchmakerPlayerLeftResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<NotifyMatchmakerPlayerLeftResult>>(resultRawJson); + var result = resultData.data; - NotifyMatchmakerPlayerLeftResult result = resultData.data; - - return new PlayFabResult<NotifyMatchmakerPlayerLeftResult> { Result = result }; + return new PlayFabResult<NotifyMatchmakerPlayerLeftResult> { Result = result, CustomData = customData }; } /// <summary> /// Validates a Game Server session ticket and returns details about the user /// </summary> - public static async Task<PlayFabResult<RedeemMatchmakerTicketResult>> RedeemMatchmakerTicketAsync(RedeemMatchmakerTicketRequest request) + public static async Task<PlayFabResult<RedeemMatchmakerTicketResult>> RedeemMatchmakerTicketAsync(RedeemMatchmakerTicketRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RedeemMatchmakerTicket", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RedeemMatchmakerTicket", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RedeemMatchmakerTicketResult> { Error = error, }; + return new PlayFabResult<RedeemMatchmakerTicketResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RedeemMatchmakerTicketResult>>(new JsonTextReader(new StringReader(resultRawJson))); - RedeemMatchmakerTicketResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RedeemMatchmakerTicketResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RedeemMatchmakerTicketResult> { Result = result }; + return new PlayFabResult<RedeemMatchmakerTicketResult> { Result = result, CustomData = customData }; } /// <summary> /// Set the state of the indicated Game Server Instance. Also update the heartbeat for the instance. /// </summary> - public static async Task<PlayFabResult<RefreshGameServerInstanceHeartbeatResult>> RefreshGameServerInstanceHeartbeatAsync(RefreshGameServerInstanceHeartbeatRequest request) + public static async Task<PlayFabResult<RefreshGameServerInstanceHeartbeatResult>> RefreshGameServerInstanceHeartbeatAsync(RefreshGameServerInstanceHeartbeatRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RefreshGameServerInstanceHeartbeat", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RefreshGameServerInstanceHeartbeat", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RefreshGameServerInstanceHeartbeatResult> { Error = error, }; + return new PlayFabResult<RefreshGameServerInstanceHeartbeatResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RefreshGameServerInstanceHeartbeatResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RefreshGameServerInstanceHeartbeatResult>>(resultRawJson); + var result = resultData.data; - RefreshGameServerInstanceHeartbeatResult result = resultData.data; - - return new PlayFabResult<RefreshGameServerInstanceHeartbeatResult> { Result = result }; + return new PlayFabResult<RefreshGameServerInstanceHeartbeatResult> { Result = result, CustomData = customData }; } /// <summary> /// Inform the matchmaker that a new Game Server Instance is added. /// </summary> - public static async Task<PlayFabResult<RegisterGameResponse>> RegisterGameAsync(RegisterGameRequest request) + public static async Task<PlayFabResult<RegisterGameResponse>> RegisterGameAsync(RegisterGameRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RegisterGame", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RegisterGame", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RegisterGameResponse> { Error = error, }; + return new PlayFabResult<RegisterGameResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RegisterGameResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - RegisterGameResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RegisterGameResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RegisterGameResponse> { Result = result }; + return new PlayFabResult<RegisterGameResponse> { Result = result, CustomData = customData }; } /// <summary> /// Sets the custom data of the indicated Game Server Instance /// </summary> - public static async Task<PlayFabResult<SetGameServerInstanceDataResult>> SetGameServerInstanceDataAsync(SetGameServerInstanceDataRequest request) + public static async Task<PlayFabResult<SetGameServerInstanceDataResult>> SetGameServerInstanceDataAsync(SetGameServerInstanceDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/SetGameServerInstanceData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/SetGameServerInstanceData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetGameServerInstanceDataResult> { Error = error, }; + return new PlayFabResult<SetGameServerInstanceDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetGameServerInstanceDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetGameServerInstanceDataResult>>(resultRawJson); + var result = resultData.data; - SetGameServerInstanceDataResult result = resultData.data; - - return new PlayFabResult<SetGameServerInstanceDataResult> { Result = result }; + return new PlayFabResult<SetGameServerInstanceDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Set the state of the indicated Game Server Instance. /// </summary> - public static async Task<PlayFabResult<SetGameServerInstanceStateResult>> SetGameServerInstanceStateAsync(SetGameServerInstanceStateRequest request) + public static async Task<PlayFabResult<SetGameServerInstanceStateResult>> SetGameServerInstanceStateAsync(SetGameServerInstanceStateRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/SetGameServerInstanceState", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/SetGameServerInstanceState", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetGameServerInstanceStateResult> { Error = error, }; + return new PlayFabResult<SetGameServerInstanceStateResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetGameServerInstanceStateResult>>(new JsonTextReader(new StringReader(resultRawJson))); - SetGameServerInstanceStateResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetGameServerInstanceStateResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<SetGameServerInstanceStateResult> { Result = result }; + return new PlayFabResult<SetGameServerInstanceStateResult> { Result = result, CustomData = customData }; } /// <summary> /// Set custom tags for the specified Game Server Instance /// </summary> - public static async Task<PlayFabResult<SetGameServerInstanceTagsResult>> SetGameServerInstanceTagsAsync(SetGameServerInstanceTagsRequest request) + public static async Task<PlayFabResult<SetGameServerInstanceTagsResult>> SetGameServerInstanceTagsAsync(SetGameServerInstanceTagsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/SetGameServerInstanceTags", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/SetGameServerInstanceTags", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<SetGameServerInstanceTagsResult> { Error = error, }; + return new PlayFabResult<SetGameServerInstanceTagsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<SetGameServerInstanceTagsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - SetGameServerInstanceTagsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<SetGameServerInstanceTagsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<SetGameServerInstanceTagsResult> { Result = result }; + return new PlayFabResult<SetGameServerInstanceTagsResult> { Result = result, CustomData = customData }; } /// <summary> /// Awards the specified users the specified Steam achievements /// </summary> - public static async Task<PlayFabResult<AwardSteamAchievementResult>> AwardSteamAchievementAsync(AwardSteamAchievementRequest request) + public static async Task<PlayFabResult<AwardSteamAchievementResult>> AwardSteamAchievementAsync(AwardSteamAchievementRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/AwardSteamAchievement", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/AwardSteamAchievement", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AwardSteamAchievementResult> { Error = error, }; + return new PlayFabResult<AwardSteamAchievementResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AwardSteamAchievementResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AwardSteamAchievementResult>>(resultRawJson); + var result = resultData.data; - AwardSteamAchievementResult result = resultData.data; - - return new PlayFabResult<AwardSteamAchievementResult> { Result = result }; + return new PlayFabResult<AwardSteamAchievementResult> { Result = result, CustomData = customData }; } /// <summary> /// Writes a character-based event into PlayStream. /// </summary> - public static async Task<PlayFabResult<WriteEventResponse>> WriteCharacterEventAsync(WriteServerCharacterEventRequest request) + public static async Task<PlayFabResult<WriteEventResponse>> WriteCharacterEventAsync(WriteServerCharacterEventRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/WriteCharacterEvent", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/WriteCharacterEvent", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<WriteEventResponse> { Error = error, }; + return new PlayFabResult<WriteEventResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<WriteEventResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - WriteEventResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<WriteEventResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<WriteEventResponse> { Result = result }; + return new PlayFabResult<WriteEventResponse> { Result = result, CustomData = customData }; } /// <summary> /// Writes a player-based event into PlayStream. /// </summary> - public static async Task<PlayFabResult<WriteEventResponse>> WritePlayerEventAsync(WriteServerPlayerEventRequest request) + public static async Task<PlayFabResult<WriteEventResponse>> WritePlayerEventAsync(WriteServerPlayerEventRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/WritePlayerEvent", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/WritePlayerEvent", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<WriteEventResponse> { Error = error, }; + return new PlayFabResult<WriteEventResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<WriteEventResponse>>(new JsonTextReader(new StringReader(resultRawJson))); - WriteEventResponse result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<WriteEventResponse>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<WriteEventResponse> { Result = result }; + return new PlayFabResult<WriteEventResponse> { Result = result, CustomData = customData }; } /// <summary> /// Writes a title-based event into PlayStream. /// </summary> - public static async Task<PlayFabResult<WriteEventResponse>> WriteTitleEventAsync(WriteTitleEventRequest request) + public static async Task<PlayFabResult<WriteEventResponse>> WriteTitleEventAsync(WriteTitleEventRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/WriteTitleEvent", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/WriteTitleEvent", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<WriteEventResponse> { Error = error, }; + return new PlayFabResult<WriteEventResponse> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<WriteEventResponse>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<WriteEventResponse>>(resultRawJson); + var result = resultData.data; - WriteEventResponse result = resultData.data; - - return new PlayFabResult<WriteEventResponse> { Result = result }; + return new PlayFabResult<WriteEventResponse> { Result = result, CustomData = customData }; } /// <summary> /// Adds users to the set of those able to update both the shared data, as well as the set of users in the group. Only users in the group (and the server) can add new members. /// </summary> - public static async Task<PlayFabResult<AddSharedGroupMembersResult>> AddSharedGroupMembersAsync(AddSharedGroupMembersRequest request) + public static async Task<PlayFabResult<AddSharedGroupMembersResult>> AddSharedGroupMembersAsync(AddSharedGroupMembersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/AddSharedGroupMembers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/AddSharedGroupMembers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AddSharedGroupMembersResult> { Error = error, }; + return new PlayFabResult<AddSharedGroupMembersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AddSharedGroupMembersResult>>(new JsonTextReader(new StringReader(resultRawJson))); - AddSharedGroupMembersResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AddSharedGroupMembersResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AddSharedGroupMembersResult> { Result = result }; + return new PlayFabResult<AddSharedGroupMembersResult> { Result = result, CustomData = customData }; } /// <summary> /// Requests the creation of a shared group object, containing key/value pairs which may be updated by all members of the group. When created by a server, the group will initially have no members. /// </summary> - public static async Task<PlayFabResult<CreateSharedGroupResult>> CreateSharedGroupAsync(CreateSharedGroupRequest request) + public static async Task<PlayFabResult<CreateSharedGroupResult>> CreateSharedGroupAsync(CreateSharedGroupRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/CreateSharedGroup", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/CreateSharedGroup", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<CreateSharedGroupResult> { Error = error, }; + return new PlayFabResult<CreateSharedGroupResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<CreateSharedGroupResult>>(new JsonTextReader(new StringReader(resultRawJson))); - CreateSharedGroupResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<CreateSharedGroupResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<CreateSharedGroupResult> { Result = result }; + return new PlayFabResult<CreateSharedGroupResult> { Result = result, CustomData = customData }; } /// <summary> /// Deletes a shared group, freeing up the shared group ID to be reused for a new group /// </summary> - public static async Task<PlayFabResult<EmptyResult>> DeleteSharedGroupAsync(DeleteSharedGroupRequest request) + public static async Task<PlayFabResult<EmptyResult>> DeleteSharedGroupAsync(DeleteSharedGroupRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/DeleteSharedGroup", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/DeleteSharedGroup", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<EmptyResult> { Error = error, }; + return new PlayFabResult<EmptyResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<EmptyResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<EmptyResult>>(resultRawJson); + var result = resultData.data; - EmptyResult result = resultData.data; - - return new PlayFabResult<EmptyResult> { Result = result }; + return new PlayFabResult<EmptyResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves data stored in a shared group object, as well as the list of members in the group. The server can access all public and private group data. /// </summary> - public static async Task<PlayFabResult<GetSharedGroupDataResult>> GetSharedGroupDataAsync(GetSharedGroupDataRequest request) + public static async Task<PlayFabResult<GetSharedGroupDataResult>> GetSharedGroupDataAsync(GetSharedGroupDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetSharedGroupData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetSharedGroupData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetSharedGroupDataResult> { Error = error, }; + return new PlayFabResult<GetSharedGroupDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetSharedGroupDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetSharedGroupDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetSharedGroupDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetSharedGroupDataResult> { Result = result }; + return new PlayFabResult<GetSharedGroupDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Removes users from the set of those able to update the shared data and the set of users in the group. Only users in the group can remove members. If as a result of the call, zero users remain with access, the group and its associated data will be deleted. /// </summary> - public static async Task<PlayFabResult<RemoveSharedGroupMembersResult>> RemoveSharedGroupMembersAsync(RemoveSharedGroupMembersRequest request) + public static async Task<PlayFabResult<RemoveSharedGroupMembersResult>> RemoveSharedGroupMembersAsync(RemoveSharedGroupMembersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RemoveSharedGroupMembers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RemoveSharedGroupMembers", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RemoveSharedGroupMembersResult> { Error = error, }; + return new PlayFabResult<RemoveSharedGroupMembersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RemoveSharedGroupMembersResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RemoveSharedGroupMembersResult>>(resultRawJson); + var result = resultData.data; - RemoveSharedGroupMembersResult result = resultData.data; - - return new PlayFabResult<RemoveSharedGroupMembersResult> { Result = result }; + return new PlayFabResult<RemoveSharedGroupMembersResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds, updates, and removes data keys for a shared group object. If the permission is set to Public, all fields updated or added in this call will be readable by users not in the group. By default, data permissions are set to Private. Regardless of the permission setting, only members of the group (and the server) can update the data. /// </summary> - public static async Task<PlayFabResult<UpdateSharedGroupDataResult>> UpdateSharedGroupDataAsync(UpdateSharedGroupDataRequest request) + public static async Task<PlayFabResult<UpdateSharedGroupDataResult>> UpdateSharedGroupDataAsync(UpdateSharedGroupDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateSharedGroupData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateSharedGroupData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateSharedGroupDataResult> { Error = error, }; + return new PlayFabResult<UpdateSharedGroupDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateSharedGroupDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateSharedGroupDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateSharedGroupDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateSharedGroupDataResult> { Result = result }; + return new PlayFabResult<UpdateSharedGroupDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Executes a CloudScript function, with the 'currentPlayerId' variable set to the specified PlayFabId parameter value. /// </summary> - public static async Task<PlayFabResult<ExecuteCloudScriptResult>> ExecuteCloudScriptAsync(ExecuteCloudScriptServerRequest request) + public static async Task<PlayFabResult<ExecuteCloudScriptResult>> ExecuteCloudScriptAsync(ExecuteCloudScriptServerRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/ExecuteCloudScript", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/ExecuteCloudScript", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ExecuteCloudScriptResult> { Error = error, }; + return new PlayFabResult<ExecuteCloudScriptResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ExecuteCloudScriptResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ExecuteCloudScriptResult>>(resultRawJson); + var result = resultData.data; - ExecuteCloudScriptResult result = resultData.data; - - return new PlayFabResult<ExecuteCloudScriptResult> { Result = result }; + return new PlayFabResult<ExecuteCloudScriptResult> { Result = result, CustomData = customData }; } /// <summary> /// This API retrieves a pre-signed URL for accessing a content file for the title. A subsequent HTTP GET to the returned URL will attempt to download the content. A HEAD query to the returned URL will attempt to retrieve the metadata of the content. Note that a successful result does not guarantee the existence of this content - if it has not been uploaded, the query to retrieve the data will fail. See this post for more information: https://community.playfab.com/hc/en-us/community/posts/205469488-How-to-upload-files-to-PlayFab-s-Content-Service /// </summary> - public static async Task<PlayFabResult<GetContentDownloadUrlResult>> GetContentDownloadUrlAsync(GetContentDownloadUrlRequest request) + public static async Task<PlayFabResult<GetContentDownloadUrlResult>> GetContentDownloadUrlAsync(GetContentDownloadUrlRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetContentDownloadUrl", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetContentDownloadUrl", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetContentDownloadUrlResult> { Error = error, }; + return new PlayFabResult<GetContentDownloadUrlResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetContentDownloadUrlResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetContentDownloadUrlResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetContentDownloadUrlResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetContentDownloadUrlResult> { Result = result }; + return new PlayFabResult<GetContentDownloadUrlResult> { Result = result, CustomData = customData }; } /// <summary> /// Deletes the specific character ID from the specified user. /// </summary> - public static async Task<PlayFabResult<DeleteCharacterFromUserResult>> DeleteCharacterFromUserAsync(DeleteCharacterFromUserRequest request) + public static async Task<PlayFabResult<DeleteCharacterFromUserResult>> DeleteCharacterFromUserAsync(DeleteCharacterFromUserRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/DeleteCharacterFromUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/DeleteCharacterFromUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<DeleteCharacterFromUserResult> { Error = error, }; + return new PlayFabResult<DeleteCharacterFromUserResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<DeleteCharacterFromUserResult>>(new JsonTextReader(new StringReader(resultRawJson))); - DeleteCharacterFromUserResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<DeleteCharacterFromUserResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<DeleteCharacterFromUserResult> { Result = result }; + return new PlayFabResult<DeleteCharacterFromUserResult> { Result = result, CustomData = customData }; } /// <summary> /// Lists all of the characters that belong to a specific user. CharacterIds are not globally unique; characterId must be evaluated with the parent PlayFabId to guarantee uniqueness. /// </summary> - public static async Task<PlayFabResult<ListUsersCharactersResult>> GetAllUsersCharactersAsync(ListUsersCharactersRequest request) + public static async Task<PlayFabResult<ListUsersCharactersResult>> GetAllUsersCharactersAsync(ListUsersCharactersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetAllUsersCharacters", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetAllUsersCharacters", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<ListUsersCharactersResult> { Error = error, }; + return new PlayFabResult<ListUsersCharactersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<ListUsersCharactersResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<ListUsersCharactersResult>>(resultRawJson); + var result = resultData.data; - ListUsersCharactersResult result = resultData.data; - - return new PlayFabResult<ListUsersCharactersResult> { Result = result }; + return new PlayFabResult<ListUsersCharactersResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked characters for the given statistic, starting from the indicated point in the leaderboard /// </summary> - public static async Task<PlayFabResult<GetCharacterLeaderboardResult>> GetCharacterLeaderboardAsync(GetCharacterLeaderboardRequest request) + public static async Task<PlayFabResult<GetCharacterLeaderboardResult>> GetCharacterLeaderboardAsync(GetCharacterLeaderboardRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetCharacterLeaderboard", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetCharacterLeaderboard", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterLeaderboardResult> { Error = error, }; + return new PlayFabResult<GetCharacterLeaderboardResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterLeaderboardResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetCharacterLeaderboardResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterLeaderboardResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetCharacterLeaderboardResult> { Result = result }; + return new PlayFabResult<GetCharacterLeaderboardResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the details of all title-specific statistics for the specific character /// </summary> - public static async Task<PlayFabResult<GetCharacterStatisticsResult>> GetCharacterStatisticsAsync(GetCharacterStatisticsRequest request) + public static async Task<PlayFabResult<GetCharacterStatisticsResult>> GetCharacterStatisticsAsync(GetCharacterStatisticsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetCharacterStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetCharacterStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterStatisticsResult> { Error = error, }; + return new PlayFabResult<GetCharacterStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterStatisticsResult>>(resultRawJson); + var result = resultData.data; - GetCharacterStatisticsResult result = resultData.data; - - return new PlayFabResult<GetCharacterStatisticsResult> { Result = result }; + return new PlayFabResult<GetCharacterStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of ranked characters for the given statistic, centered on the requested user /// </summary> - public static async Task<PlayFabResult<GetLeaderboardAroundCharacterResult>> GetLeaderboardAroundCharacterAsync(GetLeaderboardAroundCharacterRequest request) + public static async Task<PlayFabResult<GetLeaderboardAroundCharacterResult>> GetLeaderboardAroundCharacterAsync(GetLeaderboardAroundCharacterRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetLeaderboardAroundCharacter", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetLeaderboardAroundCharacter", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardAroundCharacterResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardAroundCharacterResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardAroundCharacterResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetLeaderboardAroundCharacterResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardAroundCharacterResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetLeaderboardAroundCharacterResult> { Result = result }; + return new PlayFabResult<GetLeaderboardAroundCharacterResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves a list of all of the user's characters for the given statistic. /// </summary> - public static async Task<PlayFabResult<GetLeaderboardForUsersCharactersResult>> GetLeaderboardForUserCharactersAsync(GetLeaderboardForUsersCharactersRequest request) + public static async Task<PlayFabResult<GetLeaderboardForUsersCharactersResult>> GetLeaderboardForUserCharactersAsync(GetLeaderboardForUsersCharactersRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetLeaderboardForUserCharacters", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetLeaderboardForUserCharacters", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetLeaderboardForUsersCharactersResult> { Error = error, }; + return new PlayFabResult<GetLeaderboardForUsersCharactersResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetLeaderboardForUsersCharactersResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetLeaderboardForUsersCharactersResult>>(resultRawJson); + var result = resultData.data; - GetLeaderboardForUsersCharactersResult result = resultData.data; - - return new PlayFabResult<GetLeaderboardForUsersCharactersResult> { Result = result }; + return new PlayFabResult<GetLeaderboardForUsersCharactersResult> { Result = result, CustomData = customData }; } /// <summary> /// Grants the specified character type to the user. CharacterIds are not globally unique; characterId must be evaluated with the parent PlayFabId to guarantee uniqueness. /// </summary> - public static async Task<PlayFabResult<GrantCharacterToUserResult>> GrantCharacterToUserAsync(GrantCharacterToUserRequest request) + public static async Task<PlayFabResult<GrantCharacterToUserResult>> GrantCharacterToUserAsync(GrantCharacterToUserRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GrantCharacterToUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GrantCharacterToUser", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GrantCharacterToUserResult> { Error = error, }; + return new PlayFabResult<GrantCharacterToUserResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GrantCharacterToUserResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GrantCharacterToUserResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GrantCharacterToUserResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GrantCharacterToUserResult> { Result = result }; + return new PlayFabResult<GrantCharacterToUserResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the values of the specified title-specific statistics for the specific character /// </summary> - public static async Task<PlayFabResult<UpdateCharacterStatisticsResult>> UpdateCharacterStatisticsAsync(UpdateCharacterStatisticsRequest request) + public static async Task<PlayFabResult<UpdateCharacterStatisticsResult>> UpdateCharacterStatisticsAsync(UpdateCharacterStatisticsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateCharacterStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateCharacterStatistics", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateCharacterStatisticsResult> { Error = error, }; + return new PlayFabResult<UpdateCharacterStatisticsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateCharacterStatisticsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateCharacterStatisticsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateCharacterStatisticsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateCharacterStatisticsResult> { Result = result }; + return new PlayFabResult<UpdateCharacterStatisticsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterDataAsync(GetCharacterDataRequest request) + public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterDataAsync(GetCharacterDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetCharacterData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetCharacterData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterDataResult> { Error = error, }; + return new PlayFabResult<GetCharacterDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterDataResult>>(resultRawJson); + var result = resultData.data; - GetCharacterDataResult result = resultData.data; - - return new PlayFabResult<GetCharacterDataResult> { Result = result }; + return new PlayFabResult<GetCharacterDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user's character which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterInternalDataAsync(GetCharacterDataRequest request) + public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterInternalDataAsync(GetCharacterDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetCharacterInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetCharacterInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterDataResult> { Error = error, }; + return new PlayFabResult<GetCharacterDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetCharacterDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetCharacterDataResult> { Result = result }; + return new PlayFabResult<GetCharacterDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves the title-specific custom data for the user's character which can only be read by the client /// </summary> - public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterReadOnlyDataAsync(GetCharacterDataRequest request) + public static async Task<PlayFabResult<GetCharacterDataResult>> GetCharacterReadOnlyDataAsync(GetCharacterDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetCharacterReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetCharacterReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetCharacterDataResult> { Error = error, }; + return new PlayFabResult<GetCharacterDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetCharacterDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetCharacterDataResult>>(resultRawJson); + var result = resultData.data; - GetCharacterDataResult result = resultData.data; - - return new PlayFabResult<GetCharacterDataResult> { Result = result }; + return new PlayFabResult<GetCharacterDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title-specific custom data for the user's chjaracter which is readable and writable by the client /// </summary> - public static async Task<PlayFabResult<UpdateCharacterDataResult>> UpdateCharacterDataAsync(UpdateCharacterDataRequest request) + public static async Task<PlayFabResult<UpdateCharacterDataResult>> UpdateCharacterDataAsync(UpdateCharacterDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateCharacterData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateCharacterData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateCharacterDataResult> { Error = error, }; + return new PlayFabResult<UpdateCharacterDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateCharacterDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateCharacterDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateCharacterDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateCharacterDataResult> { Result = result }; + return new PlayFabResult<UpdateCharacterDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title-specific custom data for the user's character which cannot be accessed by the client /// </summary> - public static async Task<PlayFabResult<UpdateCharacterDataResult>> UpdateCharacterInternalDataAsync(UpdateCharacterDataRequest request) + public static async Task<PlayFabResult<UpdateCharacterDataResult>> UpdateCharacterInternalDataAsync(UpdateCharacterDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateCharacterInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateCharacterInternalData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateCharacterDataResult> { Error = error, }; + return new PlayFabResult<UpdateCharacterDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateCharacterDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateCharacterDataResult>>(resultRawJson); + var result = resultData.data; - UpdateCharacterDataResult result = resultData.data; - - return new PlayFabResult<UpdateCharacterDataResult> { Result = result }; + return new PlayFabResult<UpdateCharacterDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Updates the title-specific custom data for the user's character which can only be read by the client /// </summary> - public static async Task<PlayFabResult<UpdateCharacterDataResult>> UpdateCharacterReadOnlyDataAsync(UpdateCharacterDataRequest request) + public static async Task<PlayFabResult<UpdateCharacterDataResult>> UpdateCharacterReadOnlyDataAsync(UpdateCharacterDataRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/UpdateCharacterReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/UpdateCharacterReadOnlyData", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<UpdateCharacterDataResult> { Error = error, }; + return new PlayFabResult<UpdateCharacterDataResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<UpdateCharacterDataResult>>(new JsonTextReader(new StringReader(resultRawJson))); - UpdateCharacterDataResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<UpdateCharacterDataResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<UpdateCharacterDataResult> { Result = result }; + return new PlayFabResult<UpdateCharacterDataResult> { Result = result, CustomData = customData }; } /// <summary> /// Adds a given tag to a player profile. The tag's namespace is automatically generated based on the source of the tag. /// </summary> - public static async Task<PlayFabResult<AddPlayerTagResult>> AddPlayerTagAsync(AddPlayerTagRequest request) + public static async Task<PlayFabResult<AddPlayerTagResult>> AddPlayerTagAsync(AddPlayerTagRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/AddPlayerTag", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/AddPlayerTag", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<AddPlayerTagResult> { Error = error, }; + return new PlayFabResult<AddPlayerTagResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<AddPlayerTagResult>>(new JsonTextReader(new StringReader(resultRawJson))); - AddPlayerTagResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<AddPlayerTagResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<AddPlayerTagResult> { Result = result }; + return new PlayFabResult<AddPlayerTagResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieve a list of all PlayStream actions groups. /// </summary> - public static async Task<PlayFabResult<GetAllActionGroupsResult>> GetAllActionGroupsAsync(GetAllActionGroupsRequest request) + public static async Task<PlayFabResult<GetAllActionGroupsResult>> GetAllActionGroupsAsync(GetAllActionGroupsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetAllActionGroups", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetAllActionGroups", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetAllActionGroupsResult> { Error = error, }; + return new PlayFabResult<GetAllActionGroupsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetAllActionGroupsResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetAllActionGroupsResult>>(resultRawJson); + var result = resultData.data; - GetAllActionGroupsResult result = resultData.data; - - return new PlayFabResult<GetAllActionGroupsResult> { Result = result }; + return new PlayFabResult<GetAllActionGroupsResult> { Result = result, CustomData = customData }; } /// <summary> /// Retrieves an array of player segment definitions. Results from this can be used in subsequent API calls such as GetPlayersInSegment which requires a Segment ID. While segment names can change the ID for that segment will not change. /// </summary> - public static async Task<PlayFabResult<GetAllSegmentsResult>> GetAllSegmentsAsync(GetAllSegmentsRequest request) + public static async Task<PlayFabResult<GetAllSegmentsResult>> GetAllSegmentsAsync(GetAllSegmentsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetAllSegments", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetAllSegments", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetAllSegmentsResult> { Error = error, }; + return new PlayFabResult<GetAllSegmentsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetAllSegmentsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetAllSegmentsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetAllSegmentsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetAllSegmentsResult> { Result = result }; + return new PlayFabResult<GetAllSegmentsResult> { Result = result, CustomData = customData }; } /// <summary> /// List all segments that a player currently belongs to at this moment in time. /// </summary> - public static async Task<PlayFabResult<GetPlayerSegmentsResult>> GetPlayerSegmentsAsync(GetPlayersSegmentsRequest request) + public static async Task<PlayFabResult<GetPlayerSegmentsResult>> GetPlayerSegmentsAsync(GetPlayersSegmentsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetPlayerSegments", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetPlayerSegments", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerSegmentsResult> { Error = error, }; + return new PlayFabResult<GetPlayerSegmentsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerSegmentsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerSegmentsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerSegmentsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerSegmentsResult> { Result = result }; + return new PlayFabResult<GetPlayerSegmentsResult> { Result = result, CustomData = customData }; } /// <summary> /// Allows for paging through all players in a given segment. This API creates a snapshot of all player profiles that match the segment definition at the time of its creation and lives through the Total Seconds to Live, refreshing its life span on each subsequent use of the Continuation Token. Profiles that change during the course of paging will not be reflected in the results. AB Test segments are currently not supported by this operation. /// </summary> - public static async Task<PlayFabResult<GetPlayersInSegmentResult>> GetPlayersInSegmentAsync(GetPlayersInSegmentRequest request) + public static async Task<PlayFabResult<GetPlayersInSegmentResult>> GetPlayersInSegmentAsync(GetPlayersInSegmentRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetPlayersInSegment", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetPlayersInSegment", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayersInSegmentResult> { Error = error, }; + return new PlayFabResult<GetPlayersInSegmentResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayersInSegmentResult>>(new JsonTextReader(new StringReader(resultRawJson))); + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayersInSegmentResult>>(resultRawJson); + var result = resultData.data; - GetPlayersInSegmentResult result = resultData.data; - - return new PlayFabResult<GetPlayersInSegmentResult> { Result = result }; + return new PlayFabResult<GetPlayersInSegmentResult> { Result = result, CustomData = customData }; } /// <summary> /// Get all tags with a given Namespace (optional) from a player profile. /// </summary> - public static async Task<PlayFabResult<GetPlayerTagsResult>> GetPlayerTagsAsync(GetPlayerTagsRequest request) + public static async Task<PlayFabResult<GetPlayerTagsResult>> GetPlayerTagsAsync(GetPlayerTagsRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/GetPlayerTags", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/GetPlayerTags", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<GetPlayerTagsResult> { Error = error, }; + return new PlayFabResult<GetPlayerTagsResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<GetPlayerTagsResult>>(new JsonTextReader(new StringReader(resultRawJson))); - GetPlayerTagsResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<GetPlayerTagsResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<GetPlayerTagsResult> { Result = result }; + return new PlayFabResult<GetPlayerTagsResult> { Result = result, CustomData = customData }; } /// <summary> /// Remove a given tag from a player profile. The tag's namespace is automatically generated based on the source of the tag. /// </summary> - public static async Task<PlayFabResult<RemovePlayerTagResult>> RemovePlayerTagAsync(RemovePlayerTagRequest request) + public static async Task<PlayFabResult<RemovePlayerTagResult>> RemovePlayerTagAsync(RemovePlayerTagRequest request, object customData = null) { if (PlayFabSettings.DeveloperSecretKey == null) throw new Exception ("Must have PlayFabSettings.DeveloperSecretKey set to call this method"); - object httpResult = await PlayFabHTTP.DoPost("/Server/RemovePlayerTag", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); + var httpResult = await PlayFabHttp.DoPost("/Server/RemovePlayerTag", request, "X-SecretKey", PlayFabSettings.DeveloperSecretKey); if(httpResult is PlayFabError) { - PlayFabError error = (PlayFabError)httpResult; + var error = (PlayFabError)httpResult; if (PlayFabSettings.GlobalErrorHandler != null) PlayFabSettings.GlobalErrorHandler(error); - return new PlayFabResult<RemovePlayerTagResult> { Error = error, }; + return new PlayFabResult<RemovePlayerTagResult> { Error = error, CustomData = customData }; } - string resultRawJson = (string)httpResult; - - var serializer = JsonSerializer.Create(PlayFabUtil.JsonSettings); - var resultData = serializer.Deserialize<PlayFabJsonSuccess<RemovePlayerTagResult>>(new JsonTextReader(new StringReader(resultRawJson))); - RemovePlayerTagResult result = resultData.data; + var resultRawJson = (string)httpResult; + var resultData = JsonWrapper.DeserializeObject<PlayFabJsonSuccess<RemovePlayerTagResult>>(resultRawJson); + var result = resultData.data; - return new PlayFabResult<RemovePlayerTagResult> { Result = result }; + return new PlayFabResult<RemovePlayerTagResult> { Result = result, CustomData = customData }; } } diff --git a/PlayFabServerSDK/source/PlayFabServerModels.cs b/PlayFabServerSDK/source/PlayFabServerModels.cs index 76b15e48..8609cc1c 100644 --- a/PlayFabServerSDK/source/PlayFabServerModels.cs +++ b/PlayFabServerSDK/source/PlayFabServerModels.cs @@ -1,11 +1,73 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; using PlayFab.Internal; using System; using System.Collections.Generic; namespace PlayFab.ServerModels { + public class ActionsOnPlayersInSegmentTaskSummary + { + /// <summary> + /// ID of the task instance. + /// </summary> + public string TaskInstanceId; + + /// <summary> + /// Identifier of the task this instance belongs to. + /// </summary> + public NameIdentifier TaskIdentifier; + + /// <summary> + /// UTC timestamp when the task started. + /// </summary> + public DateTime StartedAt; + + /// <summary> + /// UTC timestamp when the task completed. + /// </summary> + public DateTime? CompletedAt; + + /// <summary> + /// Current status of the task instance. + /// </summary> + public TaskInstanceStatus? Status; + + /// <summary> + /// Progress represented as percentage. + /// </summary> + public double? PercentComplete; + + /// <summary> + /// Estimated time remaining in seconds. + /// </summary> + public double? EstimatedSecondsRemaining; + + /// <summary> + /// If manually scheduled, ID of user who scheduled the task. + /// </summary> + public string ScheduledByUserId; + + /// <summary> + /// Error message for last processing attempt, if an error occured. + /// </summary> + public string ErrorMessage; + + /// <summary> + /// Flag indicating if the error was fatal, if false job will be retried. + /// </summary> + public bool? ErrorWasFatal; + + /// <summary> + /// Total players in segment when task was started. + /// </summary> + public int? TotalPlayersInSegment; + + /// <summary> + /// Total number of players that have had the actions applied to. + /// </summary> + public int? TotalPlayersProcessed; + + } + public class AdCampaignAttribution { /// <summary> @@ -25,7 +87,7 @@ public class AdCampaignAttribution } - public class AddCharacterVirtualCurrencyRequest + public class AddCharacterVirtualCurrencyRequest : PlayFabRequestCommon { /// <summary> /// PlayFab unique identifier of the user whose virtual currency balance is to be incremented. @@ -49,7 +111,7 @@ public class AddCharacterVirtualCurrencyRequest } - public class AddFriendRequest + public class AddFriendRequest : PlayFabRequestCommon { /// <summary> /// PlayFab identifier of the player to add a new friend. @@ -78,7 +140,7 @@ public class AddFriendRequest } - public class AddPlayerTagRequest + public class AddPlayerTagRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -96,7 +158,7 @@ public class AddPlayerTagResult : PlayFabResultCommon { } - public class AddSharedGroupMembersRequest + public class AddSharedGroupMembersRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group. @@ -114,7 +176,7 @@ public class AddSharedGroupMembersResult : PlayFabResultCommon { } - public class AddUserVirtualCurrencyRequest + public class AddUserVirtualCurrencyRequest : PlayFabRequestCommon { /// <summary> /// PlayFab unique identifier of the user whose virtual currency balance is to be increased. @@ -133,7 +195,7 @@ public class AddUserVirtualCurrencyRequest } - public class AuthenticateSessionTicketRequest + public class AuthenticateSessionTicketRequest : PlayFabRequestCommon { /// <summary> /// Session ticket as issued by a PlayFab client login API. @@ -170,7 +232,7 @@ public class AwardSteamAchievementItem } - public class AwardSteamAchievementRequest + public class AwardSteamAchievementRequest : PlayFabRequestCommon { /// <summary> /// Array of achievements to grant and the users to whom they are to be granted. @@ -238,7 +300,7 @@ public class BanInfo /// <summary> /// Represents a single ban request. /// </summary> - public class BanRequest + public class BanRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -267,7 +329,7 @@ public class BanRequest } - public class BanUsersRequest + public class BanUsersRequest : PlayFabRequestCommon { /// <summary> /// List of ban requests to be applied. Maximum 100. @@ -377,7 +439,7 @@ public class CatalogItem : IComparable<CatalogItem> public bool IsLimitedEdition; /// <summary> - /// BETA: If IsLImitedEdition is true, then this determines amount of the item initially available. Note that this fieldis ignored if the catalog item already existed in this catalog, or the field is less than 1. + /// If IsLImitedEdition is true, then this determines amount of the item initially available. Note that this fieldis ignored if the catalog item already existed in this catalog, or the field is less than 1. /// </summary> public int InitialLimitedEditionCount; @@ -539,7 +601,7 @@ public enum CloudScriptRevisionOption Specific } - public class ConsumeItemRequest + public class ConsumeItemRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -577,7 +639,273 @@ public class ConsumeItemResult : PlayFabResultCommon } - public class CreateSharedGroupRequest + + public enum ContinentCode + { + AF, + AN, + AS, + EU, + NA, + OC, + SA + } + + + public enum CountryCode + { + AF, + AX, + AL, + DZ, + AS, + AD, + AO, + AI, + AQ, + AG, + AR, + AM, + AW, + AU, + AT, + AZ, + BS, + BH, + BD, + BB, + BY, + BE, + BZ, + BJ, + BM, + BT, + BO, + BQ, + BA, + BW, + BV, + BR, + IO, + BN, + BG, + BF, + BI, + KH, + CM, + CA, + CV, + KY, + CF, + TD, + CL, + CN, + CX, + CC, + CO, + KM, + CG, + CD, + CK, + CR, + CI, + HR, + CU, + CW, + CY, + CZ, + DK, + DJ, + DM, + DO, + EC, + EG, + SV, + GQ, + ER, + EE, + ET, + FK, + FO, + FJ, + FI, + FR, + GF, + PF, + TF, + GA, + GM, + GE, + DE, + GH, + GI, + GR, + GL, + GD, + GP, + GU, + GT, + GG, + GN, + GW, + GY, + HT, + HM, + VA, + HN, + HK, + HU, + IS, + IN, + ID, + IR, + IQ, + IE, + IM, + IL, + IT, + JM, + JP, + JE, + JO, + KZ, + KE, + KI, + KP, + KR, + KW, + KG, + LA, + LV, + LB, + LS, + LR, + LY, + LI, + LT, + LU, + MO, + MK, + MG, + MW, + MY, + MV, + ML, + MT, + MH, + MQ, + MR, + MU, + YT, + MX, + FM, + MD, + MC, + MN, + ME, + MS, + MA, + MZ, + MM, + NA, + NR, + NP, + NL, + NC, + NZ, + NI, + NE, + NG, + NU, + NF, + MP, + NO, + OM, + PK, + PW, + PS, + PA, + PG, + PY, + PE, + PH, + PN, + PL, + PT, + PR, + QA, + RE, + RO, + RU, + RW, + BL, + SH, + KN, + LC, + MF, + PM, + VC, + WS, + SM, + ST, + SA, + SN, + RS, + SC, + SL, + SG, + SX, + SK, + SI, + SB, + SO, + ZA, + GS, + SS, + ES, + LK, + SD, + SR, + SJ, + SZ, + SE, + CH, + SY, + TW, + TJ, + TZ, + TH, + TL, + TG, + TK, + TO, + TT, + TN, + TR, + TM, + TC, + TV, + UG, + UA, + AE, + GB, + US, + UM, + UY, + UZ, + VU, + VE, + VN, + VG, + VI, + WF, + EH, + YE, + ZM, + ZW + } + + public class CreateSharedGroupRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group (a random identifier will be assigned, if one is not specified). @@ -762,7 +1090,7 @@ public enum Currency ZWD } - public class DeleteCharacterFromUserRequest + public class DeleteCharacterFromUserRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -785,7 +1113,7 @@ public class DeleteCharacterFromUserResult : PlayFabResultCommon { } - public class DeleteSharedGroupRequest + public class DeleteSharedGroupRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group. @@ -794,7 +1122,7 @@ public class DeleteSharedGroupRequest } - public class DeleteUsersRequest + public class DeleteUsersRequest : PlayFabRequestCommon { /// <summary> /// An array of unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -812,7 +1140,7 @@ public class DeleteUsersResult : PlayFabResultCommon { } - public class DeregisterGameRequest + public class DeregisterGameRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the Game Server Instance that is being deregistered. @@ -829,7 +1157,7 @@ public class EmptyResult : PlayFabResultCommon { } - public class EvaluateRandomResultTableRequest : PlayFabResultCommon + public class EvaluateRandomResultTableRequest : PlayFabRequestCommon { /// <summary> /// The unique identifier of the Random Result Table to use. @@ -900,7 +1228,7 @@ public class ExecuteCloudScriptResult : PlayFabResultCommon } - public class ExecuteCloudScriptServerRequest + public class ExecuteCloudScriptServerRequest : PlayFabRequestCommon { /// <summary> /// The unique user identifier for the player on whose behalf the script is being run @@ -920,7 +1248,6 @@ public class ExecuteCloudScriptServerRequest /// <summary> /// Option for which revision of the CloudScript to execute. 'Latest' executes the most recently created revision, 'Live' executes the current live, published revision, and 'Specific' executes the specified revision. The default value is 'Specific', if the SpeificRevision parameter is specified, otherwise it is 'Live'. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public CloudScriptRevisionOption? RevisionSelection; /// <summary> @@ -1014,7 +1341,7 @@ public class GetActionGroupResult : PlayFabResultCommon } - public class GetAllActionGroupsRequest + public class GetAllActionGroupsRequest : PlayFabRequestCommon { } @@ -1027,7 +1354,7 @@ public class GetAllActionGroupsResult : PlayFabResultCommon } - public class GetAllSegmentsRequest + public class GetAllSegmentsRequest : PlayFabRequestCommon { } @@ -1040,7 +1367,7 @@ public class GetAllSegmentsResult : PlayFabResultCommon } - public class GetCatalogItemsRequest + public class GetCatalogItemsRequest : PlayFabRequestCommon { /// <summary> /// Which catalog is being requested. If null, uses the default catalog. @@ -1059,7 +1386,7 @@ public class GetCatalogItemsResult : PlayFabResultCommon } - public class GetCharacterDataRequest + public class GetCharacterDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1107,7 +1434,7 @@ public class GetCharacterDataResult : PlayFabResultCommon } - public class GetCharacterInventoryRequest + public class GetCharacterInventoryRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1156,7 +1483,7 @@ public class GetCharacterInventoryResult : PlayFabResultCommon } - public class GetCharacterLeaderboardRequest + public class GetCharacterLeaderboardRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID for a specific character owned by a user @@ -1194,7 +1521,7 @@ public class GetCharacterLeaderboardResult : PlayFabResultCommon } - public class GetCharacterStatisticsRequest + public class GetCharacterStatisticsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1227,7 +1554,7 @@ public class GetCharacterStatisticsResult : PlayFabResultCommon } - public class GetContentDownloadUrlRequest + public class GetContentDownloadUrlRequest : PlayFabRequestCommon { /// <summary> /// Key of the content item to fetch, usually formatted as a path, e.g. images/a.png @@ -1255,7 +1582,7 @@ public class GetContentDownloadUrlResult : PlayFabResultCommon } - public class GetFriendLeaderboardRequest + public class GetFriendLeaderboardRequest : PlayFabRequestCommon { /// <summary> /// The player whose friend leaderboard to get @@ -1289,7 +1616,7 @@ public class GetFriendLeaderboardRequest } - public class GetFriendsListRequest + public class GetFriendsListRequest : PlayFabRequestCommon { /// <summary> /// PlayFab identifier of the player whose friend list to get. @@ -1317,7 +1644,7 @@ public class GetFriendsListResult : PlayFabResultCommon } - public class GetLeaderboardAroundCharacterRequest + public class GetLeaderboardAroundCharacterRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title-specific statistic for the leaderboard. @@ -1355,7 +1682,7 @@ public class GetLeaderboardAroundCharacterResult : PlayFabResultCommon } - public class GetLeaderboardAroundUserRequest + public class GetLeaderboardAroundUserRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title-specific statistic for the leaderboard. @@ -1383,7 +1710,7 @@ public class GetLeaderboardAroundUserResult : PlayFabResultCommon } - public class GetLeaderboardForUsersCharactersRequest + public class GetLeaderboardForUsersCharactersRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title-specific statistic for the leaderboard. @@ -1411,7 +1738,7 @@ public class GetLeaderboardForUsersCharactersResult : PlayFabResultCommon } - public class GetLeaderboardRequest + public class GetLeaderboardRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the title-specific statistic for the leaderboard. @@ -1439,7 +1766,7 @@ public class GetLeaderboardResult : PlayFabResultCommon } - public class GetPlayerCombinedInfoRequest + public class GetPlayerCombinedInfoRequest : PlayFabRequestCommon { /// <summary> /// PlayFabId of the user whose data will be returned @@ -1536,7 +1863,7 @@ public class GetPlayerCombinedInfoResult : PlayFabResultCommon } - public class GetPlayerCombinedInfoResultPayload : PlayFabResultCommon + public class GetPlayerCombinedInfoResultPayload { /// <summary> /// Account information for the user. This is always retrieved. @@ -1610,7 +1937,7 @@ public class GetPlayerSegmentsResult : PlayFabResultCommon } - public class GetPlayersInSegmentRequest + public class GetPlayersInSegmentRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for this segment. @@ -1653,7 +1980,7 @@ public class GetPlayersInSegmentResult : PlayFabResultCommon } - public class GetPlayersSegmentsRequest + public class GetPlayersSegmentsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1662,7 +1989,7 @@ public class GetPlayersSegmentsRequest } - public class GetPlayerStatisticsRequest + public class GetPlayerStatisticsRequest : PlayFabRequestCommon { /// <summary> /// user for whom statistics are being requested @@ -1695,7 +2022,7 @@ public class GetPlayerStatisticsResult : PlayFabResultCommon } - public class GetPlayerStatisticVersionsRequest + public class GetPlayerStatisticVersionsRequest : PlayFabRequestCommon { /// <summary> /// unique name of the statistic @@ -1713,7 +2040,7 @@ public class GetPlayerStatisticVersionsResult : PlayFabResultCommon } - public class GetPlayerTagsRequest + public class GetPlayerTagsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1741,7 +2068,7 @@ public class GetPlayerTagsResult : PlayFabResultCommon } - public class GetPlayFabIDsFromFacebookIDsRequest + public class GetPlayFabIDsFromFacebookIDsRequest : PlayFabRequestCommon { /// <summary> /// Array of unique Facebook identifiers for which the title needs to get PlayFab identifiers. @@ -1759,7 +2086,7 @@ public class GetPlayFabIDsFromFacebookIDsResult : PlayFabResultCommon } - public class GetPlayFabIDsFromSteamIDsRequest + public class GetPlayFabIDsFromSteamIDsRequest : PlayFabRequestCommon { /// <summary> /// Array of unique Steam identifiers (Steam profile IDs) for which the title needs to get PlayFab identifiers. @@ -1777,7 +2104,7 @@ public class GetPlayFabIDsFromSteamIDsResult : PlayFabResultCommon } - public class GetPublisherDataRequest + public class GetPublisherDataRequest : PlayFabRequestCommon { /// <summary> /// array of keys to get back data from the Publisher data blob, set by the admin tools @@ -1795,7 +2122,7 @@ public class GetPublisherDataResult : PlayFabResultCommon } - public class GetRandomResultTablesRequest : PlayFabResultCommon + public class GetRandomResultTablesRequest : PlayFabRequestCommon { /// <summary> /// Specifies the catalog version that should be used to retrieve the Random Result Tables. If unspecified, uses default/primary catalog. @@ -1837,7 +2164,7 @@ public class GetSegmentResult : PlayFabResultCommon } - public class GetSharedGroupDataRequest + public class GetSharedGroupDataRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group. @@ -1870,7 +2197,7 @@ public class GetSharedGroupDataResult : PlayFabResultCommon } - public class GetTimeRequest + public class GetTimeRequest : PlayFabRequestCommon { } @@ -1883,7 +2210,7 @@ public class GetTimeResult : PlayFabResultCommon } - public class GetTitleDataRequest + public class GetTitleDataRequest : PlayFabRequestCommon { /// <summary> /// Specific keys to search for in the title data (leave null to get all keys) @@ -1901,7 +2228,7 @@ public class GetTitleDataResult : PlayFabResultCommon } - public class GetTitleNewsRequest + public class GetTitleNewsRequest : PlayFabRequestCommon { /// <summary> /// Limits the results to the last n entries. Defaults to 10 if not set. @@ -1919,7 +2246,7 @@ public class GetTitleNewsResult : PlayFabResultCommon } - public class GetUserAccountInfoRequest + public class GetUserAccountInfoRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1937,7 +2264,7 @@ public class GetUserAccountInfoResult : PlayFabResultCommon } - public class GetUserBansRequest + public class GetUserBansRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1955,7 +2282,7 @@ public class GetUserBansResult : PlayFabResultCommon } - public class GetUserDataRequest + public class GetUserDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -1993,7 +2320,7 @@ public class GetUserDataResult : PlayFabResultCommon } - public class GetUserInventoryRequest + public class GetUserInventoryRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2027,7 +2354,7 @@ public class GetUserInventoryResult : PlayFabResultCommon } - public class GrantCharacterToUserRequest + public class GrantCharacterToUserRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2159,7 +2486,7 @@ public int CompareTo(GrantedItemInstance other) } - public class GrantItemsToCharacterRequest + public class GrantItemsToCharacterRequest : PlayFabRequestCommon { /// <summary> /// Catalog version from which items are to be granted. @@ -2197,7 +2524,7 @@ public class GrantItemsToCharacterResult : PlayFabResultCommon } - public class GrantItemsToUserRequest + public class GrantItemsToUserRequest : PlayFabRequestCommon { /// <summary> /// Catalog version from which items are to be granted. @@ -2230,7 +2557,7 @@ public class GrantItemsToUserResult : PlayFabResultCommon } - public class GrantItemsToUsersRequest + public class GrantItemsToUsersRequest : PlayFabRequestCommon { /// <summary> /// Catalog version from which items are to be granted. @@ -2377,7 +2704,7 @@ public int CompareTo(ItemInstance other) } - public class ListUsersCharactersRequest + public class ListUsersCharactersRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2443,7 +2770,7 @@ public class ModifyCharacterVirtualCurrencyResult : PlayFabResultCommon } - public class ModifyItemUsesRequest + public class ModifyItemUsesRequest : PlayFabRequestCommon { /// <summary> /// PlayFab unique identifier of the user whose item is being modified. @@ -2500,7 +2827,7 @@ public class ModifyUserVirtualCurrencyResult : PlayFabResultCommon } - public class MoveItemToCharacterFromCharacterRequest + public class MoveItemToCharacterFromCharacterRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2528,7 +2855,7 @@ public class MoveItemToCharacterFromCharacterResult : PlayFabResultCommon { } - public class MoveItemToCharacterFromUserRequest + public class MoveItemToCharacterFromUserRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2551,7 +2878,7 @@ public class MoveItemToCharacterFromUserResult : PlayFabResultCommon { } - public class MoveItemToUserFromCharacterRequest + public class MoveItemToUserFromCharacterRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -2574,7 +2901,18 @@ public class MoveItemToUserFromCharacterResult : PlayFabResultCommon { } - public class NotifyMatchmakerPlayerLeftRequest + /// <summary> + /// Identifier by either name or ID. Note that a name may change due to renaming, or reused after being deleted. ID is immutable and unique. + /// </summary> + public class NameIdentifier + { + public string Name; + + public string Id; + + } + + public class NotifyMatchmakerPlayerLeftRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier of the Game Instance the user is leaving. @@ -2593,7 +2931,6 @@ public class NotifyMatchmakerPlayerLeftResult : PlayFabResultCommon /// <summary> /// State of user leaving the Game Server Instance. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public PlayerConnectionState? PlayerState; } @@ -2636,7 +2973,6 @@ public class PlayerLinkedAccount /// <summary> /// Authentication platform /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public LoginIdentityProvider? Platform; /// <summary> @@ -2656,6 +2992,35 @@ public class PlayerLinkedAccount } + public class PlayerLocation + { + /// <summary> + /// The two-character continent code for this location + /// </summary> + public ContinentCode ContinentCode; + + /// <summary> + /// The two-character ISO 3166-1 country code for the country associated with the location + /// </summary> + public CountryCode CountryCode; + + /// <summary> + /// City of the player's geographic location. + /// </summary> + public string City; + + /// <summary> + /// Latitude coordinate of the player's geographic location. + /// </summary> + public double? Latitude; + + /// <summary> + /// Longitude coordinate of the player's geographic location. + /// </summary> + public double? Longitude; + + } + public class PlayerProfile { /// <summary> @@ -2681,7 +3046,6 @@ public class PlayerProfile /// <summary> /// Player account origination /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public LoginIdentityProvider? Origination; /// <summary> @@ -2719,6 +3083,11 @@ public class PlayerProfile /// </summary> public List<string> Tags; + /// <summary> + /// Dictionary of player's locations by type. + /// </summary> + public Dictionary<string,PlayerLocation> Locations; + /// <summary> /// Dictionary of player's virtual currency balances /// </summary> @@ -2816,7 +3185,6 @@ public class PushNotificationRegistration /// <summary> /// Push notification platform /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public PushNotificationPlatform? Platform; /// <summary> @@ -2826,7 +3194,7 @@ public class PushNotificationRegistration } - public class RandomResultTableListing : PlayFabResultCommon + public class RandomResultTableListing { /// <summary> /// Catalog version this table is associated with @@ -2845,7 +3213,7 @@ public class RandomResultTableListing : PlayFabResultCommon } - public class RedeemCouponRequest + public class RedeemCouponRequest : PlayFabRequestCommon { /// <summary> /// Generated coupon code to redeem. @@ -2862,6 +3230,11 @@ public class RedeemCouponRequest /// </summary> public string CatalogVersion; + /// <summary> + /// Optional identifier for the Character that should receive the item. If null, item is added to the player + /// </summary> + public string CharacterId; + } public class RedeemCouponResult : PlayFabResultCommon @@ -2873,7 +3246,7 @@ public class RedeemCouponResult : PlayFabResultCommon } - public class RedeemMatchmakerTicketRequest + public class RedeemMatchmakerTicketRequest : PlayFabRequestCommon { /// <summary> /// Server authorization ticket passed back from a call to Matchmake or StartGame. @@ -2906,7 +3279,7 @@ public class RedeemMatchmakerTicketResult : PlayFabResultCommon } - public class RefreshGameServerInstanceHeartbeatRequest + public class RefreshGameServerInstanceHeartbeatRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier of the Game Server Instance for which the heartbeat is updated. @@ -2931,7 +3304,7 @@ public enum Region Australia } - public class RegisterGameRequest + public class RegisterGameRequest : PlayFabRequestCommon { /// <summary> /// IP address of the Game Server Instance. @@ -2951,7 +3324,6 @@ public class RegisterGameRequest /// <summary> /// Region in which the Game Server Instance is running. For matchmaking using non-AWS region names, set this to any AWS region and use Tags (below) to specify your custom region. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Region Region; /// <summary> @@ -2975,7 +3347,7 @@ public class RegisterGameResponse : PlayFabResultCommon } - public class RemoveFriendRequest + public class RemoveFriendRequest : PlayFabRequestCommon { /// <summary> /// PlayFab identifier of the friend account which is to be removed. @@ -2989,7 +3361,7 @@ public class RemoveFriendRequest } - public class RemovePlayerTagRequest + public class RemovePlayerTagRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3007,7 +3379,7 @@ public class RemovePlayerTagResult : PlayFabResultCommon { } - public class RemoveSharedGroupMembersRequest + public class RemoveSharedGroupMembersRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group. @@ -3025,7 +3397,7 @@ public class RemoveSharedGroupMembersResult : PlayFabResultCommon { } - public class ReportPlayerServerRequest + public class ReportPlayerServerRequest : PlayFabRequestCommon { /// <summary> /// PlayFabId of the reporting player. @@ -3063,12 +3435,11 @@ public class ReportPlayerServerResult : PlayFabResultCommon } - public class ResultTableNode : PlayFabResultCommon + public class ResultTableNode { /// <summary> /// Whether this entry in the table is an item or a link to another table /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public ResultTableNodeType ResultItemType; /// <summary> @@ -3090,7 +3461,7 @@ public enum ResultTableNodeType TableId } - public class RevokeAllBansForUserRequest + public class RevokeAllBansForUserRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3108,7 +3479,7 @@ public class RevokeAllBansForUserResult : PlayFabResultCommon } - public class RevokeBansRequest + public class RevokeBansRequest : PlayFabRequestCommon { /// <summary> /// Ids of the bans to be revoked. Maximum 100. @@ -3126,7 +3497,7 @@ public class RevokeBansResult : PlayFabResultCommon } - public class RevokeInventoryItemRequest + public class RevokeInventoryItemRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3168,7 +3539,7 @@ public class ScriptExecutionError } - public class SendPushNotificationRequest + public class SendPushNotificationRequest : PlayFabRequestCommon { /// <summary> /// PlayFabId of the recipient of the push notification. @@ -3191,7 +3562,7 @@ public class SendPushNotificationResult : PlayFabResultCommon { } - public class SetGameServerInstanceDataRequest + public class SetGameServerInstanceDataRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier of the Game Instance to be updated. @@ -3209,7 +3580,7 @@ public class SetGameServerInstanceDataResult : PlayFabResultCommon { } - public class SetGameServerInstanceStateRequest + public class SetGameServerInstanceStateRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier of the Game Instance to be updated. @@ -3219,7 +3590,6 @@ public class SetGameServerInstanceStateRequest /// <summary> /// State to set for the specified game server instance. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public GameInstanceState State; } @@ -3228,7 +3598,7 @@ public class SetGameServerInstanceStateResult : PlayFabResultCommon { } - public class SetGameServerInstanceTagsRequest + public class SetGameServerInstanceTagsRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier of the Game Server Instance to be updated. @@ -3246,7 +3616,7 @@ public class SetGameServerInstanceTagsResult : PlayFabResultCommon { } - public class SetPublisherDataRequest + public class SetPublisherDataRequest : PlayFabRequestCommon { /// <summary> /// key we want to set a value on (note, this is additive - will only replace an existing key's value if they are the same name.) Keys are trimmed of whitespace. Keys may not begin with the '!' character. @@ -3264,7 +3634,7 @@ public class SetPublisherDataResult : PlayFabResultCommon { } - public class SetTitleDataRequest + public class SetTitleDataRequest : PlayFabRequestCommon { /// <summary> /// key we want to set a value on (note, this is additive - will only replace an existing key's value if they are the same name.) Keys are trimmed of whitespace. Keys may not begin with the '!' character. @@ -3302,7 +3672,6 @@ public class SharedGroupDataRecord /// <summary> /// Indicates whether this data can be read by all users (public) or only members of the group (private). /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -3373,7 +3742,7 @@ public class SteamPlayFabIdPair } - public class SubtractCharacterVirtualCurrencyRequest + public class SubtractCharacterVirtualCurrencyRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3397,7 +3766,7 @@ public class SubtractCharacterVirtualCurrencyRequest } - public class SubtractUserVirtualCurrencyRequest + public class SubtractUserVirtualCurrencyRequest : PlayFabRequestCommon { /// <summary> /// PlayFab unique identifier of the user whose virtual currency balance is to be decreased. @@ -3417,6 +3786,17 @@ public class SubtractUserVirtualCurrencyRequest } + public enum TaskInstanceStatus + { + Succeeded, + Starting, + InProgress, + Failed, + Aborted, + Pending + } + + public enum TitleActivationStatus { None, @@ -3450,7 +3830,7 @@ public class TitleNewsItem } - public class UnlockContainerInstanceRequest + public class UnlockContainerInstanceRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3479,7 +3859,7 @@ public class UnlockContainerInstanceRequest } - public class UnlockContainerItemRequest + public class UnlockContainerItemRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3530,7 +3910,7 @@ public class UnlockContainerItemResult : PlayFabResultCommon /// <summary> /// Represents a single update ban request. /// </summary> - public class UpdateBanRequest + public class UpdateBanRequest : PlayFabRequestCommon { /// <summary> /// The id of the ban to be updated. @@ -3569,7 +3949,7 @@ public class UpdateBanRequest } - public class UpdateBansRequest + public class UpdateBansRequest : PlayFabRequestCommon { /// <summary> /// List of bans to be updated. Maximum 100. @@ -3587,7 +3967,7 @@ public class UpdateBansResult : PlayFabResultCommon } - public class UpdateCharacterDataRequest + public class UpdateCharacterDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3612,7 +3992,6 @@ public class UpdateCharacterDataRequest /// <summary> /// Permission to be applied to all user data keys written in this request. Defaults to "private" if not set. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -3626,7 +4005,7 @@ public class UpdateCharacterDataResult : PlayFabResultCommon } - public class UpdateCharacterStatisticsRequest + public class UpdateCharacterStatisticsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3649,7 +4028,7 @@ public class UpdateCharacterStatisticsResult : PlayFabResultCommon { } - public class UpdatePlayerStatisticsRequest + public class UpdatePlayerStatisticsRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3661,13 +4040,18 @@ public class UpdatePlayerStatisticsRequest /// </summary> public List<StatisticUpdate> Statistics; + /// <summary> + /// Indicates whether the statistics provided should be set, regardless of the aggregation method set on the statistic. Default is false. + /// </summary> + public bool? ForceUpdate; + } public class UpdatePlayerStatisticsResult : PlayFabResultCommon { } - public class UpdateSharedGroupDataRequest + public class UpdateSharedGroupDataRequest : PlayFabRequestCommon { /// <summary> /// Unique identifier for the shared group. @@ -3687,7 +4071,6 @@ public class UpdateSharedGroupDataRequest /// <summary> /// Permission to be applied to all user data keys in this request. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -3696,7 +4079,7 @@ public class UpdateSharedGroupDataResult : PlayFabResultCommon { } - public class UpdateUserDataRequest + public class UpdateUserDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3716,7 +4099,6 @@ public class UpdateUserDataRequest /// <summary> /// Permission to be applied to all user data keys written in this request. Defaults to "private" if not set. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -3730,7 +4112,7 @@ public class UpdateUserDataResult : PlayFabResultCommon } - public class UpdateUserInternalDataRequest + public class UpdateUserInternalDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3749,7 +4131,7 @@ public class UpdateUserInternalDataRequest } - public class UpdateUserInventoryItemDataRequest + public class UpdateUserInventoryItemDataRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -3905,7 +4287,6 @@ public class UserDataRecord /// <summary> /// Indicates whether this data can be read by all users (public) or only the user (private). This is used for GetUserData requests being made by one player about another player. /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserDataPermission? Permission; } @@ -4040,13 +4421,11 @@ public class UserSteamInfo /// <summary> /// currency type set in the user Steam account /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public Currency? SteamCurrency; /// <summary> /// what stage of game ownership the user is listed as being in, from Steam /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public TitleActivationStatus? SteamActivationStatus; } @@ -4061,7 +4440,6 @@ public class UserTitleInfo /// <summary> /// source by which the user first joined the game, if known /// </summary> - [JsonConverter(typeof(StringEnumConverter))] public UserOrigination? Origination; /// <summary> @@ -4131,13 +4509,13 @@ public class VirtualCurrencyRechargeTime public class WriteEventResponse : PlayFabResultCommon { /// <summary> - /// The unique identifier of the event. This can be used to retrieve the event's properties using the GetEvent API. The values of this identifier consist of ASCII characters and are not constrained to any particular format. + /// The unique identifier of the event. The values of this identifier consist of ASCII characters and are not constrained to any particular format. /// </summary> public string EventId; } - public class WriteServerCharacterEventRequest + public class WriteServerCharacterEventRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -4166,7 +4544,7 @@ public class WriteServerCharacterEventRequest } - public class WriteServerPlayerEventRequest + public class WriteServerPlayerEventRequest : PlayFabRequestCommon { /// <summary> /// Unique PlayFab assigned ID of the user on whom the operation will be performed. @@ -4190,7 +4568,7 @@ public class WriteServerPlayerEventRequest } - public class WriteTitleEventRequest + public class WriteTitleEventRequest : PlayFabRequestCommon { /// <summary> /// The name of the event, within the namespace scoped to the title. The naming convention is up to the caller, but it commonly follows the subject_verb_object pattern (e.g. player_logged_in). diff --git a/PlayFabServerSDK/source/PlayFabSettings.cs b/PlayFabServerSDK/source/PlayFabSettings.cs index 7b345c18..27f979b1 100644 --- a/PlayFabServerSDK/source/PlayFabSettings.cs +++ b/PlayFabServerSDK/source/PlayFabSettings.cs @@ -1,13 +1,11 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; namespace PlayFab { public class PlayFabSettings { - public const string SdkVersion = "0.40.161017"; + public const string SdkVersion = "1.0.161107"; public const string BuildIdentifier = "jbuild_csharpsdk_1"; - public const string SdkVersionString = "CSharpSDK-0.40.161017"; + public const string SdkVersionString = "CSharpSDK-1.0.161107"; /// <summary> This is for PlayFab internal debugging. Generally you shouldn't touch this </summary> public static bool UseDevelopmentEnvironment = false; @@ -25,7 +23,7 @@ public class PlayFabSettings public static string GetFullUrl(string apiCall) { - string baseUrl = UseDevelopmentEnvironment ? DevelopmentEnvironmentUrl : ProductionEnvironmentUrl; + var baseUrl = UseDevelopmentEnvironment ? DevelopmentEnvironmentUrl : ProductionEnvironmentUrl; if (baseUrl.StartsWith("http")) return baseUrl; return "https://" + TitleId + baseUrl + apiCall; diff --git a/PlayFabServerSDK/source/PlayFabUtil.cs b/PlayFabServerSDK/source/PlayFabUtil.cs index 283fff71..51a3870c 100644 --- a/PlayFabServerSDK/source/PlayFabUtil.cs +++ b/PlayFabServerSDK/source/PlayFabUtil.cs @@ -1,7 +1,8 @@ +using PlayFab.Json; using System; +using System.IO; using System.Text; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; +using System.Threading.Tasks; using PlayFab.ServerModels; namespace PlayFab @@ -19,7 +20,7 @@ public Unordered(string sortProperty) } } - public static class PlayFabUtil + public static partial class PlayFabUtil { public static readonly string[] DefaultDateTimeFormats = { // All parseable ISO 8601 formats for DateTime.[Try]ParseExact - Lets us deserialize any legacy timestamps in one of these formats // These are the standard format with ISO 8601 UTC markers (T/Z) @@ -38,32 +39,13 @@ public static class PlayFabUtil }; public const int DEFAULT_UTC_OUTPUT_INDEX = 2; // The default format everybody should use public const int DEFAULT_LOCAL_OUTPUT_INDEX = 7; // The default format if you want to use local time (This doesn't have universal support in all PlayFab code) - public static JsonSerializerSettings JsonSettings = new JsonSerializerSettings - { - NullValueHandling = NullValueHandling.Ignore, - Converters = { new IsoDateTimeConverter { DateTimeFormat = DefaultDateTimeFormats[0] } }, - }; - public static Formatting JsonFormatting = Formatting.None; - private static readonly StringBuilder Sb = new StringBuilder(); public static string GetErrorReport(PlayFabError error) { - if (error == null) - return null; - Sb.Length = 0; - if (error.ErrorMessage != null) - Sb.Append(error.ErrorMessage); - if (error.ErrorDetails == null) - return Sb.ToString(); - - foreach (var pair in error.ErrorDetails) - { - foreach (var eachMsg in pair.Value) - Sb.Append(pair.Key).Append(": ").Append(eachMsg); - } - return Sb.ToString(); + return error?.GenerateErrorReport(); } + private static readonly StringBuilder Sb = new StringBuilder(); public static string GetCloudScriptErrorReport(PlayFabResult<ExecuteCloudScriptResult> result) { if (result.Error != null) @@ -89,28 +71,9 @@ public static string GetCloudScriptErrorReport(PlayFabResult<ExecuteCloudScriptR if (!string.IsNullOrEmpty(eachLog.Message)) Sb.Append(" - ").Append(eachLog.Message); if (eachLog.Data != null) - Sb.Append("\n").Append(JsonConvert.SerializeObject(eachLog.Data, Formatting.Indented)); + Sb.Append("\n").Append(JsonWrapper.SerializeObject(eachLog.Data)); } return Sb.ToString(); } - - public class TimeSpanFloatSeconds : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - var timeSpan = (TimeSpan)value; - serializer.Serialize(writer, timeSpan.TotalSeconds); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - return TimeSpan.FromSeconds(serializer.Deserialize<float>(reader)); - } - - public override bool CanConvert(Type objectType) - { - return objectType == typeof(TimeSpan); - } - } } } diff --git a/PlayFabServerSDK/source/Uunit/PlayFabApiTest.cs b/PlayFabServerSDK/source/Uunit/PlayFabApiTest.cs new file mode 100644 index 00000000..14b0a3e3 --- /dev/null +++ b/PlayFabServerSDK/source/Uunit/PlayFabApiTest.cs @@ -0,0 +1,431 @@ +#if !DISABLE_PLAYFABCLIENT_API + +using PlayFab.ClientModels; +using PlayFab.Internal; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using PlayFab.Json; + +namespace PlayFab.UUnit +{ + /// <summary> + /// A real system would potentially run only the client or server API, and not both. + /// But, they still interact with eachother directly. + /// The tests can't be independent for Client/Server, as the sequence of calls isn't really independent for real-world scenarios. + /// The client logs in, which triggers a server, and then back and forth. + /// For the purpose of testing, they each have pieces of information they share with one another, and that sharing makes various calls possible. + /// </summary> + public class PlayFabApiTest : UUnitTestCase + { + private const string TEST_STAT_NAME = "str"; + private const string TEST_DATA_KEY = "testCounter"; + + private int _testInteger; + + // Functional + private static bool TITLE_INFO_SET = false; + + // Fixed values provided from testInputs + private static string USER_EMAIL; + + // Information fetched by appropriate API calls + public static string PlayFabId; + + // Performance + [ThreadStatic] + private static StringBuilder _sb; + + /// <summary> + /// PlayFab Title cannot be created from SDK tests, so you must provide your titleId to run unit tests. + /// (Also, we don't want lots of excess unused titles) + /// </summary> + public static void SetTitleInfo(Dictionary<string, string> testInputs) + { + string eachValue; + + TITLE_INFO_SET = true; + + // Parse all the inputs + TITLE_INFO_SET &= testInputs.TryGetValue("titleId", out eachValue); + PlayFabSettings.TitleId = eachValue; + + TITLE_INFO_SET &= testInputs.TryGetValue("userEmail", out USER_EMAIL); + + // Verify all the inputs won't cause crashes in the tests + TITLE_INFO_SET &= !string.IsNullOrEmpty(PlayFabSettings.TitleId) + && !string.IsNullOrEmpty(USER_EMAIL); + } + + public override void SetUp(UUnitTestContext testContext) + { + if (!TITLE_INFO_SET) + testContext.Skip(); // We cannot do client tests if the titleId is not given + } + + public override void Tick(UUnitTestContext testContext) + { + // No work needed, async tests will end themselves + } + + public override void TearDown(UUnitTestContext testContext) + { + } + + private static void ContinueWithContext<T>(Task<PlayFabResult<T>> srcTask, UUnitTestContext testContext, Action<PlayFabResult<T>, UUnitTestContext, string> continueAction, bool expectSuccess, string failMessage, bool endTest) where T : PlayFabResultCommon + { + srcTask.ContinueWith(task => + { + var failed = true; + try + { + if (expectSuccess) + { + testContext.NotNull(task.Result, failMessage); + testContext.IsNull(task.Result.Error, PlayFabUtil.GetErrorReport(task.Result.Error)); + testContext.NotNull(task.Result.Result, failMessage); + } + continueAction?.Invoke(task.Result, testContext, failMessage); + failed = false; + } + catch (UUnitSkipException uu) + { + // Silence the assert and ensure the test is marked as complete - The exception is just to halt the test process + testContext.EndTest(UUnitFinishState.SKIPPED, uu.Message); + } + catch (UUnitException uu) + { + // Silence the assert and ensure the test is marked as complete - The exception is just to halt the test process + testContext.EndTest(UUnitFinishState.FAILED, uu.Message + "\n" + uu.StackTrace); + } + catch (Exception e) + { + // Report this exception as an unhandled failure in the test + testContext.EndTest(UUnitFinishState.FAILED, e.ToString()); + } + if (!failed && endTest) + testContext.EndTest(UUnitFinishState.PASSED, null); + } + ); + } + + private static string CompileErrorReport(PlayFabError error) + { + if (_sb == null) + _sb = new StringBuilder(); + _sb.Length = 0; + _sb.Append(error.ErrorMessage); + foreach (var detailPair in error.ErrorDetails) + foreach (var msg in detailPair.Value) + _sb.Append("\n").Append(detailPair.Key).Append(": ").Append(msg); + return _sb.ToString(); + } + + /// <summary> + /// CLIENT API + /// Try to deliberately log in with an inappropriate password, + /// and verify that the error displays as expected. + /// </summary> + [UUnitTest] + public void InvalidLogin(UUnitTestContext testContext) + { + // If the setup failed to log in a user, we need to create one. + var request = new LoginWithEmailAddressRequest + { + TitleId = PlayFabSettings.TitleId, + Email = USER_EMAIL, + Password = "INVALID", + }; + var loginTask = PlayFabClientAPI.LoginWithEmailAddressAsync(request); + ContinueWithContext(loginTask, testContext, InvalidLoginContinued, false, "Login should fail", true); + } + private void InvalidLoginContinued(PlayFabResult<LoginResult> loginResult, UUnitTestContext testContext, string failMessage) + { + testContext.NotNull(loginResult, failMessage); + testContext.IsNull(loginResult.Result, failMessage); + testContext.NotNull(loginResult.Error, failMessage); + testContext.True(loginResult.Error.ErrorMessage.Contains("password"), loginResult.Error.ErrorMessage); + } + + /// <summary> + /// CLIENT API + /// Try to deliberately register a user with an invalid email and password + /// Verify that errorDetails are populated correctly. + /// </summary> + [UUnitTest] + public void InvalidRegistration(UUnitTestContext testContext) + { + var registerRequest = new RegisterPlayFabUserRequest + { + TitleId = PlayFabSettings.TitleId, + Username = "x", + Email = "x", + Password = "x", + }; + var registerTask = PlayFabClientAPI.RegisterPlayFabUserAsync(registerRequest); + ContinueWithContext(registerTask, testContext, InvalidRegistrationContinued, false, "Registration should fail", true); + } + private void InvalidRegistrationContinued(PlayFabResult<RegisterPlayFabUserResult> registerResult, UUnitTestContext testContext, string failMessage) + { + testContext.NotNull(registerResult, failMessage); + testContext.IsNull(registerResult.Result, failMessage); + testContext.NotNull(registerResult.Error, failMessage); + + var expectedEmailMsg = "email address is not valid."; + var expectedPasswordMsg = "password must be between"; + var fullReport = CompileErrorReport(registerResult.Error); + + testContext.True(fullReport.ToLower().Contains(expectedEmailMsg), "Expected an error about bad email address: " + fullReport); + testContext.True(fullReport.ToLower().Contains(expectedPasswordMsg), "Expected an error about bad password: " + fullReport); + } + + /// <summary> + /// CLIENT API + /// Log in or create a user, track their PlayFabId + /// </summary> + [UUnitTest] + public void LoginOrRegister(UUnitTestContext testContext) + { + var loginRequest = new LoginWithCustomIDRequest + { + TitleId = PlayFabSettings.TitleId, + CustomId = PlayFabSettings.BuildIdentifier, + CreateAccount = true + }; + var loginTask = PlayFabClientAPI.LoginWithCustomIDAsync(loginRequest); + ContinueWithContext(loginTask, testContext, LoginOrRegisterContinued, true, "User login failed", true); + } + private void LoginOrRegisterContinued(PlayFabResult<LoginResult> loginResult, UUnitTestContext testContext, string failMessage) + { + PlayFabId = loginResult.Result.PlayFabId; // Needed for subsequent tests + testContext.True(PlayFabClientAPI.IsClientLoggedIn(), "User login failed"); + } + + /// <summary> + /// CLIENT API + /// Test that the login call sequence sends the AdvertisingId when set + /// </summary> + [UUnitTest] + public void LoginWithAdvertisingId(UUnitTestContext testContext) + { + PlayFabSettings.AdvertisingIdType = PlayFabSettings.AD_TYPE_ANDROID_ID; + PlayFabSettings.AdvertisingIdValue = "PlayFabTestId"; + + var loginRequest = new LoginWithCustomIDRequest + { + TitleId = PlayFabSettings.TitleId, + CustomId = PlayFabSettings.BuildIdentifier, + CreateAccount = true + }; + var loginTask = PlayFabClientAPI.LoginWithCustomIDAsync(loginRequest); + ContinueWithContext(loginTask, testContext, LoginWithAdvertisingIdContinued, true, "Login with advertId failed", true); + } + private void LoginWithAdvertisingIdContinued(PlayFabResult<LoginResult> loginResult, UUnitTestContext testContext, string failMessage) + { + PlayFabId = loginResult.Result.PlayFabId; // Needed for subsequent tests + testContext.True(PlayFabClientAPI.IsClientLoggedIn(), "User login failed"); + + testContext.StringEquals(PlayFabSettings.AD_TYPE_ANDROID_ID + "_Successful", PlayFabSettings.AdvertisingIdType); + } + + /// <summary> + /// CLIENT API + /// Test a sequence of calls that modifies saved data, + /// and verifies that the next sequential API call contains updated data. + /// Verify that the data is correctly modified on the next call. + /// Parameter types tested: string, Dictionary>string, string>, DateTime + /// </summary> + [UUnitTest] + public void UserDataApi(UUnitTestContext testContext) + { + var getRequest = new GetUserDataRequest(); + var getDataTask1 = PlayFabClientAPI.GetUserDataAsync(getRequest); + ContinueWithContext(getDataTask1, testContext, UserDataApiContinued1, true, "GetUserData1 call failed", false); + } + private void UserDataApiContinued1(PlayFabResult<GetUserDataResult> getDataResult1, UUnitTestContext testContext, string failMessage) + { + UserDataRecord testCounter; + if (!getDataResult1.Result.Data.TryGetValue(TEST_DATA_KEY, out testCounter)) + testCounter = new UserDataRecord { Value = "0" }; + int.TryParse(testCounter.Value, out _testInteger); + _testInteger = (_testInteger + 1) % 100; // This test is about the expected value changing - but not testing more complicated issues like bounds + + var updateRequest = new UpdateUserDataRequest { Data = new Dictionary<string, string> { { TEST_DATA_KEY, _testInteger.ToString() } } }; + var updateTask = PlayFabClientAPI.UpdateUserDataAsync(updateRequest); + ContinueWithContext(updateTask, testContext, UserDataApiContinued2, true, "UpdateUserData call failed", false); // The update doesn't return anything interesting except versionID. It's better to just re-call GetUserData again below to verify the update + } + private void UserDataApiContinued2(PlayFabResult<UpdateUserDataResult> updateResult, UUnitTestContext testContext, string failMessage) + { + var getRequest = new GetUserDataRequest(); + var getDataTask2 = PlayFabClientAPI.GetUserDataAsync(getRequest); + ContinueWithContext(getDataTask2, testContext, UserDataApiContinued3, true, "GetUserData2 call failed", true); + } + private void UserDataApiContinued3(PlayFabResult<GetUserDataResult> getDataResult2, UUnitTestContext testContext, string failMessage) + { + int testCounterValueActual; + UserDataRecord testCounter; + getDataResult2.Result.Data.TryGetValue(TEST_DATA_KEY, out testCounter); + testContext.NotNull(testCounter, "The updated UserData was not found in the Api results"); + int.TryParse(testCounter.Value, out testCounterValueActual); + testContext.IntEquals(_testInteger, testCounterValueActual); + + var timeUpdated = testCounter.LastUpdated; + var testMin = DateTime.UtcNow - TimeSpan.FromMinutes(5); + var testMax = testMin + TimeSpan.FromMinutes(10); + testContext.True(testMin <= timeUpdated && timeUpdated <= testMax); + } + + /// <summary> + /// CLIENT API + /// Test a sequence of calls that modifies saved data, + /// and verifies that the next sequential API call contains updated data. + /// Verify that the data is saved correctly, and that specific types are tested + /// Parameter types tested: Dictionary>string, int> + /// </summary> + [UUnitTest] + public void PlayerStatisticsApi(UUnitTestContext testContext) + { + var getRequest = new GetPlayerStatisticsRequest(); + var getStatTask1 = PlayFabClientAPI.GetPlayerStatisticsAsync(getRequest); + ContinueWithContext(getStatTask1, testContext, PlayerStatisticsApiContinued1, true, "GetPlayerStatistics1 call failed", false); + } + private void PlayerStatisticsApiContinued1(PlayFabResult<GetPlayerStatisticsResult> getStatResult1, UUnitTestContext testContext, string failMessage) + { + foreach (var eachStat in getStatResult1.Result.Statistics) + if (eachStat.StatisticName == TEST_STAT_NAME) + _testInteger = eachStat.Value; + _testInteger = (_testInteger + 1) % 100; // This test is about the expected value changing (incrementing through from TEST_STAT_BASE to TEST_STAT_BASE * 2 - 1) + + var updateRequest = new UpdatePlayerStatisticsRequest { Statistics = new List<StatisticUpdate> { new StatisticUpdate { StatisticName = TEST_STAT_NAME, Value = _testInteger } } }; + var updateTask = PlayFabClientAPI.UpdatePlayerStatisticsAsync(updateRequest); + ContinueWithContext(updateTask, testContext, PlayerStatisticsApiContinued2, true, "UpdatePlayerStatistics call failed", false); + } + private void PlayerStatisticsApiContinued2(PlayFabResult<UpdatePlayerStatisticsResult> updateResult, UUnitTestContext testContext, string failMessage) + { + var getRequest = new GetPlayerStatisticsRequest(); + var getStatTask2 = PlayFabClientAPI.GetPlayerStatisticsAsync(getRequest); + ContinueWithContext(getStatTask2, testContext, PlayerStatisticsApiContinued3, true, "GetPlayerStatistics2 call failed", true); + } + private void PlayerStatisticsApiContinued3(PlayFabResult<GetPlayerStatisticsResult> getStatResult2, UUnitTestContext testContext, string failMessage) + { + var testStatActual = int.MinValue; + foreach (var eachStat in getStatResult2.Result.Statistics) + if (eachStat.StatisticName == TEST_STAT_NAME) + testStatActual = eachStat.Value; + testContext.IntEquals(_testInteger, testStatActual); + } + + /// <summary> + /// SERVER API + /// Get or create the given test character for the given user + /// Parameter types tested: Contained-Classes, string + /// </summary> + [UUnitTest] + public void UserCharacter(UUnitTestContext testContext) + { + var request = new ListUsersCharactersRequest { PlayFabId = PlayFabId }; + var getCharsTask = PlayFabClientAPI.GetAllUsersCharactersAsync(request); + ContinueWithContext(getCharsTask, testContext, null, true, "Failed to GetChars", true); + } + + /// <summary> + /// CLIENT AND SERVER API + /// Test that leaderboard results can be requested + /// Parameter types tested: List of contained-classes + /// </summary> + [UUnitTest] + public void LeaderBoard(UUnitTestContext testContext) + { + var clientRequest = new GetLeaderboardRequest + { + MaxResultsCount = 3, + StatisticName = TEST_STAT_NAME, + }; + var clientTask = PlayFabClientAPI.GetLeaderboardAsync(clientRequest); + ContinueWithContext(clientTask, testContext, LeaderBoardContinued, true, "Failed to get client leaderboard", true); + } + private void LeaderBoardContinued(PlayFabResult<GetLeaderboardResult> clientResult, UUnitTestContext testContext, string failMessage) + { + testContext.True(clientResult.Result.Leaderboard.Count > 0, "Leaderboard does not contain enough entries."); + } + + /// <summary> + /// CLIENT API + /// Test that AccountInfo can be requested + /// Parameter types tested: List of enum-as-strings converted to list of enums + /// </summary> + [UUnitTest] + public void AccountInfo(UUnitTestContext testContext) + { + var request = new GetAccountInfoRequest { PlayFabId = PlayFabId }; + var accountTask = PlayFabClientAPI.GetAccountInfoAsync(request); + ContinueWithContext(accountTask, testContext, LeaderBoardContinued, true, "Failed to get accountInfo", true); + } + private void LeaderBoardContinued(PlayFabResult<GetAccountInfoResult> accountResult, UUnitTestContext testContext, string failMessage) + { + testContext.True(Enum.IsDefined(typeof(UserOrigination), accountResult.Result.AccountInfo.TitleInfo.Origination.Value), "Origination Enum not valid"); + } + + /// <summary> + /// CLIENT API + /// Test that CloudScript can be properly set up and invoked + /// </summary> + [UUnitTest] + public void CloudScript(UUnitTestContext testContext) + { + var request = new ExecuteCloudScriptRequest { FunctionName = "helloWorld" }; + var cloudTask = PlayFabClientAPI.ExecuteCloudScriptAsync(request); + ContinueWithContext(cloudTask, testContext, CloudScriptContinued, true, "Failed to Execute CloudScript", true); + } + private void CloudScriptContinued(PlayFabResult<ExecuteCloudScriptResult> cloudResult, UUnitTestContext testContext, string failMessage) + { + // Get the helloWorld return message + testContext.NotNull(cloudResult.Result.FunctionResult); + var jobj = (JsonObject)cloudResult.Result.FunctionResult; + var messageValue = jobj["messageValue"] as string; + testContext.StringEquals("Hello " + PlayFabId + "!", messageValue); + } + + /// <summary> + /// CLIENT API + /// Test that CloudScript errors can be deciphered + /// </summary> + [UUnitTest] + public void CloudScriptError(UUnitTestContext testContext) + { + var request = new ExecuteCloudScriptRequest { FunctionName = "throwError" }; + var cloudTask = PlayFabClientAPI.ExecuteCloudScriptAsync(request); + ContinueWithContext(cloudTask, testContext, CloudScriptErrorContinued, true, "Failed to Execute CloudScript", true); + } + private void CloudScriptErrorContinued(PlayFabResult<ExecuteCloudScriptResult> cloudResult, UUnitTestContext testContext, string failMessage) + { + // Get the JavascriptException result + testContext.IsNull(cloudResult.Result.FunctionResult); + testContext.NotNull(cloudResult.Result.Error); + testContext.StringEquals(cloudResult.Result.Error.Error, "JavascriptException"); + } + + /// <summary> + /// CLIENT API + /// Test that the client can publish custom PlayStream events + /// </summary> + [UUnitTest] + public void WriteEvent(UUnitTestContext testContext) + { + var request = new WriteClientPlayerEventRequest + { + EventName = "ForumPostEvent", + Timestamp = DateTime.UtcNow, + Body = new Dictionary<string, object> { + { "Subject", "My First Post" }, + { "Body", "My awesome Post." }, + } + }; + + var writeTask = PlayFabClientAPI.WritePlayerEventAsync(request); + ContinueWithContext(writeTask, testContext, null, true, "PlayStream WriteEvent failed", true); + } + } +} +#endif diff --git a/PlayFabServerSDK/source/Uunit/UUnitAssertException.cs b/PlayFabServerSDK/source/Uunit/UUnitAssertException.cs index 94ce32f8..96130a17 100644 --- a/PlayFabServerSDK/source/Uunit/UUnitAssertException.cs +++ b/PlayFabServerSDK/source/Uunit/UUnitAssertException.cs @@ -10,34 +10,29 @@ namespace PlayFab.UUnit { + /// <summary> + /// The internal uunit exception base class, which you can use to capture all UUnit exceptions + /// </summary> + public class UUnitException : Exception + { + public UUnitException(string message) : base(message) { } + } + /// <summary> /// Throw this exception, via UUnitAssert utility function, in order to define when a test has been skipped. /// The only information shown will be the "skipped" notification /// </summary> - public class UUnitSkipException : Exception { } + public class UUnitSkipException : UUnitException + { + public UUnitSkipException(string message) : base(message) { } + } - /// <summary> + /// <summary> /// Throw this exception, via UUnitAssert utility functions, in order to define when a test has failed. - /// The traceback and message will automatically be displayed as a failure + /// The traceback and Message will automatically be displayed as a failure /// </summary> - public class UUnitAssertException : Exception + public class UUnitAssertException : UUnitException { - public object expected; - public object received; - public string message; - - public UUnitAssertException(string message) - : base(message) - { - this.message = message; - } - - public UUnitAssertException(object expected, object received, string message) - : base("[UUnit] - Assert Failed - Expected: " + expected + " Received: " + received + "\n\t\t(" + message + ")") - { - this.expected = (expected == null) ? "null" : expected; - this.received = (received == null) ? "null" : received; - this.message = (message == null) ? "" : message; - } + public UUnitAssertException(string message) : base(message) { } } } diff --git a/PlayFabServerSDK/source/Uunit/UUnitIncrementalTestRunner.cs b/PlayFabServerSDK/source/Uunit/UUnitIncrementalTestRunner.cs new file mode 100644 index 00000000..7f2d7624 --- /dev/null +++ b/PlayFabServerSDK/source/Uunit/UUnitIncrementalTestRunner.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +#if !DISABLE_PLAYFABCLIENT_API +using PlayFab.ClientModels; +#endif + +namespace PlayFab.UUnit +{ + public static class UUnitIncrementalTestRunner + { + public static bool SuiteFinished { get; private set; } + public static bool AllTestsPassed { get; private set; } + public static string Summary { get; private set; } + private static UUnitTestSuite _suite; + private static bool _postResultsToCloudscript; +#if !DISABLE_PLAYFABCLIENT_API + private static Action<PlayFabResult<ExecuteCloudScriptResult>> _onComplete; +#endif + + public static void Start(bool postResultsToCloudscript = true, string filter = null, Dictionary<string, string> testInputs = null +#if !DISABLE_PLAYFABCLIENT_API + , Action<PlayFabResult<ExecuteCloudScriptResult>> onComplete = null +#endif + ) + { + // Fall back on hard coded testTitleData if necessary (Put your own data here) + if (testInputs == null) + testInputs = new Dictionary<string, string> { { "titleId", "6195" }, { "userEmail", "paul@playfab.com" } }; +#if !DISABLE_PLAYFABCLIENT_API + PlayFabApiTest.SetTitleInfo(testInputs); +#endif + + SuiteFinished = false; + AllTestsPassed = false; + _postResultsToCloudscript = postResultsToCloudscript; + _suite = new UUnitTestSuite(); + _suite.FindAndAddAllTestCases(typeof(UUnitTestCase), filter); +#if !DISABLE_PLAYFABCLIENT_API + _onComplete = onComplete; +#endif + } + + public static string Tick() + { + if (SuiteFinished) + return Summary; + + SuiteFinished = _suite.TickTestSuite(); + Summary = _suite.GenerateSummary(); + AllTestsPassed = _suite.AllTestsPassed(); + + if (SuiteFinished) + OnSuiteFinish(); + + return Summary; + } + + private static void OnSuiteFinish() + { + if (_postResultsToCloudscript) + PostTestResultsToCloudScript(_suite.GetInternalReport()); + } + + private static void PostTestResultsToCloudScript(TestSuiteReport testReport) + { +#if !DISABLE_PLAYFABCLIENT_API + var request = new ExecuteCloudScriptRequest + { + FunctionName = "SaveTestData", + FunctionParameter = new Dictionary<string, object> { { "customId", PlayFabSettings.BuildIdentifier }, { "testReport", new[] { testReport } } }, + GeneratePlayStreamEvent = true + }; + var saveTask = PlayFabClientAPI.ExecuteCloudScriptAsync(request); + saveTask.ContinueWith(task => + { + if (_onComplete != null) + _onComplete(task.Result); + } + ); +#endif + } + } +} diff --git a/PlayFabServerSDK/source/Uunit/UUnitTestCase.cs b/PlayFabServerSDK/source/Uunit/UUnitTestCase.cs index 0ecc07ef..f9287dd1 100644 --- a/PlayFabServerSDK/source/Uunit/UUnitTestCase.cs +++ b/PlayFabServerSDK/source/Uunit/UUnitTestCase.cs @@ -7,102 +7,54 @@ */ using System; -using System.Diagnostics; -using System.Reflection; namespace PlayFab.UUnit { public class UUnitTestCase { - private delegate void UUnitTestDelegate(); - private static Type[] EMPTY_PARAMETER_TYPES = new Type[0]; - private static object[] EMPTY_PARAMETERS = new object[0]; - - Stopwatch setUpStopwatch = new Stopwatch(); - Stopwatch tearDownStopwatch = new Stopwatch(); - Stopwatch eachTestStopwatch = new Stopwatch(); - private string testMethodName; - - public void SetTest(string testMethodName) + /// <summary> + /// During testing, this is the first function that will be called for each UUnitTestCase. + /// This is run exactly once for this type. + /// It is not considered part of any test. A failure or exception in this method will halt the test framework. + /// </summary> + public virtual void ClassSetUp() { - this.testMethodName = testMethodName; } - public void Run(UUnitTestResults testResults) + /// <summary> + /// During testing, this will be called once before every test function with the [UUnitTest] attribute + /// This is run once for each test. + /// This is considered part of the active test. A failure or exception in this method will be considered a failure for the active test. + /// </summary> + public virtual void SetUp(UUnitTestContext testContext) { - TestFinishState testFinishState = TestFinishState.FAILED; - string message = null, stacktrace = null; - eachTestStopwatch.Reset(); - setUpStopwatch.Reset(); - tearDownStopwatch.Reset(); - - try - { - testResults.TestStarted(); - - setUpStopwatch.Start(); - SetUp(); - setUpStopwatch.Stop(); - - Type type = this.GetType(); - MethodInfo method = type.GetRuntimeMethod(testMethodName, EMPTY_PARAMETER_TYPES); // Test methods must contain no parameters - UUnitAssert.NotNull(method, "Could not execute: " + testMethodName + ", it's probably not public."); // Limited access to loaded assemblies - eachTestStopwatch.Start(); - ((UUnitTestDelegate)method.CreateDelegate(typeof(UUnitTestDelegate), this))(); // This creates a delegate of the test function, and calls it - testFinishState = TestFinishState.PASSED; - } - catch (UUnitAssertException e) - { - message = e.message; - stacktrace = e.StackTrace; - testFinishState = TestFinishState.FAILED; - } - catch (UUnitSkipException) - { - // message remains null - testFinishState = TestFinishState.SKIPPED; - } - catch (TargetInvocationException e) - { - message = e.InnerException.Message; - stacktrace = e.InnerException.StackTrace; - testFinishState = TestFinishState.FAILED; - } - catch (Exception e) - { - message = e.Message; - stacktrace = e.StackTrace; - testFinishState = TestFinishState.FAILED; - } - finally - { - eachTestStopwatch.Stop(); - - if (testFinishState != TestFinishState.SKIPPED) - { - try - { - tearDownStopwatch.Start(); - TearDown(); - tearDownStopwatch.Stop(); - } - catch (Exception e) - { - message = e.Message; - stacktrace = e.StackTrace; - testFinishState = TestFinishState.FAILED; - } - } - } + } - testResults.TestComplete(testMethodName, testFinishState, eachTestStopwatch.ElapsedMilliseconds, message, stacktrace); + /// <summary> + /// During testing, this will be called every tick that a test is asynchronous. + /// This is run every unity tick until testContext.EndTest() is called, or until the test times out. + /// This is considered part of the active test. A failure or exception in this method will be considered a failure for the active test. + /// </summary> + public virtual void Tick(UUnitTestContext testContext) + { + testContext.Fail(GetType().Name + "." + testContext.Name + ": Async TestCase does not implement Tick(). To fix this error, implement \"" + GetType().Name + ".Tick()\" in your async test, or call testContext.EndTest() in your syncronous test."); } - protected virtual void SetUp() + /// <summary> + /// During testing, this will be called once after every test function with the [UUnitTest] attribute. + /// This is run once for each test. + /// This is considered part of the active test. A failure or exception in this method will be considered a failure for the active test. + /// </summary> + public virtual void TearDown(UUnitTestContext testContext) { } - protected virtual void TearDown() + /// <summary> + /// During testing, this is the last function that will be called for each UUnitTestCase. + /// This is run exactly once for this type. + /// It is not considered part of any test. A failure or exception in this method will halt the test framework. + /// </summary> + public virtual void ClassTearDown() { } } diff --git a/PlayFabServerSDK/source/Uunit/UUnitTestContext.cs b/PlayFabServerSDK/source/Uunit/UUnitTestContext.cs new file mode 100644 index 00000000..d9c9aca3 --- /dev/null +++ b/PlayFabServerSDK/source/Uunit/UUnitTestContext.cs @@ -0,0 +1,254 @@ +/* + * UUnit system from UnityCommunity + * Heavily modified + * 0.4 release by pboechat + * http://wiki.unity3d.com/index.php?title=UUnit + * http://creativecommons.org/licenses/by-sa/3.0/ +*/ + +using System; +using System.Collections.Generic; + +namespace PlayFab.UUnit +{ + public enum UUnitActiveState + { + PENDING, // Not started + ACTIVE, // Currently testing + READY, // An answer is sent by the http thread, but the main thread hasn't finalized the test yet + COMPLETE, // Test is finalized and recorded + ABORTED // todo + }; + + public class UUnitTestContext + { + public const float DefaultFloatPrecision = 0.0001f; + public const double DefaultDoublePrecision = 0.000001; + + public UUnitActiveState ActiveState; + public UUnitFinishState FinishState; + public Action<UUnitTestContext> TestDelegate; + public UUnitTestCase TestInstance; + public DateTime StartTime; + public DateTime EndTime; + public string TestResultMsg; + public string Name; + + public UUnitTestContext(UUnitTestCase testInstance, Action<UUnitTestContext> testDelegate, string name) + { + TestInstance = testInstance; + TestDelegate = testDelegate; + ActiveState = UUnitActiveState.PENDING; + Name = name; + } + + internal void EndTest(UUnitFinishState finishState, string resultMsg) + { + EndTime = DateTime.UtcNow; + TestResultMsg = resultMsg; + FinishState = finishState; + ActiveState = UUnitActiveState.READY; + } + + public void Skip(string message = "") + { + EndTime = DateTime.UtcNow; + EndTest(UUnitFinishState.SKIPPED, message); + throw new UUnitSkipException(message); + } + + public void Fail(string message = null) + { + if (string.IsNullOrEmpty(message)) + message = "fail"; + EndTest(UUnitFinishState.FAILED, message); + throw new UUnitAssertException(message); + } + + public void True(bool boolean, string message = null) + { + if (boolean) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: true, Actual: false"; + Fail(message); + } + + public void False(bool boolean, string message = null) + { + if (!boolean) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: false, Actual: true"; + Fail(message); + } + + public void NotNull(object something, string message = null) + { + if (something != null) + return; // Success + + if (string.IsNullOrEmpty(message)) + message = "Null object"; + Fail(message); + } + + public void IsNull(object something, string message = null) + { + if (something == null) + return; + + if (string.IsNullOrEmpty(message)) + message = "Not null object"; + Fail(message); + } + + public void StringEquals(string wanted, string got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void SbyteEquals(sbyte? wanted, sbyte? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void ByteEquals(byte? wanted, byte? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void ShortEquals(short? wanted, short? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void UshortEquals(ushort? wanted, ushort? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void IntEquals(int? wanted, int? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void UintEquals(uint? wanted, uint? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void LongEquals(long? wanted, long? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void ULongEquals(ulong? wanted, ulong? got, string message = null) + { + if (wanted == got) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void FloatEquals(float? wanted, float? got, float precision = DefaultFloatPrecision, string message = null) + { + if (wanted == null && got == null) + return; + if (wanted != null && got != null && Math.Abs(wanted.Value - got.Value) < precision) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void DoubleEquals(double? wanted, double? got, double precision = DefaultDoublePrecision, string message = null) + { + if (wanted == null && got == null) + return; + if (wanted != null && got != null && Math.Abs(wanted.Value - got.Value) < precision) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void ObjEquals(object wanted, object got, string message = null) + { + if (wanted == null && got == null) + return; + if (wanted != null && got != null && wanted.Equals(got)) + return; + + if (string.IsNullOrEmpty(message)) + message = "Expected: " + wanted + ", Actual: " + got; + Fail(message); + } + + public void SequenceEquals<T>(IEnumerable<T> wanted, IEnumerable<T> got, string message = null) + { + var wEnum = wanted.GetEnumerator(); + var gEnum = got.GetEnumerator(); + + bool wNext, gNext; + int count = 0; + while (true) + { + wNext = wEnum.MoveNext(); + gNext = gEnum.MoveNext(); + if (wNext != gNext) + Fail(message); + if (!wNext) + break; + count++; + ObjEquals(wEnum.Current, gEnum.Current, "Element at " + count + ": " + message); + } + } + } +} diff --git a/PlayFabServerSDK/source/Uunit/UUnitTestReport.cs b/PlayFabServerSDK/source/Uunit/UUnitTestReport.cs new file mode 100644 index 00000000..65e37236 --- /dev/null +++ b/PlayFabServerSDK/source/Uunit/UUnitTestReport.cs @@ -0,0 +1,115 @@ +/* + * UUnit system from UnityCommunity + * Heavily modified + * 0.4 release by pboechat + * http://wiki.unity3d.com/index.php?title=UUnit + * http://creativecommons.org/licenses/by-sa/3.0/ +*/ + +using System; +using System.Collections.Generic; + +namespace PlayFab.UUnit +{ + public enum UUnitFinishState + { + PENDING, + PASSED, + FAILED, + SKIPPED, + TIMEDOUT + } + + /// <summary> + /// This is a wrapper around TestSuiteReport with the callbacks that let UUnitTestSuite manipulate/append results, and UUnitTestRunner display them + /// </summary> + public class UUnitTestReport + { + public readonly TestSuiteReport InternalReport = new TestSuiteReport(); + + public UUnitTestReport(string classname) + { + InternalReport.name = classname; + InternalReport.timestamp = DateTime.UtcNow; + } + + public void TestStarted() + { + InternalReport.tests += 1; + } + + public void TestComplete(string testName, UUnitFinishState finishState, long stopwatchMs, string message, string stacktrace) + { + var report = new TestCaseReport + { + message = message, + classname = InternalReport.name, + failureText = finishState.ToString(), + finishState = finishState, + name = testName, + time = TimeSpan.FromMilliseconds(stopwatchMs) + }; + if (InternalReport.testResults == null) + InternalReport.testResults = new List<TestCaseReport>(); + InternalReport.testResults.Add(report); + + switch (finishState) + { + case (UUnitFinishState.PASSED): + InternalReport.passed += 1; break; + case (UUnitFinishState.FAILED): + InternalReport.failures += 1; break; + case (UUnitFinishState.SKIPPED): + InternalReport.skipped += 1; break; + } + + // TODO: Add hooks for SuiteSetUp and SuiteTearDown, so this can be estimated more accurately + InternalReport.time = DateTime.UtcNow - InternalReport.timestamp; // For now, update the duration on every test complete - the last one will be essentially correct + } + + /// <summary> + /// Return that tests were run, and all of them reported FinishState + /// </summary> + public bool AllTestsPassed() + { + return InternalReport.tests > 0 && InternalReport.tests == (InternalReport.passed + InternalReport.skipped) && InternalReport.failures == 0; + } + } + + /// <summary> + /// Data container defining the test-suite data saved to JUnit XML format + /// </summary> + public class TestSuiteReport + { + // Part of the XML spec + public List<TestCaseReport> testResults; + public string name; + public int tests; + public int failures; + public int errors; + public int skipped; + public TimeSpan time; + public DateTime timestamp; + public Dictionary<string, string> properties; + // Useful for debugging but not part of the serialized format + public int passed; // Could be calculated from the others, but sometimes knowing if they don't add up means something + } + + /// <summary> + /// Data container defining the test-case data saved to JUnit XML format + /// </summary> + public class TestCaseReport + { + public string classname; + public string name; + public TimeSpan time; + // Sub-Fields in the XML spec + /// <summary> message is the descriptive text used to debug the test failure </summary> + public string message; + /// <summary> The xml spec allows failureText to be an arbitrary string. When possible it should match FinishState (But not required) </summary> + public string failureText; + public UUnitFinishState finishState; + // Other parameters not part of the xml spec, used for internal debugging + public string stacktrace; + } +} diff --git a/PlayFabServerSDK/source/Uunit/UUnitTestSuite.cs b/PlayFabServerSDK/source/Uunit/UUnitTestSuite.cs index b2197856..d5feee87 100644 --- a/PlayFabServerSDK/source/Uunit/UUnitTestSuite.cs +++ b/PlayFabServerSDK/source/Uunit/UUnitTestSuite.cs @@ -7,6 +7,7 @@ */ using System; +using System.Text; using System.Collections.Generic; using System.Reflection; @@ -19,95 +20,295 @@ public class UUnitTestAttribute : Attribute public class UUnitTestSuite { - private readonly List<UUnitTestCase> _tests = new List<UUnitTestCase>(); - private int _lastTestIndex = -1; - private readonly UUnitTestResults _testResults; + private const int TIME_ALIGNMENT_WIDTH = 10; + private static readonly TimeSpan TestTimeout = TimeSpan.FromSeconds(15); + private static readonly StringBuilder sb = new StringBuilder(); - public UUnitTestSuite(string classname) + private readonly List<UUnitTestContext> _testContexts = new List<UUnitTestContext>(); + private int _activeIndex = 0; + private readonly UUnitTestReport _testReport = new UUnitTestReport(PlayFabSettings.BuildIdentifier); + private UUnitActiveState _suiteState = UUnitActiveState.PENDING; + private UUnitTestCase activeTestInstance = null; + + public string GenerateSummary() { - _testResults = new UUnitTestResults(classname); + sb.Length = 0; + + DateTime now = DateTime.UtcNow, eachStartTime, eachEndTime; + int finished = 0, passed = 0, failed = 0, skipped = 0; + + foreach (var eachContext in _testContexts) + { + // Count tests + if (eachContext.ActiveState == UUnitActiveState.COMPLETE) + { + finished++; + eachStartTime = eachContext.StartTime; + eachEndTime = eachContext.EndTime; + if (eachContext.FinishState == UUnitFinishState.PASSED) + passed++; + else if (eachContext.FinishState == UUnitFinishState.SKIPPED) + skipped++; + else + failed++; + } + else + { + eachStartTime = eachContext.ActiveState == UUnitActiveState.PENDING ? now : eachContext.StartTime; + eachEndTime = now; + } + + // line for each test report + if (sb.Length != 0) + sb.Append("\n"); + var ms = (eachEndTime - eachStartTime).TotalMilliseconds.ToString("0"); + for (var i = ms.Length; i < TIME_ALIGNMENT_WIDTH; i++) + sb.Append(' '); + sb.Append(ms).Append(" ms - ").Append(eachContext.FinishState); + sb.Append(" - ").Append(eachContext.Name); + if (!string.IsNullOrEmpty(eachContext.TestResultMsg)) + { + sb.Append(" - ").Append(eachContext.TestResultMsg); + // TODO: stacktrace + } + } + + sb.AppendFormat("\nTesting complete: {0}/{1} test run, {2} tests passed, {3} tests failed, {4} tests skipped.", finished, _testContexts.Count, passed, failed, skipped); + + return sb.ToString(); } - public void Add(UUnitTestCase testCase) + public TestSuiteReport GetInternalReport() { - _tests.Add(testCase); + return _testReport.InternalReport; } - public void RunAllTests() + public void FindAndAddAllTestCases(Type parent, string filter = null) { - bool eachResult = false; - while (eachResult == false) - eachResult = RunOneTest(); + if (_suiteState != UUnitActiveState.PENDING) + throw new Exception("Must add all tests before executing tests."); + +#if NETFX_CORE + var eachAssembly = typeof(UUnitTestCase).GetTypeInfo().Assembly; // We can only load assemblies known in advance on WSA +#else + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + foreach (var eachAssembly in assemblies) +#endif + FindAndAddAllTestCases(eachAssembly, parent, filter); } - /// <summary> - /// Run a single test, and return whether the test suite is finished - /// </summary> - /// <returns>True when all _tests are finished</returns> - public bool RunOneTest() + public void FindAndAddAllTestCases(Assembly assembly, Type parent, string filter = null) + { + if (_suiteState != UUnitActiveState.PENDING) + throw new Exception("Must add all tests before executing tests."); + + var types = assembly.GetTypes(); + foreach (var t in types) + if (!t.GetTypeInfo().IsAbstract && t.GetTypeInfo().IsSubclassOf(parent)) + AddTestsForType(t.AsType(), filter); + } + + private void AddTestsForType(Type testCaseType, string filter = null) { - // Abort if we've already finished testing - bool doneTesting = _lastTestIndex >= _tests.Count; - if (doneTesting) return true; + if (_suiteState != UUnitActiveState.PENDING) + throw new Exception("Must add all tests before executing tests."); + + var filterSet = AssembleFilter(filter); + + UUnitTestCase newTestCase = null; + foreach (var constructorInfo in testCaseType.GetTypeInfo().GetConstructors()) + { + try + { + newTestCase = (UUnitTestCase)constructorInfo.Invoke(null); + } + catch (Exception) { } // Ignore it and try the next one + } + if (newTestCase == null) + throw new Exception(testCaseType.Name + " must have a parameter-less constructor."); + + var methods = testCaseType.GetTypeInfo().GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + var attributesList = new List<object>(); + foreach (var methodInfo in methods) + { + attributesList.Clear(); + attributesList.AddRange(methodInfo.GetCustomAttributes(typeof(UUnitTestAttribute), false)); + if (attributesList.Count == 0 || !MatchesFilters(methodInfo.Name, filterSet)) // There can only be 1, and we only care about attribute existence (no data on attribute), and it has to match the filter + continue; + + Action<UUnitTestContext> eachTestDelegate = CreateDelegate<UUnitTestContext>(testCaseType.Name, newTestCase, methodInfo); + if (eachTestDelegate != null) + _testContexts.Add(new UUnitTestContext(newTestCase, eachTestDelegate, methodInfo.Name)); + } + } - _lastTestIndex++; - doneTesting = _lastTestIndex >= _tests.Count; - if (!doneTesting) + private static Action<T> CreateDelegate<T>(string typeName, object instance, MethodInfo methodInfo) + { + Action<T> eachTestDelegate; + try + { + eachTestDelegate = methodInfo.CreateDelegate(typeof(Action<T>), instance) as Action<T>; + } + catch (Exception e) { - _tests[_lastTestIndex].Run(_testResults); + var sb = new StringBuilder(); + sb.Append(typeName).Append(".").Append(methodInfo.Name).Append(" must match the test delegate signature: Action<T>"); + sb.Append("\n").Append(e); + + sb.Append("\nExpected Params: ["); + var actionInfo = typeof(Action<T>).GetMethod("Invoke"); + foreach (var param in actionInfo.GetParameters()) + sb.Append(param.Name).Append(","); + sb.Append("]"); + + sb.Append("\nActual Params: ["); + foreach (var param in methodInfo.GetParameters()) + sb.Append(param.Name).Append(","); + sb.Append("]"); + throw new Exception(sb.ToString()); } - return doneTesting; + return eachTestDelegate; + } + + private HashSet<string> AssembleFilter(string filter) + { + if (string.IsNullOrEmpty(filter)) + return null; + var filterWords = filter.ToLower().Split(new char[] { '\n', ',', ' ' }, StringSplitOptions.RemoveEmptyEntries); + if (filterWords.Length > 0) + return new HashSet<string>(filterWords); + return null; } - public UUnitTestResults GetResults() + private bool MatchesFilters(string name, HashSet<string> filterSet) { - bool doneTesting = _lastTestIndex >= _tests.Count; - return doneTesting ? _testResults : null; // Only return the results when finished + if (filterSet == null) + return true; + var nameLc = name.ToLower(); + foreach (var eachFilter in filterSet) + if (nameLc.Contains(eachFilter)) + return true; + return false; } /// <summary> - /// If using WinStore/WinPhone, you should call via: - /// suite.FindAndAddAllTestCases(typeof(UUnitTestSuite).GetTypeInfo().Assembly, typeof(UUnitTestCase)) - /// If you have full reflection (IE everything else), call via: - /// foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) - /// suite.FindAndAddAllTestCases(assembly, typeof(UUnitTestCase)); - /// Don't add the same assembly/parent multiple times, or it'll repeat the same test multiple times + /// Return that tests were run, and all of them reported success /// </summary> - /// <param name="assembly"></param> - /// <param name="parent"></param> - public void FindAndAddAllTestCases(Assembly assembly, Type parent) + public bool AllTestsPassed() { - foreach (var t in assembly.DefinedTypes) - if (!t.IsAbstract && t.IsSubclassOf(parent)) - AddAll(t); + return _testReport.AllTestsPassed(); } - private void AddAll(TypeInfo testCaseType) + /// <summary> + /// Tick the test suite. + /// This should be called once per Update until it returns true. + /// Once it returns true, testing is complete + /// </summary> + public bool TickTestSuite() { - foreach (MethodInfo m in testCaseType.DeclaredMethods) + if (_suiteState == UUnitActiveState.COMPLETE) + return true; + if (_suiteState == UUnitActiveState.PENDING) + _suiteState = UUnitActiveState.ACTIVE; + + var nextTest = _activeIndex < _testContexts.Count ? _testContexts[_activeIndex] : null; + if (nextTest != null && nextTest.ActiveState == UUnitActiveState.COMPLETE) { - var attributes = m.GetCustomAttributes(typeof(UUnitTestAttribute), false); - foreach (var attr in attributes) - { - var constructors = testCaseType.DeclaredConstructors; - foreach (var constructor in constructors) - { - UUnitTestCase newTestCase = (UUnitTestCase)constructor.Invoke(null); - newTestCase.SetTest(m.Name); - Add(newTestCase); - break; // We only want 1 constructor, if relevant - } - break; // We only want 1 attribute, if relevant - } + _activeIndex++; + nextTest = (_activeIndex >= _testContexts.Count) ? null : _testContexts[_activeIndex]; + } + + if (nextTest != null && nextTest.ActiveState == UUnitActiveState.PENDING) + StartTest(nextTest); + else if (nextTest != null) + TickTest(nextTest); + + var testsDone = _activeIndex >= _testContexts.Count; + if (testsDone && _suiteState == UUnitActiveState.ACTIVE) + { + _suiteState = UUnitActiveState.READY; + ManageInstance(null, activeTestInstance); // Ensure that the final test is cleaned up } + return _suiteState == UUnitActiveState.READY; } /// <summary> - /// Return that _tests were run, and all of them reported success + /// Start a test, track which test is active, and manage timers /// </summary> - public bool AllTestsPassed() + private void StartTest(UUnitTestContext testContext) + { + ManageInstance(testContext.TestInstance, activeTestInstance); + + testContext.StartTime = DateTime.UtcNow; + testContext.ActiveState = UUnitActiveState.ACTIVE; + _testReport.TestStarted(); + + if (testContext.ActiveState == UUnitActiveState.ACTIVE) + Wrap(testContext, testContext.TestInstance.SetUp); + if (testContext.ActiveState == UUnitActiveState.ACTIVE) + Wrap(testContext, testContext.TestDelegate); + // Async tests can't resolve this tick, so just return + } + + /// <summary> + /// Ensure that exceptions in any test-functions are relayed to the testContext as failures + /// </summary> + private void Wrap(UUnitTestContext testContext, Action<UUnitTestContext> testFunc) + { + try + { + testFunc(testContext); + } + catch (UUnitSkipException uu) + { + // Silence the assert and ensure the test is marked as complete - The exception is just to halt the test process + testContext.EndTest(UUnitFinishState.SKIPPED, uu.Message); + } + catch (UUnitException uu) + { + // Silence the assert and ensure the test is marked as complete - The exception is just to halt the test process + testContext.EndTest(UUnitFinishState.FAILED, uu.Message + "\n" + uu.StackTrace); + } + catch (Exception e) + { + // Report this exception as an unhandled failure in the test + testContext.EndTest(UUnitFinishState.FAILED, e.ToString()); + } + } + + /// <summary> + /// Manage the ClassSetUp and ClassTearDown functions for each UUnitTestCase + /// </summary> + private void ManageInstance(UUnitTestCase newtestInstance, UUnitTestCase oldTestInstance) + { + if (ReferenceEquals(newtestInstance, oldTestInstance)) + return; + + if (oldTestInstance != null) + oldTestInstance.ClassTearDown(); + if (newtestInstance != null) + newtestInstance.ClassSetUp(); + activeTestInstance = newtestInstance; + } + + private void TickTest(UUnitTestContext testContext) { - return _testResults.AllTestsPassed(); + var now = DateTime.UtcNow; + var timedOut = (now - testContext.StartTime) > TestTimeout; + if (testContext.ActiveState != UUnitActiveState.READY && !timedOut) // Not finished & not timed out + { + testContext.TestInstance.Tick(testContext); + return; + } + else if (testContext.ActiveState == UUnitActiveState.ACTIVE && timedOut) + { + testContext.EndTest(UUnitFinishState.TIMEDOUT, "Test duration exceeded maxumum"); + } + + testContext.EndTime = now; + testContext.ActiveState = UUnitActiveState.COMPLETE; + Wrap(testContext, testContext.TestInstance.TearDown); + _testReport.TestComplete(testContext.TestDelegate.Target.GetType().Name + "." + testContext.Name, testContext.FinishState, (int)(testContext.EndTime - testContext.StartTime).TotalMilliseconds, testContext.TestResultMsg, null); } } } diff --git a/PlayFabServerSDK/source/WsaReflectionExtensions.cs b/PlayFabServerSDK/source/WsaReflectionExtensions.cs new file mode 100644 index 00000000..d4991f22 --- /dev/null +++ b/PlayFabServerSDK/source/WsaReflectionExtensions.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +#if NETFX_CORE +/// <summary>Specifies flags that control binding and the way in which the search for members and types is conducted by reflection.</summary> +[Flags] +public enum BindingFlags +{ + IgnoreCase = 1, + DeclaredOnly = 2, + Instance = 4, + Static = 8, + Public = 16, + NonPublic = 32, + FlattenHierarchy = 64, +} +#endif + +public static class WsaReflectionExtensions +{ + public static Type AsType(this Type type) + { + return type; + } +#if !NETFX_CORE + public static Delegate CreateDelegate(this MethodInfo methodInfo, Type delegateType, object instance) + { + return Delegate.CreateDelegate(delegateType, instance, methodInfo); + } + public static Assembly GetAssembly(this Type type) + { + return type.Assembly; + } + public static Type GetTypeInfo(this Type type) + { + return type; + } + public static string GetDelegateName(this Delegate delegateInstance) + { + return delegateInstance.Method.Name; + } +#else + public static bool IsAssignableFrom(this Type type, Type other) + { + return type.GetTypeInfo().IsAssignableFrom(other.GetTypeInfo()); + } + public static bool IsAssignableFrom(this Type type, TypeInfo other) + { + return type.GetTypeInfo().IsAssignableFrom(other); + } + public static Assembly GetAssembly(this Type type) + { + return type.GetTypeInfo().Assembly; + } + public static bool IsInstanceOfType(this Type type, object obj) + { + return obj != null && type.GetTypeInfo().IsAssignableFrom(obj.GetType().GetTypeInfo()); + } + public static string GetDelegateName(this Delegate delegateInstance) + { + return delegateInstance.ToString(); + } + public static MethodInfo GetMethod(this Type type, string methodName) + { + return type.GetTypeInfo().GetDeclaredMethod(methodName); + } + public static IEnumerable<FieldInfo> GetFields(this TypeInfo typeInfo) + { + return typeInfo.DeclaredFields; + } + public static TypeInfo GetTypeInfo(this TypeInfo typeInfo) + { + return typeInfo; + } + public static IEnumerable<ConstructorInfo> GetConstructors(this TypeInfo typeInfo) + { + return typeInfo.DeclaredConstructors; + } + public static IEnumerable<MethodInfo> GetMethods(this TypeInfo typeInfo, BindingFlags ignored) + { + return typeInfo.DeclaredMethods; + } + public static IEnumerable<TypeInfo> GetTypes(this Assembly assembly) + { + return assembly.DefinedTypes; + } +#endif +}