diff --git a/Assets/Xbox Live/Editor/XboxLiveConfigurationEditor.cs b/Assets/Xbox Live/Editor/XboxLiveConfigurationEditor.cs index 51a80ab..8de37f1 100644 --- a/Assets/Xbox Live/Editor/XboxLiveConfigurationEditor.cs +++ b/Assets/Xbox Live/Editor/XboxLiveConfigurationEditor.cs @@ -56,7 +56,7 @@ public class XboxLiveConfigurationEditor : EditorWindow if (this.configuration != null) { - if (string.IsNullOrEmpty(this.configuration.PrimaryServiceConfigId) || this.configuration.TitleId == 0 || string.IsNullOrEmpty(this.configuration.AppId)) + if (string.IsNullOrEmpty(this.configuration.ServiceConfigurationId) || this.configuration.TitleId == 0 || string.IsNullOrEmpty(this.configuration.AppId)) { EditorGUILayout.HelpBox("Your Xbox Live configuration appears invalid. You will need to re-associate your game before you can create a finished build.", MessageType.Warning, true); } @@ -67,7 +67,7 @@ public class XboxLiveConfigurationEditor : EditorWindow PropertyLabel("Publisher", this.configuration.PublisherDisplayName); PropertyLabel("App ID", this.configuration.AppId); PropertyLabel("Product Family Name", this.configuration.ProductFamilyName); - PropertyLabel("SCID", this.configuration.PrimaryServiceConfigId); + PropertyLabel("SCID", this.configuration.ServiceConfigurationId); PropertyLabel("Title ID", this.configuration.TitleId.ToString()); PropertyLabel("Sandbox", this.configuration.Sandbox); } diff --git a/Assets/Xbox Live/GameSave/Scripts/GameSaveHelper.cs b/Assets/Xbox Live/GameSave/Scripts/GameSaveHelper.cs index 0dfe799..e9a8728 100644 --- a/Assets/Xbox Live/GameSave/Scripts/GameSaveHelper.cs +++ b/Assets/Xbox Live/GameSave/Scripts/GameSaveHelper.cs @@ -35,7 +35,7 @@ namespace Microsoft.Xbox.Services.ConnectedStorage if (resultCallBack != null) { #if ENABLE_WINMD_SUPPORT - var configId = XboxLive.Instance.AppConfig.PrimaryServiceConfigId; + var configId = XboxLive.Instance.AppConfig.ServiceConfigurationId; var initTask = GameSaveProvider.GetForUserAsync(xboxLiveUser.WindowsSystemUser, configId).AsTask(); if (initTask.Result.Status == GameSaveErrorStatus.Ok) { diff --git a/Assets/Xbox Live/Scripts/UserProfile.cs b/Assets/Xbox Live/Scripts/UserProfile.cs index 20692d6..0fbefef 100644 --- a/Assets/Xbox Live/Scripts/UserProfile.cs +++ b/Assets/Xbox Live/Scripts/UserProfile.cs @@ -64,7 +64,7 @@ public class UserProfile : MonoBehaviour public void Start() { // Disable the sign-in button if there's no configuration available. - if (XboxLive.Instance.AppConfig == null || XboxLive.Instance.AppConfig.AppId == null) + if (XboxLive.Instance.AppConfig == null || XboxLive.Instance.AppConfig.ServiceConfigurationId == null) { this.ConfigAvailable = false; @@ -86,7 +86,7 @@ public class UserProfile : MonoBehaviour { XboxLiveUserManager.Instance.UserForSingleUserMode = Instantiate(this.XboxLiveUserPrefab); this.XboxLiveUser = XboxLiveUserManager.Instance.UserForSingleUserMode; - if (XboxLive.Instance.AppConfig != null && XboxLive.Instance.AppConfig.AppId != null) + if (XboxLive.Instance.AppConfig != null && XboxLive.Instance.AppConfig.ServiceConfigurationId != null) { this.SignIn(); } diff --git a/Assets/Xbox Live/Scripts/XboxLiveUserInfo.cs b/Assets/Xbox Live/Scripts/XboxLiveUserInfo.cs index b1c834f..83258b1 100644 --- a/Assets/Xbox Live/Scripts/XboxLiveUserInfo.cs +++ b/Assets/Xbox Live/Scripts/XboxLiveUserInfo.cs @@ -44,8 +44,6 @@ public class XboxLiveUserInfo : MonoBehaviour } } } - - MockXboxLiveData.Load(Path.Combine(Application.dataPath, "MockData.json")); } public void Initialize() diff --git a/CSharpSource/.gitignore b/CSharpSource/.gitignore index 4c166c8..0c1dc67 100644 --- a/CSharpSource/.gitignore +++ b/CSharpSource/.gitignore @@ -49,6 +49,7 @@ External/**/lib/ External/**/bin/ External/**/Debug/ External/**/Release/ +Tests/**/*.dll **/*.classpath diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.CSharp.sln b/CSharpSource/Source/Microsoft.Xbox.Services.CSharp.sln index f4f0eef..ea86435 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.CSharp.sln +++ b/CSharpSource/Source/Microsoft.Xbox.Services.CSharp.sln @@ -29,6 +29,7 @@ Global api\Microsoft.Xbox.Services.Shared.projitems*{035e5e11-4a0b-4d1f-ba13-9b62ccafb2b8}*SharedItemsImports = 13 api\Microsoft.Xbox.Services.Shared.projitems*{b7130c4b-b36b-4449-80b0-60037fc2e0cd}*SharedItemsImports = 4 api\Microsoft.Xbox.Services.Shared.projitems*{cbd81e44-f37f-47d6-b71b-a43a748ae09c}*SharedItemsImports = 4 + api\Microsoft.Xbox.Services.Shared.projitems*{cfb2ca8f-6611-4dca-981c-4b7afcca19a8}*SharedItemsImports = 4 EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM @@ -165,6 +166,54 @@ Global {4C1806D5-7279-4DFC-8874-13D66D52A31B}.ReleaseNET35|ARM.ActiveCfg = Release|ARM {4C1806D5-7279-4DFC-8874-13D66D52A31B}.ReleaseNET35|x64.ActiveCfg = Release|x64 {4C1806D5-7279-4DFC-8874-13D66D52A31B}.ReleaseNET35|x86.ActiveCfg = Release|x86 + {8F96710E-5169-4917-8874-7DE248F4D243}.Debug|ARM.ActiveCfg = Debug|ARM + {8F96710E-5169-4917-8874-7DE248F4D243}.Debug|ARM.Build.0 = Debug|ARM + {8F96710E-5169-4917-8874-7DE248F4D243}.Debug|x64.ActiveCfg = Debug|x64 + {8F96710E-5169-4917-8874-7DE248F4D243}.Debug|x64.Build.0 = Debug|x64 + {8F96710E-5169-4917-8874-7DE248F4D243}.Debug|x86.ActiveCfg = Debug|Win32 + {8F96710E-5169-4917-8874-7DE248F4D243}.Debug|x86.Build.0 = Debug|Win32 + {8F96710E-5169-4917-8874-7DE248F4D243}.DebugNET35|ARM.ActiveCfg = Debug|ARM + {8F96710E-5169-4917-8874-7DE248F4D243}.DebugNET35|ARM.Build.0 = Debug|ARM + {8F96710E-5169-4917-8874-7DE248F4D243}.DebugNET35|x64.ActiveCfg = Debug|x64 + {8F96710E-5169-4917-8874-7DE248F4D243}.DebugNET35|x64.Build.0 = Debug|x64 + {8F96710E-5169-4917-8874-7DE248F4D243}.DebugNET35|x86.ActiveCfg = Debug|Win32 + {8F96710E-5169-4917-8874-7DE248F4D243}.DebugNET35|x86.Build.0 = Debug|Win32 + {8F96710E-5169-4917-8874-7DE248F4D243}.Release|ARM.ActiveCfg = Release|ARM + {8F96710E-5169-4917-8874-7DE248F4D243}.Release|ARM.Build.0 = Release|ARM + {8F96710E-5169-4917-8874-7DE248F4D243}.Release|x64.ActiveCfg = Release|x64 + {8F96710E-5169-4917-8874-7DE248F4D243}.Release|x64.Build.0 = Release|x64 + {8F96710E-5169-4917-8874-7DE248F4D243}.Release|x86.ActiveCfg = Release|Win32 + {8F96710E-5169-4917-8874-7DE248F4D243}.Release|x86.Build.0 = Release|Win32 + {8F96710E-5169-4917-8874-7DE248F4D243}.ReleaseNET35|ARM.ActiveCfg = Release|ARM + {8F96710E-5169-4917-8874-7DE248F4D243}.ReleaseNET35|ARM.Build.0 = Release|ARM + {8F96710E-5169-4917-8874-7DE248F4D243}.ReleaseNET35|x64.ActiveCfg = Release|x64 + {8F96710E-5169-4917-8874-7DE248F4D243}.ReleaseNET35|x64.Build.0 = Release|x64 + {8F96710E-5169-4917-8874-7DE248F4D243}.ReleaseNET35|x86.ActiveCfg = Release|Win32 + {8F96710E-5169-4917-8874-7DE248F4D243}.ReleaseNET35|x86.Build.0 = Release|Win32 + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Debug|ARM.ActiveCfg = Debug|ARM + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Debug|ARM.Build.0 = Debug|ARM + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Debug|x64.ActiveCfg = Debug|x64 + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Debug|x64.Build.0 = Debug|x64 + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Debug|x86.ActiveCfg = Debug|Win32 + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Debug|x86.Build.0 = Debug|Win32 + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.DebugNET35|ARM.ActiveCfg = Debug|ARM + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.DebugNET35|ARM.Build.0 = Debug|ARM + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.DebugNET35|x64.ActiveCfg = Debug|x64 + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.DebugNET35|x64.Build.0 = Debug|x64 + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.DebugNET35|x86.ActiveCfg = Debug|Win32 + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.DebugNET35|x86.Build.0 = Debug|Win32 + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Release|ARM.ActiveCfg = Release|ARM + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Release|ARM.Build.0 = Release|ARM + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Release|x64.ActiveCfg = Release|x64 + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Release|x64.Build.0 = Release|x64 + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Release|x86.ActiveCfg = Release|Win32 + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Release|x86.Build.0 = Release|Win32 + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.ReleaseNET35|ARM.ActiveCfg = Release|ARM + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.ReleaseNET35|ARM.Build.0 = Release|ARM + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.ReleaseNET35|x64.ActiveCfg = Release|x64 + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.ReleaseNET35|x64.Build.0 = Release|x64 + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.ReleaseNET35|x86.ActiveCfg = Release|Win32 + {1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.ReleaseNET35|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.Test.CSharp/System/UserImpl.cs b/CSharpSource/Source/Microsoft.Xbox.Services.Test.CSharp/System/UserImpl.cs index 023c79e..dcad092 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.Test.CSharp/System/UserImpl.cs +++ b/CSharpSource/Source/Microsoft.Xbox.Services.Test.CSharp/System/UserImpl.cs @@ -29,7 +29,6 @@ namespace Microsoft.Xbox.Services.System public string AgeGroup { get; set; } public string Privileges { get; set; } public string WebAccountId { get; set; } - public AuthConfig AuthConfig { get; set; } public IntPtr XboxLiveUserPtr { get; } public Task SignInImpl(bool showUI, bool forceRefresh) @@ -37,10 +36,10 @@ namespace Microsoft.Xbox.Services.System return Task.FromResult(new SignInResult(SignInStatus.Success)); } - public Task InternalGetTokenAndSignatureAsync(string httpMethod, string url, string headers, byte[] body, bool promptForCredentialsIfNeeded, bool forceRefresh) + public Task InternalGetTokenAndSignatureAsync(string httpMethod, string url, string headers, byte[] body, bool promptForCredentialsIfNeeded, bool forceRefresh) { string[] authHeaderParts = authHeader.Substring(9).Split(';'); - return Task.FromResult(new TokenAndSignatureResult + return Task.FromResult(new GetTokenAndSignatureResult { Gamertag = this.Gamertag, XboxUserId = this.XboxUserId, diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.Test.CSharp/XboxLive.cs b/CSharpSource/Source/Microsoft.Xbox.Services.Test.CSharp/XboxLive.cs index 75cd76d..28956d8 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.Test.CSharp/XboxLive.cs +++ b/CSharpSource/Source/Microsoft.Xbox.Services.Test.CSharp/XboxLive.cs @@ -3,17 +3,11 @@ // namespace Microsoft.Xbox.Services { - public partial class XboxLive { public static bool UseMockServices { get { return false; } } - - public static bool UseMockHttp - { - get { return true; } - } } } \ No newline at end of file diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.Test.CSharp/XboxLiveAppConfiguration.cs b/CSharpSource/Source/Microsoft.Xbox.Services.Test.CSharp/XboxLiveAppConfiguration.cs index be9c6d2..0236a8e 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.Test.CSharp/XboxLiveAppConfiguration.cs +++ b/CSharpSource/Source/Microsoft.Xbox.Services.Test.CSharp/XboxLiveAppConfiguration.cs @@ -5,11 +5,11 @@ namespace Microsoft.Xbox.Services { public partial class XboxLiveAppConfiguration { - public static XboxLiveAppConfiguration Load(string path) + private static XboxLiveAppConfiguration Load() { return new XboxLiveAppConfiguration { - PrimaryServiceConfigId = "00000000-0000-0000-0000-0000694f5acb", + ServiceConfigurationId = "00000000-0000-0000-0000-0000694f5acb", TitleId = 1766808267, Environment = string.Empty, Sandbox = "JDTDWX.0", diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Common/XboxLive.cs b/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Common/XboxLive.cs index 0a707cd..28956d8 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Common/XboxLive.cs +++ b/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Common/XboxLive.cs @@ -9,10 +9,5 @@ namespace Microsoft.Xbox.Services { get { return false; } } - - public static bool UseMockHttp - { - get { return false; } - } } } \ No newline at end of file diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Common/XboxLiveAppConfiguration.cs b/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Common/XboxLiveAppConfiguration.cs index e8d1b34..4b600ee 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Common/XboxLiveAppConfiguration.cs +++ b/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Common/XboxLiveAppConfiguration.cs @@ -4,28 +4,43 @@ namespace Microsoft.Xbox.Services { - using global::System.IO; + using global::Microsoft.Xbox.Services.System; + using global::System; + using global::System.Runtime.InteropServices; public partial class XboxLiveAppConfiguration { - public static XboxLiveAppConfiguration Load(string path) + private static XboxLiveAppConfiguration Load() { - Windows.ApplicationModel.Package package = Windows.ApplicationModel.Package.Current; - Windows.Storage.StorageFolder installedLocation = package.InstalledLocation; - - string fullPath = Path.Combine(installedLocation.Path, path); - if (!File.Exists(fullPath)) + IntPtr appConfigPtr; + var result = GetXboxLiveAppConfigSingleton(out appConfigPtr); + if (result != XSAPI_RESULT.XSAPI_RESULT_OK) { - throw new FileNotFoundException(string.Format("Unable to find Xbox Live app configuration file '{0}'.", path)); + throw new XboxException(result); } - string content = File.ReadAllText(fullPath); - if (string.IsNullOrWhiteSpace(content)) - { - throw new XboxException(string.Format("Xbox Live app configeration file '{0}' was empty.", path)); - } + var appConfigStruct = Marshal.PtrToStructure(appConfigPtr); - return JsonSerialization.FromJson(content); + return new XboxLiveAppConfiguration + { + TitleId = appConfigStruct.titleId, + Environment = MarshalingHelpers.Utf8ToString(appConfigStruct.environment), + Sandbox = MarshalingHelpers.Utf8ToString(appConfigStruct.sandbox), + ServiceConfigurationId = MarshalingHelpers.Utf8ToString(appConfigStruct.scid) + }; } + + [StructLayout(LayoutKind.Sequential)] + private struct XSAPI_XBOX_LIVE_APP_CONFIG + { + public UInt32 titleId; + public IntPtr scid; + public IntPtr environment; + public IntPtr sandbox; + }; + + [DllImport(XboxLive.FlatCDllName)] + private static extern XSAPI_RESULT GetXboxLiveAppConfigSingleton( + out IntPtr ppConfig); } } \ No newline at end of file diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Common/XboxLiveUser.cs b/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Common/XboxLiveUser.cs index 5d30fcb..e2a2bd8 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Common/XboxLiveUser.cs +++ b/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Common/XboxLiveUser.cs @@ -3,7 +3,6 @@ namespace Microsoft.Xbox.Services { - using global::System.Threading.Tasks; using Microsoft.Xbox.Services.System; public partial class XboxLiveUser @@ -14,41 +13,51 @@ namespace Microsoft.Xbox.Services public XboxLiveUser(Windows.System.User systemUser) { - var user = new UserImpl(systemUser); + var userImpl = new UserImpl(systemUser); + this.userImpl = userImpl; // The UserImpl monitors the underlying system for sign out events // and notifies us that a user has been signed out. We can then // pass that event on the application with a concrete reference. - user.SignInCompleted += (sender, args) => + userImpl.SignInCompleted += (sender, args) => { - OnSignInCompleted(this); + if (SignInCompleted != null) + { + SignInCompleted(null, new SignInCompletedEventArgs(this)); + } }; - user.SignOutCompleted += (sender, args) => + userImpl.SignOutCompleted += (sender, args) => { - OnSignOutCompleted(this); + if (SignOutCompleted != null) + { + SignOutCompleted(null, new SignOutCompletedEventArgs(this)); + } }; - - this.userImpl = user; } internal XboxLiveUser(global::System.IntPtr xboxLiveUserPtr) { - var user = new UserImpl(xboxLiveUserPtr); + var userImpl = new UserImpl(xboxLiveUserPtr); + this.userImpl = userImpl; // The UserImpl monitors the underlying system for sign out events // and notifies us that a user has been signed out. We can then // pass that event on the application with a concrete reference. - user.SignInCompleted += (sender, args) => + userImpl.SignInCompleted += (sender, args) => { - OnSignInCompleted(this); + if (SignInCompleted != null) + { + SignInCompleted(null, new SignInCompletedEventArgs(this)); + } }; - user.SignOutCompleted += (sender, args) => + userImpl.SignOutCompleted += (sender, args) => { - OnSignOutCompleted(this); + if (SignOutCompleted != null) + { + SignOutCompleted(null, new SignOutCompletedEventArgs(this)); + } }; - - this.userImpl = user; - user.UpdatePropertiesFromXboxLiveUserPtr(); + userImpl.UpdatePropertiesFromXboxLiveUserPtr(); } public Windows.System.User WindowsSystemUser @@ -63,20 +72,5 @@ namespace Microsoft.Xbox.Services { get { return (this.userImpl as UserImpl); } } - - internal static void CleanupEventHandler() - { - foreach (var eh in signInDelegates) - { - InternalSignInCompleted -= eh; - } - signInDelegates.Clear(); - - foreach (var eh in signOutDelegates) - { - InternalSignOutCompleted -= eh; - } - signOutDelegates.Clear(); - } } } \ No newline at end of file diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Microsoft.Xbox.Services.UWP.CSharp.csproj b/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Microsoft.Xbox.Services.UWP.CSharp.csproj index 647dc57..d0bb34a 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Microsoft.Xbox.Services.UWP.CSharp.csproj +++ b/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Microsoft.Xbox.Services.UWP.CSharp.csproj @@ -100,7 +100,6 @@ - diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Social/Manager/SocialManager.cs b/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Social/Manager/SocialManager.cs index 864305e..b9364ff 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Social/Manager/SocialManager.cs +++ b/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Social/Manager/SocialManager.cs @@ -6,7 +6,6 @@ namespace Microsoft.Xbox.Services.Social.Manager using global::System; using global::System.Collections.Generic; using global::System.Runtime.InteropServices; - using Microsoft.Xbox.Services.Presence; using System; public partial class SocialManager : ISocialManager @@ -26,19 +25,14 @@ namespace Microsoft.Xbox.Services.Social.Manager { if (user == null) throw new ArgumentNullException("user"); - // Allocates memory for returned objects - IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf()); - + IntPtr cErrMessage; // Invokes the c method - XSAPI_RESULT errCode = SocialManagerAddLocalUser(user.Impl.XboxLiveUserPtr, extraDetailLevel, cErrMessage); + XSAPI_RESULT errCode = SocialManagerAddLocalUser(user.Impl.XboxLiveUserPtr, extraDetailLevel, out cErrMessage); // Handles error - string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage)); - Marshal.FreeHGlobal(cErrMessage); - if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK) { - // todo do something + throw new XboxException(errCode, cErrMessage); } m_localUsers.Add(user); @@ -48,19 +42,13 @@ namespace Microsoft.Xbox.Services.Social.Manager { if (user == null) throw new ArgumentNullException("user"); - // Allocates memory for returned objects - IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf()); - + IntPtr cErrMessage; // Invokes the c method - XSAPI_RESULT errCode = SocialManagerRemoveLocalUser(user.Impl.XboxLiveUserPtr, cErrMessage); - - // Handles error - string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage)); - Marshal.FreeHGlobal(cErrMessage); + XSAPI_RESULT errCode = SocialManagerRemoveLocalUser(user.Impl.XboxLiveUserPtr, out cErrMessage); if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK) { - // todo do something + throw new XboxException(errCode, cErrMessage); } m_localUsers.Remove(user); @@ -70,25 +58,18 @@ namespace Microsoft.Xbox.Services.Social.Manager { if (user == null) throw new ArgumentNullException("user"); - // Allocates memory for returned objects - IntPtr cGroupPtr = Marshal.AllocHGlobal(Marshal.SizeOf()); - IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf()); - + IntPtr cGroupPtr; + IntPtr cErrMessage; // Invokes the c method - XSAPI_RESULT errCode = SocialManagerCreateSocialUserGroupFromFilters(user.Impl.XboxLiveUserPtr, presenceFilter, relationshipFilter, cGroupPtr, cErrMessage); - - // Handles error - string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage)); - Marshal.FreeHGlobal(cErrMessage); + XSAPI_RESULT errCode = SocialManagerCreateSocialUserGroupFromFilters(user.Impl.XboxLiveUserPtr, presenceFilter, relationshipFilter, out cGroupPtr, out cErrMessage); if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK) { - // todo do something + throw new XboxException(errCode, cErrMessage); } // Handles returned objects - XboxSocialUserGroup socialUserGroup = new XboxSocialUserGroup(Marshal.ReadIntPtr(cGroupPtr)); - Marshal.FreeHGlobal(cGroupPtr); + XboxSocialUserGroup socialUserGroup = new XboxSocialUserGroup(cGroupPtr); m_groups.Add(socialUserGroup); return socialUserGroup; @@ -100,41 +81,23 @@ namespace Microsoft.Xbox.Services.Social.Manager if (xboxUserIdList == null) throw new ArgumentNullException("xboxUserIdList"); // Allocates memory for parameters - List userIdPtrs = new List(); - for (int i = 0; i < xboxUserIdList.Count; i++) - { - IntPtr cXuid = Marshal.StringToHGlobalAnsi(xboxUserIdList[i]); - userIdPtrs.Add(cXuid); - } - IntPtr cUserIds = Marshal.AllocHGlobal(Marshal.SizeOf() * xboxUserIdList.Count); - Marshal.Copy(userIdPtrs.ToArray(), 0, cUserIds, xboxUserIdList.Count); + IntPtr cUserIds = MarshalingHelpers.StringListToHGlobalUtf8StringArray(xboxUserIdList); // Allocates memory for returned objects - IntPtr cGroupPtr = Marshal.AllocHGlobal(Marshal.SizeOf()); - IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf()); + IntPtr cGroupPtr; + IntPtr cErrMessage; // Invokes the c method - XSAPI_RESULT errCode = SocialManagerCreateSocialUserGroupFromList(user.Impl.XboxLiveUserPtr, cUserIds, (uint)xboxUserIdList.Count, cGroupPtr, cErrMessage); - - // Handles error - string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage)); - Marshal.FreeHGlobal(cErrMessage); + XSAPI_RESULT errCode = SocialManagerCreateSocialUserGroupFromList(user.Impl.XboxLiveUserPtr, cUserIds, (uint)xboxUserIdList.Count, out cGroupPtr, out cErrMessage); + MarshalingHelpers.FreeHGlobalUtf8StringArray(cUserIds, xboxUserIdList.Count); if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK) { - // todo do something + throw new XboxException(errCode, cErrMessage); } - // Cleans up parameters - foreach (IntPtr ptr in userIdPtrs) - { - Marshal.FreeHGlobal(ptr); - } - Marshal.FreeHGlobal(cUserIds); - // Handles returned objects - XboxSocialUserGroup socialUserGroup = new XboxSocialUserGroup(Marshal.ReadIntPtr(cGroupPtr)); - Marshal.FreeHGlobal(cGroupPtr); + XboxSocialUserGroup socialUserGroup = new XboxSocialUserGroup(cGroupPtr); m_groups.Add(socialUserGroup); return socialUserGroup; @@ -146,37 +109,20 @@ namespace Microsoft.Xbox.Services.Social.Manager if (users == null) throw new ArgumentNullException("users"); // Allocates memory for parameters - List userIdPtrs = new List(); - for (int i = 0; i < users.Count; i++) - { - IntPtr cXuid = Marshal.StringToHGlobalUni(users[i]); - userIdPtrs.Add(cXuid); - } - IntPtr cUserIds = Marshal.AllocHGlobal(Marshal.SizeOf() * users.Count); - Marshal.Copy(userIdPtrs.ToArray(), 0, cUserIds, users.Count); + IntPtr cUserIds = MarshalingHelpers.StringListToHGlobalUtf8StringArray(users); // Allocates memory for returned objects - IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf()); + IntPtr cErrMessage; // Invokes the c method - XSAPI_RESULT errCode = SocialManagerUpdateSocialUserGroup(socialGroup.GetPtr(), cUserIds, (uint)users.Count, cErrMessage); - - // Handles error - string errMessage = Marshal.PtrToStringUni(Marshal.ReadIntPtr(cErrMessage)); - Marshal.FreeHGlobal(cErrMessage); + XSAPI_RESULT errCode = SocialManagerUpdateSocialUserGroup(socialGroup.GetPtr(), cUserIds, (uint)users.Count, out cErrMessage); + MarshalingHelpers.FreeHGlobalUtf8StringArray(cUserIds, users.Count); if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK) { - // todo do something + throw new XboxException(errCode, cErrMessage); } - // Cleans up parameters - foreach (IntPtr ptr in userIdPtrs) - { - Marshal.FreeHGlobal(ptr); - } - Marshal.FreeHGlobal(cUserIds); - // Does local work socialGroup.Refresh(); } @@ -184,39 +130,27 @@ namespace Microsoft.Xbox.Services.Social.Manager public void DestroySocialUserGroup(XboxSocialUserGroup xboxSocialUserGroup) { if (xboxSocialUserGroup == null) throw new ArgumentNullException("xboxSocialUserGroup"); - - // Allocates memory for returned objects - IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf()); + IntPtr cErrMessage; // Invokes the c method - XSAPI_RESULT errCode = SocialManagerDestroySocialUserGroup(xboxSocialUserGroup.GetPtr(), cErrMessage); - - // Handles error - string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage)); - Marshal.FreeHGlobal(cErrMessage); + XSAPI_RESULT errCode = SocialManagerDestroySocialUserGroup(xboxSocialUserGroup.GetPtr(), out cErrMessage); if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK) { - // todo do something + throw new XboxException(errCode, cErrMessage); } - + // Does local work m_groups.Remove(xboxSocialUserGroup); } public IList DoWork() { - - // Allocates memory for returned objects - IntPtr cEventsCount = Marshal.AllocHGlobal(Marshal.SizeOf()); - + UInt32 eventsCount; // Invokes the c method - IntPtr eventsPtr = SocialManagerDoWork(cEventsCount); - - // Does local work - uint eventsCount = (uint)Marshal.ReadInt32(cEventsCount); - Marshal.FreeHGlobal(cEventsCount); + IntPtr eventsPtr = SocialManagerDoWork(out eventsCount); + // Does local work List events = new List(); if (eventsCount > 0) @@ -250,19 +184,13 @@ namespace Microsoft.Xbox.Services.Social.Manager { if (user == null) throw new ArgumentNullException("user"); - // Allocates memory for returned objects - IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf()); - + IntPtr cErrMessage; // Invokes the c method - XSAPI_RESULT errCode = SocialManagerSetRichPresencePollingStatus(user.Impl.XboxLiveUserPtr, shouldEnablePolling, cErrMessage); - - // Handles error - string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage)); - Marshal.FreeHGlobal(cErrMessage); + XSAPI_RESULT errCode = SocialManagerSetRichPresencePollingStatus(user.Impl.XboxLiveUserPtr, shouldEnablePolling, out cErrMessage); if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK) { - // todo do something + throw new XboxException(errCode, cErrMessage); } // Does local work @@ -271,28 +199,28 @@ namespace Microsoft.Xbox.Services.Social.Manager // Marshaling [DllImport(XboxLive.FlatCDllName)] - private static extern XSAPI_RESULT SocialManagerAddLocalUser(IntPtr user, SocialManagerExtraDetailLevel extraDetailLevel, IntPtr errMessage); + private static extern XSAPI_RESULT SocialManagerAddLocalUser(IntPtr user, SocialManagerExtraDetailLevel extraDetailLevel, out IntPtr errMessage); [DllImport(XboxLive.FlatCDllName)] - private static extern XSAPI_RESULT SocialManagerRemoveLocalUser(IntPtr user, IntPtr errMessage); + private static extern XSAPI_RESULT SocialManagerRemoveLocalUser(IntPtr user, out IntPtr errMessage); [DllImport(XboxLive.FlatCDllName)] - private static extern XSAPI_RESULT SocialManagerCreateSocialUserGroupFromFilters(IntPtr user, PresenceFilter presenceDetailFilter, RelationshipFilter filter, IntPtr returnGroup, IntPtr errMessage); + private static extern XSAPI_RESULT SocialManagerCreateSocialUserGroupFromFilters(IntPtr user, PresenceFilter presenceDetailFilter, RelationshipFilter filter, out IntPtr returnGroup, out IntPtr errMessage); [DllImport(XboxLive.FlatCDllName)] - private static extern XSAPI_RESULT SocialManagerCreateSocialUserGroupFromList(IntPtr group, IntPtr users, UInt32 usersCount, IntPtr returnGroup, IntPtr errMessage); + private static extern XSAPI_RESULT SocialManagerCreateSocialUserGroupFromList(IntPtr group, IntPtr users, UInt32 usersCount, out IntPtr returnGroup, out IntPtr errMessage); [DllImport(XboxLive.FlatCDllName)] - private static extern XSAPI_RESULT SocialManagerUpdateSocialUserGroup(IntPtr group, IntPtr users, UInt32 usersCount, IntPtr errMessage); + private static extern XSAPI_RESULT SocialManagerUpdateSocialUserGroup(IntPtr group, IntPtr users, UInt32 usersCount, out IntPtr errMessage); [DllImport(XboxLive.FlatCDllName)] - private static extern XSAPI_RESULT SocialManagerDestroySocialUserGroup(IntPtr group, IntPtr errMessage); + private static extern XSAPI_RESULT SocialManagerDestroySocialUserGroup(IntPtr group, out IntPtr errMessage); [DllImport(XboxLive.FlatCDllName)] - private static extern IntPtr SocialManagerDoWork(IntPtr numOfEvents); + private static extern IntPtr SocialManagerDoWork(out UInt32 numOfEvents); [DllImport(XboxLive.FlatCDllName)] - private static extern XSAPI_RESULT SocialManagerSetRichPresencePollingStatus(IntPtr user, bool shouldEnablePolling, IntPtr errMessage); + private static extern XSAPI_RESULT SocialManagerSetRichPresencePollingStatus(IntPtr user, bool shouldEnablePolling, out IntPtr errMessage); [StructLayout(LayoutKind.Sequential)] diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Social/Manager/TitleHistory.cs b/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Social/Manager/TitleHistory.cs index 15c6eb2..aab9efb 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Social/Manager/TitleHistory.cs +++ b/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Social/Manager/TitleHistory.cs @@ -12,7 +12,6 @@ namespace Microsoft.Xbox.Services.Social.Manager TITLE_HISTORY cTitleHistory = Marshal.PtrToStructure(titleHistoryPtr); HasUserPlayed = cTitleHistory.UserHasPlayed; - // todo test LastTimeUserPlayed = DateTimeOffset.FromUnixTimeSeconds(cTitleHistory.LastTimeUserPlayed); } diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Statistics/Manager/StatisticManager.cs b/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Statistics/Manager/StatisticManager.cs index fef5805..5f10b4d 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Statistics/Manager/StatisticManager.cs +++ b/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/Statistics/Manager/StatisticManager.cs @@ -15,24 +15,18 @@ namespace Microsoft.Xbox.Services.Statistics.Manager private readonly List m_localUsers = new List(); [DllImport(XboxLive.FlatCDllName)] - private static extern XSAPI_RESULT StatsManagerAddLocalUser(IntPtr user, IntPtr errMessage); + private static extern XSAPI_RESULT StatsManagerAddLocalUser(IntPtr user, out IntPtr errMessage); public void AddLocalUser(XboxLiveUser user) { if (user == null) throw new ArgumentNullException("user"); - // Allocates memory for returned objects - IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf()); - + IntPtr cErrMessage; // Invokes the c method - XSAPI_RESULT errCode = StatsManagerAddLocalUser(user.Impl.XboxLiveUserPtr, cErrMessage); - - // Handles error - string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage)); - Marshal.FreeHGlobal(cErrMessage); + XSAPI_RESULT errCode = StatsManagerAddLocalUser(user.Impl.XboxLiveUserPtr, out cErrMessage); if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK) { - // todo do something + throw new XboxException(errCode, cErrMessage); } // Does local work @@ -40,24 +34,18 @@ namespace Microsoft.Xbox.Services.Statistics.Manager } [DllImport(XboxLive.FlatCDllName)] - private static extern XSAPI_RESULT StatsManagerRemoveLocalUser(IntPtr user, IntPtr errMessage); + private static extern XSAPI_RESULT StatsManagerRemoveLocalUser(IntPtr user, out IntPtr errMessage); public void RemoveLocalUser(XboxLiveUser user) { if (user == null) throw new ArgumentNullException("user"); - // Allocates memory for returned objects - IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf()); - + IntPtr cErrMessage; // Invokes the c method - XSAPI_RESULT errCode = StatsManagerRemoveLocalUser(user.Impl.XboxLiveUserPtr, cErrMessage); - - // Handles error - string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage)); - Marshal.FreeHGlobal(cErrMessage); + XSAPI_RESULT errCode = StatsManagerRemoveLocalUser(user.Impl.XboxLiveUserPtr, out cErrMessage); if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK) { - // todo do something + throw new XboxException(errCode, cErrMessage); } // Does local work @@ -65,40 +53,29 @@ namespace Microsoft.Xbox.Services.Statistics.Manager } [DllImport(XboxLive.FlatCDllName)] - private static extern XSAPI_RESULT StatsManagerRequestFlushToService(IntPtr user, bool isHighPriority, IntPtr errMessage); + private static extern XSAPI_RESULT StatsManagerRequestFlushToService(IntPtr user, bool isHighPriority, out IntPtr errMessage); public void RequestFlushToService(XboxLiveUser user, bool isHighPriority = false) { if (user == null) throw new ArgumentNullException("user"); - // Allocates memory for returned objects - IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf()); - + IntPtr cErrMessage; // Invokes the c method - XSAPI_RESULT errCode = StatsManagerRequestFlushToService(user.Impl.XboxLiveUserPtr, isHighPriority, cErrMessage); - - // Handles error - string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage)); - Marshal.FreeHGlobal(cErrMessage); + XSAPI_RESULT errCode = StatsManagerRequestFlushToService(user.Impl.XboxLiveUserPtr, isHighPriority, out cErrMessage); if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK) { - // todo do something + throw new XboxException(errCode, cErrMessage); } } [DllImport(XboxLive.FlatCDllName)] - private static extern IntPtr StatsManagerDoWork(IntPtr numOfEvents); + private static extern IntPtr StatsManagerDoWork(out Int32 numOfEvents); public IList DoWork() { - // Allocates memory for returned objects - IntPtr cEventsCount = Marshal.AllocHGlobal(Marshal.SizeOf()); + Int32 eventsCount; // Invokes the c method - IntPtr eventsPtr = StatsManagerDoWork(cEventsCount); - - // Does local work - uint eventsCount = (uint)Marshal.ReadInt32(cEventsCount); - Marshal.FreeHGlobal(cEventsCount); + IntPtr eventsPtr = StatsManagerDoWork(out eventsCount); List events = new List(); @@ -123,176 +100,134 @@ namespace Microsoft.Xbox.Services.Statistics.Manager } [DllImport(XboxLive.FlatCDllName)] - private static extern XSAPI_RESULT StatsManagerSetStatisticNumberData(IntPtr user, string statName, double value, IntPtr errMessage); + private static extern XSAPI_RESULT StatsManagerSetStatisticNumberData(IntPtr user, string statName, double value, out IntPtr errMessage); public void SetStatisticNumberData(XboxLiveUser user, string statName, double value) { if (user == null) throw new ArgumentNullException("user"); - // Allocates memory for returned objects - IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf()); - + IntPtr cErrMessage; // Invokes the c method - XSAPI_RESULT errCode = StatsManagerSetStatisticNumberData(user.Impl.XboxLiveUserPtr, statName, value, cErrMessage); - - // Handles error - string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage)); - Marshal.FreeHGlobal(cErrMessage); + XSAPI_RESULT errCode = StatsManagerSetStatisticNumberData(user.Impl.XboxLiveUserPtr, statName, value, out cErrMessage); if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK) { - // todo do something + throw new XboxException(errCode, cErrMessage); } } [DllImport(XboxLive.FlatCDllName)] - private static extern XSAPI_RESULT StatsManagerSetStatisticIntegerData(IntPtr user, string statName, long value, IntPtr errMessage); + private static extern XSAPI_RESULT StatsManagerSetStatisticIntegerData(IntPtr user, string statName, long value, out IntPtr errMessage); public void SetStatisticIntegerData(XboxLiveUser user, string statName, long value) { - // Allocates memory for returned objects - IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf()); - + IntPtr cErrMessage; // Invokes the c method - XSAPI_RESULT errCode = StatsManagerSetStatisticIntegerData(user.Impl.XboxLiveUserPtr, statName, value, cErrMessage); - - // Handles error - string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage)); - Marshal.FreeHGlobal(cErrMessage); + XSAPI_RESULT errCode = StatsManagerSetStatisticIntegerData(user.Impl.XboxLiveUserPtr, statName, value, out cErrMessage); if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK) { - // todo do something + throw new XboxException(errCode, cErrMessage); } } [DllImport(XboxLive.FlatCDllName)] - private static extern XSAPI_RESULT StatsManagerSetStatisticStringData(IntPtr user, string statName, string value, IntPtr errMessage); + private static extern XSAPI_RESULT StatsManagerSetStatisticStringData(IntPtr user, string statName, string value, out IntPtr errMessage); public void SetStatisticStringData(XboxLiveUser user, string statName, string value) { - // Allocates memory for returned objects - IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf()); - + IntPtr cErrMessage; // Invokes the c method - XSAPI_RESULT errCode = StatsManagerSetStatisticStringData(user.Impl.XboxLiveUserPtr, statName, value, cErrMessage); - - // Handles error - string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage)); - Marshal.FreeHGlobal(cErrMessage); + XSAPI_RESULT errCode = StatsManagerSetStatisticStringData(user.Impl.XboxLiveUserPtr, statName, value, out cErrMessage); if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK) { - // todo do something + throw new XboxException(errCode, cErrMessage); } } [DllImport(XboxLive.FlatCDllName)] - private static extern XSAPI_RESULT StatsManagerDeleteStat(IntPtr user, string statName, IntPtr errMessage); + private static extern XSAPI_RESULT StatsManagerDeleteStat(IntPtr user, string statName, out IntPtr errMessage); public void DeleteStatistic(XboxLiveUser user, string statName) { if (user == null) throw new ArgumentNullException("user"); - // Allocates memory for returned objects - IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf()); - + IntPtr cErrMessage; // Invokes the c method - XSAPI_RESULT errCode = StatsManagerDeleteStat(user.Impl.XboxLiveUserPtr, statName, cErrMessage); - - // Handles error - string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage)); - Marshal.FreeHGlobal(cErrMessage); + XSAPI_RESULT errCode = StatsManagerDeleteStat(user.Impl.XboxLiveUserPtr, statName, out cErrMessage); if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK) { - // todo do something + throw new XboxException(errCode, cErrMessage); } } [DllImport(XboxLive.FlatCDllName)] - private static extern XSAPI_RESULT StatsManagerGetLeaderboard(IntPtr user, string statName, IntPtr query, IntPtr errMessage); + private static extern XSAPI_RESULT StatsManagerGetLeaderboard(IntPtr user, string statName, IntPtr query, out IntPtr errMessage); public void GetLeaderboard(XboxLiveUser user, string statName, LeaderboardQuery query) { if (user == null) throw new ArgumentNullException("user"); - // Allocates memory for returned objects - IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf()); - + IntPtr cErrMessage; // Invokes the c method - XSAPI_RESULT errCode = StatsManagerGetLeaderboard(user.Impl.XboxLiveUserPtr, statName, query.GetPtr(), cErrMessage); - - // Handles error - string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage)); - Marshal.FreeHGlobal(cErrMessage); + XSAPI_RESULT errCode = StatsManagerGetLeaderboard(user.Impl.XboxLiveUserPtr, statName, query.GetPtr(), out cErrMessage); if (errCode > 0) { - // todo do something + throw new XboxException(errCode, cErrMessage); } } [DllImport(XboxLive.FlatCDllName)] - private static extern XSAPI_RESULT StatsManagerGetSocialLeaderboard(IntPtr user, string statName, string socialGroup, IntPtr query, IntPtr errMessage); + private static extern XSAPI_RESULT StatsManagerGetSocialLeaderboard(IntPtr user, string statName, string socialGroup, IntPtr query, out IntPtr errMessage); public void GetSocialLeaderboard(XboxLiveUser user, string statName, string socialGroup, LeaderboardQuery query) { if (user == null) throw new ArgumentNullException("user"); - // Allocates memory for returned objects - IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf()); - + IntPtr cErrMessage; // Invokes the c method - XSAPI_RESULT errCode = StatsManagerGetSocialLeaderboard(user.Impl.XboxLiveUserPtr, statName, socialGroup, query.GetPtr(), cErrMessage); - - // Handles error - string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage)); - Marshal.FreeHGlobal(cErrMessage); + XSAPI_RESULT errCode = StatsManagerGetSocialLeaderboard(user.Impl.XboxLiveUserPtr, statName, socialGroup, query.GetPtr(), out cErrMessage); if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK) { - // todo do something + throw new XboxException(errCode, cErrMessage); } } [DllImport(XboxLive.FlatCDllName)] - private static extern XSAPI_RESULT StatsManagerGetStat(IntPtr user, IntPtr statName, IntPtr statValue, IntPtr errMessage); + private static extern XSAPI_RESULT StatsManagerGetStat(IntPtr user, IntPtr statName, out IntPtr statValue, out IntPtr errMessage); public StatisticValue GetStatistic(XboxLiveUser user, string statName) { if (user == null) throw new ArgumentNullException("user"); // Allocates memory for returned objects - IntPtr cStatValue = Marshal.AllocHGlobal(Marshal.SizeOf()); - IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf()); - IntPtr cStatName = Marshal.StringToHGlobalAnsi(statName); + IntPtr cStatValue; + IntPtr cErrMessage; + IntPtr cStatName = MarshalingHelpers.StringToHGlobalUtf8(statName); // Invokes the c method - XSAPI_RESULT errCode = StatsManagerGetStat(user.Impl.XboxLiveUserPtr, cStatName, cStatValue, cErrMessage); - - // Handles error - string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage)); - Marshal.FreeHGlobal(cErrMessage); + XSAPI_RESULT errCode = StatsManagerGetStat(user.Impl.XboxLiveUserPtr, cStatName, out cStatValue, out cErrMessage); + Marshal.FreeHGlobal(cStatName); if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK) { - // todo do something + throw new XboxException(errCode, cErrMessage); } // Handles returned objects - StatisticValue statValue = new StatisticValue(Marshal.ReadIntPtr(cStatValue)); - Marshal.FreeHGlobal(cStatValue); + StatisticValue statValue = new StatisticValue(cStatValue); return statValue; } [DllImport(XboxLive.FlatCDllName)] - private static extern XSAPI_RESULT StatsManagerGetStatNames(IntPtr user, IntPtr statNameList, IntPtr statNameListCount, IntPtr errMessage); + private static extern XSAPI_RESULT StatsManagerGetStatNames(IntPtr user, out IntPtr statNameList, out UInt32 statNameListCount, out IntPtr errMessage); public IList GetStatisticNames(XboxLiveUser user) { if (user == null) throw new ArgumentNullException("user"); - // Allocates memory for returned objects - IntPtr cStatListPtr = Marshal.AllocHGlobal(Marshal.SizeOf()); - IntPtr cStatListCount = Marshal.AllocHGlobal(Marshal.SizeOf()); - IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf()); - + IntPtr cStatListPtr; + UInt32 statListCount; + IntPtr cErrMessage; // Invokes the c method - XSAPI_RESULT errCode = StatsManagerGetStatNames(user.Impl.XboxLiveUserPtr, cStatListPtr, cStatListCount, cErrMessage); + XSAPI_RESULT errCode = StatsManagerGetStatNames(user.Impl.XboxLiveUserPtr, out cStatListPtr, out statListCount, out cErrMessage); // Handles error string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage)); @@ -300,29 +235,9 @@ namespace Microsoft.Xbox.Services.Statistics.Manager if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK) { - // todo do something + throw new XboxException(errCode, cErrMessage); } - - // Handles returned objects - uint statListCount = (uint)Marshal.ReadInt32(cStatListCount); - Marshal.FreeHGlobal(cStatListCount); - - List statList = new List(); - - if (statListCount > 0) - { - IntPtr cListPtr = Marshal.ReadIntPtr(cStatListPtr); - IntPtr[] cStatList = new IntPtr[statListCount]; - Marshal.Copy(cListPtr, cStatList, 0, (int)statListCount); - - for (uint i = 0; i < statListCount; i++) - { - statList.Add(Marshal.PtrToStringAnsi(cStatList[i])); - } - } - Marshal.FreeHGlobal(cStatListPtr); - - return statList; + return MarshalingHelpers.Utf8StringArrayToStringList(cStatListPtr, statListCount); } } } diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/System/TokenRequestResult.cs b/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/System/TokenRequestResult.cs deleted file mode 100644 index 9d7b416..0000000 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/System/TokenRequestResult.cs +++ /dev/null @@ -1,41 +0,0 @@ - -namespace Microsoft.Xbox.Services.System -{ - using global::System.Collections.Generic; - using global::System.Linq; - using Windows.Security.Authentication.Web.Core; - - internal class TokenRequestResult - { - public WebProviderError ResponseError { get; set; } - - public WebTokenRequestStatus ResponseStatus { get; set; } - - public IDictionary Properties { get; set; } - - public WebProviderError ProviderError { get; set; } - - public string Token { get; set; } - - public string WebAccountId { get; set; } - - public TokenRequestResult(WebTokenRequestResult result) - { - if (result != null) - { - this.ResponseStatus = result.ResponseStatus; - this.ResponseError = result.ResponseError; - - if (result.ResponseData != null && result.ResponseData.Count > 0) - { - var responseData = result.ResponseData.FirstOrDefault(); - - this.Properties = responseData.Properties; - this.ProviderError = responseData.ProviderError; - this.Token = responseData.Token; - this.WebAccountId = responseData.WebAccount?.Id; - } - } - } - } -} diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/System/UserImpl.cs b/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/System/UserImpl.cs index 7dca6a8..5c657b9 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/System/UserImpl.cs +++ b/CSharpSource/Source/Microsoft.Xbox.Services.UWP.CSharp/System/UserImpl.cs @@ -23,7 +23,6 @@ namespace Microsoft.Xbox.Services.System public string AgeGroup { get; private set; } public string Privileges { get; private set; } public string WebAccountId { get; private set; } - public AuthConfig AuthConfig { get; private set; } // TODO remove this public User CreationContext { get; private set; } public IntPtr XboxLiveUserPtr { get; private set; } @@ -48,7 +47,6 @@ namespace Microsoft.Xbox.Services.System { throw new XboxException(result); } - Init(); } @@ -62,16 +60,7 @@ namespace Microsoft.Xbox.Services.System { signOutHandlerContext = AddSignOutCompletedHandler(OnSignOutCompleted); xboxLiveUserInstanceMap[XboxLiveUserPtr] = this; - - // TODO: This config is broken. - var appConfig = XboxLiveAppConfiguration.Instance; - this.AuthConfig = new AuthConfig - { - Sandbox = appConfig.Sandbox, - EnvironmentPrefix = appConfig.EnvironmentPrefix, - Environment = appConfig.Environment, - UseCompactTicket = appConfig.UseFirstPartyToken - }; + var appConfig = XboxLiveAppConfiguration.SingletonInstance; } ~UserImpl() @@ -177,9 +166,9 @@ namespace Microsoft.Xbox.Services.System } } - public Task InternalGetTokenAndSignatureAsync(string httpMethod, string url, string headers, byte[] body, bool promptForCredentialsIfNeeded, bool forceRefresh) + public Task InternalGetTokenAndSignatureAsync(string httpMethod, string url, string headers, byte[] body, bool promptForCredentialsIfNeeded, bool forceRefresh) { - var tcs = new TaskCompletionSource(); + var tcs = new TaskCompletionSource(); Task.Run(() => { @@ -196,7 +185,7 @@ namespace Microsoft.Xbox.Services.System } int contextKey; - var context = XsapiCallbackContext.CreateContext(this, tcs, out contextKey); + var context = XsapiCallbackContext.CreateContext(this, tcs, out contextKey); context.PointersToFree = new List { pHttpMethod, pUrl, pHeaders, pBody }; var result = XboxLiveUserGetTokenAndSignature( @@ -223,12 +212,12 @@ namespace Microsoft.Xbox.Services.System { int contextKey = context.ToInt32(); - XsapiCallbackContext contextObject; - if (XsapiCallbackContext.TryRemove(contextKey, out contextObject)) + XsapiCallbackContext contextObject; + if (XsapiCallbackContext.TryRemove(contextKey, out contextObject)) { if (result.errorCode == XSAPI_RESULT.XSAPI_RESULT_OK) { - contextObject.TaskCompletionSource.SetResult(new TokenAndSignatureResult + contextObject.TaskCompletionSource.SetResult(new GetTokenAndSignatureResult { WebAccountId = MarshalingHelpers.Utf8ToString(payload.WebAccountId), Privileges = MarshalingHelpers.Utf8ToString(payload.Privileges), @@ -237,7 +226,6 @@ namespace Microsoft.Xbox.Services.System XboxUserId = MarshalingHelpers.Utf8ToString(payload.XboxUserId), Signature = MarshalingHelpers.Utf8ToString(payload.Signature), Token = MarshalingHelpers.Utf8ToString(payload.Token) - //TokenRequestResultStatus = tokenResult.ResponseStatus // TODO }); } else @@ -333,7 +321,7 @@ namespace Microsoft.Xbox.Services.System [StructLayout(LayoutKind.Sequential)] private struct XSAPI_SIGN_IN_RESULT -{ + { public SignInStatus status; } diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.UnitTests/UserTest.cs b/CSharpSource/Source/Microsoft.Xbox.Services.UWP.UnitTests/UserTest.cs index 2ae0ebc..a2b5c5b 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UWP.UnitTests/UserTest.cs +++ b/CSharpSource/Source/Microsoft.Xbox.Services.UWP.UnitTests/UserTest.cs @@ -4,16 +4,10 @@ namespace Microsoft.Xbox.Services.UWP.UnitTests { using global::System; - using Windows.System; - using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; - using Microsoft.Xbox.Services.System; using global::System.Linq; - using Moq; using global::System.Threading.Tasks; - using UITestMethod = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.AppContainer.UITestMethodAttribute; - using Windows.Security.Authentication.Web.Core; - using global::System.Collections.Generic; - using global::System.Threading; + using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; + using Windows.System; [TestClass] public class UserTest @@ -30,28 +24,9 @@ namespace Microsoft.Xbox.Services.UWP.UnitTests private const int mockErrorcode = 9999; private const string mockErrorMessage = "mock error message"; - private TokenRequestResult CreateSuccessTokenResponse() - { - var result = new TokenRequestResult(null); - result.ResponseStatus = WebTokenRequestStatus.Success; - result.Token = mockToken; - result.WebAccountId = mockWebAccountId; - result.Properties = new Dictionary(); - result.Properties.Add("XboxUserId", mockXuid); - result.Properties.Add("Gamertag", mockGamerTag); - result.Properties.Add("AgeGroup", mockAgeGroup); - result.Properties.Add("Environment", mockEnvironment); - result.Properties.Add("Sandbox", mockSandbox); - result.Properties.Add("Signature", mockSignature); - result.Properties.Add("Privileges", mockPrivileges); - - return result; - } - [TestCleanup] public void Cleanup() { - XboxLiveUser.CleanupEventHandler(); } [TestCategory("XboxLiveUser")] @@ -71,156 +46,5 @@ namespace Microsoft.Xbox.Services.UWP.UnitTests var xbluser = new XboxLiveUser(systemUser); Assert.AreEqual(systemUser.NonRoamableId, xbluser.WindowsSystemUser.NonRoamableId); } - - [TestCategory("XboxLiveUser")] - [TestMethod] - public async Task UserSigninSilentlySuccess() - { - var user = new XboxLiveUser(); - Assert.IsFalse(user.IsSignedIn); - - AutoResetEvent signinEvent = new AutoResetEvent(false); - XboxLiveUser.SignInCompleted += (Object o, SignInCompletedEventArgs args) => - { - Assert.AreEqual(args.User, user); - signinEvent.Set(); - }; - var response = CreateSuccessTokenResponse(); - - // Create xbl user with system user - var silentResult = await user.SignInSilentlyAsync(); - Assert.AreEqual(silentResult.Status, SignInStatus.Success); - - Assert.IsTrue(user.IsSignedIn); - Assert.AreEqual(user.Gamertag, mockGamerTag); - Assert.AreEqual(user.XboxUserId, mockXuid); - Assert.AreEqual(user.AgeGroup, mockAgeGroup); - Assert.AreEqual(user.Privileges, mockPrivileges); - Assert.AreEqual(user.WebAccountId, mockWebAccountId); - - Assert.IsTrue(signinEvent.WaitOne(100), "wait signin event time out"); - - } - - [TestCategory("XboxLiveUser")] - [TestMethod] - public async Task UserSigninWithUiSuccess() - { - var user = new XboxLiveUser(); - Assert.IsFalse(user.IsSignedIn); - - AutoResetEvent signinEvent = new AutoResetEvent(false); - XboxLiveUser.SignInCompleted += ((Object o, SignInCompletedEventArgs args) => - { - Assert.AreEqual(args.User, user); - signinEvent.Set(); - }); - - var response = CreateSuccessTokenResponse(); - - var signinResult = await user.SignInAsync(); - Assert.AreEqual(signinResult.Status, SignInStatus.Success); - Assert.IsTrue(user.IsSignedIn); - Assert.AreEqual(user.Gamertag, mockGamerTag); - Assert.AreEqual(user.XboxUserId, mockXuid); - Assert.AreEqual(user.AgeGroup, mockAgeGroup); - Assert.AreEqual(user.Privileges, mockPrivileges); - Assert.AreEqual(user.WebAccountId, mockWebAccountId); - - Assert.IsTrue(signinEvent.WaitOne(100), "wait signin event time out"); - } - - [TestCategory("XboxLiveUser")] - [TestMethod] - public async Task UserSigninSilentlyUserInteractionRequired() - { - var user = new XboxLiveUser(); - var result = new TokenRequestResult(null); - result.ResponseStatus = WebTokenRequestStatus.UserInteractionRequired; - - var signinResult = await user.SignInSilentlyAsync(); - Assert.AreEqual(signinResult.Status, SignInStatus.UserInteractionRequired); - Assert.IsFalse(user.IsSignedIn); - } - - [TestCategory("XboxLiveUser")] - [TestMethod] - public async Task UserSigninUIUserCancel() - { - var user = new XboxLiveUser(); - var result = new TokenRequestResult(null); - result.ResponseStatus = WebTokenRequestStatus.UserCancel; - - var signinResult = await user.SignInAsync(); - Assert.AreEqual(signinResult.Status, SignInStatus.UserCancel); - Assert.IsFalse(user.IsSignedIn); - } - - [TestCategory("XboxLiveUser")] - [TestMethod] - public async Task UserSigninProviderError() - // provider error - { - var user = new XboxLiveUser(); - var result = new TokenRequestResult(null); - result.ResponseStatus = WebTokenRequestStatus.ProviderError; - result.ResponseError = new WebProviderError(mockErrorcode, mockErrorMessage); - - // ProviderError will convert to exception - try - { - var silentResult = await user.SignInSilentlyAsync(); - } - catch (XboxException ex) - { - Assert.AreEqual(ex.HResult, mockErrorcode); - Assert.IsFalse(string.IsNullOrEmpty(ex.Message)); - Assert.IsFalse(user.IsSignedIn); - - return; - } - - Assert.Fail("No exception was thrown."); - } - - [TestCategory("XboxLiveUser")] - [TestMethod] - public async Task UserSignOut() - // provider error - { - var user = new XboxLiveUser(); - Assert.IsFalse(user.IsSignedIn); - - AutoResetEvent signoutEvent = new AutoResetEvent(false); - XboxLiveUser.SignOutCompleted += ((Object o, SignOutCompletedEventArgs args) => - { - Assert.AreEqual(args.User, user); - signoutEvent.Set(); - }); - - var successResponse = CreateSuccessTokenResponse(); - var errorResponse = new TokenRequestResult(null); - errorResponse.ResponseStatus = WebTokenRequestStatus.UserInteractionRequired; - - var silentResult = await user.SignInSilentlyAsync(); - Assert.AreEqual(silentResult.Status, SignInStatus.Success); - Assert.IsTrue(user.IsSignedIn); - - try - { - var token = await user.GetTokenAndSignatureAsync("GET", "", ""); - } - catch(XboxException ex) - { - Assert.IsFalse(string.IsNullOrEmpty(ex.Message)); - Assert.IsFalse(user.IsSignedIn); - - Assert.IsTrue(signoutEvent.WaitOne(100), "wait signout event time out"); - - return; - } - - Assert.Fail("No exception was thrown."); - } } } diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/CallBufferTimerTests.cs b/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/CallBufferTimerTests.cs deleted file mode 100644 index 7fe3757..0000000 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/CallBufferTimerTests.cs +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Xbox.Services.UnitTests -{ - using global::System; - using global::System.Collections.Generic; - using global::System.Diagnostics; - using global::System.Linq; - using global::System.Threading; - using global::System.Threading.Tasks; - - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Microsoft.Xbox.Services.Shared; - - [TestClass] - public class CallBufferTimerTests - { - [TestMethod] - public async Task BasicCallback() - { - bool completed = false; - - CallBufferTimer timer = new CallBufferTimer(TimeSpan.FromSeconds(1)); - timer.Completed += (sender, o) => { completed = true; }; - - var timerTask = timer.Fire(new List { new object() }); - - var result = await Task.WhenAny(timerTask, Task.Delay(TimeSpan.FromSeconds(2))); - if (result != timerTask) - { - // This means the delay task completed. - Assert.Fail("Timer was never called."); - } - - Assert.IsTrue(completed); - } - - [TestMethod] - public async Task ThrottledCallback() - { - int completedCount = 0; - CallBufferTimer timer = new CallBufferTimer(TimeSpan.FromSeconds(1)); - timer.Completed += (sender, o) => - { - string batchedElements = string.Join(", ", o.Elements.Select(e => e.ToString())); - Debug.WriteLine($"Batched request being made at {DateTime.UtcNow:h:mm:ss.fff} with elements {batchedElements}"); - - Interlocked.Increment(ref completedCount); - }; - - List timerTasks = Enumerable.Range(1, 10).Select(i => timer.Fire(new[] { i }.ToList())).ToList(); - - Task delayTask = Task.Delay(TimeSpan.FromSeconds(2)); - timerTasks.Add(delayTask); - - var result = await Task.WhenAny(timerTasks); - if (result == delayTask) - { - // This means the delay task completed. - Assert.Fail("Timer was never called."); - } - - Assert.AreEqual(1, completedCount); - - await Task.WhenAll(timerTasks); - } - - /// - /// Verifies that - /// - /// - [TestMethod] - public async Task QueuedThrottledCallback() - { - int completedCount = 0; - CallBufferTimer timer = new CallBufferTimer(TimeSpan.FromMilliseconds(250)); - timer.Completed += (sender, o) => - { - Thread.Sleep(100); - - string batchedElements = string.Join(", ", o.Elements.Select(e => e.ToString())); - Debug.WriteLine($"Batched request being made at {DateTime.UtcNow:h:mm:ss.fff} with elements {batchedElements}"); - - Interlocked.Increment(ref completedCount); - }; - - // Create a first batch of 10. We don't care when these finish, so let the tasks go. - List batch1Tasks = Enumerable.Range(1, 5).Select(i => timer.Fire(new[] { i }.ToList())).ToList(); - - // Make sure the first batch has started. - await Task.Delay(251); - - // Start a second batch after the first one is running. - List timerTasks = Enumerable.Range(6, 5).Select(i => timer.Fire(new[] { i }.ToList())).ToList(); - - Task delayTask = Task.Delay(TimeSpan.FromSeconds(2)); - timerTasks.Add(delayTask); - - var result = await Task.WhenAny(timerTasks); - if (result == delayTask) - { - // This means the delay task completed. - Assert.Fail("Second batch was never triggered."); - } - - Debug.WriteLine($"Completed count: {completedCount}"); - Assert.AreEqual(completedCount, 2, "completedCount == 2"); - } - - /// - /// Verifies that a call to fire will be immediately (or nearly immediately) executed if - /// no call has been made in the past "period" amount of time. - /// - /// - [TestMethod] - public async Task ExecuteImmediatelyIfPastPeriod() - { - int completedCount = 0; - CallBufferTimer timer = new CallBufferTimer(TimeSpan.FromMilliseconds(50)); - timer.Completed += (sender, o) => - { - string batchedElements = string.Join(", ", o.Elements.Select(e => e.ToString())); - Debug.WriteLine($"Batched request being made at {DateTime.UtcNow:h:mm:ss.fff} with elements [{batchedElements}]"); - - Interlocked.Increment(ref completedCount); - }; - - var timerTask = timer.Fire(new List { 1 }); - - await Task.Yield(); - - Task delayTask = Task.Delay(TimeSpan.FromSeconds(2)); - - var result = await Task.WhenAny(timerTask, delayTask); - if (result == delayTask) - { - // This means the delay task completed. - Assert.Fail("Second batch was never triggered."); - } - - Assert.IsTrue(timerTask.IsCompleted); - } - - /// - /// Verifies that if you add an element to the buffer while an existing call is queued - /// it get's executed with that batch as opposed to the next. - /// - [TestMethod] - public async Task AddWhileQueued() - { - int completedCount = 0; - CallBufferTimer timer = new CallBufferTimer(TimeSpan.FromMilliseconds(1000)); - timer.Completed += (sender, o) => - { - string batchedElements = string.Join(", ", o.Elements.Select(e => e.ToString())); - Debug.WriteLine($"Batched request being made at {DateTime.UtcNow:h:mm:ss.fff} with elements [{batchedElements}]"); - - Interlocked.Increment(ref completedCount); - }; - - Debug.WriteLine($"Now: {DateTime.UtcNow:O}"); - - // Execute and wait for a single call - await timer.Fire(new List { 1 }); - - // Fire another event which will queue up a new timer. - var timerTask1 = timer.Fire(new List { 2 }); - - await Task.Delay(200); - - var timerTask2 = timer.Fire(new List { 3 }); - - Assert.AreEqual(timerTask1, timerTask2); - - await timerTask2; - } - } -} \ No newline at end of file diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Leaderboards/LeaderboardTests.cs b/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Leaderboards/LeaderboardTests.cs deleted file mode 100644 index d31c374..0000000 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Leaderboards/LeaderboardTests.cs +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Xbox.Services.UnitTests.Leaderboards -{ - using global::System; - using global::System.Threading.Tasks; - using Newtonsoft.Json.Linq; - - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Microsoft.Xbox.Services.Leaderboard; - - [TestClass] - public class LeaderboardTests : TestBase - { - private LeaderboardService leaderboardService; - - [TestInitialize] - public override void TestInitialize() - { - base.TestInitialize(); - MockXboxLiveData.Load(Environment.CurrentDirectory + "\\Leaderboards\\MockDataForLeaderboardTests.json"); - this.leaderboardService = new LeaderboardService(); - } - - [TestCleanup] - public void TestCleanup() - { - XboxLive.Instance.Dispose(); - } - - private static void VerifyLeaderboardColumn(LeaderboardColumn column, JObject columnToVerify) - { - Assert.AreNotEqual(column, null, "LeaderboardColumn was null."); - Assert.AreEqual(column.StatisticName, columnToVerify["statName"].ToString()); - Assert.AreEqual(column.StatisticType.ToString(), columnToVerify["type"].ToString()); - } - - private static void VerifyLeaderboardRow(LeaderboardRow row, JObject rowToVerify) - { - Assert.AreNotEqual(row, null, "LeaderboardRow was null."); - - Assert.AreEqual(row.Gamertag, rowToVerify["gamertag"].ToString()); - Assert.AreEqual(row.XboxUserId, rowToVerify["xuid"].ToString()); - Assert.AreEqual(row.Percentile, (double)rowToVerify["percentile"]); - Assert.AreEqual(row.Rank, (int)rowToVerify["rank"]); - - // TODO Add checks for values - } - - private static void VerifyLeaderboardResult(LeaderboardResult result, JObject resultToVerify) - { - Assert.AreNotEqual(result, null, "LeaderboardResult was null."); - - JObject leaderboardInfoJson = JObject.Parse(resultToVerify["leaderboardInfo"].ToString()); - Assert.AreEqual(result.TotalRowCount, (uint)leaderboardInfoJson["totalCount"]); - - JObject jsonColumn = JObject.Parse(leaderboardInfoJson["columnDefinition"].ToString()); - VerifyLeaderboardColumn(result.Columns[0], jsonColumn); - - JArray jsonRows = (JArray)(resultToVerify)["userList"]; - int index = 0; - foreach (var row in jsonRows) - { - VerifyLeaderboardRow(result.Rows[index++], (JObject)row); - } - } - } -} \ No newline at end of file diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Leaderboards/MockDataForLeaderboardTests.json b/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Leaderboards/MockDataForLeaderboardTests.json deleted file mode 100644 index 10e2acc..0000000 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Leaderboards/MockDataForLeaderboardTests.json +++ /dev/null @@ -1,140 +0,0 @@ -{ - "defaultLeaderboardData": { - "Request" : { - "method": "GET", - "serverName": "https://leaderboards.xboxlive.com", - "pathQueryFragment": "/scids/00000000-0000-0000-0000-0000694f5acb/leaderboards/stat(Jumps)?maxItems=100" - }, - "Response" : { - "httpStatus": 200, - "bodyType": 2, - "body": { - "pagingInfo": { - "continuationToken": "6" - }, - "leaderboardInfo": { - "totalCount": 38, - "columnDefinition": { - "statName": "Jumps", - "type": "Integer" - } - }, - "userList": [ - { - "gamertag": "NSC FaceRocker", - "xuid": "2533275015216241", - "percentile": 0.9954, - "rank": 1, - "globalrank": 1, - "value": "3660", - "valuemetadata": "{\"HasSkull\": true, \"Kills\": 11, \"Level\": \"Hardcake\", \"Empty\": null}" - }, - { - "gamertag": "isspmarkbou", - "xuid": "2533275024657260", - "percentile": 0.9908, - "rank": 2, - "globalrank": 2, - "value": "2208", - "valuemetadata": "{\"HasSkull\": false, \"Level\": \"Hardcake\", \"Empty\": null}" - }, - { - "gamertag": "UnloosedLeech", - "xuid": "2535449359478292", - "percentile": 0.9862, - "rank": 3, - "globalrank": 3, - "value": "1064", - "valuemetadata": "{\"HasSkull\": null, \"Kills\": 11, \"Level\": \"Hardcake\", \"Empty\": null}" - }, - { - "gamertag": "MSFT JEFFSHI 00", - "xuid": "2814662167029838", - "percentile": 0.9817, - "rank": 4, - "globalrank": 4, - "value": "783", - "valuemetadata": "{\"HasSkull\": true, \"Kills\": 11, \"Level\": \"Hardcake\", \"Empty\": null}" - }, - { - "gamertag": "ProfittMan", - "xuid": "2533274998970959", - "percentile": 0.9771, - "rank": 5, - "globalrank": 5, - "value": "535", - "valuemetadata": "{\"HasSkull\": true, \"Kills\": 11, \"Level\": \"Hardcake\", \"Empty\": null}" - } - ] - } - } - }, - "defaultLeaderboardDataWithContinuationToken": { - "Request" : { - "method": "GET", - "serverName": "https://leaderboards.xboxlive.com", - "pathQueryFragment": "/scids/00000000-0000-0000-0000-0000694f5acb/leaderboards/stat(Jumps)?maxItems=100&continuationToken=6" - }, - "Response" : { - "httpStatus": 200, - "bodyType": 2, - "body": { - "pagingInfo": null, - "leaderboardInfo": { - "totalCount": 38, - "columnDefinition": { - "statName": "EnemyDefeats", - "type": "Integer" - } - }, - "userList": [ - { - "gamertag": "NSC FaceRocker", - "xuid": "2533275015216241", - "percentile": 0.9954, - "rank": 1, - "globalrank": 1, - "value": "3660", - "valuemetadata": "{\"HasSkull\": true, \"Kills\": 11, \"Level\": \"Hardcake\", \"Empty\": null}" - }, - { - "gamertag": "isspmarkbou", - "xuid": "2533275024657260", - "percentile": 0.9908, - "rank": 2, - "globalrank": 2, - "value": "2208", - "valuemetadata": "{\"HasSkull\": false, \"Level\": \"Hardcake\", \"Empty\": null}" - }, - { - "gamertag": "UnloosedLeech", - "xuid": "2535449359478292", - "percentile": 0.9862, - "rank": 3, - "globalrank": 3, - "value": "1064", - "valuemetadata": "{\"HasSkull\": null, \"Kills\": 11, \"Level\": \"Hardcake\", \"Empty\": null}" - }, - { - "gamertag": "MSFT JEFFSHI 00", - "xuid": "2814662167029838", - "percentile": 0.9817, - "rank": 4, - "globalrank": 4, - "value": "783", - "valuemetadata": "{\"HasSkull\": true, \"Kills\": 11, \"Level\": \"Hardcake\", \"Empty\": null}" - }, - { - "gamertag": "ProfittMan", - "xuid": "2533274998970959", - "percentile": 0.9771, - "rank": 5, - "globalrank": 5, - "value": "535", - "valuemetadata": "{\"HasSkull\": true, \"Kills\": 11, \"Level\": \"Hardcake\", \"Empty\": null}" - } - ] - } - } - } -} \ No newline at end of file diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Microsoft.Xbox.Services.UnitTests.csproj b/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Microsoft.Xbox.Services.UnitTests.csproj index 49f6542..6372cda 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Microsoft.Xbox.Services.UnitTests.csproj +++ b/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Microsoft.Xbox.Services.UnitTests.csproj @@ -56,10 +56,6 @@ - - - - @@ -73,22 +69,7 @@ - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - Always - - - Always - PreserveNewest diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Privacy/MockDataForPrivacyTests.json b/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Privacy/MockDataForPrivacyTests.json deleted file mode 100644 index 432b4fc..0000000 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Privacy/MockDataForPrivacyTests.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "defaultCheckPermissionsResponse": { - "Request" : { - "method": "GET", - "serverName": "https://privacy.xboxlive.com", - "pathQueryFragment": "/users/xuid(2814662072777140)/permission/validate?setting=ViewTargetVideoHistory&target=xuid(2814680291986301)" - }, - "Response" : { - "httpStatus": 200, - "bodyType": 2, - "body": { - "isAllowed":false, - "reasons":[ - { - "reason":"NotAllowed" - }, - { - "reason":"BlockListRestrictsTarget" - }, - { - "reason":"MuteListRestrictsTarget" - } - ] - } - } - }, - "defaultCheckMultiplePermissionsResponse": { - "Request" : { - "method": "POST", - "serverName": "https://privacy.xboxlive.com", - "pathQueryFragment": "/users/xuid(2814662072777140)/permission/validate" - }, - "Response" : { - "httpStatus": 200, - "bodyType": 2, - "body": { - "responses": [{ - "user": { - "xuid": "2814680291986301" - }, - "permissions": [{ - "isAllowed": false, - "reasons": [{ - "reason": "NotAllowed" - }] - }, - { - "isAllowed": false, - "reasons": [{ - "reason": "NotAllowed" - }] - }, - { - "isAllowed": true - }] - }, - { - "user": { - "xuid": "2814634309691161" - }, - "permissions": [{ - "isAllowed": false, - "reasons": [{ - "reason": "NotAllowed" - }] - }, - { - "isAllowed": false, - "reasons": [{ - "reason": "NotAllowed" - }] - }, - { - "isAllowed": true - }] - }] - } - } - } -} \ No newline at end of file diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Privacy/PrivacyTests.cs b/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Privacy/PrivacyTests.cs deleted file mode 100644 index 1d0655f..0000000 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Privacy/PrivacyTests.cs +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Xbox.Services.UnitTests.Leaderboards -{ - using global::System; - using global::System.Collections.Generic; - using global::System.Threading.Tasks; - using Newtonsoft.Json.Linq; - - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Microsoft.Xbox.Services.Privacy; - - [TestClass] - public class PrivacyTests : TestBase - { - [TestInitialize] - public override void TestInitialize() - { - base.TestInitialize(); - MockXboxLiveData.Load(Environment.CurrentDirectory + "\\Privacy\\MockDataForPrivacyTests.json"); - } - - [TestCleanup] - public void TestCleanup() - { - } - - void VerifyPermissionCheckResult(PermissionCheckResult result, JObject resultToVerify) - { - var isAllowed = resultToVerify.SelectToken("isAllowed").Value(); - Assert.AreEqual(result.IsAllowed, isAllowed); - - int index = 0; - JArray jsonReasons = (JArray)(resultToVerify)["reasons"]; - if (jsonReasons != null) - { - foreach (var reason in jsonReasons) - { - Assert.AreEqual(result.Reasons[index].Reason, reason["reason"].ToString()); - ++index; - } - } - } - - void VerifyMultiplePermissionsCheckResult(List result, JObject resultToVerify) - { - int multiplePermIndex = 0; - JArray jsonResponses = (JArray)(resultToVerify)["responses"]; - foreach (var response in jsonResponses) - { - Assert.AreEqual(result[multiplePermIndex].XboxUserId, response["user"]["xuid"].ToString()); - - JArray jsonPermissions = (JArray)(response)["permissions"]; - int index = 0; - foreach (var permission in jsonPermissions) - { - VerifyPermissionCheckResult(result[multiplePermIndex].Items[index], (JObject)permission); - ++index; - } - - ++multiplePermIndex; - } - } - - [TestMethod] - public async Task CheckPermissionWithTargetUserAsync() - { - PermissionCheckResult result = await this.user.Services.PrivacyService.CheckPermissionWithTargetUserAsync(PermissionIdConstants.ViewTargetVideoHistory, "2814680291986301"); - MockXboxLiveData.MockRequestData mockRequestData = MockXboxLiveData.MockResponses["defaultCheckPermissionsResponse"]; - JObject responseJson = JObject.Parse(mockRequestData.Response.ResponseBodyString); - Assert.AreEqual("GET", mockRequestData.Request.Method); - Assert.AreEqual("https://privacy.xboxlive.com/users/xuid(2814662072777140)/permission/validate?setting=ViewTargetVideoHistory&target=xuid(2814680291986301)", mockRequestData.Request.Url); - VerifyPermissionCheckResult(result, responseJson); - } - - [TestMethod] - public async Task CheckMultiplePermissionsWithMultipleTargetUsersAsync() - { - List permissionIds = new List(); - permissionIds.Add(PermissionIdConstants.ViewTargetVideoHistory); - permissionIds.Add(PermissionIdConstants.ViewTargetMusicStatus); - permissionIds.Add(PermissionIdConstants.ViewTargetGameHistory); - - List xuids = new List(); - xuids.Add("2814680291986301"); - xuids.Add("2814634309691161"); - - List result = await this.user.Services.PrivacyService.CheckMultiplePermissionsWithMultipleTargetUsersAsync(permissionIds, xuids); - MockXboxLiveData.MockRequestData mockRequestData = MockXboxLiveData.MockResponses["defaultCheckMultiplePermissionsResponse"]; - JObject responseJson = JObject.Parse(mockRequestData.Response.ResponseBodyString); - Assert.AreEqual("POST", mockRequestData.Request.Method); - Assert.AreEqual("https://privacy.xboxlive.com/users/xuid(2814662072777140)/permission/validate", mockRequestData.Request.Url); - VerifyMultiplePermissionsCheckResult(result, responseJson); - } - } -} \ No newline at end of file diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Social/SocialManagerTests.cs b/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Social/SocialManagerTests.cs index f53a1a9..aec0701 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Social/SocialManagerTests.cs +++ b/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Social/SocialManagerTests.cs @@ -16,7 +16,6 @@ namespace Microsoft.Xbox.Services.UnitTests.Social public override void TestInitialize() { base.TestInitialize(); - MockXboxLiveData.Load(Environment.CurrentDirectory + "\\Social\\SocialManagerUT.json"); } [TestMethod] diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Social/SocialManagerUT.json b/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Social/SocialManagerUT.json deleted file mode 100644 index 450403b..0000000 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Social/SocialManagerUT.json +++ /dev/null @@ -1,144 +0,0 @@ -{ - "GettingProfile": { - "Request": { - "method": "GET", - "serverName": "https://peoplehub.xboxlive.com", - "pathQueryFragment": "/users/me/people/xuids(2814662072777140)/decoration/presenceDetail" - }, - "Response": { - "httpStatus": 200, - "bodyType": 2, - "body": { - "people": [ - { - "xuid": "2814662072777140", - "isFavorite": false, - "isFollowingCaller": false, - "isFollowedByCaller": false, - "isIdentityShared": false, - "addedDateTimeUtc": null, - "displayName": "2 Dev 183714711", - "realName": "", - "displayPicRaw": "http://images-eds.xboxlive.com/image?url=z951ykn43p4FqWbbFvR2Ec.8vbDhj8G2Xe7JngaTToBrrCmIEEXHC9UNrdJ6P7KIU5Sj_1hNZHeOVzbgzVj2gl0huLzRktrOPIt7LWZyuaghGltBhJkDROP7NOeAebn4&format=png", - "useAvatar": false, - "gamertag": "2 Dev 183714711", - "gamerScore": "0", - "xboxOneRep": "GoodPlayer", - "presenceState": "Offline", - "presenceText": "Offline", - "presenceDevices": null, - "isBroadcasting": false, - "isCloaked": null, - "suggestion": null, - "recommendation": null, - "titleHistory": null, - "multiplayerSummary": null, - "recentPlayer": null, - "follower": null, - "preferredColor": null, - "presenceDetails": [ ], - "titlePresence": null, - "titleSummaries": null, - "presenceTitleIds": null, - "detail": null, - "communityManagerTitles": null, - "socialManager": null, - "broadcast": null, - "tournamentSummary": null - } - ], - "recommendationSummary": null, - "friendFinderState": null - } - } - }, - "GettingSocial": { - "Request": { - "method": "GET", - "serverName": "https://peoplehub.xboxlive.com", - "pathQueryFragment": "/users/xuid(2814662072777140)/people/social" - }, - "Response": { - "httpStatus": 200, - "bodyType": 2, - "body": { - "people": [ ], - "recommendationSummary": null, - "friendFinderState": null - } - } - }, - "GettingProfileWithTitleHistory": { - "Request": { - "method": "GET", - "serverName": "https://peoplehub.xboxlive.com", - "pathQueryFragment": "/users/me/people/xuids(2814662072777140)/decoration/titlehistory(1766808267),preferredcolor,presenceDetail" - }, - "Response": { - "httpStatus": 200, - "bodyType": 2, - "body": { - "people": [ - { - "xuid": "2814662072777140", - "isFavorite": false, - "isFollowingCaller": false, - "isFollowedByCaller": false, - "isIdentityShared": false, - "addedDateTimeUtc": null, - "displayName": "2 Dev 183714711", - "realName": "", - "displayPicRaw": "http://images-eds.xboxlive.com/image?url=z951ykn43p4FqWbbFvR2Ec.8vbDhj8G2Xe7JngaTToBrrCmIEEXHC9UNrdJ6P7KIU5Sj_1hNZHeOVzbgzVj2gl0huLzRktrOPIt7LWZyuaghGltBhJkDROP7NOeAebn4&format=png", - "useAvatar": false, - "gamertag": "2 Dev 183714711", - "gamerScore": "0", - "xboxOneRep": "GoodPlayer", - "presenceState": "Offline", - "presenceText": "Offline", - "presenceDevices": null, - "isBroadcasting": false, - "isCloaked": null, - "suggestion": null, - "recommendation": null, - "titleHistory": null, - "multiplayerSummary": null, - "recentPlayer": null, - "follower": null, - "preferredColor": { - "primaryColor": "107c10", - "secondaryColor": "102b14", - "tertiaryColor": "155715" - }, - "presenceDetails": [ ], - "titlePresence": null, - "titleSummaries": null, - "presenceTitleIds": null, - "detail": null, - "communityManagerTitles": null, - "socialManager": null, - "broadcast": null, - "tournamentSummary": null - } - ], - "recommendationSummary": null, - "friendFinderState": null - } - } - }, - "GettingSocialWithTitleHistory": { - "Request": { - "method": "GET", - "serverName": "https://peoplehub.xboxlive.com", - "pathQueryFragment": "/users/xuid(2814662072777140)/people/social/decoration/titlehistory(1766808267),preferredcolor,presenceDetail" - }, - "Response": { - "httpStatus": 200, - "bodyType": 2, - "body": { - "people": [ ], - "recommendationSummary": null, - "friendFinderState": null - } - } - } -} diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Social/SocialUserGroupTests.cs b/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Social/SocialUserGroupTests.cs deleted file mode 100644 index 81262bc..0000000 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Social/SocialUserGroupTests.cs +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// -namespace Microsoft.Xbox.Services.UnitTests.Social -{ - using global::System; - using global::System.Collections.Generic; - using global::System.Linq; - using global::System.Threading.Tasks; - - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Microsoft.Xbox.Services.Social.Manager; - using Microsoft.Xbox.Services.System; - - [TestClass] - public class SocialUserGroupUnitTests - { - private XboxLiveUser user; - - [TestInitialize] - public void TestInitialize() - { - this.user = new XboxLiveUser(); - MockXboxLiveData.Load(Environment.CurrentDirectory + "\\Social\\SocialUserGroupUT.json"); - SocialManager.Instance.AddLocalUser(this.user, SocialManagerExtraDetailLevel.PreferredColorLevel); - } - - [TestMethod] - public void CreateSocialGroupWithSelfFromSocialManager() - { - var group = SocialManager.Instance.CreateSocialUserGroupFromList(this.user, new List { this.user.XboxUserId }); - Assert.IsNotNull(group); - - DoWorkUntil(() => group.Count == 1); - - Assert.AreEqual(this.user.XboxUserId, group.First().XboxUserId); - } - - [TestMethod] - public void CreateSocialGroupWithFilterOnlineFriendsFromSocialManager() - { - var group = SocialManager.Instance.CreateSocialUserGroupFromFilters(this.user, PresenceFilter.AllOnline, RelationshipFilter.Friends); - Assert.IsNotNull(group); - - DoWorkUntil(() => group.Count > 0); - - Assert.IsTrue(group.Count > 1); - } - - [TestMethod] - public void CreateSocialGroupWithFilterOnlineFavoritesFromSocialManager() - { - var group = SocialManager.Instance.CreateSocialUserGroupFromFilters(this.user, PresenceFilter.AllOnline, RelationshipFilter.Favorite); - Assert.IsNotNull(group); - - DoWorkUntil(() => group.Count > 0); - - Assert.IsTrue(group.Count > 1); - } - - [TestMethod] - public void CreateSocialGroupWithFilterOfflineFavoritesFromSocialManager() - { - var group = SocialManager.Instance.CreateSocialUserGroupFromFilters(this.user, PresenceFilter.AllOffline, RelationshipFilter.Favorite); - Assert.IsNotNull(group); - - DoWorkUntil(() => group.Count > 0); - - Assert.IsTrue(group.Count > 1); - } - - [TestMethod] - public void CreateSocialGroupWithOthers() - { - } - - private static Task DoWorkUntil(Func predicate) - { - return DoWorkUntil(predicate, TimeSpan.FromSeconds(5)); - } - - private static async Task DoWorkUntil(Func predicate, TimeSpan maxDuration) - { - DateTime workUntil = DateTime.UtcNow + maxDuration; - - do - { - IList events = SocialManager.Instance.DoWork(); - await Task.Delay(TimeSpan.FromMilliseconds(100)); - } - while (!predicate() && DateTime.UtcNow < workUntil); - - if (!predicate()) - { - Assert.Fail("Request did not complete as expected"); - } - } - } -} \ No newline at end of file diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Social/SocialUserGroupUT.json b/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Social/SocialUserGroupUT.json deleted file mode 100644 index cdecb7f..0000000 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/Social/SocialUserGroupUT.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "GettingProfile": { - "Request": { - "method": "GET", - "serverName": "https://peoplehub.xboxlive.com", - "pathQueryFragment": "/users/xuid(2814662072777140)/people/social/decoration/preferredcolor,presenceDetail" - }, - "Response": { - "httpStatus": 200, - "bodyType": 2, - "body": { - "people": [ ], - "recommendationSummary": null, - "friendFinderState": null - } - } - }, - "GettingSocial": { - "Request": { - "method": "GET", - "serverName": "https://peoplehub.xboxlive.com", - "pathQueryFragment": "/users/me/people/xuids(2814662072777140)/decoration/preferredcolor,presenceDetail" - }, - "Response": { - "httpStatus": 200, - "bodyType": 2, - "body": { - "people": [ - { - "xuid": "2814662072777140", - "isFavorite": false, - "isFollowingCaller": false, - "isFollowedByCaller": false, - "isIdentityShared": false, - "addedDateTimeUtc": null, - "displayName": "2 Dev 183714711", - "realName": "", - "displayPicRaw": "http://images-eds.xboxlive.com/image?url=z951ykn43p4FqWbbFvR2Ec.8vbDhj8G2Xe7JngaTToBrrCmIEEXHC9UNrdJ6P7KIU5Sj_1hNZHeOVzbgzVj2gl0huLzRktrOPIt7LWZyuaghGltBhJkDROP7NOeAebn4&format=png", - "useAvatar": false, - "gamertag": "2 Dev 183714711", - "gamerScore": "0", - "xboxOneRep": "GoodPlayer", - "presenceState": "Offline", - "presenceText": "Offline", - "presenceDevices": null, - "isBroadcasting": false, - "isCloaked": null, - "suggestion": null, - "recommendation": null, - "titleHistory": null, - "multiplayerSummary": null, - "recentPlayer": null, - "follower": null, - "preferredColor": { - "primaryColor": "107c10", - "secondaryColor": "102b14", - "tertiaryColor": "155715" - }, - "presenceDetails": [ ], - "titlePresence": null, - "titleSummaries": null, - "presenceTitleIds": null, - "detail": null, - "communityManagerTitles": null, - "socialManager": null, - "broadcast": null, - "tournamentSummary": null - } - ], - "recommendationSummary": null, - "friendFinderState": null - } - } - } -} diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/TitleStorage/TitleStorageUT.json b/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/TitleStorage/TitleStorageUT.json deleted file mode 100644 index 8917036..0000000 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UnitTests/TitleStorage/TitleStorageUT.json +++ /dev/null @@ -1,233 +0,0 @@ -{ - "GlobalStorageGetQuota": { - "Request": { - "method": "GET", - "serverName": "https://titlestorage.xboxlive.com", - "pathQueryFragment": "/global/scids/00000000-0000-0000-0000-0000694f5acb" - }, - "Response": { - "httpStatus": 200, - "bodyType": 2, - "body": { - "quotaInfo": { - "usedBytes": 605, - "quotaBytes": 268435456 - } - } - } - }, - "TrustedPlatformGetQuota": { - "Request": { - "method": "GET", - "serverName": "https://titlestorage.xboxlive.com", - "pathQueryFragment": "/trustedplatform/users/xuid(2814662072777140)/scids/00000000-0000-0000-0000-0000694f5acb" - }, - "Response": { - "httpStatus": 200, - "bodyType": 2, - "body": { - "quotaInfo": { - "usedBytes": 605, - "quotaBytes": 268435456 - } - } - } - }, - "UniversalPlatformGetQuota": { - "Request": { - "method": "GET", - "serverName": "https://titlestorage.xboxlive.com", - "pathQueryFragment": "/universalplatform/users/xuid(2814662072777140)/scids/00000000-0000-0000-0000-0000694f5acb" - }, - "Response": { - "httpStatus": 200, - "bodyType": 2, - "body": { - "quotaInfo": { - "usedBytes": 605, - "quotaBytes": 268435456 - } - } - } - }, - "UniversalPlatformUploadBlob": { - "Request": { - "method": "PUT", - "serverName": "https://titlestorage.xboxlive.com", - "pathQueryFragment": "/universalplatform/users/xuid(2814662072777140)/scids/00000000-0000-0000-0000-0000694f5acb/data/queststatus/quest01.json,json", - "body": { - "QuestName": "Quest 01", - "CharactersInvolved": [ - "Character 01", - "Character 02", - "Character 03" - ] - } - }, - "Response": { - "httpStatus": 201, - "bodyType": 2, - "body": { - - } - } - }, - "UniversalPlatformDeleteBlob": { - "Request": { - "method": "DELETE", - "serverName": "https://titlestorage.xboxlive.com", - "pathQueryFragment": "/universalplatform/users/xuid(2814662072777140)/scids/00000000-0000-0000-0000-0000694f5acb/data/queststatus/quest01.json,json" - }, - "Response": { - "httpStatus": 200, - "bodyType": 2, - "body": { - - } - } - }, - "UniversalPlatformUploadBinary01": { - "Request": { - "method": "PUT", - "serverName": "https://titlestorage.xboxlive.com", - "pathQueryFragment": "/universalplatform/users/xuid(2814662072777140)/scids/00000000-0000-0000-0000-0000694f5acb/data/file.bin,binary?finalBlock=True" - }, - "Response": { - "httpStatus": 200, - "bodyType": 2, - "body": { - "continuationToken": "40b2d28a-da60-4c80-b772-3208a1512bd2-1" - } - } - }, - "UniversalPlatformUploadBinary02": { - "Request": { - "method": "PUT", - "serverName": "https://titlestorage.xboxlive.com", - "pathQueryFragment": "/universalplatform/users/xuid(2814662072777140)/scids/00000000-0000-0000-0000-0000694f5acb/data/file.bin,binary?continuationToken=40b2d28a-da60-4c80-b772-3208a1512bd2-1&finalBlock=True" - }, - "Response": { - "httpStatus": 200, - "bodyType": 2, - "body": { - } - } - }, - "UniversalPlatformGetBlobMetadata": { - "Request": { - "method": "GET", - "serverName": "https://titlestorage.xboxlive.com", - "pathQueryFragment": "/universalplatform/users/xuid(2814662072777140)/scids/00000000-0000-0000-0000-0000694f5acb/data/queststatus" - }, - "Response": { - "httpStatus": 200, - "bodyType": 2, - "body": { - "blobs": [ - { - "fileName": "queststatus/quest01.json,json", - "etag": "0x8D47D2671F4407E", - "size": 122 - }, - { - "fileName": "queststatus/quest5.json,json", - "etag": "0x8D47C5A027989C3", - "size": 121 - }, - { - "fileName": "queststatus/quest6.json,json", - "etag": "0x8D47C5A02AC0C43", - "size": 121 - }, - { - "fileName": "queststatus/quest7.json,json", - "etag": "0x8D47C5A02D28094", - "size": 121 - }, - { - "fileName": "queststatus/quest8.json,json", - "etag": "0x8D47C5A02F8A6AF", - "size": 121 - }, - { - "fileName": "queststatus/quest9.json,json", - "etag": "0x8D47C5A03207A91", - "size": 121 - } - ], - "pagingInfo": { - "totalItems": 6, - "continuationToken": null - } - } - } - }, - "UniversalPlatformGetBlobMetadata2": { - "Request": { - "method": "GET", - "serverName": "https://titlestorage.xboxlive.com", - "pathQueryFragment": "/universalplatform/users/xuid(2814662072777140)/scids/00000000-0000-0000-0000-0000694f5acb/data/queststatus" - }, - "Response": { - "httpStatus": 200, - "bodyType": 2, - "body": { - "blobs": [ - { - "fileName": "queststatus/quest01.json,json", - "etag": "0x8D47D2671F4407E", - "size": 122 - }, - { - "fileName": "queststatus/quest5.json,json", - "etag": "0x8D47C5A027989C3", - "size": 121 - }, - { - "fileName": "queststatus/quest6.json,json", - "etag": "0x8D47C5A02AC0C43", - "size": 121 - }, - { - "fileName": "queststatus/quest7.json,json", - "etag": "0x8D47C5A02D28094", - "size": 121 - }, - { - "fileName": "queststatus/quest8.json,json", - "etag": "0x8D47C5A02F8A6AF", - "size": 121 - }, - { - "fileName": "queststatus/quest9.json,json", - "etag": "0x8D47C5A03207A91", - "size": 121 - } - ], - "pagingInfo": { - "totalItems": 6, - "continuationToken": null - } - } - } - }, - "UniversalPlatformDownloadBlob": { - "Request": { - "method": "GET", - "serverName": "https://titlestorage.xboxlive.com", - "pathQueryFragment": "/universalplatform/users/xuid(2814662072777140)/scids/00000000-0000-0000-0000-0000694f5acb/data/queststatus/quest01.json,json" - }, - "Response": { - "httpStatus": 200, - "bodyType": 2, - "body": { - "QuestName": "Quest 01", - "CharactersInvolved": [ - "Character 01", - "Character 02", - "Character 03" - ] - } - } - } -} \ No newline at end of file diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/Common/XboxLive.cs b/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/Common/XboxLive.cs index 21d270e..cbe4915 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/Common/XboxLive.cs +++ b/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/Common/XboxLive.cs @@ -10,10 +10,5 @@ namespace Microsoft.Xbox.Services { get { return true; } } - - public static bool UseMockHttp - { - get { return false; } - } } } \ No newline at end of file diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/Common/XboxLiveAppConfiguration.cs b/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/Common/XboxLiveAppConfiguration.cs index 05127ee..70f55b3 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/Common/XboxLiveAppConfiguration.cs +++ b/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/Common/XboxLiveAppConfiguration.cs @@ -4,10 +4,30 @@ namespace Microsoft.Xbox.Services { + using Newtonsoft.Json; using global::System.IO; public partial class XboxLiveAppConfiguration { + public string PublisherId { get; set; } + + public string PublisherDisplayName { get; set; } + + public string PackageIdentityName { get; set; } + + public string DisplayName { get; set; } + + public string AppId { get; set; } + + public string ProductFamilyName { get; set; } + + public bool XboxLiveCreatorsTitle { get; set; } + + private static XboxLiveAppConfiguration Load() + { + return XboxLiveAppConfiguration.Load(FileName); + } + public static XboxLiveAppConfiguration Load(string path) { if (!File.Exists(path)) @@ -21,7 +41,7 @@ namespace Microsoft.Xbox.Services throw new XboxException(string.Format("Xbox Live app configeration file '{0}' was empty.", path)); } - return JsonSerialization.FromJson(content); + return JsonConvert.DeserializeObject(content); } } } \ No newline at end of file diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/Leaderboard/LeaderboardQuery.cs b/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/Leaderboard/LeaderboardQuery.cs index e76d0d7..d80a23d 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/Leaderboard/LeaderboardQuery.cs +++ b/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/Leaderboard/LeaderboardQuery.cs @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation // Licensed under the MIT license. See LICENSE file in the project root for full license information. +// namespace Microsoft.Xbox.Services.Leaderboard { diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/Leaderboard/LeaderboardQueryUnityEditorImpl.cs b/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/Leaderboard/LeaderboardQueryUnityEditorImpl.cs index 53a4afa..eaa4307 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/Leaderboard/LeaderboardQueryUnityEditorImpl.cs +++ b/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/Leaderboard/LeaderboardQueryUnityEditorImpl.cs @@ -1,12 +1,15 @@ - -using System; +// Copyright (c) Microsoft Corporation +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// namespace Microsoft.Xbox.Services.Leaderboard { + using global::System; + class LeaderboardQueryUnityEditorImpl : ILeaderboardQueryImpl { public IntPtr GetPtr() { return IntPtr.Zero; } - + uint m_maxItems; public uint GetMaxItems() { diff --git a/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/System/UserImpl.cs b/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/System/UserImpl.cs index 24c0a74..06c001a 100644 --- a/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/System/UserImpl.cs +++ b/CSharpSource/Source/Microsoft.Xbox.Services.UnityEditor.CSharp/System/UserImpl.cs @@ -16,11 +16,10 @@ namespace Microsoft.Xbox.Services.System public string AgeGroup { get; set; } public string Privileges { get; set; } public string WebAccountId { get; set; } - public AuthConfig AuthConfig { get; set; } private static int numberOfInstances; private static Random random = new Random(); - + public Task SignInImpl(bool showUI, bool forceRefresh) { if (XboxLive.UseMockServices) @@ -36,11 +35,11 @@ namespace Microsoft.Xbox.Services.System throw new NotImplementedException(); } - public Task InternalGetTokenAndSignatureAsync(string httpMethod, string url, string headers, byte[] body, bool promptForCredentialsIfNeeded, bool forceRefresh) + public Task InternalGetTokenAndSignatureAsync(string httpMethod, string url, string headers, byte[] body, bool promptForCredentialsIfNeeded, bool forceRefresh) { if (XboxLive.UseMockServices) { - return Task.FromResult(new TokenAndSignatureResult + return Task.FromResult(new GetTokenAndSignatureResult { Gamertag = this.Gamertag, XboxUserId = this.XboxUserId, diff --git a/CSharpSource/Source/api/Common/HttpCallRequestMessage.cs b/CSharpSource/Source/api/Common/HttpCallRequestMessage.cs index e28e22b..52224a4 100644 --- a/CSharpSource/Source/api/Common/HttpCallRequestMessage.cs +++ b/CSharpSource/Source/api/Common/HttpCallRequestMessage.cs @@ -1,33 +1,17 @@ // Copyright (c) Microsoft Corporation // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using System; -using System.Linq; -using System.Collections.Generic; -using System.Threading.Tasks; namespace Microsoft.Xbox.Services { + using global::System; + public class HttpCallRequestMessage { + public HttpRequestMessageType GetHttpRequestMessageType { get; private set; } - public HttpRequestMessageType GetHttpRequestMessageType - { - get; - private set; - } - - public Byte[] RequestMessageVector - { - get; - private set; - } - - public string RequestMessageString - { - get; - private set; - } + public Byte[] RequestMessageVector { get; private set; } + public string RequestMessageString { get; private set; } } } diff --git a/CSharpSource/Source/api/Common/HttpCallResponseBodyType.cs b/CSharpSource/Source/api/Common/HttpCallResponseBodyType.cs index de94210..45afd07 100644 --- a/CSharpSource/Source/api/Common/HttpCallResponseBodyType.cs +++ b/CSharpSource/Source/api/Common/HttpCallResponseBodyType.cs @@ -3,8 +3,6 @@ // namespace Microsoft.Xbox.Services { - using global::System; - public enum HttpCallResponseBodyType : uint { StringBody, diff --git a/CSharpSource/Source/api/Common/HttpMethod.cs b/CSharpSource/Source/api/Common/HttpMethod.cs deleted file mode 100644 index b1a64d2..0000000 --- a/CSharpSource/Source/api/Common/HttpMethod.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// -namespace Microsoft.Xbox.Services -{ - public static class HttpMethod - { - public const string Get = "GET"; - public const string Put = "PUT"; - public const string Post = "POST"; - public const string Delete = "DELETE"; - public const string Patch = "PATCH"; - public const string Options = "OPTIONS"; - } -} \ No newline at end of file diff --git a/CSharpSource/Source/api/Common/HttpRetryAfterAPIState.cs b/CSharpSource/Source/api/Common/HttpRetryAfterAPIState.cs deleted file mode 100644 index 4bb12b7..0000000 --- a/CSharpSource/Source/api/Common/HttpRetryAfterAPIState.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// -namespace Microsoft.Xbox.Services -{ - using global::System; - - public class HttpRetryAfterApiState - { - public DateTime RetryAfterTime { get; set; } - public Exception Exception { get; set; } - public XboxLiveHttpResponse HttpCallResponse { get; set; } - } -} - - diff --git a/CSharpSource/Source/api/Common/HttpRetryAfterManager.cs b/CSharpSource/Source/api/Common/HttpRetryAfterManager.cs deleted file mode 100644 index 001b6d5..0000000 --- a/CSharpSource/Source/api/Common/HttpRetryAfterManager.cs +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// -namespace Microsoft.Xbox.Services -{ - using global::System; - using global::System.Collections.Generic; - - public class HttpRetryAfterManager - { - private static readonly object instanceLock = new object(); - private static HttpRetryAfterManager instance; - private readonly Dictionary apiStateMap = new Dictionary(); - - public static HttpRetryAfterManager Instance - { - get - { - if (instance == null) - { - lock (instanceLock) - { - if (instance == null) - { - instance = new HttpRetryAfterManager(); - } - } - } - return instance; - } - - private set - { - instance = null; - } - } - - public void SetState( - XboxLiveAPIName xboxLiveApi, - HttpRetryAfterApiState state - ) - { - lock (instanceLock) - { - this.apiStateMap[xboxLiveApi] = state; - } - } - - public void ClearState( - XboxLiveAPIName xboxLiveApi - ) - { - lock (instanceLock) - { - this.apiStateMap.Remove(xboxLiveApi); - } - - } - - public bool GetState( - XboxLiveAPIName xboxLiveApi, - out HttpRetryAfterApiState returnValue - ) - { - lock (instanceLock) - { - return this.apiStateMap.TryGetValue(xboxLiveApi, out returnValue); - } - } - }; -} - - diff --git a/CSharpSource/Source/api/Common/IXboxLiveUser.cs b/CSharpSource/Source/api/Common/IXboxLiveUser.cs index 61c2e7b..eb8ca8d 100644 --- a/CSharpSource/Source/api/Common/IXboxLiveUser.cs +++ b/CSharpSource/Source/api/Common/IXboxLiveUser.cs @@ -5,7 +5,7 @@ namespace Microsoft.Xbox.Services { using global::System.Threading.Tasks; - public interface IXboxLiveUser + internal interface IXboxLiveUser { string WebAccountId { get; } @@ -29,10 +29,10 @@ namespace Microsoft.Xbox.Services Task SignInSilentlyAsync(); - Task GetTokenAndSignatureAsync(string httpMethod, string url, string headers); + Task GetTokenAndSignatureAsync(string httpMethod, string url, string headers); - Task GetTokenAndSignatureAsync(string httpMethod, string url, string headers, string body); + Task GetTokenAndSignatureAsync(string httpMethod, string url, string headers, string body); - Task GetTokenAndSignatureArrayAsync(string httpMethod, string url, string headers, byte[] body); + Task GetTokenAndSignatureArrayAsync(string httpMethod, string url, string headers, byte[] body); } } \ No newline at end of file diff --git a/CSharpSource/Source/api/Common/SignInCompletedEventArgs.cs b/CSharpSource/Source/api/Common/SignInCompletedEventArgs.cs index 559a8b1..b7ad91d 100644 --- a/CSharpSource/Source/api/Common/SignInCompletedEventArgs.cs +++ b/CSharpSource/Source/api/Common/SignInCompletedEventArgs.cs @@ -7,11 +7,11 @@ namespace Microsoft.Xbox.Services public class SignInCompletedEventArgs : EventArgs { - public SignInCompletedEventArgs(IXboxLiveUser user) + public SignInCompletedEventArgs(XboxLiveUser user) { this.User = user; } - public IXboxLiveUser User { get; private set; } + public XboxLiveUser User { get; private set; } } } \ No newline at end of file diff --git a/CSharpSource/Source/api/Common/SignOutCompletedEventArgs.cs b/CSharpSource/Source/api/Common/SignOutCompletedEventArgs.cs index fa09e25..9b3a024 100644 --- a/CSharpSource/Source/api/Common/SignOutCompletedEventArgs.cs +++ b/CSharpSource/Source/api/Common/SignOutCompletedEventArgs.cs @@ -7,12 +7,11 @@ namespace Microsoft.Xbox.Services public class SignOutCompletedEventArgs : EventArgs { - public SignOutCompletedEventArgs(IXboxLiveUser user) + public SignOutCompletedEventArgs(XboxLiveUser user) { this.User = user; } - // TODO change this to XboxLiveUser instead of IXboxLive user to match WinRT projections - public IXboxLiveUser User { get; private set; } + public XboxLiveUser User { get; private set; } } } \ No newline at end of file diff --git a/CSharpSource/Source/api/Common/TokenAndSignatureResult.cs b/CSharpSource/Source/api/Common/TokenAndSignatureResult.cs index 2f90eec..1913127 100644 --- a/CSharpSource/Source/api/Common/TokenAndSignatureResult.cs +++ b/CSharpSource/Source/api/Common/TokenAndSignatureResult.cs @@ -8,7 +8,7 @@ using Windows.Security.Authentication.Web.Core; namespace Microsoft.Xbox.Services { - public class TokenAndSignatureResult + public class GetTokenAndSignatureResult { public string WebAccountId { get; set; } @@ -25,10 +25,5 @@ namespace Microsoft.Xbox.Services public string Signature { get; set; } public string Token { get; set; } - - internal string Reserved { get; set; } -#if WINDOWS_UWP - internal WebTokenRequestStatus TokenRequestResultStatus { get; set; } -#endif } } \ No newline at end of file diff --git a/CSharpSource/Source/api/Common/XboxException.cs b/CSharpSource/Source/api/Common/XboxException.cs index 58ea78f..97c6c4e 100644 --- a/CSharpSource/Source/api/Common/XboxException.cs +++ b/CSharpSource/Source/api/Common/XboxException.cs @@ -30,6 +30,11 @@ namespace Microsoft.Xbox.Services { } + internal XboxException(XSAPI_RESULT result, IntPtr errorMessagePtr) + : base(string.Format("Xbox Services flat C API return error code {0} with message \"{1}\"", result.ToString("g"), MarshalingHelpers.Utf8ToString(errorMessagePtr))) + { + } + internal XboxException(XSAPI_RESULT_INFO resultInfo) : base (string.Format("Xbox Services flat C API return error code {0} with message \"{1}\"", resultInfo.errorCode.ToString("g"), MarshalingHelpers.Utf8ToString(resultInfo.errorMessage))) { diff --git a/CSharpSource/Source/api/Common/XboxLive.cs b/CSharpSource/Source/api/Common/XboxLive.cs index 008dc41..e063759 100644 --- a/CSharpSource/Source/api/Common/XboxLive.cs +++ b/CSharpSource/Source/api/Common/XboxLive.cs @@ -5,9 +5,7 @@ namespace Microsoft.Xbox.Services { using global::System; using global::System.IO; - using global::System.ComponentModel; using global::System.Runtime.InteropServices; - using Microsoft.Xbox.Services.Presence; using Microsoft.Xbox.Services.Social.Manager; using Microsoft.Xbox.Services.Statistics.Manager; using Microsoft.Xbox.Services.System; @@ -16,7 +14,6 @@ namespace Microsoft.Xbox.Services { private bool disposed; private static XboxLive instance; - private XboxLiveSettings settings; private IStatisticManager statsManager; private ISocialManager socialManager; @@ -32,24 +29,23 @@ namespace Microsoft.Xbox.Services private XboxLive() { - this.settings = new XboxLiveSettings(); - try { - this.appConfig = XboxLiveAppConfiguration.Instance; +#if WINDOWS_UWP + var result = XBLGlobalInitialize(); + if (result != XSAPI_RESULT.XSAPI_RESULT_OK) + { + throw new XboxException(result); + } +#endif + // TODO flat C APIs for settings + //this.Settings = null; + this.appConfig = XboxLiveAppConfiguration.SingletonInstance; } catch (FileLoadException) { this.appConfig = null; } - -#if WINDOWS_UWP - var result = XBLGlobalInitialize(); - if (result != XSAPI_RESULT.XSAPI_RESULT_OK) - { - throw new XboxException(result); - } -#endif } ~XboxLive() @@ -104,15 +100,14 @@ namespace Microsoft.Xbox.Services } } - public XboxLiveSettings Settings - { - get { return Instance.settings; } - set { Instance.settings = value; } - } + //public XboxLiveContextSettings Settings { get; private set; } public XboxLiveAppConfiguration AppConfig { - get { return Instance.appConfig; } + get + { + return Instance.appConfig; + } } protected virtual void Dispose(bool disposing) @@ -134,7 +129,7 @@ namespace Microsoft.Xbox.Services GC.SuppressFinalize(this); } - public static Int64 DefaultTaskGroupId + internal static Int64 DefaultTaskGroupId { get { diff --git a/CSharpSource/Source/api/Common/XboxLiveAPIName.cs b/CSharpSource/Source/api/Common/XboxLiveAPIName.cs deleted file mode 100644 index 38bbbbf..0000000 --- a/CSharpSource/Source/api/Common/XboxLiveAPIName.cs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// -namespace Microsoft.Xbox.Services -{ - public enum XboxLiveAPIName : uint - { - Unspecified = 0, - AllocateCluster, - AllocateClusterInline, - AllocateSessionHost, - BrowseCatalogBundlesHelper, - BrowseCatalogHelper, - CheckMultiplePermissionsWithMultipleTargetUsers, - CheckPermissionWithTargetUser, - ClearActivity, - ClearSearchHandle, - ConsumeInventoryItem, - CreateMatchTicket, - DeleteBlob, - DeleteMatchTicket, - DownloadBlob, - GetAchievement, - GetAchievements, - GetActivitiesForSocialGroup, - GetActivitiesForUsers, - GetAvoidOrMuteList, - GetBlobMetadata, - GetBroadcasts, - GetCatalogItemDetails, - GetConfiguration, - GetCurrentSession, - GetCurrentSessionByHandle, - GetGameClips, - GetGameServerMetadata, - GetHopperStatistics, - GetInventoryItem, - GetInventoryItems, - GetLeaderboardForSocialGroupInternal, - GetLeaderboardInternal, - GetMatchTicketDetails, - GetMultipleUserStatisticsForMultipleServiceConfigurations, - GetPresence, - GetPresenceForMultipleUsers, - GetPresenceForSocialGroup, - GetQualityOfServiceServers, - GetQuota, - GetQuotaForSessionStorage, - GetSearchHandles, - GetSessionHostAllocationStatus, - GetSessions, - GetSingleUserStatistics, - GetSocialGraph, - GetSocialRelationships, - GetStatsValueDocument, - GetTicketStatus, - GetTournaments, - GetTournamentDetails, - GetTeams, - GetTeamDetails, - GetUserProfiles, - GetProfileInfo, - GetUserProfilesForSocialGroup, - RegisterTeam, - SendInvites, - SetActivity, - SetPresenceHelper, - SetSearchHandle, - SetTransferHandle, - SubmitBatchReputationFeedback, - SubmitReputationFeedback, - SubscribeToNotifications, - UpdateAchievement, - UpdateStatsValueDocument, - UploadBlob, - VerifyStrings, - WriteSessionUsingSubpath, - XboxOnePinsAddItem, - XboxOnePinsContainsItem, - XboxOnePinsRemoveItem - }; -} - diff --git a/CSharpSource/Source/api/Common/XboxLiveAppConfiguration.cs b/CSharpSource/Source/api/Common/XboxLiveAppConfiguration.cs index 7893685..4c08555 100644 --- a/CSharpSource/Source/api/Common/XboxLiveAppConfiguration.cs +++ b/CSharpSource/Source/api/Common/XboxLiveAppConfiguration.cs @@ -4,8 +4,9 @@ namespace Microsoft.Xbox.Services { using global::System; - - using Newtonsoft.Json; +#if UNITY_EDITOR + using global::Newtonsoft.Json; +#endif public partial class XboxLiveAppConfiguration { @@ -14,45 +15,10 @@ namespace Microsoft.Xbox.Services private static readonly object instanceLock = new object(); private static XboxLiveAppConfiguration instance; - public static XboxLiveAppConfiguration Instance - { - get - { - if (instance == null) - { - lock (instanceLock) - { - if (instance == null) - { - instance = Load(); - } - } - } - return instance; - } - } - - private XboxLiveAppConfiguration() - { - } - - public string PublisherId { get; set; } - - public string PublisherDisplayName { get; set; } - - public string PackageIdentityName { get; set; } - - public string DisplayName { get; set; } - - public string AppId { get; set; } - - public string ProductFamilyName { get; set; } - - internal string EnvironmentPrefix { get; set; } - - internal bool UseFirstPartyToken { get; set; } - - public string PrimaryServiceConfigId { get; set; } +#if UNITY_EDITOR + [JsonProperty("PrimaryServiceConfigId")] +#endif + public string ServiceConfigurationId { get; set; } public uint TitleId { get; set; } @@ -60,30 +26,34 @@ namespace Microsoft.Xbox.Services public string Environment { get; set; } - public bool XboxLiveCreatorsTitle { get; set; } - - public string GetEndpointForService(string serviceName, string protocol = "https") + public static XboxLiveAppConfiguration SingletonInstance { - return string.Format("{0}://{1}{2}.xboxlive.com", protocol, serviceName, string.IsNullOrEmpty(this.Environment) ? string.Empty : ("." + this.Environment)); - } - - public static XboxLiveAppConfiguration Load() - { - try + get { - // Attempt to load it from a file - return Load(FileName); - } - catch (Exception e) - { - // If we're unable to load the file for some reason, we can just use an empty file - // if mock data is enable. - if (XboxLive.UseMockServices || XboxLive.UseMockHttp) + if (instance == null) { - return new XboxLiveAppConfiguration(); + lock (instanceLock) + { + try + { + if (instance == null) + { + instance = XboxLiveAppConfiguration.Load(); + } + } + catch(Exception e) + { + // If we're unable to load the file for some reason, we can just use an empty file + // if mock data is enable. + if (XboxLive.UseMockServices) + { + return new XboxLiveAppConfiguration(); + } + throw new XboxException(string.Format("Unable to find or load Xbox Live configuration. Make sure a properly configured Xboxservices.config exists."), e); + } + } } - - throw new XboxException(string.Format("Unable to find or load Xbox Live configuration. Make sure a properly configured {0} exists.", FileName), e); + return instance; } } } diff --git a/CSharpSource/Source/api/Common/XboxLiveContextRecommendedSetting.cs b/CSharpSource/Source/api/Common/XboxLiveContextRecommendedSetting.cs index b474f95..8f42aa0 100644 --- a/CSharpSource/Source/api/Common/XboxLiveContextRecommendedSetting.cs +++ b/CSharpSource/Source/api/Common/XboxLiveContextRecommendedSetting.cs @@ -1,10 +1,6 @@ // Copyright (c) Microsoft Corporation // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using System; -using System.Linq; -using System.Collections.Generic; -using System.Threading.Tasks; namespace Microsoft.Xbox.Services { @@ -12,5 +8,4 @@ namespace Microsoft.Xbox.Services { ThisCodeNeedsToBeChangedToFollowBestPractices = 0, } - -} +} \ No newline at end of file diff --git a/CSharpSource/Source/api/Common/XboxLiveContextThrottleSetting.cs b/CSharpSource/Source/api/Common/XboxLiveContextThrottleSetting.cs index f41acb2..58fd38a 100644 --- a/CSharpSource/Source/api/Common/XboxLiveContextThrottleSetting.cs +++ b/CSharpSource/Source/api/Common/XboxLiveContextThrottleSetting.cs @@ -1,10 +1,6 @@ // Copyright (c) Microsoft Corporation // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using System; -using System.Linq; -using System.Collections.Generic; -using System.Threading.Tasks; namespace Microsoft.Xbox.Services { @@ -12,5 +8,4 @@ namespace Microsoft.Xbox.Services { ThisCodeNeedsToBeChangedToAvoidThrottling = 0, } - -} +} \ No newline at end of file diff --git a/CSharpSource/Source/api/Common/XboxLiveHttpRequest.cs b/CSharpSource/Source/api/Common/XboxLiveHttpRequest.cs deleted file mode 100644 index 3c4f563..0000000 --- a/CSharpSource/Source/api/Common/XboxLiveHttpRequest.cs +++ /dev/null @@ -1,639 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -namespace Microsoft.Xbox.Services -{ - using global::System; - using global::System.Diagnostics; - using global::System.Collections.Generic; - using global::System.Globalization; - using global::System.IO; - using global::System.Net; - using global::System.Reflection; - using global::System.Runtime.InteropServices; - using global::System.Text; - using global::System.Threading; - using global::System.Threading.Tasks; - - public class XboxLiveHttpRequest - { - private const string AuthorizationHeaderName = "Authorization"; - private const string SignatureHeaderName = "Signature"; - private const string RangeHeaderName = "Range"; - private const string ContentLengthHeaderName = "Content-Length"; - private const double DefaultHttpTimeoutSeconds = 30.0; - private const double MinHttpTimeoutSeconds = 5.0; - private const int HttpStatusCodeTooManyRequests = 429; - private const double MaxDelayTimeInSec = 60.0; - private const int MinDelayForHttpInternalErrorInSec = 10; - private static string userAgentVersion; - - internal XboxLiveHttpRequest(string method, string serverName, string pathQueryFragment) - { - this.iterationNumber = 0; - this.Method = method; - this.Url = serverName + pathQueryFragment; - this.contextSettings = XboxLive.Instance.Settings; - this.webRequest = (HttpWebRequest)WebRequest.Create(new Uri(this.Url)); - this.webRequest.Method = method; - this.ResponseBodyType = HttpCallResponseBodyType.StringBody; - this.RetryAllowed = true; - - this.SetCustomHeader("Accept-Language", CultureInfo.CurrentUICulture + "," + CultureInfo.CurrentUICulture.TwoLetterISOLanguageName); -#if WINDOWS_UWP - this.SetCustomHeader("Accept", "*/*"); -#else - this.webRequest.Accept = "*/*"; -#endif - this.SetCustomHeader("Cache-Control", "no-cache"); - this.ContentType = "application/json; charset=utf-8"; - } - - internal readonly XboxLiveSettings contextSettings; - internal HttpWebRequest webRequest; - internal readonly Dictionary customHeaders = new Dictionary(); - internal bool hasPerformedRetryOn401 { get; set; } - internal uint iterationNumber { get; set; } - internal DateTime firstCallStartTime { get; set; } - internal TimeSpan delayBeforeRetry { get; set; } - - public bool LongHttpCall { get; set; } - public string Method { get; private set; } - public string Url { get; private set; } - public string ContractVersion { get; set; } - public bool RetryAllowed { get; set; } - public string ContentType { get; set; } - public string RequestBody { get; set; } - public HttpCallResponseBodyType ResponseBodyType { get; set; } - public XboxLiveUser User { get; private set; } - public XboxLiveAPIName XboxLiveAPI { get; set; } - public string CallerContext { get; set; } - - private string Headers - { - get - { - StringBuilder sb = new StringBuilder(); - bool isFirstVal = true; - foreach (var header in this.customHeaders) - { - if (isFirstVal) - { - isFirstVal = false; - } - else - { - sb.AppendLine(); - } - - sb.AppendFormat("{0}: {1}", header.Key, header.Value); - } - return sb.ToString(); - } - } - - public Task GetResponseWithAuth(XboxLiveUser user) - { - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); - this.User = user; - - user.GetTokenAndSignatureAsync(this.Method, this.Url, this.Headers).ContinueWith( - tokenTask => - { - if (tokenTask.IsFaulted) - { - taskCompletionSource.SetException(tokenTask.Exception); - return; - } - - try - { - this.SetAuthHeaders(tokenTask.Result); - this.SetRequestHeaders(); - this.InternalGetResponse().ContinueWith(getResponseTask => - { - if (getResponseTask.IsFaulted) - { - taskCompletionSource.SetException(getResponseTask.Exception); - } - else - { - taskCompletionSource.SetResult(getResponseTask.Result); - } - }); - } - catch (Exception e) - { - taskCompletionSource.SetException(e); - } - }); - - return taskCompletionSource.Task; - } - - private void SetAuthHeaders(TokenAndSignatureResult result) - { -#if !WINDOWS_UWP - this.SetCustomHeader(AuthorizationHeaderName, string.Format("XBL3.0 x={0};{1}", result.XboxUserHash, result.Token)); -#else - this.SetCustomHeader(AuthorizationHeaderName, string.Format("{0}", result.Token)); -#endif - this.SetCustomHeader(SignatureHeaderName, result.Signature); - } - - private void SetRequestHeaders() - { - if (!string.IsNullOrEmpty(this.ContractVersion)) - { - this.SetCustomHeader("x-xbl-contract-version", this.ContractVersion); - } - - foreach (KeyValuePair customHeader in this.customHeaders) - { - this.webRequest.Headers[customHeader.Key] = customHeader.Value; - } - } - - public virtual Task GetResponseWithoutAuth() - { - this.SetRequestHeaders(); - return this.InternalGetResponse(); - } - - private void HandleThrottledCalls(XboxLiveHttpResponse httpCallResponse) - { - if (string.Equals(XboxLiveAppConfiguration.Instance.Sandbox, "RETAIL", StringComparison.Ordinal) || - this.contextSettings.AreAssertsForThrottlingInDevSandboxesDisabled) - return; - -#if DEBUG - string msg; - msg = "Xbox Live service call to " + httpCallResponse.Url.ToString() + " was throttled\r\n"; - msg += httpCallResponse.RequestBody; - msg += "\r\n"; - msg += "You can temporarily disable the assert by calling\r\n"; - msg += "XboxLive.Instance.Settings.DisableAssertsForXboxLiveThrottlingInDevSandboxes()\r\n"; - msg += "Note that this will only disable this assert. You will still be throttled in all sandboxes.\r\n"; - Debug.WriteLine(msg); -#endif - - throw new XboxException("Xbox Live service call was throttled. See Output for more detail"); - } - - private Task InternalGetResponse() - { - DateTime requestStartTime = DateTime.UtcNow; - if (this.iterationNumber == 0) - { - this.firstCallStartTime = requestStartTime; - } - this.iterationNumber++; - - HttpRetryAfterApiState apiState; - if (HttpRetryAfterManager.Instance.GetState(this.XboxLiveAPI, out apiState)) - { - if (this.ShouldFastFail(apiState, requestStartTime)) - { - return this.HandleFastFail(apiState); - } - else - { - HttpRetryAfterManager.Instance.ClearState(this.XboxLiveAPI); - } - } - - this.SetUserAgent(); - - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); - - this.WriteRequestBodyAsync().ContinueWith(writeBodyTask => - { - // The explicit cast in the next method should not be necessary, but Visual Studio is complaining - // that the call is ambiguous. This removes that in-editor error. - Task.Factory.FromAsync(this.webRequest.BeginGetResponse, (Func)this.webRequest.EndGetResponse, null) - .ContinueWith(getResponseTask => - { - var httpWebResponse = ExtractHttpWebResponse(getResponseTask); - int httpStatusCode = 0; - bool networkFailure = false; - if (httpWebResponse != null) - { - httpStatusCode = (int)httpWebResponse.StatusCode; - } - else - { - // classify as network failure if there's no HTTP status code and didn't get response - networkFailure = getResponseTask.IsFaulted || getResponseTask.IsCanceled; - } - - var httpCallResponse = new XboxLiveHttpResponse( - httpStatusCode, - networkFailure, - httpWebResponse, - DateTime.UtcNow, - requestStartTime, - this.User != null ? this.User.XboxUserId : "", - this.contextSettings, - this.Url, - this.XboxLiveAPI, - this.Method, - this.RequestBody, - this.ResponseBodyType - ); - - if (this.ShouldRetry(httpCallResponse)) - { - // Wait and retry call - this.RecordServiceResult(httpCallResponse, getResponseTask.Exception); - this.RouteServiceCall(httpCallResponse); - Sleep(this.delayBeforeRetry); - this.webRequest = CloneHttpWebRequest(this.webRequest); - this.InternalGetResponse().ContinueWith(retryGetResponseTask => - { - if (retryGetResponseTask.IsFaulted) - { - taskCompletionSource.SetException(retryGetResponseTask.Exception); - } - else - { - taskCompletionSource.SetResult(retryGetResponseTask.Result); - } - }); - } - else if (!networkFailure) // Got HTTP status code - { - // HTTP 429: TOO MANY REQUESTS errors should return a JSON debug payload - // describing the details about why the call was throttled - this.RecordServiceResult(httpCallResponse, getResponseTask.Exception); - this.RouteServiceCall(httpCallResponse); - - if (httpCallResponse.HttpStatus == HttpStatusCodeTooManyRequests) - { - this.HandleThrottledCalls(httpCallResponse); - } - - if (getResponseTask.IsFaulted) - { - taskCompletionSource.SetException(getResponseTask.Exception); - } - else - { - taskCompletionSource.SetResult(httpCallResponse); - } - } - else - { - // Handle network errors - - // HandleResponseError(); // TODO: extract error from JSON - this.RecordServiceResult(httpCallResponse, getResponseTask.Exception); - this.RouteServiceCall(httpCallResponse); - taskCompletionSource.SetException(getResponseTask.Exception); - } - }); - }); - - return taskCompletionSource.Task; - } - - private bool ShouldFastFail( - HttpRetryAfterApiState apiState, - DateTime currentTime - ) - { - if (apiState.Exception == null) - { - return false; - } - - TimeSpan remainingTimeBeforeRetryAfter = apiState.RetryAfterTime - currentTime; - if (remainingTimeBeforeRetryAfter.Ticks <= 0) - { - return false; - } - - DateTime timeoutTime = this.firstCallStartTime + this.contextSettings.HttpTimeoutWindow; - - // If the Retry-After will happen first, just wait till Retry-After is done, and don't fast fail - if (apiState.RetryAfterTime < timeoutTime) - { - Sleep(remainingTimeBeforeRetryAfter); - return false; - } - else - { - return true; - } - } - - private Task HandleFastFail(HttpRetryAfterApiState apiState) - { - XboxLiveHttpResponse httpCallResponse = apiState.HttpCallResponse; - this.RouteServiceCall(httpCallResponse); - - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); - taskCompletionSource.SetException(apiState.Exception); - return taskCompletionSource.Task; - } - - private void SetUserAgent() - { - const string userAgentType = "XboxServicesAPICSharp"; - lock (XboxLive.Instance) - { - if (string.IsNullOrEmpty(userAgentVersion)) - { -#if !WINDOWS_UWP - userAgentVersion = typeof(XboxLiveHttpRequest).Assembly.GetName().Version.ToString(); -#else - userAgentVersion = typeof(XboxLiveHttpRequest).GetTypeInfo().Assembly.GetName().Version.ToString(); -#endif - } - } - - string userAgent = userAgentType + "/" + userAgentVersion; - if (!string.IsNullOrEmpty(this.CallerContext)) - { - userAgent += " " + this.CallerContext; - } - this.SetCustomHeader("UserAgent", userAgent); - } - - private bool ShouldRetry(XboxLiveHttpResponse httpCallResponse) - { - int httpStatus = httpCallResponse.HttpStatus; - - if (!this.RetryAllowed && - !(httpStatus == (int)HttpStatusCode.Unauthorized && this.User != null)) - { - return false; - } - - if ((httpStatus == (int)HttpStatusCode.Unauthorized && !this.hasPerformedRetryOn401) || - httpStatus == (int)HttpStatusCode.RequestTimeout || - httpStatus == HttpStatusCodeTooManyRequests || - httpStatus == (int)HttpStatusCode.InternalServerError || - httpStatus == (int)HttpStatusCode.BadGateway || - httpStatus == (int)HttpStatusCode.ServiceUnavailable || - httpStatus == (int)HttpStatusCode.GatewayTimeout || - httpCallResponse.NetworkFailure - ) - { - TimeSpan retryAfter = httpCallResponse.RetryAfter; - - // Compute how much time left before hitting the HttpTimeoutWindow setting. - TimeSpan timeElapsedSinceFirstCall = httpCallResponse.ResponseReceivedTime - this.firstCallStartTime; - TimeSpan remainingTimeBeforeTimeout = this.contextSettings.HttpTimeoutWindow - timeElapsedSinceFirstCall; - if (remainingTimeBeforeTimeout.TotalSeconds <= MinHttpTimeoutSeconds) // Need at least 5 seconds to bother making a call - { - return false; - } - - // Based on the retry iteration, delay 2,4,8,16,etc seconds by default between retries - // Jitter the response between the current and next delay based on system clock - // Max wait time is 1 minute - double secondsToWaitMin = Math.Pow(this.contextSettings.HttpRetryDelay.TotalSeconds, this.iterationNumber); - double secondsToWaitMax = Math.Pow(this.contextSettings.HttpRetryDelay.TotalSeconds, this.iterationNumber + 1); - double secondsToWaitDelta = secondsToWaitMax - secondsToWaitMin; - DateTime responseDate = httpCallResponse.ResponseReceivedTime; - double randTime = - (httpCallResponse.ResponseReceivedTime.Minute * 60.0 * 1000.0) + - (httpCallResponse.ResponseReceivedTime.Second * 1000.0) + - httpCallResponse.ResponseReceivedTime.Millisecond; - double lerpScaler = (randTime % 10000) / 10000.0; // from 0 to 1 based on clock - - if (XboxLive.UseMockHttp) - { - lerpScaler = 0; // make tests deterministic - } - - double secondsToWaitUncapped = secondsToWaitMin + secondsToWaitDelta * lerpScaler; // lerp between min & max wait - double secondsToWait = Math.Min(secondsToWaitUncapped, MaxDelayTimeInSec); // cap max wait to 1 min - TimeSpan waitTime = TimeSpan.FromSeconds(secondsToWait); - if (retryAfter.TotalMilliseconds > 0) - { - // Use either the waitTime or Retry-After header, whichever is bigger - this.delayBeforeRetry = (waitTime > retryAfter) ? waitTime : retryAfter; - } - else - { - this.delayBeforeRetry = waitTime; - } - - if (remainingTimeBeforeTimeout < this.delayBeforeRetry + TimeSpan.FromSeconds(MinHttpTimeoutSeconds)) - { - // Don't bother retrying when out of time - return false; - } - - if (httpStatus == (int)HttpStatusCode.InternalServerError) - { - // For 500 - Internal Error, wait at least 10 seconds before retrying. - TimeSpan minDelayForHttpInternalError = TimeSpan.FromSeconds(MinDelayForHttpInternalErrorInSec); - if (this.delayBeforeRetry < minDelayForHttpInternalError) - { - this.delayBeforeRetry = minDelayForHttpInternalError; - } - } - else if (httpStatus == (int)HttpStatusCode.Unauthorized) - { - return this.HandleUnauthorizedError(); - } - - return true; - } - - return false; - } - - private bool HandleUnauthorizedError() - { - if (this.User != null) // if this is null, it does not need a valid token anyways - { - try - { - Task task = this.User.RefreshToken(); - task.Wait(); - this.hasPerformedRetryOn401 = true; - } - catch (Exception) - { - return false; // if getting a new token failed, then we need to just return the 401 upwards - } - } - else - { - this.hasPerformedRetryOn401 = true; - } - - return true; - } - - /// - /// If a request body has been provided, this will write it to the stream. If there is no request body a completed task - /// will be returned. - /// - /// A task that represents to request body write work. - /// This is used to make request chaining a little bit easier. - private Task WriteRequestBodyAsync() - { - if (string.IsNullOrEmpty(this.RequestBody)) - { - return Task.FromResult(true); - } - - this.webRequest.ContentType = this.ContentType; - -#if !WINDOWS_UWP - this.webRequest.ContentLength = this.RequestBody.Length; -#else - this.webRequest.Headers[ContentLengthHeaderName] = this.RequestBody.Length.ToString(); -#endif - - // The explicit cast in the next method should not be necessary, but Visual Studio is complaining - // that the call is ambiguous. This removes that in-editor error. - return Task.Factory.FromAsync(this.webRequest.BeginGetRequestStream, (Func)this.webRequest.EndGetRequestStream, null) - .ContinueWith(t => - { - using (Stream body = t.Result) - { - using (StreamWriter sw = new StreamWriter(body)) - { - sw.Write(this.RequestBody); - sw.Flush(); - } - } - }); - } - - public void SetCustomHeader(string headerName, string headerValue) - { - if (!this.customHeaders.ContainsKey(headerName)) - { - this.customHeaders.Add(headerName, headerValue); - } - else - { - this.customHeaders[headerName] = headerValue; - } - } - - public static XboxLiveHttpRequest Create(string httpMethod, string serverName, string pathQueryFragment) - { - return XboxLive.UseMockHttp ? - new MockXboxLiveHttpRequest(httpMethod, serverName, pathQueryFragment) : - new XboxLiveHttpRequest(httpMethod, serverName, pathQueryFragment); - } - - public void SetRangeHeader(uint startByte, uint endByte) - { - var byteRange = "bytes=" + startByte + "-" + endByte; -#if !WINDOWS_UWP - this.webRequest.AddRange((int)startByte, (int)endByte); -#else - this.webRequest.Headers[RangeHeaderName] = byteRange; -#endif - } - - /// - /// Creates a query string out of a list of parameters - /// - /// List of Parameters to be added to the query - /// a query string that should be appended to the request - public static string GetQueryFromParams(Dictionary paramDictionary) - { - var queryString = new StringBuilder(); - if (paramDictionary.Count > 0) - { - queryString.Append("?"); - const string queryDelimiter = "&"; - var firstParameter = true; - foreach (var paramPair in paramDictionary) - { - if (firstParameter) - firstParameter = false; - else - queryString.Append(queryDelimiter); - - queryString.Append(string.Format("{0}={1}", paramPair.Key, paramPair.Value)); - } - } - - return queryString.ToString(); - } - - private void RecordServiceResult(XboxLiveHttpResponse httpCallResponse, Exception exception) - { - // Only remember result if there was an error and there was a Retry-After header - if (this.XboxLiveAPI != XboxLiveAPIName.Unspecified && - httpCallResponse.HttpStatus >= 400 //&& - //httpCallResponse.RetryAfter.TotalSeconds > 0 - ) - { - DateTime currentTime = DateTime.UtcNow; - HttpRetryAfterApiState state = new HttpRetryAfterApiState(); - state.RetryAfterTime = currentTime + httpCallResponse.RetryAfter; - state.HttpCallResponse = httpCallResponse; - state.Exception = exception; - HttpRetryAfterManager.Instance.SetState(this.XboxLiveAPI, state); - } - } - - private void RouteServiceCall(XboxLiveHttpResponse httpCallResponse) - { - // TODO: port route logic - } - - public static void Sleep(TimeSpan timeSpan) - { - // WinRT doesn't have Thread.Sleep, so using ManualResetEvent - new ManualResetEvent(false).WaitOne(timeSpan); - } - - private HttpWebResponse ExtractHttpWebResponse(Task getResponseTask) - { - if (getResponseTask.IsFaulted && getResponseTask.Exception != null) - { - if (getResponseTask.Exception.InnerException is WebException) - { - WebException e = (WebException)getResponseTask.Exception.InnerException; - if (e.Response is HttpWebResponse) - { - HttpWebResponse w = (HttpWebResponse)e.Response; - return w; - } - } - - return null; - } - else - { - return (HttpWebResponse)getResponseTask.Result; - } - } - - public static HttpWebRequest CloneHttpWebRequest(HttpWebRequest original) - { - HttpWebRequest clone = (HttpWebRequest)WebRequest.Create(original.RequestUri.AbsoluteUri); - PropertyInfo[] properties = original.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); - foreach (PropertyInfo property in properties) - { - if (property.Name != "ContentLength" && property.Name != "Headers") - { - object value = property.GetValue(original, null); - if (property.CanWrite) - { - property.SetValue(clone, value, null); - } - } - } - foreach (var item in original.Headers.AllKeys) - { - clone.Headers[item] = original.Headers[item]; - } - - return clone; - } - } -} diff --git a/CSharpSource/Source/api/Common/XboxLiveHttpResponse.cs b/CSharpSource/Source/api/Common/XboxLiveHttpResponse.cs deleted file mode 100644 index ef4a6be..0000000 --- a/CSharpSource/Source/api/Common/XboxLiveHttpResponse.cs +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// -namespace Microsoft.Xbox.Services -{ - using global::System; - using global::System.Collections.Generic; - using global::System.IO; - using global::System.Net; - using global::System.Text; - - public class XboxLiveHttpResponse - { - public const string RetryAfterHeader = "Retry-After"; - public const int RetryAfterCapInSeconds = 15; - public const string ETagHeader = "ETag"; - public const string DateHeader = "Date"; - - public TimeSpan RetryAfter { get; private set; } - - public DateTime ResponseReceivedTime { get; private set; } - - public DateTime RequestStartTime { get; private set; } - - public string ETag { get; private set; } - - public string ResponseDate { get; private set; } - - public string ErrorMessage { get; private set; } - - public int ErrorCode { get; private set; } - - public int HttpStatus { get; private set; } - - public Dictionary Headers { get; private set; } - - public byte[] ResponseBodyVector { get; private set; } - - public string ResponseBodyString { get; private set; } - - public HttpWebResponse response { get; private set; } - - public string XboxUserId { get; private set; } - - public XboxLiveSettings ContextSettings { get; private set; } - - public string Url { get; private set; } - - public XboxLiveAPIName XboxLiveAPI { get; private set; } - - public string Method { get; private set; } - - public string RequestBody { get; private set; } - - public HttpCallResponseBodyType ResponseBodyType { get; private set; } - - public bool NetworkFailure { get; private set; } - - internal XboxLiveHttpResponse() - { - } - - internal XboxLiveHttpResponse( - int httpStatusCode, - bool networkFailure, - HttpWebResponse response, - DateTime responseReceivedTime, - DateTime requestStartTime, - string xboxUserId, - XboxLiveSettings contextSettings, - string url, - XboxLiveAPIName xboxLiveAPI, - string method, - string requestBody, - HttpCallResponseBodyType responseBodyType - ) - { - this.HttpStatus = httpStatusCode; - this.NetworkFailure = networkFailure; - this.response = response; - this.ResponseReceivedTime = responseReceivedTime; - this.RequestStartTime = requestStartTime; - this.XboxUserId = xboxUserId; - this.ContextSettings = contextSettings; - this.Url = url; - this.XboxLiveAPI = xboxLiveAPI; - this.Method = method; - this.RequestBody = requestBody; - this.ResponseBodyType = responseBodyType; - - if (response != null) - { - using (Stream body = response.GetResponseStream()) - { - this.Initialize((int)response.StatusCode, body, response.ContentLength, "utf-8", response.Headers); - } - } - } - - protected void Initialize(int httpStatus, Stream body, long contentLength, string characterSet, WebHeaderCollection headers) - { - if (this.HttpStatus == 0) - { - this.HttpStatus = httpStatus; - } - this.Headers = new Dictionary(); - - int vectorSize = contentLength > int.MaxValue ? int.MaxValue : (int)contentLength; - this.ResponseBodyVector = new byte[vectorSize]; - if (contentLength > 0) - { - int totalBytesRead = 0; - do - { - int bytesRead = body.Read(this.ResponseBodyVector, totalBytesRead, this.ResponseBodyVector.Length - totalBytesRead); - - // This means we're at the end of the stream. - if (bytesRead == 0) - { - throw new ArgumentException(string.Format("Expected body stream to contain {0} bytes but only read {1} bytes.", contentLength, totalBytesRead), "body"); - } - - totalBytesRead += bytesRead; - } - while (totalBytesRead < contentLength); - - - if (this.ResponseBodyType != HttpCallResponseBodyType.VectorBody) - { - Encoding encoding; - switch (characterSet.ToLower()) - { - case "utf-8": - encoding = Encoding.UTF8; - break; - case "ascii": - encoding = Encoding.ASCII; - break; - default: - encoding = Encoding.UTF8; - break; - } - - this.ResponseBodyString = encoding.GetString(this.ResponseBodyVector); - } - } - - for (int i = 0; i < headers.Count; ++i) - { - var key = headers.AllKeys[i]; - this.Headers.Add(key, headers[key]); - } - - string retryAfterInSeconds; - this.Headers.TryGetValue(RetryAfterHeader, out retryAfterInSeconds); - if (!string.IsNullOrEmpty(retryAfterInSeconds)) - { - int numRetryAfterInSeconds = 0; - int.TryParse(retryAfterInSeconds, out numRetryAfterInSeconds); - numRetryAfterInSeconds = Math.Min(numRetryAfterInSeconds, RetryAfterCapInSeconds); - this.RetryAfter = TimeSpan.FromSeconds(numRetryAfterInSeconds); - } - - string value = string.Empty; - this.Headers.TryGetValue(ETagHeader, out value); - this.ETag = value; - - value = string.Empty; - this.Headers.TryGetValue(DateHeader, out value); - this.ResponseDate = value; - } - } -} - diff --git a/CSharpSource/Source/api/Common/XboxLiveLogCallEventArgs.cs b/CSharpSource/Source/api/Common/XboxLiveLogCallEventArgs.cs index 4225c0f..1d3d45d 100644 --- a/CSharpSource/Source/api/Common/XboxLiveLogCallEventArgs.cs +++ b/CSharpSource/Source/api/Common/XboxLiveLogCallEventArgs.cs @@ -1,33 +1,17 @@ // Copyright (c) Microsoft Corporation // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using System; -using System.Linq; -using System.Collections.Generic; -using System.Threading.Tasks; namespace Microsoft.Xbox.Services { + using global::System; + public class XboxLiveLogCallEventArgs : EventArgs { + public string Message { get; private set; } - public string Message - { - get; - private set; - } - - public string Category - { - get; - private set; - } - - public XboxServicesDiagnosticsTraceLevel Level - { - get; - private set; - } + public string Category { get; private set; } + public XboxServicesDiagnosticsTraceLevel Level { get; private set; } } -} +} \ No newline at end of file diff --git a/CSharpSource/Source/api/Common/XboxLiveServices.cs b/CSharpSource/Source/api/Common/XboxLiveServices.cs index 991a801..ef65c1e 100644 --- a/CSharpSource/Source/api/Common/XboxLiveServices.cs +++ b/CSharpSource/Source/api/Common/XboxLiveServices.cs @@ -16,11 +16,7 @@ namespace Microsoft.Xbox.Services public XboxLiveServices(XboxLiveUser user) { -#if UNITY_EDITOR - // TODO Implement mock title storage service for unity editor - this.TitleStorageService = null; - this.PrivacyService = null; -#else +#if WINDOWS_UWP IntPtr xboxLiveContext; var xsapiResult = XboxLiveContextCreate(user.PCXboxLiveUser, out xboxLiveContext); @@ -32,6 +28,10 @@ namespace Microsoft.Xbox.Services this.TitleStorageService = new TitleStorageService(XboxLiveContextPtr); this.PrivacyService = new PrivacyService(XboxLiveContextPtr); +#else + // TODO MockServices and/or MockHttp + this.TitleStorageService = null; + this.PrivacyService = null; #endif } diff --git a/CSharpSource/Source/api/Common/XboxLiveSettings.cs b/CSharpSource/Source/api/Common/XboxLiveSettings.cs index f4e5707..3601937 100644 --- a/CSharpSource/Source/api/Common/XboxLiveSettings.cs +++ b/CSharpSource/Source/api/Common/XboxLiveSettings.cs @@ -5,22 +5,16 @@ namespace Microsoft.Xbox.Services { using global::System; - public class XboxLiveSettings + public class XboxLiveContextSettings { - private const int DefaultHttpTimeoutWindowInSeconds = 20; - private const int DefaultLongHttpTimeoutInSeconds = 5 * 60; - private const int DefaultRetryDelayInSeconds = 2; - - public XboxLiveSettings() + public XboxLiveContextSettings() { - this.DiagnosticsTraceLevel = XboxServicesDiagnosticsTraceLevel.Off; - this.HttpTimeoutWindow = TimeSpan.FromSeconds(DefaultHttpTimeoutWindowInSeconds); - this.LongHttpTimeout = TimeSpan.FromSeconds(DefaultLongHttpTimeoutInSeconds); - this.HttpRetryDelay = TimeSpan.FromSeconds(DefaultRetryDelayInSeconds); } public bool UseCoreDispatcherForEventRouting { get; set; } + public TimeSpan HttpTimeout { get; set; } + public TimeSpan HttpTimeoutWindow { get; set; } public TimeSpan HttpRetryDelay { get; set; } @@ -39,15 +33,15 @@ namespace Microsoft.Xbox.Services } } - //public TimeSpan WebsocketTimeoutWindow { get; set; } + public TimeSpan WebsocketTimeoutWindow { get; set; } - //public event EventHandler LogCallRouted; + public event EventHandler LogCallRouted; - //public bool EnableServiceCallRoutedEvents { get; set; } + public bool EnableServiceCallRoutedEvents { get; set; } - //public void DisableAssertsForMaximumNumberOfWebsocketsActivated(XboxLiveContextRecommendedSetting setting) - //{ - // throw new NotImplementedException(); - //} + public void DisableAssertsForMaximumNumberOfWebsocketsActivated(XboxLiveContextRecommendedSetting setting) + { + throw new NotImplementedException(); + } } } \ No newline at end of file diff --git a/CSharpSource/Source/api/Common/XboxLiveUser.cs b/CSharpSource/Source/api/Common/XboxLiveUser.cs index 6b33f1f..e676e53 100644 --- a/CSharpSource/Source/api/Common/XboxLiveUser.cs +++ b/CSharpSource/Source/api/Common/XboxLiveUser.cs @@ -4,10 +4,8 @@ namespace Microsoft.Xbox.Services { using global::System; - using global::System.Collections.Generic; using global::System.Text; using global::System.Threading.Tasks; - using Microsoft.Xbox.Services.System; public partial class XboxLiveUser : IXboxLiveUser @@ -17,38 +15,9 @@ namespace Microsoft.Xbox.Services private readonly IUserImpl userImpl; private XboxLiveServices xboxLiveServices; - private static event EventHandler InternalSignInCompleted; - private static List> signInDelegates = new List>(); - public static event EventHandler SignInCompleted - { - add - { - InternalSignInCompleted += value; - signInDelegates.Add(value); - } - remove - { - InternalSignInCompleted -= value; - signInDelegates.Remove(value); - } - } + public static event EventHandler SignInCompleted; + public static event EventHandler SignOutCompleted; - private static event EventHandler InternalSignOutCompleted; - private static List> signOutDelegates = new List>(); - public static event EventHandler SignOutCompleted - { - add - { - InternalSignOutCompleted += value; - signOutDelegates.Add(value); - } - remove - { - InternalSignOutCompleted -= value; - signOutDelegates.Remove(value); - } - } - public string WebAccountId { get @@ -136,36 +105,19 @@ namespace Microsoft.Xbox.Services return this.userImpl.SignInImpl(false, false); } - public Task GetTokenAndSignatureAsync(string httpMethod, string url, string headers) + public Task GetTokenAndSignatureAsync(string httpMethod, string url, string headers) { return this.GetTokenAndSignatureArrayAsync(httpMethod, url, headers, null); } - public Task GetTokenAndSignatureAsync(string httpMethod, string url, string headers, string body) + public Task GetTokenAndSignatureAsync(string httpMethod, string url, string headers, string body) { return this.GetTokenAndSignatureArrayAsync(httpMethod, url, headers, body == null ? null : Encoding.UTF8.GetBytes(body)); } - public Task GetTokenAndSignatureArrayAsync(string httpMethod, string url, string headers, byte[] body) + public Task GetTokenAndSignatureArrayAsync(string httpMethod, string url, string headers, byte[] body) { return this.userImpl.InternalGetTokenAndSignatureAsync(httpMethod, url, headers, body, false, false); } - - public Task RefreshToken() - { - return this.userImpl.InternalGetTokenAndSignatureAsync("GET", this.userImpl.AuthConfig.XboxLiveEndpoint, null, null, false, true); - } - - protected static void OnSignInCompleted(IXboxLiveUser user) - { - var handler = InternalSignInCompleted; - if (handler != null) handler(null, new SignInCompletedEventArgs(user)); - } - - protected static void OnSignOutCompleted(IXboxLiveUser user) - { - var handler = InternalSignOutCompleted; - if (handler != null) handler(null, new SignOutCompletedEventArgs(user)); - } } } \ No newline at end of file diff --git a/CSharpSource/Source/api/Common/XboxServiceCallRoutedEventArgs.cs b/CSharpSource/Source/api/Common/XboxServiceCallRoutedEventArgs.cs index 5413540..6512f6c 100644 --- a/CSharpSource/Source/api/Common/XboxServiceCallRoutedEventArgs.cs +++ b/CSharpSource/Source/api/Common/XboxServiceCallRoutedEventArgs.cs @@ -1,111 +1,44 @@ // Copyright (c) Microsoft Corporation // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using System; -using System.Linq; -using System.Collections.Generic; -using System.Threading.Tasks; namespace Microsoft.Xbox.Services { + using global::System; + public class XboxServiceCallRoutedEventArgs : EventArgs { - public string XboxUserId - { - get; - private set; - } + public string XboxUserId { get; private set; } - public TimeSpan ElapsedCallTime - { - get; - private set; - } + public TimeSpan ElapsedCallTime { get; private set; } - public DateTimeOffset ResponseTimeUTC - { - get; - private set; - } + public DateTimeOffset ResponseTimeUTC { get; private set; } - public DateTimeOffset RequestTimeUTC - { - get; - private set; - } + public DateTimeOffset RequestTimeUTC { get; private set; } - public string FullResponseToString - { - get; - private set; - } + public string FullResponseToString { get; private set; } - public uint HttpStatus - { - get; - private set; - } + public uint HttpStatus { get; private set; } - public string Signature - { - get; - private set; - } + public string Signature { get; private set; } - public string Token - { - get; - private set; - } + public string Token { get; private set; } - public string ETag - { - get; - private set; - } + public string ETag { get; private set; } - public string ResponseBody - { - get; - private set; - } + public string ResponseBody { get; private set;} - public string ResponseHeaders - { - get; - private set; - } + public string ResponseHeaders { get; private set; } - public uint ResponseCount - { - get; - private set; - } + public uint ResponseCount { get; private set; } - public HttpCallRequestMessage RequestBody - { - get; - private set; - } + public HttpCallRequestMessage RequestBody { get; private set; } - public string RequestHeaders - { - get; - private set; - } + public string RequestHeaders { get; private set; } - public Uri Url - { - get; - private set; - } - - public string HttpMethod - { - get; - private set; - } + public Uri Url { get; private set; } + public string HttpMethod { get; private set; } } } diff --git a/CSharpSource/Source/api/Common/XboxServicesDiagnosticsTraceLevel.cs b/CSharpSource/Source/api/Common/XboxServicesDiagnosticsTraceLevel.cs index 9eb5a4e..9cb0c44 100644 --- a/CSharpSource/Source/api/Common/XboxServicesDiagnosticsTraceLevel.cs +++ b/CSharpSource/Source/api/Common/XboxServicesDiagnosticsTraceLevel.cs @@ -1,10 +1,6 @@ // Copyright (c) Microsoft Corporation // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using System; -using System.Linq; -using System.Collections.Generic; -using System.Threading.Tasks; namespace Microsoft.Xbox.Services { @@ -16,5 +12,4 @@ namespace Microsoft.Xbox.Services Info = 3, Verbose = 4, } - -} +} \ No newline at end of file diff --git a/CSharpSource/Source/api/Leaderboard/ILeaderboardQueryImpl.cs b/CSharpSource/Source/api/Leaderboard/ILeaderboardQueryImpl.cs index 9b12d68..bc1ff23 100644 --- a/CSharpSource/Source/api/Leaderboard/ILeaderboardQueryImpl.cs +++ b/CSharpSource/Source/api/Leaderboard/ILeaderboardQueryImpl.cs @@ -6,7 +6,7 @@ namespace Microsoft.Xbox.Services.Leaderboard internal interface ILeaderboardQueryImpl { IntPtr GetPtr(); - + uint GetSkipResultToRank(); void SetSkipResultToRank(uint skipResultToRank); diff --git a/CSharpSource/Source/api/Leaderboard/LeaderboardService.cs b/CSharpSource/Source/api/Leaderboard/LeaderboardService.cs index 8879d80..a419eff 100644 --- a/CSharpSource/Source/api/Leaderboard/LeaderboardService.cs +++ b/CSharpSource/Source/api/Leaderboard/LeaderboardService.cs @@ -4,138 +4,17 @@ namespace Microsoft.Xbox.Services.Leaderboard { using global::System; - using global::System.Collections.Generic; - using global::System.Text; using global::System.Threading.Tasks; public class LeaderboardService : ILeaderboardService { - private const string leaderboardApiContract = "4"; - - private static readonly Uri leaderboardsBaseUri = new Uri("https://leaderboards.xboxlive.com"); - - private readonly XboxLiveAppConfiguration appConfig; - internal LeaderboardService() { - this.appConfig = XboxLive.Instance.AppConfig; } - /// public Task GetLeaderboardAsync(XboxLiveUser user, LeaderboardQuery query) { - string skipToXboxUserId = null; - if (query.SkipResultToMe) - { - skipToXboxUserId = user.XboxUserId; - } - - string requestPath = ""; - //if (string.IsNullOrEmpty(query.SocialGroup)) - //{ - // requestPath = CreateLeaderboardUrlPath(this.appConfig.PrimaryServiceConfigId, query.StatName, query.MaxItems, skipToXboxUserId, query.SkipResultToRank, query.ContinuationToken); - //} - //else - //{ - // requestPath = CreateSocialLeaderboardUrlPath(this.appConfig.PrimaryServiceConfigId, query.StatName, user.XboxUserId, query.MaxItems, skipToXboxUserId, query.SkipResultToRank, query.ContinuationToken, query.SocialGroup); - //} - - XboxLiveHttpRequest request = XboxLiveHttpRequest.Create(HttpMethod.Get, leaderboardsBaseUri.ToString(), requestPath); - request.ContractVersion = leaderboardApiContract; - request.XboxLiveAPI = XboxLiveAPIName.GetLeaderboardInternal; - return request.GetResponseWithAuth(user) - .ContinueWith( - responseTask => - { - return this.HandleLeaderboardResponse(responseTask, query); - }); - } - - internal LeaderboardResult HandleLeaderboardResponse(Task responseTask, LeaderboardQuery query) - { - XboxLiveHttpResponse response = responseTask.Result; - - if (response.HttpStatus != 200) - { - throw new XboxException("Leaderboard request failed with " + response.HttpStatus); - } - - LeaderboardResponse lbResponse = JsonSerialization.FromJson(response.ResponseBodyString); - - IList columns = new List { lbResponse.LeaderboardInfo.Column }; - - IList rows = new List(); - foreach (LeaderboardRowResponse row in lbResponse.Rows) - { - LeaderboardRow newRow = new LeaderboardRow - { - Gamertag = row.Gamertag, - Percentile = row.Percentile, - Rank = (uint)row.Rank, - XboxUserId = row.XboxUserId, - Values = row.Value != null ? new List { row.Value } : row.Values, - }; - rows.Add(newRow); - } - - LeaderboardQuery nextQuery = new LeaderboardQuery(query, lbResponse.PagingInfo != null ? lbResponse.PagingInfo.ContinuationToken : null); - LeaderboardResult result = new LeaderboardResult(rows, columns, lbResponse.LeaderboardInfo.TotalCount); - return result; - } - - private static string CreateLeaderboardUrlPath(string serviceConfigurationId, string statName, uint maxItems, string skipToXboxUserId, uint skipToRank, string continuationToken) - { - StringBuilder requestPath = new StringBuilder(); - requestPath.AppendFormat("scids/{0}/leaderboards/stat({1})?", serviceConfigurationId, statName); - AppendQueryParameters(requestPath, maxItems, skipToXboxUserId, skipToRank, continuationToken); - - return requestPath.ToString(); - } - - private static string CreateSocialLeaderboardUrlPath(string serviceConfigurationId, string statName, string xuid, uint maxItems, string skipToXboxUserId, uint skipToRank, string continuationToken, string socialGroup) - { - StringBuilder requestPath = new StringBuilder(); - requestPath.AppendFormat("users/xuid({0})/scids/{1}/stats/{2}/people/{3}?", xuid, serviceConfigurationId, statName, socialGroup); - AppendQueryParameters(requestPath, maxItems, skipToXboxUserId, skipToRank, continuationToken); - - return requestPath.ToString(); - } - - private static void AppendQueryParameters(StringBuilder queryString, uint maxItems, string skipToXboxUserId, uint skipToRank, string continuationToken) - { - if (maxItems > 0) - { - AppendQueryParameter(queryString, "maxItems", maxItems); - } - - if (!string.IsNullOrEmpty(skipToXboxUserId) && skipToRank > 0) - { - throw new ArgumentException("Cannot provide both user and rank to skip to."); - } - - if (continuationToken != null) - { - AppendQueryParameter(queryString, "continuationToken", continuationToken); - } - else if (!string.IsNullOrEmpty(skipToXboxUserId)) - { - AppendQueryParameter(queryString, "skipToUser", skipToXboxUserId); - } - else if (skipToRank > 0) - { - AppendQueryParameter(queryString, "skipToRank", skipToRank); - } - - // Remove the trailing query string bit - queryString.Remove(queryString.Length - 1, 1); - } - - private static void AppendQueryParameter(StringBuilder builder, string parameterName, object parameterValue) - { - builder.Append(parameterName); - builder.Append("="); - builder.Append(parameterValue); - builder.Append("&"); + throw new NotImplementedException(); } } } \ No newline at end of file diff --git a/CSharpSource/Source/api/Leaderboard/MockLeaderboardService.cs b/CSharpSource/Source/api/Leaderboard/MockLeaderboardService.cs index db83005..84fb003 100644 --- a/CSharpSource/Source/api/Leaderboard/MockLeaderboardService.cs +++ b/CSharpSource/Source/api/Leaderboard/MockLeaderboardService.cs @@ -3,6 +3,7 @@ namespace Microsoft.Xbox.Services.Leaderboard { + using global::Newtonsoft.Json; using global::System.Collections.Generic; using global::System.Linq; using global::System.Threading.Tasks; @@ -20,7 +21,7 @@ namespace Microsoft.Xbox.Services.Leaderboard internal LeaderboardResult CreateLeaderboardResponse(LeaderboardQuery query) { - LeaderboardResponse lbResponse = JsonSerialization.FromJson(@"{""pagingInfo"":null,""leaderboardInfo"":{""totalCount"":10,""columnDefinition"":{""statName"":""EnemysDefeated"",""type"":""Double""}},""userList"":[{""gamertag"":""Fake User 1"",""xuid"":""1111111111111111"",""percentile"":0.1,""rank"":1,""globalrank"":10,""value"":""1000"",""valuemetadata"":null},{""gamertag"":""Fake User 2"",""xuid"":""2222222222222222"",""percentile"":0.2,""rank"":2,""globalrank"":20,""value"":""900"",""valuemetadata"":null},{""gamertag"":""Fake User 3"",""xuid"":""3333333333333333"",""percentile"":0.3,""rank"":3,""globalrank"":30,""value"":""800"",""valuemetadata"":null},{""gamertag"":""Fake User 4"",""xuid"":""4444444444444444"",""percentile"":0.4,""rank"":4,""globalrank"":40,""value"":""700"",""valuemetadata"":null},{""gamertag"":""Fake User 5"",""xuid"":""5555555555555555"",""percentile"":0.5,""rank"":5,""globalrank"":50,""value"":""600"",""valuemetadata"":null},{""gamertag"":""Fake User 6"",""xuid"":""6666666666666666"",""percentile"":0.6,""rank"":6,""globalrank"":60,""value"":""500"",""valuemetadata"":null},{""gamertag"":""Fake User 7"",""xuid"":""7777777777777777"",""percentile"":0.7,""rank"":7,""globalrank"":70,""value"":""400"",""valuemetadata"":null},{""gamertag"":""Fake User 8"",""xuid"":""8888888888888888"",""percentile"":0.8,""rank"":8,""globalrank"":80,""value"":""300"",""valuemetadata"":null},{""gamertag"":""Fake User 9"",""xuid"":""9999999999999999"",""percentile"":0.9,""rank"":9,""globalrank"":90,""value"":""200"",""valuemetadata"":null},{""gamertag"":""Fake User 10"",""xuid"":""1010101010101010"",""percentile"":1.0,""rank"":10,""globalrank"":100,""value"":""100"",""valuemetadata"":null},]}"); + LeaderboardResponse lbResponse = JsonConvert.DeserializeObject(@"{""pagingInfo"":null,""leaderboardInfo"":{""totalCount"":10,""columnDefinition"":{""statName"":""EnemysDefeated"",""type"":""Double""}},""userList"":[{""gamertag"":""Fake User 1"",""xuid"":""1111111111111111"",""percentile"":0.1,""rank"":1,""globalrank"":10,""value"":""1000"",""valuemetadata"":null},{""gamertag"":""Fake User 2"",""xuid"":""2222222222222222"",""percentile"":0.2,""rank"":2,""globalrank"":20,""value"":""900"",""valuemetadata"":null},{""gamertag"":""Fake User 3"",""xuid"":""3333333333333333"",""percentile"":0.3,""rank"":3,""globalrank"":30,""value"":""800"",""valuemetadata"":null},{""gamertag"":""Fake User 4"",""xuid"":""4444444444444444"",""percentile"":0.4,""rank"":4,""globalrank"":40,""value"":""700"",""valuemetadata"":null},{""gamertag"":""Fake User 5"",""xuid"":""5555555555555555"",""percentile"":0.5,""rank"":5,""globalrank"":50,""value"":""600"",""valuemetadata"":null},{""gamertag"":""Fake User 6"",""xuid"":""6666666666666666"",""percentile"":0.6,""rank"":6,""globalrank"":60,""value"":""500"",""valuemetadata"":null},{""gamertag"":""Fake User 7"",""xuid"":""7777777777777777"",""percentile"":0.7,""rank"":7,""globalrank"":70,""value"":""400"",""valuemetadata"":null},{""gamertag"":""Fake User 8"",""xuid"":""8888888888888888"",""percentile"":0.8,""rank"":8,""globalrank"":80,""value"":""300"",""valuemetadata"":null},{""gamertag"":""Fake User 9"",""xuid"":""9999999999999999"",""percentile"":0.9,""rank"":9,""globalrank"":90,""value"":""200"",""valuemetadata"":null},{""gamertag"":""Fake User 10"",""xuid"":""1010101010101010"",""percentile"":1.0,""rank"":10,""globalrank"":100,""value"":""100"",""valuemetadata"":null},]}"); IList columns = new List { lbResponse.LeaderboardInfo.Column }; @@ -34,7 +35,7 @@ namespace Microsoft.Xbox.Services.Leaderboard Values = row.Value != null ? new List { row.Value } : row.Values }).ToList(); - // Create a result with an 'empty' next query so that it won't have paiging. + // Create a result with an 'empty' next query so that it won't have paging. LeaderboardResult result = new LeaderboardResult(rows, columns, lbResponse.LeaderboardInfo.TotalCount); return result; } diff --git a/CSharpSource/Source/api/Microsoft.Xbox.Services.Shared.projitems b/CSharpSource/Source/api/Microsoft.Xbox.Services.Shared.projitems index ce6d46b..4788ed8 100644 --- a/CSharpSource/Source/api/Microsoft.Xbox.Services.Shared.projitems +++ b/CSharpSource/Source/api/Microsoft.Xbox.Services.Shared.projitems @@ -25,11 +25,8 @@ - - - - + @@ -39,12 +36,9 @@ - - - @@ -79,16 +73,19 @@ + + + - + @@ -98,31 +95,24 @@ - - - + + + - - - - - - - @@ -195,7 +185,6 @@ - @@ -214,7 +203,6 @@ - @@ -228,13 +216,9 @@ - - - - diff --git a/CSharpSource/Source/api/Mock/MockXboxLiveData.cs b/CSharpSource/Source/api/Mock/MockXboxLiveData.cs deleted file mode 100644 index 0e42458..0000000 --- a/CSharpSource/Source/api/Mock/MockXboxLiveData.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Xbox.Services -{ - using global::System; - using global::System.Collections.Generic; - using global::System.IO; - - using Newtonsoft.Json; - - public static class MockXboxLiveData - { - public static Dictionary MockResponses { get; set; } - - static MockXboxLiveData() - { - MockResponses = new Dictionary(); - } - - public static void Load(string path) - { - if (!File.Exists(path)) - { - return; - } - - string rawData = File.ReadAllText(path); - MockResponses = JsonConvert.DeserializeObject>(rawData); - } - - public static XboxLiveHttpResponse GetMockResponse(XboxLiveHttpRequest request) - { - XboxLiveHttpRequestEqualityComparer comparer = new XboxLiveHttpRequestEqualityComparer(); - foreach (var mockData in MockResponses.Values) - { - if (comparer.Equals(request, mockData.Request)) - { - return mockData.Response; - } - } - - Dictionary headers = new Dictionary - { - { "X-XblCorrelationId", Guid.NewGuid().ToString() }, - { "Date", DateTime.UtcNow.ToString("R") }, - }; - - return new MockXboxLiveHttpResponse(404, headers); - } - - public class MockRequestData - { - public MockXboxLiveHttpRequest Request { get; set; } - public MockXboxLiveHttpResponse Response { get; set; } - } - } -} \ No newline at end of file diff --git a/CSharpSource/Source/api/Mock/MockXboxLiveHttpRequest.cs b/CSharpSource/Source/api/Mock/MockXboxLiveHttpRequest.cs deleted file mode 100644 index 6b659f8..0000000 --- a/CSharpSource/Source/api/Mock/MockXboxLiveHttpRequest.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// -namespace Microsoft.Xbox.Services -{ - using global::System; - using global::System.Diagnostics; - using global::System.IO; - using global::System.Threading.Tasks; - - using Newtonsoft.Json; - - public class MockXboxLiveHttpRequest : XboxLiveHttpRequest - { - public static string MockDataPath; - - public MockXboxLiveHttpRequest(string method, string serverName, string pathQueryFragment) : base(method, serverName, pathQueryFragment) - { - } - - public override Task GetResponseWithoutAuth() - { - // Save the mock data out for testing. - string requestData = JsonConvert.SerializeObject(this, Formatting.Indented); - - string outputDir = @"C:\Temp\MockData"; - if(!Directory.Exists(outputDir)) - { - Directory.CreateDirectory(outputDir); - } - - string outputPath = Path.Combine(outputDir, "data.txt"); - using (var stream = this.GetWriteStream(outputPath)) - { - using (var writer = new StreamWriter(stream)) - { - writer.Write(requestData); - } - } - return Task.FromResult(MockXboxLiveData.GetMockResponse(this)); - } - - // This is used because there are times when multiple requests are issued at the same time - // As a result the output file becomes locked for the first request resulting in the other - // requests being unable to edit the file. - private FileStream GetWriteStream(string path, int timeoutMs = 1000) - { - var time = Stopwatch.StartNew(); - while (time.ElapsedMilliseconds < timeoutMs) - { - try - { - return new FileStream(path, FileMode.Append, FileAccess.Write); - } - catch (IOException) - { - } - } - - throw new TimeoutException(string.Format("Failed to get a write handle to {0} within {1} ms.", path, timeoutMs)); - } - } -} \ No newline at end of file diff --git a/CSharpSource/Source/api/Mock/MockXboxLiveHttpResponse.cs b/CSharpSource/Source/api/Mock/MockXboxLiveHttpResponse.cs deleted file mode 100644 index ea7cb5d..0000000 --- a/CSharpSource/Source/api/Mock/MockXboxLiveHttpResponse.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// -namespace Microsoft.Xbox.Services -{ - using global::System.Collections.Generic; - using global::System.IO; - using global::System.Net; - using global::System.Text; - - using Newtonsoft.Json; - using Newtonsoft.Json.Linq; - - public class MockXboxLiveHttpResponse : XboxLiveHttpResponse - { - public MockXboxLiveHttpResponse(int httpStatus) : this(httpStatus, null, null, new Dictionary()) - { - } - - public MockXboxLiveHttpResponse(int httpStatus, Dictionary headers) : this(httpStatus, null, null, headers) - { - } - - [JsonConstructor] - public MockXboxLiveHttpResponse(int httpStatus, JObject body, string characterSet = null, Dictionary headers = null) - { - string bodyJson = JsonConvert.SerializeObject(body); - byte[] bodyBytes = Encoding.UTF8.GetBytes(bodyJson ?? ""); - Stream bodyStream = new MemoryStream(bodyBytes); - - WebHeaderCollection webHeaders = new WebHeaderCollection(); - if (headers != null) - { - foreach (KeyValuePair header in headers) - { - webHeaders[header.Key] = header.Value; - } - } - - this.Initialize(httpStatus, bodyStream, bodyStream.Length, characterSet ?? "utf-8", webHeaders); - } - } -} \ No newline at end of file diff --git a/CSharpSource/Source/api/Mock/XboxLiveHttpRequestEqualityComparer.cs b/CSharpSource/Source/api/Mock/XboxLiveHttpRequestEqualityComparer.cs deleted file mode 100644 index 7b9f2e9..0000000 --- a/CSharpSource/Source/api/Mock/XboxLiveHttpRequestEqualityComparer.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// -namespace Microsoft.Xbox.Services -{ - using global::System.Collections.Generic; - using global::System.Linq; - - public sealed class XboxLiveHttpRequestEqualityComparer : IEqualityComparer - { - public static List IgnoredHeaders = new List - { - "Authorization" - }; - - public bool Equals(XboxLiveHttpRequest x, XboxLiveHttpRequest y) - { - if (ReferenceEquals(x, y)) return true; - if (ReferenceEquals(x, null)) return false; - if (ReferenceEquals(y, null)) return false; - if (x.GetType() != y.GetType()) return false; - return string.Equals(x.Method, y.Method) - && string.Equals(x.Url, y.Url); - } - - private static bool CheckHeadersAreEqual(IDictionary x, IDictionary y) - { - if (x.Count != y.Count) - { - return false; - } - - return x.Keys.Where(key => !IgnoredHeaders.Contains(key)).All(key => x[key] == y[key]); - } - - public int GetHashCode(XboxLiveHttpRequest obj) - { - unchecked - { - var hashCode = obj.Method.GetHashCode(); - hashCode = (hashCode * 397) ^ obj.Url.GetHashCode(); - return hashCode; - } - } - } -} \ No newline at end of file diff --git a/CSharpSource/Source/api/Privacy/IPrivacyService.cs b/CSharpSource/Source/api/Privacy/IPrivacyService.cs index 3aec192..b3f0a26 100644 --- a/CSharpSource/Source/api/Privacy/IPrivacyService.cs +++ b/CSharpSource/Source/api/Privacy/IPrivacyService.cs @@ -12,8 +12,8 @@ namespace Microsoft.Xbox.Services.Privacy /// Get the list of Xbox Live Ids the calling user should avoid during multiplayer matchmaking. /// /// A collection of XboxUserIds that correspond to the calling user's avoid list. - Task> GetAvoidListAsync(); - + Task> GetAvoidListAsync(); + /// /// Check a single permission with a single target user. /// @@ -33,15 +33,15 @@ namespace Microsoft.Xbox.Services.Privacy /// See Microsoft::Xbox::Services::Privacy::PermissionIdConstants for the latest options. /// The collection of target Xbox user IDs to check permissions against. /// A collection of objects containing results of the target xbox user ids. - Task> CheckMultiplePermissionsWithMultipleTargetUsersAsync( - IList permissionIds, - IList targetXboxUserIds + Task> CheckMultiplePermissionsWithMultipleTargetUsersAsync( + IReadOnlyList permissionIds, + IReadOnlyList targetXboxUserIds ); /// /// Get the list of Xbox Live Ids that the calling user should not hear (mute) during multiplayer matchmaking. /// /// The collection of Xbox user IDs that represent the mute list for a user. - Task> GetMuteListAsync(); + Task> GetMuteListAsync(); } } diff --git a/CSharpSource/Source/api/Privacy/MultiplePermissionsCheckResult.cs b/CSharpSource/Source/api/Privacy/MultiplePermissionsCheckResult.cs index a7d7c3d..db05192 100644 --- a/CSharpSource/Source/api/Privacy/MultiplePermissionsCheckResult.cs +++ b/CSharpSource/Source/api/Privacy/MultiplePermissionsCheckResult.cs @@ -10,7 +10,7 @@ namespace Microsoft.Xbox.Services.Privacy public class MultiplePermissionsCheckResult { - public IList Items { get; private set; } + public IReadOnlyList Items { get; private set; } public string XboxUserId { get; private set; } @@ -20,7 +20,7 @@ namespace Microsoft.Xbox.Services.Privacy XboxUserId = MarshalingHelpers.Utf8ToString(multiplePermissionsStruct.xboxUserId); - Items = new List((int)multiplePermissionsStruct.itemsCount); + var items = new List((int)multiplePermissionsStruct.itemsCount); int size = MarshalingHelpers.SizeOf(); IntPtr permissionStructPtr = multiplePermissionsStruct.items; @@ -28,9 +28,10 @@ namespace Microsoft.Xbox.Services.Privacy for (ulong i = 0; i < multiplePermissionsStruct.itemsCount; ++i) { var permissionCheckResultStruct = MarshalingHelpers.PtrToStructure(permissionStructPtr); - Items.Add(new PermissionCheckResult(permissionCheckResultStruct)); + items.Add(new PermissionCheckResult(permissionCheckResultStruct)); permissionStructPtr = permissionStructPtr.Increment(size); } + Items = items; } } diff --git a/CSharpSource/Source/api/Privacy/PermissionCheckResult.cs b/CSharpSource/Source/api/Privacy/PermissionCheckResult.cs index 1b6b543..fe22119 100644 --- a/CSharpSource/Source/api/Privacy/PermissionCheckResult.cs +++ b/CSharpSource/Source/api/Privacy/PermissionCheckResult.cs @@ -11,7 +11,7 @@ namespace Microsoft.Xbox.Services.Privacy public class PermissionCheckResult { - public IList Reasons { get; private set; } + public IReadOnlyList DenyReasons { get; private set; } public string PermissionRequested { get; private set; } @@ -27,17 +27,17 @@ namespace Microsoft.Xbox.Services.Privacy IsAllowed = permissionCheckResultStruct.isAllowed; PermissionRequested = MarshalingHelpers.Utf8ToString(permissionCheckResultStruct.permissionRequested); - Reasons = new List((int)permissionCheckResultStruct.denyReasonsCount); + var denyReasons = new List((int)permissionCheckResultStruct.denyReasonsCount); int size = MarshalingHelpers.SizeOf(); IntPtr denyReasonPtr = permissionCheckResultStruct.denyReasons; for (ulong i = 0; i < permissionCheckResultStruct.denyReasonsCount; ++i) { - Reasons.Add(new PermissionDenyReason(denyReasonPtr)); + denyReasons.Add(new PermissionDenyReason(denyReasonPtr)); denyReasonPtr = denyReasonPtr.Increment(size); } - + DenyReasons = denyReasons; } } diff --git a/CSharpSource/Source/api/Privacy/PrivacyService.cs b/CSharpSource/Source/api/Privacy/PrivacyService.cs index 77d24f3..60edd25 100644 --- a/CSharpSource/Source/api/Privacy/PrivacyService.cs +++ b/CSharpSource/Source/api/Privacy/PrivacyService.cs @@ -19,12 +19,12 @@ namespace Microsoft.Xbox.Services.Privacy this.pCXboxLiveContext = pCXboxLiveContext; } - public Task> GetAvoidListAsync() + public Task> GetAvoidListAsync() { - var tcs = new TaskCompletionSource>(); + var tcs = new TaskCompletionSource>(); Task.Run(() => { - int contextKey = XsapiCallbackContext>.CreateContext(null, tcs); + int contextKey = XsapiCallbackContext>.CreateContext(null, tcs); var xsapiResult = PrivacyGetAvoidList(this.pCXboxLiveContext, GetPrivacyUserListComplete, (IntPtr)contextKey, XboxLive.DefaultTaskGroupId); if (xsapiResult != XSAPI_RESULT.XSAPI_RESULT_OK) @@ -35,12 +35,12 @@ namespace Microsoft.Xbox.Services.Privacy return tcs.Task; } - public Task> GetMuteListAsync() + public Task> GetMuteListAsync() { - var tcs = new TaskCompletionSource>(); + var tcs = new TaskCompletionSource>(); Task.Run(() => { - int contextKey = XsapiCallbackContext>.CreateContext(null, tcs); + int contextKey = XsapiCallbackContext>.CreateContext(null, tcs); var xsapiResult = PrivacyGetMuteList(this.pCXboxLiveContext, GetPrivacyUserListComplete, (IntPtr)contextKey, XboxLive.DefaultTaskGroupId); if (xsapiResult != XSAPI_RESULT.XSAPI_RESULT_OK) @@ -58,7 +58,7 @@ namespace Microsoft.Xbox.Services.Privacy { if (result.errorCode == XSAPI_RESULT.XSAPI_RESULT_OK) { - context.TaskCompletionSource.SetResult(MarshalingHelpers.Utf8StringArrayToStringList(xboxUserIdList, (int)count)); + context.TaskCompletionSource.SetResult(MarshalingHelpers.Utf8StringArrayToStringList(xboxUserIdList, count)); } else { @@ -109,15 +109,15 @@ namespace Microsoft.Xbox.Services.Privacy } } - public Task> CheckMultiplePermissionsWithMultipleTargetUsersAsync(IList permissionIds, IList targetXboxUserIds) + public Task> CheckMultiplePermissionsWithMultipleTargetUsersAsync(IReadOnlyList permissionIds, IReadOnlyList targetXboxUserIds) { - var tcs = new TaskCompletionSource>(); + var tcs = new TaskCompletionSource>(); Task.Run(() => { var permissionIdsArray = MarshalingHelpers.StringListToHGlobalUtf8StringArray(permissionIds); var xuidsArray = MarshalingHelpers.StringListToHGlobalUtf8StringArray(targetXboxUserIds); - int contextKey = XsapiCallbackContext>.CreateContext( + int contextKey = XsapiCallbackContext>.CreateContext( new CheckMultiplePermissionsContext { permissionIdsArray = permissionIdsArray, diff --git a/CSharpSource/Source/api/Shared/CallBufferTimer.cs b/CSharpSource/Source/api/Shared/CallBufferTimer.cs deleted file mode 100644 index 8f90bdc..0000000 --- a/CSharpSource/Source/api/Shared/CallBufferTimer.cs +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Xbox.Services.Shared -{ - using global::System; - using global::System.Collections.Generic; - using global::System.Linq; - using global::System.Threading.Tasks; - - internal class CallBufferEventArgs : EventArgs - { - public CallBufferEventArgs(List elements) - { - this.Elements = elements; - } - - public List Elements { get; private set; } - } - - /// - /// A helper class to throttle calls and buffer call data. One or more calls made to will be - /// batched together and passed as a single - /// - internal class CallBufferTimer - { - private readonly TimeSpan period; - private DateTime previousTime; - - private readonly object elementBufferLock = new object(); - private readonly HashSet elementBuffer; - private TaskCompletionSource currentCompletionSource = new TaskCompletionSource(); - - /// - /// A lock around the current call to prevent multiple callers - /// - private readonly object callLock = new object(); - - /// - /// A task that represents the current call in progress. - /// - private Task inProgressTask = Task.FromResult(true); - - public event EventHandler> Completed; - - /// - /// Create a - /// - /// The minimum duration between triggers of the event. - /// If not null, overrides the comparer used to compare elements in the buffer. - public CallBufferTimer(TimeSpan period, IEqualityComparer comparer = null) - { - this.period = period; - this.elementBuffer = new HashSet(comparer); - } - - public Task Fire(IList elements) - { - if (elements == null) - { - throw new ArgumentNullException("elements"); - } - - if (elements.Count == 0) - { - return Task.FromResult(true); - } - - TaskCompletionSource tcs; - lock (this.elementBufferLock) - { - foreach (T user in elements) - { - this.elementBuffer.Add(user); - } - // Grab the TCS associated with this buffer. This will complete - // when all the elements in this buffer have been sent. - tcs = this.currentCompletionSource; - } - - this.FireHelper(); - - return tcs.Task; - } - - private void FireHelper() - { - // If there's a call in progress, it will queue up a new - // task once it's done so we can just return. - if (!this.inProgressTask.IsCompleted) return; - - TaskCompletionSource inProgressCompletionSource; - - // Prevent multiple people from initiating calls at the same time. - lock (this.callLock) - { - if (!this.inProgressTask.IsCompleted) return; - - // Grab the current completion source, and mark it as in-progress by - // setting it's task as the current in progress task. Note that we - // are not swapping out the completion source yet, which means that - // people can continue to queue elements into this buffer until we - // actually execute this call. - inProgressCompletionSource = this.currentCompletionSource; - this.inProgressTask = inProgressCompletionSource.Task; - } - - // Determine if we need to delay at all. - TimeSpan callDelay = this.period - (DateTime.Now - this.previousTime); - if (callDelay < TimeSpan.Zero) callDelay = TimeSpan.Zero; - - // Yes, we will 'delay' for zero time in some cases, but without await - // it would be much uglier to handle both cases explicitly. - Task.Delay(callDelay).ContinueWith(continuationAction => - { - if (continuationAction.IsFaulted) - { - inProgressCompletionSource.SetException(continuationAction.Exception); - return; - } - - // Copy the current buffer and TCS out and replace them with new ones. - // Anyone who attempts to add stuff to the buffer after this point will - // get a new TCS and as a result will wait until the next call occurs. - List elements; - lock (this.elementBufferLock) - { - inProgressCompletionSource = this.currentCompletionSource; - this.currentCompletionSource = new TaskCompletionSource(); - - elements = this.elementBuffer.ToList(); - this.elementBuffer.Clear(); - } - - this.inProgressTask = inProgressCompletionSource.Task; - - if (elements.Count == 0) - { - // No elements to request so complete immediately - inProgressCompletionSource.SetResult(true); - return; - } - - try - { - this.previousTime = DateTime.Now; - - this.OnCompleted(new CallBufferEventArgs(elements)); - inProgressCompletionSource.SetResult(true); - - if (this.elementBuffer.Count > 0) - { - this.FireHelper(); - } - } - catch (Exception e) - { - inProgressCompletionSource.SetException(e); - } - }); - } - - protected virtual void OnCompleted(CallBufferEventArgs e) - { - var handler = this.Completed; - if (handler != null) handler(this, e); - } - } -} \ No newline at end of file diff --git a/CSharpSource/Source/api/Shared/IXboxWebsocketClient.cs b/CSharpSource/Source/api/Shared/IXboxWebsocketClient.cs deleted file mode 100644 index fec70ff..0000000 --- a/CSharpSource/Source/api/Shared/IXboxWebsocketClient.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Xbox.Services.System; - -namespace Microsoft.Xbox.Services.Shared -{ - interface IXboxWebsocketClient : IDisposable - { - Task Connect( - XboxLiveUser xblUser, - string uri, - string subprotocol); - - void Send(string message, Action onSendComplete); - - void Close(); - } -} diff --git a/CSharpSource/Source/api/Social/Manager/MockSocialManager.cs b/CSharpSource/Source/api/Social/Manager/MockSocialManager.cs index 1a43c67..1bc1a74 100644 --- a/CSharpSource/Source/api/Social/Manager/MockSocialManager.cs +++ b/CSharpSource/Source/api/Social/Manager/MockSocialManager.cs @@ -163,7 +163,7 @@ namespace Microsoft.Xbox.Services.Social.Manager { new SocialManagerPresenceTitleRecord { - TitleId = XboxLiveAppConfiguration.Instance.TitleId, + TitleId = XboxLiveAppConfiguration.SingletonInstance.TitleId, IsTitleActive = true, } }; diff --git a/CSharpSource/Source/api/Social/Manager/SocialManager.cs b/CSharpSource/Source/api/Social/Manager/SocialManager.cs index 225c4ed..0cb3551 100644 --- a/CSharpSource/Source/api/Social/Manager/SocialManager.cs +++ b/CSharpSource/Source/api/Social/Manager/SocialManager.cs @@ -35,6 +35,5 @@ namespace Microsoft.Xbox.Services.Social.Manager return m_instance; } } - } } \ No newline at end of file diff --git a/CSharpSource/Source/api/Social/ProfileService.cs b/CSharpSource/Source/api/Social/ProfileService.cs index 3be024a..fa765ad 100644 --- a/CSharpSource/Source/api/Social/ProfileService.cs +++ b/CSharpSource/Source/api/Social/ProfileService.cs @@ -9,101 +9,21 @@ namespace Microsoft.Xbox.Services.Social public class ProfileService { - private readonly string profileEndpoint; - - protected XboxLiveAppConfiguration config; - internal ProfileService() { - this.config = XboxLive.Instance.AppConfig; - this.profileEndpoint = this.config.GetEndpointForService("profile"); } - public Task GetUserProfileAsync(XboxLiveUser user, string xboxUserId) + public Task GetUserProfileAsync(string xboxUserId) { - if (string.IsNullOrEmpty(xboxUserId)) - { - throw new ArgumentException("invalid xboxUserId", "xboxUserId"); - } - - List profiles = new List { xboxUserId }; - - return this.GetUserProfilesAsync(user, profiles).ContinueWith(task => task.Result[0]); + throw new NotImplementedException(); } - public Task> GetUserProfilesAsync(XboxLiveUser user, List xboxUserIds) + public Task> GetUserProfilesAsync(IReadOnlyList xboxUserIds) { - if (xboxUserIds == null) - { - throw new ArgumentNullException("xboxUserIds"); - } - if (xboxUserIds.Count == 0) - { - throw new ArgumentOutOfRangeException("xboxUserIds", "Empty list of user ids"); - } - - if (XboxLive.UseMockServices) - { - Random rand = new Random(); - List outputUsers = new List(xboxUserIds.Count); - foreach (string xuid in xboxUserIds) - { - // generate a fake dev gamertag - string gamertag = "2 dev " + rand.Next(10000); - XboxUserProfile profile = new XboxUserProfile() - { - XboxUserId = xuid, - ApplicationDisplayName = gamertag, - ApplicationDisplayPictureResizeUri = new Uri("http://images-eds.xboxlive.com/image?url=z951ykn43p4FqWbbFvR2Ec.8vbDhj8G2Xe7JngaTToBrrCmIEEXHC9UNrdJ6P7KI4AAOijCgOA3.jozKovAH98vieJP1ResWJCw2dp82QtambLRqzQbSIiqrCug0AvP4&format=png"), - GameDisplayName = gamertag, - GameDisplayPictureResizeUri = new Uri("http://images-eds.xboxlive.com/image?url=z951ykn43p4FqWbbFvR2Ec.8vbDhj8G2Xe7JngaTToBrrCmIEEXHC9UNrdJ6P7KI4AAOijCgOA3.jozKovAH98vieJP1ResWJCw2dp82QtambLRqzQbSIiqrCug0AvP4&format=png"), - Gamerscore = rand.Next(250000).ToString(), - Gamertag = gamertag - }; - - outputUsers.Add(profile); - } - - return Task.FromResult(outputUsers); - } - else - { - XboxLiveHttpRequest req = XboxLiveHttpRequest.Create(HttpMethod.Post, profileEndpoint, "/users/batch/profile/settings"); - - req.ContractVersion = "2"; - req.ContentType = "application/json; charset=utf-8"; - Models.ProfileSettingsRequest reqBodyObject = new Models.ProfileSettingsRequest(xboxUserIds, true); - req.RequestBody = JsonSerialization.ToJson(reqBodyObject); - req.XboxLiveAPI = XboxLiveAPIName.GetUserProfiles; - return req.GetResponseWithAuth(user).ContinueWith(task => - { - XboxLiveHttpResponse response = task.Result; - Models.ProfileSettingsResponse responseBody = new Models.ProfileSettingsResponse(); - responseBody = JsonSerialization.FromJson(response.ResponseBodyString); - - List outputUsers = new List(); - foreach (Models.ProfileUser entry in responseBody.profileUsers) - { - XboxUserProfile profile = new XboxUserProfile() - { - XboxUserId = entry.id, - Gamertag = entry.Gamertag(), - GameDisplayName = entry.GameDisplayName(), - GameDisplayPictureResizeUri = new Uri(entry.GameDisplayPic()), - ApplicationDisplayName = entry.AppDisplayName(), - ApplicationDisplayPictureResizeUri = new Uri(entry.AppDisplayPic()), - Gamerscore = entry.Gamerscore() - }; - - outputUsers.Add(profile); - } - - return outputUsers; - }); - } + throw new NotImplementedException(); } - public Task> GetUserProfilesForSocialGroupAsync(string socialGroup) + public Task> GetUserProfilesForSocialGroupAsync(string socialGroup) { throw new NotImplementedException(); } diff --git a/CSharpSource/Source/api/System/AuthConfig.cs b/CSharpSource/Source/api/System/AuthConfig.cs deleted file mode 100644 index 8ccff8a..0000000 --- a/CSharpSource/Source/api/System/AuthConfig.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// -using System; -using System.Collections.Generic; -using System.Text; - -namespace Microsoft.Xbox.Services.System -{ - internal class AuthConfig - { - public string Sandbox { get; set; } - public string XboxLiveRelyingParty { get; set; } - public string EnvironmentPrefix { get; set; } - public string Environment { get; set; } - public bool UseCompactTicket { get; set; } - public string XboxLiveEndpoint { get; set; } - public string RPSTicketService { get; set; } - public string RPSTicketPolicy { get; set; } - public string UserTokenSiteName { get; set; } - public AuthConfig() - { - XboxLiveEndpoint = "https://xboxlive.com"; - XboxLiveRelyingParty = "https://auth.xboxlive.com"; - UserTokenSiteName = GetEndpointPath("user.auth", "", Environment, false); - RPSTicketPolicy = UseCompactTicket ? "MBI_SSL" : "DELEGATION"; - RPSTicketService = UseCompactTicket ? UserTokenSiteName : "xbl.signin xbl.friends"; - } - - public static string GetEndpointPath(string serviceName, string EnvironmentPrefix, string Environment, bool appendProtocol = true) - { - string endpointPath = ""; - if(appendProtocol) - { - endpointPath += "https://"; - } - endpointPath += EnvironmentPrefix + serviceName + Environment + ".xboxlive.com"; - return endpointPath; - } - } -} diff --git a/CSharpSource/Source/api/System/GamingPrivilege.cs b/CSharpSource/Source/api/System/GamingPrivilege.cs index b1b29d0..cb17def 100644 --- a/CSharpSource/Source/api/System/GamingPrivilege.cs +++ b/CSharpSource/Source/api/System/GamingPrivilege.cs @@ -1,10 +1,6 @@ // Copyright (c) Microsoft Corporation // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using System; -using System.Linq; -using System.Collections.Generic; -using System.Threading.Tasks; namespace Microsoft.Xbox.Services.System { @@ -33,5 +29,4 @@ namespace Microsoft.Xbox.Services.System MultiplayerSessions = 254, AddFriend = 255, } - } diff --git a/CSharpSource/Source/api/System/IUserImpl.cs b/CSharpSource/Source/api/System/IUserImpl.cs index 67ec7c0..7986c80 100644 --- a/CSharpSource/Source/api/System/IUserImpl.cs +++ b/CSharpSource/Source/api/System/IUserImpl.cs @@ -14,16 +14,14 @@ namespace Microsoft.Xbox.Services.System string AgeGroup { get; } string Privileges { get; } string WebAccountId { get; } - AuthConfig AuthConfig { get; } #if WINDOWS_UWP Windows.System.User CreationContext { get; } #endif #if !UNITY_EDITOR IntPtr XboxLiveUserPtr { get; } #endif - Task SignInImpl(bool showUI, bool forceRefresh); - Task InternalGetTokenAndSignatureAsync(string httpMethod, string url, string headers, byte[] body, bool promptForCredentialsIfNeeded, bool forceRefresh); + Task InternalGetTokenAndSignatureAsync(string httpMethod, string url, string headers, byte[] body, bool promptForCredentialsIfNeeded, bool forceRefresh); } } \ No newline at end of file diff --git a/CSharpSource/Source/api/System/JsonSerialization.cs b/CSharpSource/Source/api/System/JsonSerialization.cs deleted file mode 100644 index 474f444..0000000 --- a/CSharpSource/Source/api/System/JsonSerialization.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// -using Newtonsoft.Json; - -namespace Microsoft.Xbox.Services -{ - internal static class JsonSerialization - { - internal static T FromJson(string jsonInput) - { - return JsonConvert.DeserializeObject(jsonInput); - } - - internal static string ToJson(T input) - { - return JsonConvert.SerializeObject(input); - } - } -} diff --git a/CSharpSource/Source/api/System/MarshallingHelpers.cs b/CSharpSource/Source/api/System/MarshallingHelpers.cs index d7f5cee..5f05eae 100644 --- a/CSharpSource/Source/api/System/MarshallingHelpers.cs +++ b/CSharpSource/Source/api/System/MarshallingHelpers.cs @@ -6,6 +6,7 @@ namespace Microsoft.Xbox.Services { using global::System; using global::System.Collections.Generic; + using global::System.Linq; using global::System.Runtime.InteropServices; using global::System.Text; @@ -51,9 +52,9 @@ namespace Microsoft.Xbox.Services /// Pointer to the C-style string array /// Number of strings in the array /// - internal static IList Utf8StringArrayToStringList(IntPtr arrayPtr, int length) + internal static IList Utf8StringArrayToStringList(IntPtr arrayPtr, uint length) { - var list = new List(length); + var list = new List((int)length); for (int i = 0; i < length; ++i) { string str = MarshalingHelpers.Utf8ToString(Marshal.ReadIntPtr(arrayPtr)); @@ -69,9 +70,9 @@ namespace Microsoft.Xbox.Services /// /// The array of string to allocate /// An IntPtr to the first Utf8String pointer - internal static IntPtr StringListToHGlobalUtf8StringArray(IList strings) + internal static IntPtr StringListToHGlobalUtf8StringArray(IEnumerable strings) { - var firstString = Marshal.AllocHGlobal(IntPtr.Size * strings.Count); + var firstString = Marshal.AllocHGlobal(IntPtr.Size * strings.Count()); int offset = 0; foreach (var str in strings) { diff --git a/CSharpSource/Source/api/System/StringService.cs b/CSharpSource/Source/api/System/StringService.cs index 57c018b..67f9e1b 100644 --- a/CSharpSource/Source/api/System/StringService.cs +++ b/CSharpSource/Source/api/System/StringService.cs @@ -1,16 +1,14 @@ // Copyright (c) Microsoft Corporation // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using System; -using System.Linq; -using System.Collections.Generic; -using System.Threading.Tasks; namespace Microsoft.Xbox.Services.System { + using global::System; + using global::System.Threading.Tasks; + public class StringService { - public Task VerifyStringAsync(string stringToVerify) { throw new NotImplementedException(); diff --git a/CSharpSource/Source/api/System/VerifyStringResult.cs b/CSharpSource/Source/api/System/VerifyStringResult.cs index 6ecabb1..abec18c 100644 --- a/CSharpSource/Source/api/System/VerifyStringResult.cs +++ b/CSharpSource/Source/api/System/VerifyStringResult.cs @@ -1,16 +1,11 @@ // Copyright (c) Microsoft Corporation // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using System; -using System.Linq; -using System.Collections.Generic; -using System.Threading.Tasks; namespace Microsoft.Xbox.Services.System { public class VerifyStringResult { - public string FirstOffendingSubstring { get; diff --git a/CSharpSource/Source/api/System/VerifyStringResultCode.cs b/CSharpSource/Source/api/System/VerifyStringResultCode.cs index c7190f7..6be8c82 100644 --- a/CSharpSource/Source/api/System/VerifyStringResultCode.cs +++ b/CSharpSource/Source/api/System/VerifyStringResultCode.cs @@ -1,10 +1,6 @@ // Copyright (c) Microsoft Corporation // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using System; -using System.Linq; -using System.Collections.Generic; -using System.Threading.Tasks; namespace Microsoft.Xbox.Services.System { @@ -15,5 +11,4 @@ namespace Microsoft.Xbox.Services.System TooLong = 2, UnknownError = 3, } - } diff --git a/CSharpSource/Source/api/System/XboxLiveServicesSettings.cs b/CSharpSource/Source/api/System/XboxLiveServicesSettings.cs index ca1d81c..f8cfbae 100644 --- a/CSharpSource/Source/api/System/XboxLiveServicesSettings.cs +++ b/CSharpSource/Source/api/System/XboxLiveServicesSettings.cs @@ -11,6 +11,6 @@ namespace Microsoft.Xbox.Services.System public static XboxLiveServicesSettings SingletonInstance { get; private set; } - //public event EventHandler LogCallRouted; + public event EventHandler LogCallRouted; } } \ No newline at end of file diff --git a/CSharpSource/Source/api/System/XboxSystemFactory.cs b/CSharpSource/Source/api/System/XboxSystemFactory.cs deleted file mode 100644 index f9ca0ea..0000000 --- a/CSharpSource/Source/api/System/XboxSystemFactory.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Microsoft.Xbox.Services; -using Microsoft.Xbox.Services.Shared; - -namespace Microsoft.Xbox.Services.System -{ - class XboxSystemFactory - { - private static XboxSystemFactory factory; - public static XboxSystemFactory GetSingletonInstance() - { - if(factory == null) - { - factory = new XboxSystemFactory(); - } - - return factory; - } - - private XboxSystemFactory() - { - } - - public IXboxWebsocketClient CreateWebsocketClient() - { -#if WINDOWS_UWP - return null; -#else - return null; -#endif - } - } -} diff --git a/CSharpSource/Source/api/System/XboxUserIdEqualityComparer.cs b/CSharpSource/Source/api/System/XboxUserIdEqualityComparer.cs deleted file mode 100644 index 8ab6ded..0000000 --- a/CSharpSource/Source/api/System/XboxUserIdEqualityComparer.cs +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// -namespace Microsoft.Xbox.Services -{ - using global::System.Collections.Generic; - - using Microsoft.Xbox.Services.Social.Manager; - - /// - /// An equality comparer that only uses the XUID property. - /// - /// - /// This is used in a variety of places in order to perform dictionary lookups efficiently. - /// - public sealed class XboxUserIdEqualityComparer : IEqualityComparer - { - public bool Equals(XboxLiveUser x, XboxLiveUser y) - { - if (ReferenceEquals(x, y)) return true; - if (ReferenceEquals(x, null)) return false; - if (ReferenceEquals(y, null)) return false; - if (x.GetType() != y.GetType()) return false; - return string.Equals(x.XboxUserId, y.XboxUserId); - } - - public int GetHashCode(XboxLiveUser obj) - { - return obj.XboxUserId.GetHashCode(); - } - } - - /// - /// An equality comparer that only uses the XUID property. - /// - /// - /// This is used in a variety of places in order to perform dictionary lookups efficiently. - /// - public sealed class XboxSocialUserIdEqualityComparer : IEqualityComparer - { - private static XboxSocialUserIdEqualityComparer instance; - private static readonly object instanceLock = new object(); - - public static XboxSocialUserIdEqualityComparer Instance - { - get - { - if (instance == null) - { - lock (instanceLock) - { - if (instance == null) - { - instance = new XboxSocialUserIdEqualityComparer(); - } - } - } - return instance; - } - } - - public bool Equals(XboxSocialUser x, XboxSocialUser y) - { - if (ReferenceEquals(x, y)) return true; - if (ReferenceEquals(x, null)) return false; - if (ReferenceEquals(y, null)) return false; - if (x.GetType() != y.GetType()) return false; - return string.Equals(x.XboxUserId, y.XboxUserId); - } - - public int GetHashCode(XboxSocialUser obj) - { - return obj.XboxUserId.GetHashCode(); - } - } -} \ No newline at end of file diff --git a/CSharpSource/Source/api/System/XboxLiveCallbackContext.cs b/CSharpSource/Source/api/System/XsapiCallbackContext.cs similarity index 100% rename from CSharpSource/Source/api/System/XboxLiveCallbackContext.cs rename to CSharpSource/Source/api/System/XsapiCallbackContext.cs diff --git a/CSharpSource/Source/api/System/XboxLiveResult.cs b/CSharpSource/Source/api/System/XsapiResult.cs similarity index 100% rename from CSharpSource/Source/api/System/XboxLiveResult.cs rename to CSharpSource/Source/api/System/XsapiResult.cs diff --git a/CSharpSource/Source/api/TitleStorage/ITitleStorageService.cs b/CSharpSource/Source/api/TitleStorage/ITitleStorageService.cs index f4f45f6..76a5628 100644 --- a/CSharpSource/Source/api/TitleStorage/ITitleStorageService.cs +++ b/CSharpSource/Source/api/TitleStorage/ITitleStorageService.cs @@ -1,8 +1,11 @@ -namespace Microsoft.Xbox.Services.Shared.TitleStorage +// Copyright (c) Microsoft Corporation +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +namespace Microsoft.Xbox.Services.Shared.TitleStorage { using global::System.Collections.Generic; using global::System.Threading.Tasks; - using Microsoft.Xbox.Services.TitleStorage; /// @@ -72,7 +75,7 @@ /// The ETag match condition used to determine if the blob data should be uploaded. /// The preferred upload block size in bytes for binary blobs. /// An instance of the class with updated ETag and Length Properties. - Task UploadBlobAsync(TitleStorageBlobMetadata blobMetadata, List blobBuffer, TitleStorageETagMatchCondition etagMatchCondition, uint preferredUploadBlockSize); + Task UploadBlobAsync(TitleStorageBlobMetadata blobMetadata, IReadOnlyList blobBuffer, TitleStorageETagMatchCondition etagMatchCondition, uint preferredUploadBlockSize); } } diff --git a/CSharpSource/Source/api/TitleStorage/TitleStorageBlobMetadata.cs b/CSharpSource/Source/api/TitleStorage/TitleStorageBlobMetadata.cs index a02f20b..6d86d2e 100644 --- a/CSharpSource/Source/api/TitleStorage/TitleStorageBlobMetadata.cs +++ b/CSharpSource/Source/api/TitleStorage/TitleStorageBlobMetadata.cs @@ -23,7 +23,7 @@ namespace Microsoft.Xbox.Services.TitleStorage /// /// [optional] Timestamp assigned by the client. /// - public DateTimeOffset? ClientTimeStamp { get; private set; } + public DateTimeOffset ClientTimeStamp { get; private set; } /// /// ETag for the file used in read and write requests. @@ -157,13 +157,22 @@ namespace Microsoft.Xbox.Services.TitleStorage var displayName = MarshalingHelpers.StringToHGlobalUtf8(this.DisplayName); var etag = MarshalingHelpers.StringToHGlobalUtf8(this.ETag); - TitleStorageCreateBlobMetadata(scid, StorageType, path, BlobType, xuid, displayName, etag, IntPtr.Zero, /*TODO client timestamp*/ out metadataPtr); + IntPtr clientTimePtr = IntPtr.Zero; + if (this.ClientTimeStamp != null) + { + var clientTime = this.ClientTimeStamp.ToUnixTimeMilliseconds(); + clientTimePtr = Marshal.AllocHGlobal(MarshalingHelpers.SizeOf()); + Marshal.WriteInt64(clientTimePtr, clientTime); + } + + TitleStorageCreateBlobMetadata(scid, StorageType, path, BlobType, xuid, displayName, etag, clientTimePtr, out metadataPtr); Marshal.FreeHGlobal(scid); Marshal.FreeHGlobal(path); Marshal.FreeHGlobal(xuid); Marshal.FreeHGlobal(displayName); Marshal.FreeHGlobal(etag); + Marshal.FreeHGlobal(clientTimePtr); } internal void Refresh() diff --git a/CSharpSource/Source/api/TitleStorage/TitleStorageBlobMetadataResult.cs b/CSharpSource/Source/api/TitleStorage/TitleStorageBlobMetadataResult.cs index 39b34dd..1a41bac 100644 --- a/CSharpSource/Source/api/TitleStorage/TitleStorageBlobMetadataResult.cs +++ b/CSharpSource/Source/api/TitleStorage/TitleStorageBlobMetadataResult.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // - namespace Microsoft.Xbox.Services.TitleStorage { using global::System; diff --git a/CSharpSource/Source/api/TitleStorage/TitleStorageBlobResult.cs b/CSharpSource/Source/api/TitleStorage/TitleStorageBlobResult.cs index 3570f77..9873ab2 100644 --- a/CSharpSource/Source/api/TitleStorage/TitleStorageBlobResult.cs +++ b/CSharpSource/Source/api/TitleStorage/TitleStorageBlobResult.cs @@ -3,8 +3,8 @@ // namespace Microsoft.Xbox.Services.TitleStorage { - using global::System.Runtime.InteropServices; using global::System; + using global::System.Runtime.InteropServices; /// /// Blob data returned from the cloud. diff --git a/CSharpSource/Source/api/TitleStorage/TitleStorageQuota.cs b/CSharpSource/Source/api/TitleStorage/TitleStorageQuota.cs index 2933a1d..6b8ba59 100644 --- a/CSharpSource/Source/api/TitleStorage/TitleStorageQuota.cs +++ b/CSharpSource/Source/api/TitleStorage/TitleStorageQuota.cs @@ -28,6 +28,15 @@ namespace Microsoft.Xbox.Services.TitleStorage /// public TitleStorageType StorageType { get; private set; } + /// + /// The ID of the user associated with the storage area + /// + public string XboxUserId { get; private set; } + + /// + /// The service configuration ID to get the quota from + /// + public string ServiceConfigurationId { get; private set; } /// /// Initialze a TitleStorageQuota from the corresponding C object @@ -37,6 +46,8 @@ namespace Microsoft.Xbox.Services.TitleStorage QuotaBytes = quotaStruct.QuotaBytes; UsedBytes = quotaStruct.UsedBytes; StorageType = quotaStruct.storageType; + XboxUserId = MarshalingHelpers.Utf8ToString(quotaStruct.XboxUserId); + ServiceConfigurationId = MarshalingHelpers.Utf8ToString(quotaStruct.ServiceConfigurationId); } } diff --git a/CSharpSource/Source/api/TitleStorage/TitleStorageService.cs b/CSharpSource/Source/api/TitleStorage/TitleStorageService.cs index d17964d..91a3d65 100644 --- a/CSharpSource/Source/api/TitleStorage/TitleStorageService.cs +++ b/CSharpSource/Source/api/TitleStorage/TitleStorageService.cs @@ -5,6 +5,7 @@ namespace Microsoft.Xbox.Services.TitleStorage { using global::System; using global::System.Collections.Generic; + using global::System.Linq; using global::System.Runtime.InteropServices; using global::System.Threading.Tasks; using Microsoft.Xbox.Services.Shared.TitleStorage; @@ -38,7 +39,7 @@ namespace Microsoft.Xbox.Services.TitleStorage var tcs = new TaskCompletionSource(); Task.Run(() => { - var scid = MarshalingHelpers.StringToHGlobalUtf8(XboxLive.Instance.AppConfig.PrimaryServiceConfigId); + var scid = MarshalingHelpers.StringToHGlobalUtf8(XboxLive.Instance.AppConfig.ServiceConfigurationId); int contextKey; var context = XsapiCallbackContext.CreateContext(null, tcs, out contextKey); @@ -246,7 +247,7 @@ namespace Microsoft.Xbox.Services.TitleStorage /// The ETag match condition used to determine if the blob data should be uploaded. /// The preferred upload block size in bytes for binary blobs. /// An instance of the class with updated ETag and Length Properties. - public Task UploadBlobAsync(TitleStorageBlobMetadata blobMetadata, List blobBuffer, TitleStorageETagMatchCondition etagMatchCondition, uint preferredUploadBlockSize) + public Task UploadBlobAsync(TitleStorageBlobMetadata blobMetadata, IReadOnlyList blobBuffer, TitleStorageETagMatchCondition etagMatchCondition, uint preferredUploadBlockSize) { var tcs = new TaskCompletionSource(); Task.Run(() => @@ -255,7 +256,7 @@ namespace Microsoft.Xbox.Services.TitleStorage var context = XsapiCallbackContext.CreateContext(blobMetadata, tcs, out contextKey); var buffer = Marshal.AllocHGlobal(blobBuffer.Count); - Marshal.Copy(blobBuffer.ToArray(), 0, buffer, blobBuffer.Count); + Marshal.Copy(Enumerable.ToArray(blobBuffer), 0, buffer, blobBuffer.Count); context.PointersToFree = new List { buffer }; var xsapiResult = TitleStorageUploadBlob( diff --git a/CSharpSource/Tests/IntegrationTests/UWP/UWPIntegration/MainPage.xaml.cs b/CSharpSource/Tests/IntegrationTests/UWP/UWPIntegration/MainPage.xaml.cs index 98c442d..bc4b8ef 100644 --- a/CSharpSource/Tests/IntegrationTests/UWP/UWPIntegration/MainPage.xaml.cs +++ b/CSharpSource/Tests/IntegrationTests/UWP/UWPIntegration/MainPage.xaml.cs @@ -219,7 +219,7 @@ namespace UWPIntegration string resultText = string.Format("Allowed: {0}", result.IsAllowed); if (!result.IsAllowed) { - foreach (var reason in result.Reasons) + foreach (var reason in result.DenyReasons) { resultText += string.Format("\tReason: {0}", reason.Reason); } @@ -249,7 +249,7 @@ namespace UWPIntegration resultText += string.Format("\tPermission {0} allowed: {1}", permissionResult.PermissionRequested, permissionResult.IsAllowed); if (!permissionResult.IsAllowed) { - foreach (var reason in permissionResult.Reasons) + foreach (var reason in permissionResult.DenyReasons) { resultText += string.Format("\tReason: {0}", reason.Reason); } @@ -333,7 +333,7 @@ namespace UWPIntegration private async void TitleStorageGetQuota_Click(object sender, RoutedEventArgs e) { var quota = await this.User.Services.TitleStorageService.GetQuotaAsync( - XboxLive.Instance.AppConfig.PrimaryServiceConfigId, TitleStorageType.Universal); + XboxLive.Instance.AppConfig.ServiceConfigurationId, TitleStorageType.Universal); this.TitleStorageData.Text = string.Format("Used bytes = {0}, Quota bytes = {1}", quota.UsedBytes, quota.QuotaBytes); } @@ -343,7 +343,7 @@ namespace UWPIntegration try { var metadataResult = await this.User.Services.TitleStorageService.GetBlobMetadataAsync( - XboxLive.Instance.AppConfig.PrimaryServiceConfigId, TitleStorageType.Universal, "path/to/", this.User.XboxUserId); + XboxLive.Instance.AppConfig.ServiceConfigurationId, TitleStorageType.Universal, "path/to/", this.User.XboxUserId); var items = metadataResult.Items; if (items.Count > 0) @@ -362,7 +362,7 @@ namespace UWPIntegration { try { - var metadata = new TitleStorageBlobMetadata(XboxLive.Instance.AppConfig.PrimaryServiceConfigId, TitleStorageType.Universal, "path/to/newfile.txt", TitleStorageBlobType.Binary, this.user.XboxUserId); + var metadata = new TitleStorageBlobMetadata(XboxLive.Instance.AppConfig.ServiceConfigurationId, TitleStorageType.Universal, "path/to/newfile.txt", TitleStorageBlobType.Binary, this.user.XboxUserId); var bytes = System.Text.Encoding.Unicode.GetBytes("Hello, world!"); @@ -403,7 +403,7 @@ namespace UWPIntegration { try { - var metadata = new TitleStorageBlobMetadata(XboxLive.Instance.AppConfig.PrimaryServiceConfigId, TitleStorageType.Universal, "path/to/newfile.txt", TitleStorageBlobType.Binary, this.user.XboxUserId); + var metadata = new TitleStorageBlobMetadata(XboxLive.Instance.AppConfig.ServiceConfigurationId, TitleStorageType.Universal, "path/to/newfile.txt", TitleStorageBlobType.Binary, this.user.XboxUserId); await this.User.Services.TitleStorageService.DeleteBlobAsync(metadata, false); this.TitleStorageData.Text = string.Format("Successfully deleted blob with path \"path/to/newfile.txt\"", metadata.Length); @@ -457,7 +457,7 @@ namespace UWPIntegration } this.StatsData.Text = string.Join(Environment.NewLine, statNames.Select(n => this.StatsManager.GetStatistic(this.User, n)).Select(s => $"{s.Name} ({s.DataType}) = {GetStatValue(s)}")); } - + IList socialEvents = this.SocialManager.DoWork(); foreach (SocialEvent ev in socialEvents) { diff --git a/CSharpSource/Tests/IntegrationTests/UWP/UWPIntegration/UWPIntegration.csproj b/CSharpSource/Tests/IntegrationTests/UWP/UWPIntegration/UWPIntegration.csproj index 2e95035..4d3d37e 100644 --- a/CSharpSource/Tests/IntegrationTests/UWP/UWPIntegration/UWPIntegration.csproj +++ b/CSharpSource/Tests/IntegrationTests/UWP/UWPIntegration/UWPIntegration.csproj @@ -99,6 +99,9 @@ + + Always + Designer @@ -153,8 +156,8 @@ - - + +