Tons of cleanup working preperation for preview release (#178)
This commit is contained in:
Родитель
d75ae9d4d4
Коммит
a0570b8eef
|
@ -56,7 +56,7 @@ public class XboxLiveConfigurationEditor : EditorWindow
|
||||||
|
|
||||||
if (this.configuration != null)
|
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);
|
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("Publisher", this.configuration.PublisherDisplayName);
|
||||||
PropertyLabel("App ID", this.configuration.AppId);
|
PropertyLabel("App ID", this.configuration.AppId);
|
||||||
PropertyLabel("Product Family Name", this.configuration.ProductFamilyName);
|
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("Title ID", this.configuration.TitleId.ToString());
|
||||||
PropertyLabel("Sandbox", this.configuration.Sandbox);
|
PropertyLabel("Sandbox", this.configuration.Sandbox);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace Microsoft.Xbox.Services.ConnectedStorage
|
||||||
if (resultCallBack != null)
|
if (resultCallBack != null)
|
||||||
{
|
{
|
||||||
#if ENABLE_WINMD_SUPPORT
|
#if ENABLE_WINMD_SUPPORT
|
||||||
var configId = XboxLive.Instance.AppConfig.PrimaryServiceConfigId;
|
var configId = XboxLive.Instance.AppConfig.ServiceConfigurationId;
|
||||||
var initTask = GameSaveProvider.GetForUserAsync(xboxLiveUser.WindowsSystemUser, configId).AsTask();
|
var initTask = GameSaveProvider.GetForUserAsync(xboxLiveUser.WindowsSystemUser, configId).AsTask();
|
||||||
if (initTask.Result.Status == GameSaveErrorStatus.Ok)
|
if (initTask.Result.Status == GameSaveErrorStatus.Ok)
|
||||||
{
|
{
|
||||||
|
|
|
@ -64,7 +64,7 @@ public class UserProfile : MonoBehaviour
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
// Disable the sign-in button if there's no configuration available.
|
// 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;
|
this.ConfigAvailable = false;
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ public class UserProfile : MonoBehaviour
|
||||||
{
|
{
|
||||||
XboxLiveUserManager.Instance.UserForSingleUserMode = Instantiate(this.XboxLiveUserPrefab);
|
XboxLiveUserManager.Instance.UserForSingleUserMode = Instantiate(this.XboxLiveUserPrefab);
|
||||||
this.XboxLiveUser = XboxLiveUserManager.Instance.UserForSingleUserMode;
|
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();
|
this.SignIn();
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,8 +44,6 @@ public class XboxLiveUserInfo : MonoBehaviour
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MockXboxLiveData.Load(Path.Combine(Application.dataPath, "MockData.json"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
|
|
|
@ -49,6 +49,7 @@ External/**/lib/
|
||||||
External/**/bin/
|
External/**/bin/
|
||||||
External/**/Debug/
|
External/**/Debug/
|
||||||
External/**/Release/
|
External/**/Release/
|
||||||
|
Tests/**/*.dll
|
||||||
|
|
||||||
**/*.classpath
|
**/*.classpath
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ Global
|
||||||
api\Microsoft.Xbox.Services.Shared.projitems*{035e5e11-4a0b-4d1f-ba13-9b62ccafb2b8}*SharedItemsImports = 13
|
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*{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*{cbd81e44-f37f-47d6-b71b-a43a748ae09c}*SharedItemsImports = 4
|
||||||
|
api\Microsoft.Xbox.Services.Shared.projitems*{cfb2ca8f-6611-4dca-981c-4b7afcca19a8}*SharedItemsImports = 4
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|ARM = Debug|ARM
|
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|ARM.ActiveCfg = Release|ARM
|
||||||
{4C1806D5-7279-4DFC-8874-13D66D52A31B}.ReleaseNET35|x64.ActiveCfg = Release|x64
|
{4C1806D5-7279-4DFC-8874-13D66D52A31B}.ReleaseNET35|x64.ActiveCfg = Release|x64
|
||||||
{4C1806D5-7279-4DFC-8874-13D66D52A31B}.ReleaseNET35|x86.ActiveCfg = Release|x86
|
{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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
@ -29,7 +29,6 @@ namespace Microsoft.Xbox.Services.System
|
||||||
public string AgeGroup { get; set; }
|
public string AgeGroup { get; set; }
|
||||||
public string Privileges { get; set; }
|
public string Privileges { get; set; }
|
||||||
public string WebAccountId { get; set; }
|
public string WebAccountId { get; set; }
|
||||||
public AuthConfig AuthConfig { get; set; }
|
|
||||||
public IntPtr XboxLiveUserPtr { get; }
|
public IntPtr XboxLiveUserPtr { get; }
|
||||||
|
|
||||||
public Task<SignInResult> SignInImpl(bool showUI, bool forceRefresh)
|
public Task<SignInResult> SignInImpl(bool showUI, bool forceRefresh)
|
||||||
|
@ -37,10 +36,10 @@ namespace Microsoft.Xbox.Services.System
|
||||||
return Task.FromResult(new SignInResult(SignInStatus.Success));
|
return Task.FromResult(new SignInResult(SignInStatus.Success));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<TokenAndSignatureResult> InternalGetTokenAndSignatureAsync(string httpMethod, string url, string headers, byte[] body, bool promptForCredentialsIfNeeded, bool forceRefresh)
|
public Task<GetTokenAndSignatureResult> InternalGetTokenAndSignatureAsync(string httpMethod, string url, string headers, byte[] body, bool promptForCredentialsIfNeeded, bool forceRefresh)
|
||||||
{
|
{
|
||||||
string[] authHeaderParts = authHeader.Substring(9).Split(';');
|
string[] authHeaderParts = authHeader.Substring(9).Split(';');
|
||||||
return Task.FromResult(new TokenAndSignatureResult
|
return Task.FromResult(new GetTokenAndSignatureResult
|
||||||
{
|
{
|
||||||
Gamertag = this.Gamertag,
|
Gamertag = this.Gamertag,
|
||||||
XboxUserId = this.XboxUserId,
|
XboxUserId = this.XboxUserId,
|
||||||
|
|
|
@ -3,17 +3,11 @@
|
||||||
//
|
//
|
||||||
namespace Microsoft.Xbox.Services
|
namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
|
|
||||||
public partial class XboxLive
|
public partial class XboxLive
|
||||||
{
|
{
|
||||||
public static bool UseMockServices
|
public static bool UseMockServices
|
||||||
{
|
{
|
||||||
get { return false; }
|
get { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool UseMockHttp
|
|
||||||
{
|
|
||||||
get { return true; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,11 +5,11 @@ namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
public partial class XboxLiveAppConfiguration
|
public partial class XboxLiveAppConfiguration
|
||||||
{
|
{
|
||||||
public static XboxLiveAppConfiguration Load(string path)
|
private static XboxLiveAppConfiguration Load()
|
||||||
{
|
{
|
||||||
return new XboxLiveAppConfiguration
|
return new XboxLiveAppConfiguration
|
||||||
{
|
{
|
||||||
PrimaryServiceConfigId = "00000000-0000-0000-0000-0000694f5acb",
|
ServiceConfigurationId = "00000000-0000-0000-0000-0000694f5acb",
|
||||||
TitleId = 1766808267,
|
TitleId = 1766808267,
|
||||||
Environment = string.Empty,
|
Environment = string.Empty,
|
||||||
Sandbox = "JDTDWX.0",
|
Sandbox = "JDTDWX.0",
|
||||||
|
|
|
@ -9,10 +9,5 @@ namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
get { return false; }
|
get { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool UseMockHttp
|
|
||||||
{
|
|
||||||
get { return false; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,28 +4,43 @@
|
||||||
|
|
||||||
namespace Microsoft.Xbox.Services
|
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 partial class XboxLiveAppConfiguration
|
||||||
{
|
{
|
||||||
public static XboxLiveAppConfiguration Load(string path)
|
private static XboxLiveAppConfiguration Load()
|
||||||
{
|
{
|
||||||
Windows.ApplicationModel.Package package = Windows.ApplicationModel.Package.Current;
|
IntPtr appConfigPtr;
|
||||||
Windows.Storage.StorageFolder installedLocation = package.InstalledLocation;
|
var result = GetXboxLiveAppConfigSingleton(out appConfigPtr);
|
||||||
|
if (result != XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
string fullPath = Path.Combine(installedLocation.Path, path);
|
|
||||||
if (!File.Exists(fullPath))
|
|
||||||
{
|
{
|
||||||
throw new FileNotFoundException(string.Format("Unable to find Xbox Live app configuration file '{0}'.", path));
|
throw new XboxException(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
string content = File.ReadAllText(fullPath);
|
var appConfigStruct = Marshal.PtrToStructure<XSAPI_XBOX_LIVE_APP_CONFIG>(appConfigPtr);
|
||||||
if (string.IsNullOrWhiteSpace(content))
|
|
||||||
{
|
|
||||||
throw new XboxException(string.Format("Xbox Live app configeration file '{0}' was empty.", path));
|
|
||||||
}
|
|
||||||
|
|
||||||
return JsonSerialization.FromJson<XboxLiveAppConfiguration>(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);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
namespace Microsoft.Xbox.Services
|
namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
using global::System.Threading.Tasks;
|
|
||||||
using Microsoft.Xbox.Services.System;
|
using Microsoft.Xbox.Services.System;
|
||||||
|
|
||||||
public partial class XboxLiveUser
|
public partial class XboxLiveUser
|
||||||
|
@ -14,41 +13,51 @@ namespace Microsoft.Xbox.Services
|
||||||
|
|
||||||
public XboxLiveUser(Windows.System.User systemUser)
|
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
|
// The UserImpl monitors the underlying system for sign out events
|
||||||
// and notifies us that a user has been signed out. We can then
|
// and notifies us that a user has been signed out. We can then
|
||||||
// pass that event on the application with a concrete reference.
|
// 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)
|
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
|
// The UserImpl monitors the underlying system for sign out events
|
||||||
// and notifies us that a user has been signed out. We can then
|
// and notifies us that a user has been signed out. We can then
|
||||||
// pass that event on the application with a concrete reference.
|
// 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));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
userImpl.UpdatePropertiesFromXboxLiveUserPtr();
|
||||||
this.userImpl = user;
|
|
||||||
user.UpdatePropertiesFromXboxLiveUserPtr();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Windows.System.User WindowsSystemUser
|
public Windows.System.User WindowsSystemUser
|
||||||
|
@ -63,20 +72,5 @@ namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
get { return (this.userImpl as UserImpl); }
|
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -100,7 +100,6 @@
|
||||||
<Compile Include="Statistics\Manager\StatisticEvent.cs" />
|
<Compile Include="Statistics\Manager\StatisticEvent.cs" />
|
||||||
<Compile Include="Statistics\Manager\StatisticManager.cs" />
|
<Compile Include="Statistics\Manager\StatisticManager.cs" />
|
||||||
<Compile Include="System\TitleCallableUI.cs" />
|
<Compile Include="System\TitleCallableUI.cs" />
|
||||||
<Compile Include="System\TokenRequestResult.cs" />
|
|
||||||
<Compile Include="System\UserImpl.cs" />
|
<Compile Include="System\UserImpl.cs" />
|
||||||
<Compile Include="Common\XboxLiveUser.cs" />
|
<Compile Include="Common\XboxLiveUser.cs" />
|
||||||
<Compile Include="Common\XboxLiveAppConfiguration.cs" />
|
<Compile Include="Common\XboxLiveAppConfiguration.cs" />
|
||||||
|
|
|
@ -6,7 +6,6 @@ namespace Microsoft.Xbox.Services.Social.Manager
|
||||||
using global::System;
|
using global::System;
|
||||||
using global::System.Collections.Generic;
|
using global::System.Collections.Generic;
|
||||||
using global::System.Runtime.InteropServices;
|
using global::System.Runtime.InteropServices;
|
||||||
using Microsoft.Xbox.Services.Presence;
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
public partial class SocialManager : ISocialManager
|
public partial class SocialManager : ISocialManager
|
||||||
|
@ -26,19 +25,14 @@ namespace Microsoft.Xbox.Services.Social.Manager
|
||||||
{
|
{
|
||||||
if (user == null) throw new ArgumentNullException("user");
|
if (user == null) throw new ArgumentNullException("user");
|
||||||
|
|
||||||
// Allocates memory for returned objects
|
IntPtr cErrMessage;
|
||||||
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
|
||||||
|
|
||||||
// Invokes the c method
|
// 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
|
// Handles error
|
||||||
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
|
|
||||||
Marshal.FreeHGlobal(cErrMessage);
|
|
||||||
|
|
||||||
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
{
|
{
|
||||||
// todo do something
|
throw new XboxException(errCode, cErrMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_localUsers.Add(user);
|
m_localUsers.Add(user);
|
||||||
|
@ -48,19 +42,13 @@ namespace Microsoft.Xbox.Services.Social.Manager
|
||||||
{
|
{
|
||||||
if (user == null) throw new ArgumentNullException("user");
|
if (user == null) throw new ArgumentNullException("user");
|
||||||
|
|
||||||
// Allocates memory for returned objects
|
IntPtr cErrMessage;
|
||||||
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
|
||||||
|
|
||||||
// Invokes the c method
|
// Invokes the c method
|
||||||
XSAPI_RESULT errCode = SocialManagerRemoveLocalUser(user.Impl.XboxLiveUserPtr, cErrMessage);
|
XSAPI_RESULT errCode = SocialManagerRemoveLocalUser(user.Impl.XboxLiveUserPtr, out cErrMessage);
|
||||||
|
|
||||||
// Handles error
|
|
||||||
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
|
|
||||||
Marshal.FreeHGlobal(cErrMessage);
|
|
||||||
|
|
||||||
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
{
|
{
|
||||||
// todo do something
|
throw new XboxException(errCode, cErrMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_localUsers.Remove(user);
|
m_localUsers.Remove(user);
|
||||||
|
@ -70,25 +58,18 @@ namespace Microsoft.Xbox.Services.Social.Manager
|
||||||
{
|
{
|
||||||
if (user == null) throw new ArgumentNullException("user");
|
if (user == null) throw new ArgumentNullException("user");
|
||||||
|
|
||||||
// Allocates memory for returned objects
|
IntPtr cGroupPtr;
|
||||||
IntPtr cGroupPtr = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
IntPtr cErrMessage;
|
||||||
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
|
||||||
|
|
||||||
// Invokes the c method
|
// Invokes the c method
|
||||||
XSAPI_RESULT errCode = SocialManagerCreateSocialUserGroupFromFilters(user.Impl.XboxLiveUserPtr, presenceFilter, relationshipFilter, cGroupPtr, cErrMessage);
|
XSAPI_RESULT errCode = SocialManagerCreateSocialUserGroupFromFilters(user.Impl.XboxLiveUserPtr, presenceFilter, relationshipFilter, out cGroupPtr, out cErrMessage);
|
||||||
|
|
||||||
// Handles error
|
|
||||||
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
|
|
||||||
Marshal.FreeHGlobal(cErrMessage);
|
|
||||||
|
|
||||||
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
{
|
{
|
||||||
// todo do something
|
throw new XboxException(errCode, cErrMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handles returned objects
|
// Handles returned objects
|
||||||
XboxSocialUserGroup socialUserGroup = new XboxSocialUserGroup(Marshal.ReadIntPtr(cGroupPtr));
|
XboxSocialUserGroup socialUserGroup = new XboxSocialUserGroup(cGroupPtr);
|
||||||
Marshal.FreeHGlobal(cGroupPtr);
|
|
||||||
m_groups.Add(socialUserGroup);
|
m_groups.Add(socialUserGroup);
|
||||||
|
|
||||||
return socialUserGroup;
|
return socialUserGroup;
|
||||||
|
@ -100,41 +81,23 @@ namespace Microsoft.Xbox.Services.Social.Manager
|
||||||
if (xboxUserIdList == null) throw new ArgumentNullException("xboxUserIdList");
|
if (xboxUserIdList == null) throw new ArgumentNullException("xboxUserIdList");
|
||||||
|
|
||||||
// Allocates memory for parameters
|
// Allocates memory for parameters
|
||||||
List<IntPtr> userIdPtrs = new List<IntPtr>();
|
IntPtr cUserIds = MarshalingHelpers.StringListToHGlobalUtf8StringArray(xboxUserIdList);
|
||||||
for (int i = 0; i < xboxUserIdList.Count; i++)
|
|
||||||
{
|
|
||||||
IntPtr cXuid = Marshal.StringToHGlobalAnsi(xboxUserIdList[i]);
|
|
||||||
userIdPtrs.Add(cXuid);
|
|
||||||
}
|
|
||||||
IntPtr cUserIds = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>() * xboxUserIdList.Count);
|
|
||||||
Marshal.Copy(userIdPtrs.ToArray(), 0, cUserIds, xboxUserIdList.Count);
|
|
||||||
|
|
||||||
// Allocates memory for returned objects
|
// Allocates memory for returned objects
|
||||||
IntPtr cGroupPtr = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
IntPtr cGroupPtr;
|
||||||
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
IntPtr cErrMessage;
|
||||||
|
|
||||||
// Invokes the c method
|
// Invokes the c method
|
||||||
XSAPI_RESULT errCode = SocialManagerCreateSocialUserGroupFromList(user.Impl.XboxLiveUserPtr, cUserIds, (uint)xboxUserIdList.Count, cGroupPtr, cErrMessage);
|
XSAPI_RESULT errCode = SocialManagerCreateSocialUserGroupFromList(user.Impl.XboxLiveUserPtr, cUserIds, (uint)xboxUserIdList.Count, out cGroupPtr, out cErrMessage);
|
||||||
|
|
||||||
// Handles error
|
|
||||||
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
|
|
||||||
Marshal.FreeHGlobal(cErrMessage);
|
|
||||||
|
|
||||||
|
MarshalingHelpers.FreeHGlobalUtf8StringArray(cUserIds, xboxUserIdList.Count);
|
||||||
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
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
|
// Handles returned objects
|
||||||
XboxSocialUserGroup socialUserGroup = new XboxSocialUserGroup(Marshal.ReadIntPtr(cGroupPtr));
|
XboxSocialUserGroup socialUserGroup = new XboxSocialUserGroup(cGroupPtr);
|
||||||
Marshal.FreeHGlobal(cGroupPtr);
|
|
||||||
m_groups.Add(socialUserGroup);
|
m_groups.Add(socialUserGroup);
|
||||||
|
|
||||||
return socialUserGroup;
|
return socialUserGroup;
|
||||||
|
@ -146,37 +109,20 @@ namespace Microsoft.Xbox.Services.Social.Manager
|
||||||
if (users == null) throw new ArgumentNullException("users");
|
if (users == null) throw new ArgumentNullException("users");
|
||||||
|
|
||||||
// Allocates memory for parameters
|
// Allocates memory for parameters
|
||||||
List<IntPtr> userIdPtrs = new List<IntPtr>();
|
IntPtr cUserIds = MarshalingHelpers.StringListToHGlobalUtf8StringArray(users);
|
||||||
for (int i = 0; i < users.Count; i++)
|
|
||||||
{
|
|
||||||
IntPtr cXuid = Marshal.StringToHGlobalUni(users[i]);
|
|
||||||
userIdPtrs.Add(cXuid);
|
|
||||||
}
|
|
||||||
IntPtr cUserIds = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>() * users.Count);
|
|
||||||
Marshal.Copy(userIdPtrs.ToArray(), 0, cUserIds, users.Count);
|
|
||||||
|
|
||||||
// Allocates memory for returned objects
|
// Allocates memory for returned objects
|
||||||
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
IntPtr cErrMessage;
|
||||||
|
|
||||||
// Invokes the c method
|
// Invokes the c method
|
||||||
XSAPI_RESULT errCode = SocialManagerUpdateSocialUserGroup(socialGroup.GetPtr(), cUserIds, (uint)users.Count, cErrMessage);
|
XSAPI_RESULT errCode = SocialManagerUpdateSocialUserGroup(socialGroup.GetPtr(), cUserIds, (uint)users.Count, out cErrMessage);
|
||||||
|
|
||||||
// Handles error
|
|
||||||
string errMessage = Marshal.PtrToStringUni(Marshal.ReadIntPtr(cErrMessage));
|
|
||||||
Marshal.FreeHGlobal(cErrMessage);
|
|
||||||
|
|
||||||
|
MarshalingHelpers.FreeHGlobalUtf8StringArray(cUserIds, users.Count);
|
||||||
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
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
|
// Does local work
|
||||||
socialGroup.Refresh();
|
socialGroup.Refresh();
|
||||||
}
|
}
|
||||||
|
@ -184,39 +130,27 @@ namespace Microsoft.Xbox.Services.Social.Manager
|
||||||
public void DestroySocialUserGroup(XboxSocialUserGroup xboxSocialUserGroup)
|
public void DestroySocialUserGroup(XboxSocialUserGroup xboxSocialUserGroup)
|
||||||
{
|
{
|
||||||
if (xboxSocialUserGroup == null) throw new ArgumentNullException("xboxSocialUserGroup");
|
if (xboxSocialUserGroup == null) throw new ArgumentNullException("xboxSocialUserGroup");
|
||||||
|
|
||||||
// Allocates memory for returned objects
|
|
||||||
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
|
||||||
|
|
||||||
|
IntPtr cErrMessage;
|
||||||
// Invokes the c method
|
// Invokes the c method
|
||||||
XSAPI_RESULT errCode = SocialManagerDestroySocialUserGroup(xboxSocialUserGroup.GetPtr(), cErrMessage);
|
XSAPI_RESULT errCode = SocialManagerDestroySocialUserGroup(xboxSocialUserGroup.GetPtr(), out cErrMessage);
|
||||||
|
|
||||||
// Handles error
|
|
||||||
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
|
|
||||||
Marshal.FreeHGlobal(cErrMessage);
|
|
||||||
|
|
||||||
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
{
|
{
|
||||||
// todo do something
|
throw new XboxException(errCode, cErrMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does local work
|
// Does local work
|
||||||
m_groups.Remove(xboxSocialUserGroup);
|
m_groups.Remove(xboxSocialUserGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IList<SocialEvent> DoWork()
|
public IList<SocialEvent> DoWork()
|
||||||
{
|
{
|
||||||
|
UInt32 eventsCount;
|
||||||
// Allocates memory for returned objects
|
|
||||||
IntPtr cEventsCount = Marshal.AllocHGlobal(Marshal.SizeOf<Int32>());
|
|
||||||
|
|
||||||
// Invokes the c method
|
// Invokes the c method
|
||||||
IntPtr eventsPtr = SocialManagerDoWork(cEventsCount);
|
IntPtr eventsPtr = SocialManagerDoWork(out eventsCount);
|
||||||
|
|
||||||
// Does local work
|
|
||||||
uint eventsCount = (uint)Marshal.ReadInt32(cEventsCount);
|
|
||||||
Marshal.FreeHGlobal(cEventsCount);
|
|
||||||
|
|
||||||
|
// Does local work
|
||||||
List<SocialEvent> events = new List<SocialEvent>();
|
List<SocialEvent> events = new List<SocialEvent>();
|
||||||
|
|
||||||
if (eventsCount > 0)
|
if (eventsCount > 0)
|
||||||
|
@ -250,19 +184,13 @@ namespace Microsoft.Xbox.Services.Social.Manager
|
||||||
{
|
{
|
||||||
if (user == null) throw new ArgumentNullException("user");
|
if (user == null) throw new ArgumentNullException("user");
|
||||||
|
|
||||||
// Allocates memory for returned objects
|
IntPtr cErrMessage;
|
||||||
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
|
||||||
|
|
||||||
// Invokes the c method
|
// Invokes the c method
|
||||||
XSAPI_RESULT errCode = SocialManagerSetRichPresencePollingStatus(user.Impl.XboxLiveUserPtr, shouldEnablePolling, cErrMessage);
|
XSAPI_RESULT errCode = SocialManagerSetRichPresencePollingStatus(user.Impl.XboxLiveUserPtr, shouldEnablePolling, out cErrMessage);
|
||||||
|
|
||||||
// Handles error
|
|
||||||
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
|
|
||||||
Marshal.FreeHGlobal(cErrMessage);
|
|
||||||
|
|
||||||
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
{
|
{
|
||||||
// todo do something
|
throw new XboxException(errCode, cErrMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does local work
|
// Does local work
|
||||||
|
@ -271,28 +199,28 @@ namespace Microsoft.Xbox.Services.Social.Manager
|
||||||
|
|
||||||
// Marshaling
|
// Marshaling
|
||||||
[DllImport(XboxLive.FlatCDllName)]
|
[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)]
|
[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)]
|
[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)]
|
[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)]
|
[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)]
|
[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)]
|
[DllImport(XboxLive.FlatCDllName)]
|
||||||
private static extern IntPtr SocialManagerDoWork(IntPtr numOfEvents);
|
private static extern IntPtr SocialManagerDoWork(out UInt32 numOfEvents);
|
||||||
|
|
||||||
[DllImport(XboxLive.FlatCDllName)]
|
[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)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
|
|
@ -12,7 +12,6 @@ namespace Microsoft.Xbox.Services.Social.Manager
|
||||||
TITLE_HISTORY cTitleHistory = Marshal.PtrToStructure<TITLE_HISTORY>(titleHistoryPtr);
|
TITLE_HISTORY cTitleHistory = Marshal.PtrToStructure<TITLE_HISTORY>(titleHistoryPtr);
|
||||||
HasUserPlayed = cTitleHistory.UserHasPlayed;
|
HasUserPlayed = cTitleHistory.UserHasPlayed;
|
||||||
|
|
||||||
// todo test
|
|
||||||
LastTimeUserPlayed = DateTimeOffset.FromUnixTimeSeconds(cTitleHistory.LastTimeUserPlayed);
|
LastTimeUserPlayed = DateTimeOffset.FromUnixTimeSeconds(cTitleHistory.LastTimeUserPlayed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,24 +15,18 @@ namespace Microsoft.Xbox.Services.Statistics.Manager
|
||||||
private readonly List<XboxLiveUser> m_localUsers = new List<XboxLiveUser>();
|
private readonly List<XboxLiveUser> m_localUsers = new List<XboxLiveUser>();
|
||||||
|
|
||||||
[DllImport(XboxLive.FlatCDllName)]
|
[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)
|
public void AddLocalUser(XboxLiveUser user)
|
||||||
{
|
{
|
||||||
if (user == null) throw new ArgumentNullException("user");
|
if (user == null) throw new ArgumentNullException("user");
|
||||||
|
|
||||||
// Allocates memory for returned objects
|
IntPtr cErrMessage;
|
||||||
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
|
||||||
|
|
||||||
// Invokes the c method
|
// Invokes the c method
|
||||||
XSAPI_RESULT errCode = StatsManagerAddLocalUser(user.Impl.XboxLiveUserPtr, cErrMessage);
|
XSAPI_RESULT errCode = StatsManagerAddLocalUser(user.Impl.XboxLiveUserPtr, out cErrMessage);
|
||||||
|
|
||||||
// Handles error
|
|
||||||
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
|
|
||||||
Marshal.FreeHGlobal(cErrMessage);
|
|
||||||
|
|
||||||
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
{
|
{
|
||||||
// todo do something
|
throw new XboxException(errCode, cErrMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does local work
|
// Does local work
|
||||||
|
@ -40,24 +34,18 @@ namespace Microsoft.Xbox.Services.Statistics.Manager
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport(XboxLive.FlatCDllName)]
|
[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)
|
public void RemoveLocalUser(XboxLiveUser user)
|
||||||
{
|
{
|
||||||
if (user == null) throw new ArgumentNullException("user");
|
if (user == null) throw new ArgumentNullException("user");
|
||||||
|
|
||||||
// Allocates memory for returned objects
|
IntPtr cErrMessage;
|
||||||
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
|
||||||
|
|
||||||
// Invokes the c method
|
// Invokes the c method
|
||||||
XSAPI_RESULT errCode = StatsManagerRemoveLocalUser(user.Impl.XboxLiveUserPtr, cErrMessage);
|
XSAPI_RESULT errCode = StatsManagerRemoveLocalUser(user.Impl.XboxLiveUserPtr, out cErrMessage);
|
||||||
|
|
||||||
// Handles error
|
|
||||||
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
|
|
||||||
Marshal.FreeHGlobal(cErrMessage);
|
|
||||||
|
|
||||||
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
{
|
{
|
||||||
// todo do something
|
throw new XboxException(errCode, cErrMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does local work
|
// Does local work
|
||||||
|
@ -65,40 +53,29 @@ namespace Microsoft.Xbox.Services.Statistics.Manager
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport(XboxLive.FlatCDllName)]
|
[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)
|
public void RequestFlushToService(XboxLiveUser user, bool isHighPriority = false)
|
||||||
{
|
{
|
||||||
if (user == null) throw new ArgumentNullException("user");
|
if (user == null) throw new ArgumentNullException("user");
|
||||||
|
|
||||||
// Allocates memory for returned objects
|
IntPtr cErrMessage;
|
||||||
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
|
||||||
|
|
||||||
// Invokes the c method
|
// Invokes the c method
|
||||||
XSAPI_RESULT errCode = StatsManagerRequestFlushToService(user.Impl.XboxLiveUserPtr, isHighPriority, cErrMessage);
|
XSAPI_RESULT errCode = StatsManagerRequestFlushToService(user.Impl.XboxLiveUserPtr, isHighPriority, out cErrMessage);
|
||||||
|
|
||||||
// Handles error
|
|
||||||
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
|
|
||||||
Marshal.FreeHGlobal(cErrMessage);
|
|
||||||
|
|
||||||
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
{
|
{
|
||||||
// todo do something
|
throw new XboxException(errCode, cErrMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport(XboxLive.FlatCDllName)]
|
[DllImport(XboxLive.FlatCDllName)]
|
||||||
private static extern IntPtr StatsManagerDoWork(IntPtr numOfEvents);
|
private static extern IntPtr StatsManagerDoWork(out Int32 numOfEvents);
|
||||||
public IList<StatisticEvent> DoWork()
|
public IList<StatisticEvent> DoWork()
|
||||||
{
|
{
|
||||||
// Allocates memory for returned objects
|
|
||||||
IntPtr cEventsCount = Marshal.AllocHGlobal(Marshal.SizeOf<Int32>());
|
|
||||||
|
|
||||||
|
Int32 eventsCount;
|
||||||
// Invokes the c method
|
// Invokes the c method
|
||||||
IntPtr eventsPtr = StatsManagerDoWork(cEventsCount);
|
IntPtr eventsPtr = StatsManagerDoWork(out eventsCount);
|
||||||
|
|
||||||
// Does local work
|
|
||||||
uint eventsCount = (uint)Marshal.ReadInt32(cEventsCount);
|
|
||||||
Marshal.FreeHGlobal(cEventsCount);
|
|
||||||
|
|
||||||
List<StatisticEvent> events = new List<StatisticEvent>();
|
List<StatisticEvent> events = new List<StatisticEvent>();
|
||||||
|
|
||||||
|
@ -123,176 +100,134 @@ namespace Microsoft.Xbox.Services.Statistics.Manager
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport(XboxLive.FlatCDllName)]
|
[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)
|
public void SetStatisticNumberData(XboxLiveUser user, string statName, double value)
|
||||||
{
|
{
|
||||||
if (user == null) throw new ArgumentNullException("user");
|
if (user == null) throw new ArgumentNullException("user");
|
||||||
|
|
||||||
// Allocates memory for returned objects
|
IntPtr cErrMessage;
|
||||||
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
|
||||||
|
|
||||||
// Invokes the c method
|
// Invokes the c method
|
||||||
XSAPI_RESULT errCode = StatsManagerSetStatisticNumberData(user.Impl.XboxLiveUserPtr, statName, value, cErrMessage);
|
XSAPI_RESULT errCode = StatsManagerSetStatisticNumberData(user.Impl.XboxLiveUserPtr, statName, value, out cErrMessage);
|
||||||
|
|
||||||
// Handles error
|
|
||||||
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
|
|
||||||
Marshal.FreeHGlobal(cErrMessage);
|
|
||||||
|
|
||||||
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
{
|
{
|
||||||
// todo do something
|
throw new XboxException(errCode, cErrMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport(XboxLive.FlatCDllName)]
|
[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)
|
public void SetStatisticIntegerData(XboxLiveUser user, string statName, long value)
|
||||||
{
|
{
|
||||||
// Allocates memory for returned objects
|
IntPtr cErrMessage;
|
||||||
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
|
||||||
|
|
||||||
// Invokes the c method
|
// Invokes the c method
|
||||||
XSAPI_RESULT errCode = StatsManagerSetStatisticIntegerData(user.Impl.XboxLiveUserPtr, statName, value, cErrMessage);
|
XSAPI_RESULT errCode = StatsManagerSetStatisticIntegerData(user.Impl.XboxLiveUserPtr, statName, value, out cErrMessage);
|
||||||
|
|
||||||
// Handles error
|
|
||||||
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
|
|
||||||
Marshal.FreeHGlobal(cErrMessage);
|
|
||||||
|
|
||||||
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
{
|
{
|
||||||
// todo do something
|
throw new XboxException(errCode, cErrMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport(XboxLive.FlatCDllName)]
|
[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)
|
public void SetStatisticStringData(XboxLiveUser user, string statName, string value)
|
||||||
{
|
{
|
||||||
// Allocates memory for returned objects
|
IntPtr cErrMessage;
|
||||||
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
|
||||||
|
|
||||||
// Invokes the c method
|
// Invokes the c method
|
||||||
XSAPI_RESULT errCode = StatsManagerSetStatisticStringData(user.Impl.XboxLiveUserPtr, statName, value, cErrMessage);
|
XSAPI_RESULT errCode = StatsManagerSetStatisticStringData(user.Impl.XboxLiveUserPtr, statName, value, out cErrMessage);
|
||||||
|
|
||||||
// Handles error
|
|
||||||
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
|
|
||||||
Marshal.FreeHGlobal(cErrMessage);
|
|
||||||
|
|
||||||
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
{
|
{
|
||||||
// todo do something
|
throw new XboxException(errCode, cErrMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport(XboxLive.FlatCDllName)]
|
[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)
|
public void DeleteStatistic(XboxLiveUser user, string statName)
|
||||||
{
|
{
|
||||||
if (user == null) throw new ArgumentNullException("user");
|
if (user == null) throw new ArgumentNullException("user");
|
||||||
|
|
||||||
// Allocates memory for returned objects
|
IntPtr cErrMessage;
|
||||||
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
|
||||||
|
|
||||||
// Invokes the c method
|
// Invokes the c method
|
||||||
XSAPI_RESULT errCode = StatsManagerDeleteStat(user.Impl.XboxLiveUserPtr, statName, cErrMessage);
|
XSAPI_RESULT errCode = StatsManagerDeleteStat(user.Impl.XboxLiveUserPtr, statName, out cErrMessage);
|
||||||
|
|
||||||
// Handles error
|
|
||||||
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
|
|
||||||
Marshal.FreeHGlobal(cErrMessage);
|
|
||||||
|
|
||||||
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
{
|
{
|
||||||
// todo do something
|
throw new XboxException(errCode, cErrMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport(XboxLive.FlatCDllName)]
|
[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)
|
public void GetLeaderboard(XboxLiveUser user, string statName, LeaderboardQuery query)
|
||||||
{
|
{
|
||||||
if (user == null) throw new ArgumentNullException("user");
|
if (user == null) throw new ArgumentNullException("user");
|
||||||
|
|
||||||
// Allocates memory for returned objects
|
IntPtr cErrMessage;
|
||||||
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
|
||||||
|
|
||||||
// Invokes the c method
|
// Invokes the c method
|
||||||
XSAPI_RESULT errCode = StatsManagerGetLeaderboard(user.Impl.XboxLiveUserPtr, statName, query.GetPtr(), cErrMessage);
|
XSAPI_RESULT errCode = StatsManagerGetLeaderboard(user.Impl.XboxLiveUserPtr, statName, query.GetPtr(), out cErrMessage);
|
||||||
|
|
||||||
// Handles error
|
|
||||||
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
|
|
||||||
Marshal.FreeHGlobal(cErrMessage);
|
|
||||||
|
|
||||||
if (errCode > 0)
|
if (errCode > 0)
|
||||||
{
|
{
|
||||||
// todo do something
|
throw new XboxException(errCode, cErrMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport(XboxLive.FlatCDllName)]
|
[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)
|
public void GetSocialLeaderboard(XboxLiveUser user, string statName, string socialGroup, LeaderboardQuery query)
|
||||||
{
|
{
|
||||||
if (user == null) throw new ArgumentNullException("user");
|
if (user == null) throw new ArgumentNullException("user");
|
||||||
|
|
||||||
// Allocates memory for returned objects
|
IntPtr cErrMessage;
|
||||||
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
|
||||||
|
|
||||||
// Invokes the c method
|
// Invokes the c method
|
||||||
XSAPI_RESULT errCode = StatsManagerGetSocialLeaderboard(user.Impl.XboxLiveUserPtr, statName, socialGroup, query.GetPtr(), cErrMessage);
|
XSAPI_RESULT errCode = StatsManagerGetSocialLeaderboard(user.Impl.XboxLiveUserPtr, statName, socialGroup, query.GetPtr(), out cErrMessage);
|
||||||
|
|
||||||
// Handles error
|
|
||||||
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
|
|
||||||
Marshal.FreeHGlobal(cErrMessage);
|
|
||||||
|
|
||||||
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
{
|
{
|
||||||
// todo do something
|
throw new XboxException(errCode, cErrMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport(XboxLive.FlatCDllName)]
|
[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)
|
public StatisticValue GetStatistic(XboxLiveUser user, string statName)
|
||||||
{
|
{
|
||||||
if (user == null) throw new ArgumentNullException("user");
|
if (user == null) throw new ArgumentNullException("user");
|
||||||
|
|
||||||
// Allocates memory for returned objects
|
// Allocates memory for returned objects
|
||||||
IntPtr cStatValue = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
IntPtr cStatValue;
|
||||||
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
IntPtr cErrMessage;
|
||||||
IntPtr cStatName = Marshal.StringToHGlobalAnsi(statName);
|
IntPtr cStatName = MarshalingHelpers.StringToHGlobalUtf8(statName);
|
||||||
|
|
||||||
// Invokes the c method
|
// Invokes the c method
|
||||||
XSAPI_RESULT errCode = StatsManagerGetStat(user.Impl.XboxLiveUserPtr, cStatName, cStatValue, cErrMessage);
|
XSAPI_RESULT errCode = StatsManagerGetStat(user.Impl.XboxLiveUserPtr, cStatName, out cStatValue, out cErrMessage);
|
||||||
|
|
||||||
// Handles error
|
|
||||||
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
|
|
||||||
Marshal.FreeHGlobal(cErrMessage);
|
|
||||||
|
|
||||||
|
Marshal.FreeHGlobal(cStatName);
|
||||||
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
{
|
{
|
||||||
// todo do something
|
throw new XboxException(errCode, cErrMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handles returned objects
|
// Handles returned objects
|
||||||
StatisticValue statValue = new StatisticValue(Marshal.ReadIntPtr(cStatValue));
|
StatisticValue statValue = new StatisticValue(cStatValue);
|
||||||
Marshal.FreeHGlobal(cStatValue);
|
|
||||||
|
|
||||||
return statValue;
|
return statValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport(XboxLive.FlatCDllName)]
|
[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<string> GetStatisticNames(XboxLiveUser user)
|
public IList<string> GetStatisticNames(XboxLiveUser user)
|
||||||
{
|
{
|
||||||
if (user == null) throw new ArgumentNullException("user");
|
if (user == null) throw new ArgumentNullException("user");
|
||||||
|
|
||||||
// Allocates memory for returned objects
|
IntPtr cStatListPtr;
|
||||||
IntPtr cStatListPtr = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
UInt32 statListCount;
|
||||||
IntPtr cStatListCount = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
IntPtr cErrMessage;
|
||||||
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
|
|
||||||
|
|
||||||
// Invokes the c method
|
// 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
|
// Handles error
|
||||||
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
|
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
|
||||||
|
@ -300,29 +235,9 @@ namespace Microsoft.Xbox.Services.Statistics.Manager
|
||||||
|
|
||||||
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
{
|
{
|
||||||
// todo do something
|
throw new XboxException(errCode, cErrMessage);
|
||||||
}
|
}
|
||||||
|
return MarshalingHelpers.Utf8StringArrayToStringList(cStatListPtr, statListCount);
|
||||||
// Handles returned objects
|
|
||||||
uint statListCount = (uint)Marshal.ReadInt32(cStatListCount);
|
|
||||||
Marshal.FreeHGlobal(cStatListCount);
|
|
||||||
|
|
||||||
List<string> statList = new List<string>();
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<string, string> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -23,7 +23,6 @@ namespace Microsoft.Xbox.Services.System
|
||||||
public string AgeGroup { get; private set; }
|
public string AgeGroup { get; private set; }
|
||||||
public string Privileges { get; private set; }
|
public string Privileges { get; private set; }
|
||||||
public string WebAccountId { 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 User CreationContext { get; private set; }
|
||||||
public IntPtr XboxLiveUserPtr { get; private set; }
|
public IntPtr XboxLiveUserPtr { get; private set; }
|
||||||
|
|
||||||
|
@ -48,7 +47,6 @@ namespace Microsoft.Xbox.Services.System
|
||||||
{
|
{
|
||||||
throw new XboxException(result);
|
throw new XboxException(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,16 +60,7 @@ namespace Microsoft.Xbox.Services.System
|
||||||
{
|
{
|
||||||
signOutHandlerContext = AddSignOutCompletedHandler(OnSignOutCompleted);
|
signOutHandlerContext = AddSignOutCompletedHandler(OnSignOutCompleted);
|
||||||
xboxLiveUserInstanceMap[XboxLiveUserPtr] = this;
|
xboxLiveUserInstanceMap[XboxLiveUserPtr] = this;
|
||||||
|
var appConfig = XboxLiveAppConfiguration.SingletonInstance;
|
||||||
// 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
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~UserImpl()
|
~UserImpl()
|
||||||
|
@ -177,9 +166,9 @@ namespace Microsoft.Xbox.Services.System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<TokenAndSignatureResult> InternalGetTokenAndSignatureAsync(string httpMethod, string url, string headers, byte[] body, bool promptForCredentialsIfNeeded, bool forceRefresh)
|
public Task<GetTokenAndSignatureResult> InternalGetTokenAndSignatureAsync(string httpMethod, string url, string headers, byte[] body, bool promptForCredentialsIfNeeded, bool forceRefresh)
|
||||||
{
|
{
|
||||||
var tcs = new TaskCompletionSource<TokenAndSignatureResult>();
|
var tcs = new TaskCompletionSource<GetTokenAndSignatureResult>();
|
||||||
|
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
|
@ -196,7 +185,7 @@ namespace Microsoft.Xbox.Services.System
|
||||||
}
|
}
|
||||||
|
|
||||||
int contextKey;
|
int contextKey;
|
||||||
var context = XsapiCallbackContext<UserImpl, TokenAndSignatureResult>.CreateContext(this, tcs, out contextKey);
|
var context = XsapiCallbackContext<UserImpl, GetTokenAndSignatureResult>.CreateContext(this, tcs, out contextKey);
|
||||||
context.PointersToFree = new List<IntPtr> { pHttpMethod, pUrl, pHeaders, pBody };
|
context.PointersToFree = new List<IntPtr> { pHttpMethod, pUrl, pHeaders, pBody };
|
||||||
|
|
||||||
var result = XboxLiveUserGetTokenAndSignature(
|
var result = XboxLiveUserGetTokenAndSignature(
|
||||||
|
@ -223,12 +212,12 @@ namespace Microsoft.Xbox.Services.System
|
||||||
{
|
{
|
||||||
int contextKey = context.ToInt32();
|
int contextKey = context.ToInt32();
|
||||||
|
|
||||||
XsapiCallbackContext<UserImpl, TokenAndSignatureResult> contextObject;
|
XsapiCallbackContext<UserImpl, GetTokenAndSignatureResult> contextObject;
|
||||||
if (XsapiCallbackContext<UserImpl, TokenAndSignatureResult>.TryRemove(contextKey, out contextObject))
|
if (XsapiCallbackContext<UserImpl, GetTokenAndSignatureResult>.TryRemove(contextKey, out contextObject))
|
||||||
{
|
{
|
||||||
if (result.errorCode == XSAPI_RESULT.XSAPI_RESULT_OK)
|
if (result.errorCode == XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
{
|
{
|
||||||
contextObject.TaskCompletionSource.SetResult(new TokenAndSignatureResult
|
contextObject.TaskCompletionSource.SetResult(new GetTokenAndSignatureResult
|
||||||
{
|
{
|
||||||
WebAccountId = MarshalingHelpers.Utf8ToString(payload.WebAccountId),
|
WebAccountId = MarshalingHelpers.Utf8ToString(payload.WebAccountId),
|
||||||
Privileges = MarshalingHelpers.Utf8ToString(payload.Privileges),
|
Privileges = MarshalingHelpers.Utf8ToString(payload.Privileges),
|
||||||
|
@ -237,7 +226,6 @@ namespace Microsoft.Xbox.Services.System
|
||||||
XboxUserId = MarshalingHelpers.Utf8ToString(payload.XboxUserId),
|
XboxUserId = MarshalingHelpers.Utf8ToString(payload.XboxUserId),
|
||||||
Signature = MarshalingHelpers.Utf8ToString(payload.Signature),
|
Signature = MarshalingHelpers.Utf8ToString(payload.Signature),
|
||||||
Token = MarshalingHelpers.Utf8ToString(payload.Token)
|
Token = MarshalingHelpers.Utf8ToString(payload.Token)
|
||||||
//TokenRequestResultStatus = tokenResult.ResponseStatus // TODO
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -333,7 +321,7 @@ namespace Microsoft.Xbox.Services.System
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
private struct XSAPI_SIGN_IN_RESULT
|
private struct XSAPI_SIGN_IN_RESULT
|
||||||
{
|
{
|
||||||
public SignInStatus status;
|
public SignInStatus status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,16 +4,10 @@
|
||||||
namespace Microsoft.Xbox.Services.UWP.UnitTests
|
namespace Microsoft.Xbox.Services.UWP.UnitTests
|
||||||
{
|
{
|
||||||
using global::System;
|
using global::System;
|
||||||
using Windows.System;
|
|
||||||
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
|
|
||||||
using Microsoft.Xbox.Services.System;
|
|
||||||
using global::System.Linq;
|
using global::System.Linq;
|
||||||
using Moq;
|
|
||||||
using global::System.Threading.Tasks;
|
using global::System.Threading.Tasks;
|
||||||
using UITestMethod = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.AppContainer.UITestMethodAttribute;
|
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
|
||||||
using Windows.Security.Authentication.Web.Core;
|
using Windows.System;
|
||||||
using global::System.Collections.Generic;
|
|
||||||
using global::System.Threading;
|
|
||||||
|
|
||||||
[TestClass]
|
[TestClass]
|
||||||
public class UserTest
|
public class UserTest
|
||||||
|
@ -30,28 +24,9 @@ namespace Microsoft.Xbox.Services.UWP.UnitTests
|
||||||
private const int mockErrorcode = 9999;
|
private const int mockErrorcode = 9999;
|
||||||
private const string mockErrorMessage = "mock error message";
|
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<string, string>();
|
|
||||||
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]
|
[TestCleanup]
|
||||||
public void Cleanup()
|
public void Cleanup()
|
||||||
{
|
{
|
||||||
XboxLiveUser.CleanupEventHandler();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCategory("XboxLiveUser")]
|
[TestCategory("XboxLiveUser")]
|
||||||
|
@ -71,156 +46,5 @@ namespace Microsoft.Xbox.Services.UWP.UnitTests
|
||||||
var xbluser = new XboxLiveUser(systemUser);
|
var xbluser = new XboxLiveUser(systemUser);
|
||||||
Assert.AreEqual(systemUser.NonRoamableId, xbluser.WindowsSystemUser.NonRoamableId);
|
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.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<object> timer = new CallBufferTimer<object>(TimeSpan.FromSeconds(1));
|
|
||||||
timer.Completed += (sender, o) => { completed = true; };
|
|
||||||
|
|
||||||
var timerTask = timer.Fire(new List<object> { 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<int> timer = new CallBufferTimer<int>(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<Task> 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Verifies that
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
[TestMethod]
|
|
||||||
public async Task QueuedThrottledCallback()
|
|
||||||
{
|
|
||||||
int completedCount = 0;
|
|
||||||
CallBufferTimer<int> timer = new CallBufferTimer<int>(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<Task> 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<Task> 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");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 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.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
[TestMethod]
|
|
||||||
public async Task ExecuteImmediatelyIfPastPeriod()
|
|
||||||
{
|
|
||||||
int completedCount = 0;
|
|
||||||
CallBufferTimer<int> timer = new CallBufferTimer<int>(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<int> { 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 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.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public async Task AddWhileQueued()
|
|
||||||
{
|
|
||||||
int completedCount = 0;
|
|
||||||
CallBufferTimer<int> timer = new CallBufferTimer<int>(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<int> { 1 });
|
|
||||||
|
|
||||||
// Fire another event which will queue up a new timer.
|
|
||||||
var timerTask1 = timer.Fire(new List<int> { 2 });
|
|
||||||
|
|
||||||
await Task.Delay(200);
|
|
||||||
|
|
||||||
var timerTask2 = timer.Fire(new List<int> { 3 });
|
|
||||||
|
|
||||||
Assert.AreEqual(timerTask1, timerTask2);
|
|
||||||
|
|
||||||
await timerTask2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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}"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -56,10 +56,6 @@
|
||||||
</Otherwise>
|
</Otherwise>
|
||||||
</Choose>
|
</Choose>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="CallBufferTimerTests.cs" />
|
|
||||||
<Compile Include="Leaderboards\LeaderboardTests.cs" />
|
|
||||||
<Compile Include="Privacy\PrivacyTests.cs" />
|
|
||||||
<Compile Include="Social\SocialUserGroupTests.cs" />
|
|
||||||
<Compile Include="Social\SocialManagerTests.cs" />
|
<Compile Include="Social\SocialManagerTests.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Stats\StatsManagerTests.cs" />
|
<Compile Include="Stats\StatsManagerTests.cs" />
|
||||||
|
@ -73,22 +69,7 @@
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Leaderboards\MockDataForLeaderboardTests.json">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="TitleStorage\TitleStorageUT.json">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
<Content Include="Privacy\MockDataForPrivacyTests.json">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Social\SocialUserGroupUT.json">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Social\SocialManagerUT.json">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<None Include="XboxServices.config">
|
<None Include="XboxServices.config">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
|
@ -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
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<bool>();
|
|
||||||
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<MultiplePermissionsCheckResult> 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<string> permissionIds = new List<string>();
|
|
||||||
permissionIds.Add(PermissionIdConstants.ViewTargetVideoHistory);
|
|
||||||
permissionIds.Add(PermissionIdConstants.ViewTargetMusicStatus);
|
|
||||||
permissionIds.Add(PermissionIdConstants.ViewTargetGameHistory);
|
|
||||||
|
|
||||||
List<string> xuids = new List<string>();
|
|
||||||
xuids.Add("2814680291986301");
|
|
||||||
xuids.Add("2814634309691161");
|
|
||||||
|
|
||||||
List<MultiplePermissionsCheckResult> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -16,7 +16,6 @@ namespace Microsoft.Xbox.Services.UnitTests.Social
|
||||||
public override void TestInitialize()
|
public override void TestInitialize()
|
||||||
{
|
{
|
||||||
base.TestInitialize();
|
base.TestInitialize();
|
||||||
MockXboxLiveData.Load(Environment.CurrentDirectory + "\\Social\\SocialManagerUT.json");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<string> { 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<bool> predicate)
|
|
||||||
{
|
|
||||||
return DoWorkUntil(predicate, TimeSpan.FromSeconds(5));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task DoWorkUntil(Func<bool> predicate, TimeSpan maxDuration)
|
|
||||||
{
|
|
||||||
DateTime workUntil = DateTime.UtcNow + maxDuration;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
IList<SocialEvent> 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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,10 +10,5 @@ namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
get { return true; }
|
get { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool UseMockHttp
|
|
||||||
{
|
|
||||||
get { return false; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,10 +4,30 @@
|
||||||
|
|
||||||
namespace Microsoft.Xbox.Services
|
namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
|
using Newtonsoft.Json;
|
||||||
using global::System.IO;
|
using global::System.IO;
|
||||||
|
|
||||||
public partial class XboxLiveAppConfiguration
|
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)
|
public static XboxLiveAppConfiguration Load(string path)
|
||||||
{
|
{
|
||||||
if (!File.Exists(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));
|
throw new XboxException(string.Format("Xbox Live app configeration file '{0}' was empty.", path));
|
||||||
}
|
}
|
||||||
|
|
||||||
return JsonSerialization.FromJson<XboxLiveAppConfiguration>(content);
|
return JsonConvert.DeserializeObject<XboxLiveAppConfiguration>(content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
// Copyright (c) Microsoft Corporation
|
// Copyright (c) Microsoft Corporation
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
//
|
||||||
|
|
||||||
namespace Microsoft.Xbox.Services.Leaderboard
|
namespace Microsoft.Xbox.Services.Leaderboard
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
using System;
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
//
|
||||||
|
|
||||||
namespace Microsoft.Xbox.Services.Leaderboard
|
namespace Microsoft.Xbox.Services.Leaderboard
|
||||||
{
|
{
|
||||||
|
using global::System;
|
||||||
|
|
||||||
class LeaderboardQueryUnityEditorImpl : ILeaderboardQueryImpl
|
class LeaderboardQueryUnityEditorImpl : ILeaderboardQueryImpl
|
||||||
{
|
{
|
||||||
public IntPtr GetPtr() { return IntPtr.Zero; }
|
public IntPtr GetPtr() { return IntPtr.Zero; }
|
||||||
|
|
||||||
uint m_maxItems;
|
uint m_maxItems;
|
||||||
public uint GetMaxItems()
|
public uint GetMaxItems()
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,11 +16,10 @@ namespace Microsoft.Xbox.Services.System
|
||||||
public string AgeGroup { get; set; }
|
public string AgeGroup { get; set; }
|
||||||
public string Privileges { get; set; }
|
public string Privileges { get; set; }
|
||||||
public string WebAccountId { get; set; }
|
public string WebAccountId { get; set; }
|
||||||
public AuthConfig AuthConfig { get; set; }
|
|
||||||
|
|
||||||
private static int numberOfInstances;
|
private static int numberOfInstances;
|
||||||
private static Random random = new Random();
|
private static Random random = new Random();
|
||||||
|
|
||||||
public Task<SignInResult> SignInImpl(bool showUI, bool forceRefresh)
|
public Task<SignInResult> SignInImpl(bool showUI, bool forceRefresh)
|
||||||
{
|
{
|
||||||
if (XboxLive.UseMockServices)
|
if (XboxLive.UseMockServices)
|
||||||
|
@ -36,11 +35,11 @@ namespace Microsoft.Xbox.Services.System
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<TokenAndSignatureResult> InternalGetTokenAndSignatureAsync(string httpMethod, string url, string headers, byte[] body, bool promptForCredentialsIfNeeded, bool forceRefresh)
|
public Task<GetTokenAndSignatureResult> InternalGetTokenAndSignatureAsync(string httpMethod, string url, string headers, byte[] body, bool promptForCredentialsIfNeeded, bool forceRefresh)
|
||||||
{
|
{
|
||||||
if (XboxLive.UseMockServices)
|
if (XboxLive.UseMockServices)
|
||||||
{
|
{
|
||||||
return Task.FromResult(new TokenAndSignatureResult
|
return Task.FromResult(new GetTokenAndSignatureResult
|
||||||
{
|
{
|
||||||
Gamertag = this.Gamertag,
|
Gamertag = this.Gamertag,
|
||||||
XboxUserId = this.XboxUserId,
|
XboxUserId = this.XboxUserId,
|
||||||
|
|
|
@ -1,33 +1,17 @@
|
||||||
// Copyright (c) Microsoft Corporation
|
// Copyright (c) Microsoft Corporation
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// 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
|
namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
|
using global::System;
|
||||||
|
|
||||||
public class HttpCallRequestMessage
|
public class HttpCallRequestMessage
|
||||||
{
|
{
|
||||||
|
public HttpRequestMessageType GetHttpRequestMessageType { get; private set; }
|
||||||
|
|
||||||
public HttpRequestMessageType GetHttpRequestMessageType
|
public Byte[] RequestMessageVector { get; private set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Byte[] RequestMessageVector
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string RequestMessageString
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public string RequestMessageString { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
//
|
//
|
||||||
namespace Microsoft.Xbox.Services
|
namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
using global::System;
|
|
||||||
|
|
||||||
public enum HttpCallResponseBodyType : uint
|
public enum HttpCallResponseBodyType : uint
|
||||||
{
|
{
|
||||||
StringBody,
|
StringBody,
|
||||||
|
|
|
@ -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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -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<XboxLiveAPIName, HttpRetryAfterApiState> apiStateMap = new Dictionary<XboxLiveAPIName, HttpRetryAfterApiState>();
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
using global::System.Threading.Tasks;
|
using global::System.Threading.Tasks;
|
||||||
|
|
||||||
public interface IXboxLiveUser
|
internal interface IXboxLiveUser
|
||||||
{
|
{
|
||||||
string WebAccountId { get; }
|
string WebAccountId { get; }
|
||||||
|
|
||||||
|
@ -29,10 +29,10 @@ namespace Microsoft.Xbox.Services
|
||||||
|
|
||||||
Task<SignInResult> SignInSilentlyAsync();
|
Task<SignInResult> SignInSilentlyAsync();
|
||||||
|
|
||||||
Task<TokenAndSignatureResult> GetTokenAndSignatureAsync(string httpMethod, string url, string headers);
|
Task<GetTokenAndSignatureResult> GetTokenAndSignatureAsync(string httpMethod, string url, string headers);
|
||||||
|
|
||||||
Task<TokenAndSignatureResult> GetTokenAndSignatureAsync(string httpMethod, string url, string headers, string body);
|
Task<GetTokenAndSignatureResult> GetTokenAndSignatureAsync(string httpMethod, string url, string headers, string body);
|
||||||
|
|
||||||
Task<TokenAndSignatureResult> GetTokenAndSignatureArrayAsync(string httpMethod, string url, string headers, byte[] body);
|
Task<GetTokenAndSignatureResult> GetTokenAndSignatureArrayAsync(string httpMethod, string url, string headers, byte[] body);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,11 +7,11 @@ namespace Microsoft.Xbox.Services
|
||||||
|
|
||||||
public class SignInCompletedEventArgs : EventArgs
|
public class SignInCompletedEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public SignInCompletedEventArgs(IXboxLiveUser user)
|
public SignInCompletedEventArgs(XboxLiveUser user)
|
||||||
{
|
{
|
||||||
this.User = user;
|
this.User = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IXboxLiveUser User { get; private set; }
|
public XboxLiveUser User { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,12 +7,11 @@ namespace Microsoft.Xbox.Services
|
||||||
|
|
||||||
public class SignOutCompletedEventArgs : EventArgs
|
public class SignOutCompletedEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public SignOutCompletedEventArgs(IXboxLiveUser user)
|
public SignOutCompletedEventArgs(XboxLiveUser user)
|
||||||
{
|
{
|
||||||
this.User = user;
|
this.User = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO change this to XboxLiveUser instead of IXboxLive user to match WinRT projections
|
public XboxLiveUser User { get; private set; }
|
||||||
public IXboxLiveUser User { get; private set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,7 +8,7 @@ using Windows.Security.Authentication.Web.Core;
|
||||||
|
|
||||||
namespace Microsoft.Xbox.Services
|
namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
public class TokenAndSignatureResult
|
public class GetTokenAndSignatureResult
|
||||||
{
|
{
|
||||||
public string WebAccountId { get; set; }
|
public string WebAccountId { get; set; }
|
||||||
|
|
||||||
|
@ -25,10 +25,5 @@ namespace Microsoft.Xbox.Services
|
||||||
public string Signature { get; set; }
|
public string Signature { get; set; }
|
||||||
|
|
||||||
public string Token { get; set; }
|
public string Token { get; set; }
|
||||||
|
|
||||||
internal string Reserved { get; set; }
|
|
||||||
#if WINDOWS_UWP
|
|
||||||
internal WebTokenRequestStatus TokenRequestResultStatus { get; set; }
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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)
|
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)))
|
: base (string.Format("Xbox Services flat C API return error code {0} with message \"{1}\"", resultInfo.errorCode.ToString("g"), MarshalingHelpers.Utf8ToString(resultInfo.errorMessage)))
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,9 +5,7 @@ namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
using global::System;
|
using global::System;
|
||||||
using global::System.IO;
|
using global::System.IO;
|
||||||
using global::System.ComponentModel;
|
|
||||||
using global::System.Runtime.InteropServices;
|
using global::System.Runtime.InteropServices;
|
||||||
using Microsoft.Xbox.Services.Presence;
|
|
||||||
using Microsoft.Xbox.Services.Social.Manager;
|
using Microsoft.Xbox.Services.Social.Manager;
|
||||||
using Microsoft.Xbox.Services.Statistics.Manager;
|
using Microsoft.Xbox.Services.Statistics.Manager;
|
||||||
using Microsoft.Xbox.Services.System;
|
using Microsoft.Xbox.Services.System;
|
||||||
|
@ -16,7 +14,6 @@ namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
private bool disposed;
|
private bool disposed;
|
||||||
private static XboxLive instance;
|
private static XboxLive instance;
|
||||||
private XboxLiveSettings settings;
|
|
||||||
private IStatisticManager statsManager;
|
private IStatisticManager statsManager;
|
||||||
private ISocialManager socialManager;
|
private ISocialManager socialManager;
|
||||||
|
|
||||||
|
@ -32,24 +29,23 @@ namespace Microsoft.Xbox.Services
|
||||||
|
|
||||||
private XboxLive()
|
private XboxLive()
|
||||||
{
|
{
|
||||||
this.settings = new XboxLiveSettings();
|
|
||||||
|
|
||||||
try
|
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)
|
catch (FileLoadException)
|
||||||
{
|
{
|
||||||
this.appConfig = null;
|
this.appConfig = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WINDOWS_UWP
|
|
||||||
var result = XBLGlobalInitialize();
|
|
||||||
if (result != XSAPI_RESULT.XSAPI_RESULT_OK)
|
|
||||||
{
|
|
||||||
throw new XboxException(result);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~XboxLive()
|
~XboxLive()
|
||||||
|
@ -104,15 +100,14 @@ namespace Microsoft.Xbox.Services
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public XboxLiveSettings Settings
|
//public XboxLiveContextSettings Settings { get; private set; }
|
||||||
{
|
|
||||||
get { return Instance.settings; }
|
|
||||||
set { Instance.settings = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public XboxLiveAppConfiguration AppConfig
|
public XboxLiveAppConfiguration AppConfig
|
||||||
{
|
{
|
||||||
get { return Instance.appConfig; }
|
get
|
||||||
|
{
|
||||||
|
return Instance.appConfig;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
|
@ -134,7 +129,7 @@ namespace Microsoft.Xbox.Services
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int64 DefaultTaskGroupId
|
internal static Int64 DefaultTaskGroupId
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,8 +4,9 @@
|
||||||
namespace Microsoft.Xbox.Services
|
namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
using global::System;
|
using global::System;
|
||||||
|
#if UNITY_EDITOR
|
||||||
using Newtonsoft.Json;
|
using global::Newtonsoft.Json;
|
||||||
|
#endif
|
||||||
|
|
||||||
public partial class XboxLiveAppConfiguration
|
public partial class XboxLiveAppConfiguration
|
||||||
{
|
{
|
||||||
|
@ -14,45 +15,10 @@ namespace Microsoft.Xbox.Services
|
||||||
private static readonly object instanceLock = new object();
|
private static readonly object instanceLock = new object();
|
||||||
private static XboxLiveAppConfiguration instance;
|
private static XboxLiveAppConfiguration instance;
|
||||||
|
|
||||||
public static XboxLiveAppConfiguration Instance
|
#if UNITY_EDITOR
|
||||||
{
|
[JsonProperty("PrimaryServiceConfigId")]
|
||||||
get
|
#endif
|
||||||
{
|
public string ServiceConfigurationId { get; set; }
|
||||||
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; }
|
|
||||||
|
|
||||||
public uint TitleId { get; set; }
|
public uint TitleId { get; set; }
|
||||||
|
|
||||||
|
@ -60,30 +26,34 @@ namespace Microsoft.Xbox.Services
|
||||||
|
|
||||||
public string Environment { get; set; }
|
public string Environment { get; set; }
|
||||||
|
|
||||||
public bool XboxLiveCreatorsTitle { get; set; }
|
public static XboxLiveAppConfiguration SingletonInstance
|
||||||
|
|
||||||
public string GetEndpointForService(string serviceName, string protocol = "https")
|
|
||||||
{
|
{
|
||||||
return string.Format("{0}://{1}{2}.xboxlive.com", protocol, serviceName, string.IsNullOrEmpty(this.Environment) ? string.Empty : ("." + this.Environment));
|
get
|
||||||
}
|
|
||||||
|
|
||||||
public static XboxLiveAppConfiguration Load()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
// Attempt to load it from a file
|
if (instance == null)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return instance;
|
||||||
throw new XboxException(string.Format("Unable to find or load Xbox Live configuration. Make sure a properly configured {0} exists.", FileName), e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
// Copyright (c) Microsoft Corporation
|
// Copyright (c) Microsoft Corporation
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// 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
|
namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
|
@ -12,5 +8,4 @@ namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
ThisCodeNeedsToBeChangedToFollowBestPractices = 0,
|
ThisCodeNeedsToBeChangedToFollowBestPractices = 0,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
|
@ -1,10 +1,6 @@
|
||||||
// Copyright (c) Microsoft Corporation
|
// Copyright (c) Microsoft Corporation
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// 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
|
namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
|
@ -12,5 +8,4 @@ namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
ThisCodeNeedsToBeChangedToAvoidThrottling = 0,
|
ThisCodeNeedsToBeChangedToAvoidThrottling = 0,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
|
@ -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<string, string> customHeaders = new Dictionary<string, string>();
|
|
||||||
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<XboxLiveHttpResponse> GetResponseWithAuth(XboxLiveUser user)
|
|
||||||
{
|
|
||||||
TaskCompletionSource<XboxLiveHttpResponse> taskCompletionSource = new TaskCompletionSource<XboxLiveHttpResponse>();
|
|
||||||
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<string, string> customHeader in this.customHeaders)
|
|
||||||
{
|
|
||||||
this.webRequest.Headers[customHeader.Key] = customHeader.Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual Task<XboxLiveHttpResponse> 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<XboxLiveHttpResponse> 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<XboxLiveHttpResponse> taskCompletionSource = new TaskCompletionSource<XboxLiveHttpResponse>();
|
|
||||||
|
|
||||||
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<IAsyncResult, WebResponse>)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<XboxLiveHttpResponse> HandleFastFail(HttpRetryAfterApiState apiState)
|
|
||||||
{
|
|
||||||
XboxLiveHttpResponse httpCallResponse = apiState.HttpCallResponse;
|
|
||||||
this.RouteServiceCall(httpCallResponse);
|
|
||||||
|
|
||||||
TaskCompletionSource<XboxLiveHttpResponse> taskCompletionSource = new TaskCompletionSource<XboxLiveHttpResponse>();
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 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.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>A task that represents to request body write work.</returns>
|
|
||||||
/// <remarks>This is used to make request chaining a little bit easier.</remarks>
|
|
||||||
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<IAsyncResult, Stream>)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
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a query string out of a list of parameters
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="paramDictionary">List of Parameters to be added to the query</param>
|
|
||||||
/// <returns>a query string that should be appended to the request</returns>
|
|
||||||
public static string GetQueryFromParams(Dictionary<string, string> 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<WebResponse> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<string, string> 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<string, string>();
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,33 +1,17 @@
|
||||||
// Copyright (c) Microsoft Corporation
|
// Copyright (c) Microsoft Corporation
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// 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
|
namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
|
using global::System;
|
||||||
|
|
||||||
public class XboxLiveLogCallEventArgs : EventArgs
|
public class XboxLiveLogCallEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
|
public string Message { get; private set; }
|
||||||
|
|
||||||
public string Message
|
public string Category { get; private set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Category
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public XboxServicesDiagnosticsTraceLevel Level
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public XboxServicesDiagnosticsTraceLevel Level { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,11 +16,7 @@ namespace Microsoft.Xbox.Services
|
||||||
|
|
||||||
public XboxLiveServices(XboxLiveUser user)
|
public XboxLiveServices(XboxLiveUser user)
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR
|
#if WINDOWS_UWP
|
||||||
// TODO Implement mock title storage service for unity editor
|
|
||||||
this.TitleStorageService = null;
|
|
||||||
this.PrivacyService = null;
|
|
||||||
#else
|
|
||||||
IntPtr xboxLiveContext;
|
IntPtr xboxLiveContext;
|
||||||
var xsapiResult = XboxLiveContextCreate(user.PCXboxLiveUser, out xboxLiveContext);
|
var xsapiResult = XboxLiveContextCreate(user.PCXboxLiveUser, out xboxLiveContext);
|
||||||
|
|
||||||
|
@ -32,6 +28,10 @@ namespace Microsoft.Xbox.Services
|
||||||
|
|
||||||
this.TitleStorageService = new TitleStorageService(XboxLiveContextPtr);
|
this.TitleStorageService = new TitleStorageService(XboxLiveContextPtr);
|
||||||
this.PrivacyService = new PrivacyService(XboxLiveContextPtr);
|
this.PrivacyService = new PrivacyService(XboxLiveContextPtr);
|
||||||
|
#else
|
||||||
|
// TODO MockServices and/or MockHttp
|
||||||
|
this.TitleStorageService = null;
|
||||||
|
this.PrivacyService = null;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,22 +5,16 @@ namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
using global::System;
|
using global::System;
|
||||||
|
|
||||||
public class XboxLiveSettings
|
public class XboxLiveContextSettings
|
||||||
{
|
{
|
||||||
private const int DefaultHttpTimeoutWindowInSeconds = 20;
|
public XboxLiveContextSettings()
|
||||||
private const int DefaultLongHttpTimeoutInSeconds = 5 * 60;
|
|
||||||
private const int DefaultRetryDelayInSeconds = 2;
|
|
||||||
|
|
||||||
public XboxLiveSettings()
|
|
||||||
{
|
{
|
||||||
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 bool UseCoreDispatcherForEventRouting { get; set; }
|
||||||
|
|
||||||
|
public TimeSpan HttpTimeout { get; set; }
|
||||||
|
|
||||||
public TimeSpan HttpTimeoutWindow { get; set; }
|
public TimeSpan HttpTimeoutWindow { get; set; }
|
||||||
|
|
||||||
public TimeSpan HttpRetryDelay { 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<XboxLiveLogCallEventArgs> LogCallRouted;
|
public event EventHandler<XboxLiveLogCallEventArgs> LogCallRouted;
|
||||||
|
|
||||||
//public bool EnableServiceCallRoutedEvents { get; set; }
|
public bool EnableServiceCallRoutedEvents { get; set; }
|
||||||
|
|
||||||
//public void DisableAssertsForMaximumNumberOfWebsocketsActivated(XboxLiveContextRecommendedSetting setting)
|
public void DisableAssertsForMaximumNumberOfWebsocketsActivated(XboxLiveContextRecommendedSetting setting)
|
||||||
//{
|
{
|
||||||
// throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,10 +4,8 @@
|
||||||
namespace Microsoft.Xbox.Services
|
namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
using global::System;
|
using global::System;
|
||||||
using global::System.Collections.Generic;
|
|
||||||
using global::System.Text;
|
using global::System.Text;
|
||||||
using global::System.Threading.Tasks;
|
using global::System.Threading.Tasks;
|
||||||
|
|
||||||
using Microsoft.Xbox.Services.System;
|
using Microsoft.Xbox.Services.System;
|
||||||
|
|
||||||
public partial class XboxLiveUser : IXboxLiveUser
|
public partial class XboxLiveUser : IXboxLiveUser
|
||||||
|
@ -17,38 +15,9 @@ namespace Microsoft.Xbox.Services
|
||||||
private readonly IUserImpl userImpl;
|
private readonly IUserImpl userImpl;
|
||||||
private XboxLiveServices xboxLiveServices;
|
private XboxLiveServices xboxLiveServices;
|
||||||
|
|
||||||
private static event EventHandler<SignInCompletedEventArgs> InternalSignInCompleted;
|
public static event EventHandler<SignInCompletedEventArgs> SignInCompleted;
|
||||||
private static List<EventHandler<SignInCompletedEventArgs>> signInDelegates = new List<EventHandler<SignInCompletedEventArgs>>();
|
public static event EventHandler<SignOutCompletedEventArgs> SignOutCompleted;
|
||||||
public static event EventHandler<SignInCompletedEventArgs> SignInCompleted
|
|
||||||
{
|
|
||||||
add
|
|
||||||
{
|
|
||||||
InternalSignInCompleted += value;
|
|
||||||
signInDelegates.Add(value);
|
|
||||||
}
|
|
||||||
remove
|
|
||||||
{
|
|
||||||
InternalSignInCompleted -= value;
|
|
||||||
signInDelegates.Remove(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static event EventHandler<SignOutCompletedEventArgs> InternalSignOutCompleted;
|
|
||||||
private static List<EventHandler<SignOutCompletedEventArgs>> signOutDelegates = new List<EventHandler<SignOutCompletedEventArgs>>();
|
|
||||||
public static event EventHandler<SignOutCompletedEventArgs> SignOutCompleted
|
|
||||||
{
|
|
||||||
add
|
|
||||||
{
|
|
||||||
InternalSignOutCompleted += value;
|
|
||||||
signOutDelegates.Add(value);
|
|
||||||
}
|
|
||||||
remove
|
|
||||||
{
|
|
||||||
InternalSignOutCompleted -= value;
|
|
||||||
signOutDelegates.Remove(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string WebAccountId
|
public string WebAccountId
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -136,36 +105,19 @@ namespace Microsoft.Xbox.Services
|
||||||
return this.userImpl.SignInImpl(false, false);
|
return this.userImpl.SignInImpl(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<TokenAndSignatureResult> GetTokenAndSignatureAsync(string httpMethod, string url, string headers)
|
public Task<GetTokenAndSignatureResult> GetTokenAndSignatureAsync(string httpMethod, string url, string headers)
|
||||||
{
|
{
|
||||||
return this.GetTokenAndSignatureArrayAsync(httpMethod, url, headers, null);
|
return this.GetTokenAndSignatureArrayAsync(httpMethod, url, headers, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<TokenAndSignatureResult> GetTokenAndSignatureAsync(string httpMethod, string url, string headers, string body)
|
public Task<GetTokenAndSignatureResult> GetTokenAndSignatureAsync(string httpMethod, string url, string headers, string body)
|
||||||
{
|
{
|
||||||
return this.GetTokenAndSignatureArrayAsync(httpMethod, url, headers, body == null ? null : Encoding.UTF8.GetBytes(body));
|
return this.GetTokenAndSignatureArrayAsync(httpMethod, url, headers, body == null ? null : Encoding.UTF8.GetBytes(body));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<TokenAndSignatureResult> GetTokenAndSignatureArrayAsync(string httpMethod, string url, string headers, byte[] body)
|
public Task<GetTokenAndSignatureResult> GetTokenAndSignatureArrayAsync(string httpMethod, string url, string headers, byte[] body)
|
||||||
{
|
{
|
||||||
return this.userImpl.InternalGetTokenAndSignatureAsync(httpMethod, url, headers, body, false, false);
|
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,111 +1,44 @@
|
||||||
// Copyright (c) Microsoft Corporation
|
// Copyright (c) Microsoft Corporation
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// 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
|
namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
|
using global::System;
|
||||||
|
|
||||||
public class XboxServiceCallRoutedEventArgs : EventArgs
|
public class XboxServiceCallRoutedEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
|
|
||||||
public string XboxUserId
|
public string XboxUserId { get; private set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimeSpan ElapsedCallTime
|
public TimeSpan ElapsedCallTime { get; private set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DateTimeOffset ResponseTimeUTC
|
public DateTimeOffset ResponseTimeUTC { get; private set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DateTimeOffset RequestTimeUTC
|
public DateTimeOffset RequestTimeUTC { get; private set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string FullResponseToString
|
public string FullResponseToString { get; private set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint HttpStatus
|
public uint HttpStatus { get; private set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Signature
|
public string Signature { get; private set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Token
|
public string Token { get; private set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ETag
|
public string ETag { get; private set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ResponseBody
|
public string ResponseBody { get; private set;}
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ResponseHeaders
|
public string ResponseHeaders { get; private set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint ResponseCount
|
public uint ResponseCount { get; private set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpCallRequestMessage RequestBody
|
public HttpCallRequestMessage RequestBody { get; private set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string RequestHeaders
|
public string RequestHeaders { get; private set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Uri Url
|
public Uri Url { get; private set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string HttpMethod
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public string HttpMethod { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
// Copyright (c) Microsoft Corporation
|
// Copyright (c) Microsoft Corporation
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// 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
|
namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
|
@ -16,5 +12,4 @@ namespace Microsoft.Xbox.Services
|
||||||
Info = 3,
|
Info = 3,
|
||||||
Verbose = 4,
|
Verbose = 4,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
|
@ -6,7 +6,7 @@ namespace Microsoft.Xbox.Services.Leaderboard
|
||||||
internal interface ILeaderboardQueryImpl
|
internal interface ILeaderboardQueryImpl
|
||||||
{
|
{
|
||||||
IntPtr GetPtr();
|
IntPtr GetPtr();
|
||||||
|
|
||||||
uint GetSkipResultToRank();
|
uint GetSkipResultToRank();
|
||||||
void SetSkipResultToRank(uint skipResultToRank);
|
void SetSkipResultToRank(uint skipResultToRank);
|
||||||
|
|
||||||
|
|
|
@ -4,138 +4,17 @@
|
||||||
namespace Microsoft.Xbox.Services.Leaderboard
|
namespace Microsoft.Xbox.Services.Leaderboard
|
||||||
{
|
{
|
||||||
using global::System;
|
using global::System;
|
||||||
using global::System.Collections.Generic;
|
|
||||||
using global::System.Text;
|
|
||||||
using global::System.Threading.Tasks;
|
using global::System.Threading.Tasks;
|
||||||
|
|
||||||
public class LeaderboardService : ILeaderboardService
|
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()
|
internal LeaderboardService()
|
||||||
{
|
{
|
||||||
this.appConfig = XboxLive.Instance.AppConfig;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public Task<LeaderboardResult> GetLeaderboardAsync(XboxLiveUser user, LeaderboardQuery query)
|
public Task<LeaderboardResult> GetLeaderboardAsync(XboxLiveUser user, LeaderboardQuery query)
|
||||||
{
|
{
|
||||||
string skipToXboxUserId = null;
|
throw new NotImplementedException();
|
||||||
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<XboxLiveHttpResponse> responseTask, LeaderboardQuery query)
|
|
||||||
{
|
|
||||||
XboxLiveHttpResponse response = responseTask.Result;
|
|
||||||
|
|
||||||
if (response.HttpStatus != 200)
|
|
||||||
{
|
|
||||||
throw new XboxException("Leaderboard request failed with " + response.HttpStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
LeaderboardResponse lbResponse = JsonSerialization.FromJson<LeaderboardResponse>(response.ResponseBodyString);
|
|
||||||
|
|
||||||
IList<LeaderboardColumn> columns = new List<LeaderboardColumn> { lbResponse.LeaderboardInfo.Column };
|
|
||||||
|
|
||||||
IList<LeaderboardRow> rows = new List<LeaderboardRow>();
|
|
||||||
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<string> { 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("&");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
namespace Microsoft.Xbox.Services.Leaderboard
|
namespace Microsoft.Xbox.Services.Leaderboard
|
||||||
{
|
{
|
||||||
|
using global::Newtonsoft.Json;
|
||||||
using global::System.Collections.Generic;
|
using global::System.Collections.Generic;
|
||||||
using global::System.Linq;
|
using global::System.Linq;
|
||||||
using global::System.Threading.Tasks;
|
using global::System.Threading.Tasks;
|
||||||
|
@ -20,7 +21,7 @@ namespace Microsoft.Xbox.Services.Leaderboard
|
||||||
|
|
||||||
internal LeaderboardResult CreateLeaderboardResponse(LeaderboardQuery query)
|
internal LeaderboardResult CreateLeaderboardResponse(LeaderboardQuery query)
|
||||||
{
|
{
|
||||||
LeaderboardResponse lbResponse = JsonSerialization.FromJson<LeaderboardResponse>(@"{""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<LeaderboardResponse>(@"{""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<LeaderboardColumn> columns = new List<LeaderboardColumn> { lbResponse.LeaderboardInfo.Column };
|
IList<LeaderboardColumn> columns = new List<LeaderboardColumn> { lbResponse.LeaderboardInfo.Column };
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ namespace Microsoft.Xbox.Services.Leaderboard
|
||||||
Values = row.Value != null ? new List<string> { row.Value } : row.Values
|
Values = row.Value != null ? new List<string> { row.Value } : row.Values
|
||||||
}).ToList();
|
}).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);
|
LeaderboardResult result = new LeaderboardResult(rows, columns, lbResponse.LeaderboardInfo.TotalCount);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,8 @@
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Achievements\AchievementTitleAssociation.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Achievements\AchievementTitleAssociation.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Achievements\AchievementType.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Achievements\AchievementType.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\HttpCallRequestMessage.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\HttpCallRequestMessage.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\HttpCallResponseBodyType.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\HttpMethod.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\HttpRequestMessageType.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\HttpRequestMessageType.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\HttpRetryAfterApiState.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\HttpCallResponseBodyType.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\HttpRetryAfterManager.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\IXboxLiveUser.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\IXboxLiveUser.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\ServiceCallLoggingConfig.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\ServiceCallLoggingConfig.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\SignInCompletedEventArgs.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\SignInCompletedEventArgs.cs" />
|
||||||
|
@ -39,12 +36,9 @@
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\TokenAndSignatureResult.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\TokenAndSignatureResult.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxException.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxException.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLive.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLive.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLiveAPIName.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLiveAppConfiguration.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLiveAppConfiguration.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLiveContextRecommendedSetting.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLiveContextRecommendedSetting.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLiveContextThrottleSetting.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLiveContextThrottleSetting.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLiveHttpRequest.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLiveHttpResponse.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLiveLogCallEventArgs.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLiveLogCallEventArgs.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLiveServices.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLiveServices.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLiveSettings.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLiveSettings.cs" />
|
||||||
|
@ -79,16 +73,19 @@
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)GameServerPlatform\QualityOfServiceServer.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)GameServerPlatform\QualityOfServiceServer.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\ILeaderboardQueryImpl.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\ILeaderboardQueryImpl.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\ILeaderboardResultImpl.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\ILeaderboardResultImpl.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\ILeaderboardService.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardQueryImpl.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardQueryImpl.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardResultImpl.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardResultImpl.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardService.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardStatType.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardStatType.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\MockLeaderboardResultImpl.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\MockLeaderboardResultImpl.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\MockLeaderboardService.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Privacy\IPrivacyService.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Privacy\IPrivacyService.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Privacy\Models\PrivacySettingsRequest.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Privacy\Models\PrivacySettingsRequest.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Shared\IXboxWebsocketClient.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Social\Manager\ISocialManagerPresenceRecord.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Social\Manager\ISocialManagerPresenceRecord.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Social\Manager\IXboxSocialUserGroup.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Social\Manager\IXboxSocialUserGroup.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Social\Manager\SocialManagerPresenceRecord.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Social\Manager\SocialManagerPresenceRecord.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Social\ProfileService.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Statistics\Manager\IStatisticManager.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Statistics\Manager\IStatisticManager.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Statistics\Manager\LeaderboardResultEventArgs.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Statistics\Manager\LeaderboardResultEventArgs.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Statistics\Manager\MockStatisticManager.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Statistics\Manager\MockStatisticManager.cs" />
|
||||||
|
@ -98,31 +95,24 @@
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Statistics\Manager\StatisticEventType.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Statistics\Manager\StatisticEventType.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Statistics\Manager\StatisticManager.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Statistics\Manager\StatisticManager.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Statistics\Manager\StatisticValue.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Statistics\Manager\StatisticValue.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\AuthConfig.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\IUserImpl.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)System\IUserImpl.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\MarshallingHelpers.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)System\MarshallingHelpers.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\XboxLiveCallbackContext.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)System\XboxLiveServicesSettings.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\XboxLiveResult.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)System\XsapiCallbackContext.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)System\XsapiResult.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)TitleStorage\ITitleStorageService.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)TitleStorage\ITitleStorageService.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\ILeaderboardService.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\MockLeaderboardService.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\SortOrder.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\SortOrder.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardQuery.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardQuery.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardResponse.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardResponse.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardColumn.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardColumn.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardResult.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardResult.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardRow.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardRow.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardService.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Matchmaking\CreateMatchTicketResponse.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Matchmaking\CreateMatchTicketResponse.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Matchmaking\HopperStatisticsResponse.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Matchmaking\HopperStatisticsResponse.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Matchmaking\MatchmakingService.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Matchmaking\MatchmakingService.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Matchmaking\MatchTicketDetailsResponse.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Matchmaking\MatchTicketDetailsResponse.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Matchmaking\PreserveSessionMode.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Matchmaking\PreserveSessionMode.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Matchmaking\TicketStatus.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Matchmaking\TicketStatus.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Mock\MockXboxLiveData.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Mock\MockXboxLiveHttpRequest.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Mock\MockXboxLiveHttpResponse.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Mock\XboxLiveHttpRequestEqualityComparer.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Multiplayer\Manager\FindMatchCompletedEventArgs.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Multiplayer\Manager\FindMatchCompletedEventArgs.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Multiplayer\Manager\HostChangedEventArgs.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Multiplayer\Manager\HostChangedEventArgs.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Multiplayer\Manager\Joinability.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Multiplayer\Manager\Joinability.cs" />
|
||||||
|
@ -195,7 +185,6 @@
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)RealTimeActivity\RealTimeActivitySubscriptionError.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)RealTimeActivity\RealTimeActivitySubscriptionError.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)RealTimeActivity\RealTimeActivitySubscriptionErrorEventArgs.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)RealTimeActivity\RealTimeActivitySubscriptionErrorEventArgs.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)RealTimeActivity\RealTimeActivitySubscriptionState.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)RealTimeActivity\RealTimeActivitySubscriptionState.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Shared\CallBufferTimer.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Social\Manager\ISocialManager.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Social\Manager\ISocialManager.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Social\Manager\MockSocialManager.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Social\Manager\MockSocialManager.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Social\Manager\PreferredColor.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Social\Manager\PreferredColor.cs" />
|
||||||
|
@ -214,7 +203,6 @@
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Social\Manager\XboxSocialUserGroup.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Social\Manager\XboxSocialUserGroup.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Social\Models\ProfileSettingsRequest.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Social\Models\ProfileSettingsRequest.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Social\Models\ProfileSettingsResponse.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Social\Models\ProfileSettingsResponse.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Social\ProfileService.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Social\ReputationFeedbackItem.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Social\ReputationFeedbackItem.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Social\ReputationFeedbackType.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Social\ReputationFeedbackType.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Social\ReputationService.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Social\ReputationService.cs" />
|
||||||
|
@ -228,13 +216,9 @@
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Social\XboxSocialRelationshipResult.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Social\XboxSocialRelationshipResult.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Social\XboxUserProfile.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Social\XboxUserProfile.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\GamingPrivilege.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)System\GamingPrivilege.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\JsonSerialization.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\StringService.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)System\StringService.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\VerifyStringResult.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)System\VerifyStringResult.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\VerifyStringResultCode.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)System\VerifyStringResultCode.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\XboxLiveServicesSettings.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\XboxSystemFactory.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\XboxUserIdEqualityComparer.cs" />
|
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)TitleStorage\TitleStorageBlobMetadata.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)TitleStorage\TitleStorageBlobMetadata.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)TitleStorage\TitleStorageBlobMetadataResult.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)TitleStorage\TitleStorageBlobMetadataResult.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)TitleStorage\TitleStorageBlobResult.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)TitleStorage\TitleStorageBlobResult.cs" />
|
||||||
|
|
|
@ -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<string, MockRequestData> MockResponses { get; set; }
|
|
||||||
|
|
||||||
static MockXboxLiveData()
|
|
||||||
{
|
|
||||||
MockResponses = new Dictionary<string, MockRequestData>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Load(string path)
|
|
||||||
{
|
|
||||||
if (!File.Exists(path))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
string rawData = File.ReadAllText(path);
|
|
||||||
MockResponses = JsonConvert.DeserializeObject<Dictionary<string, MockRequestData>>(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<string, string> headers = new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "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; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<XboxLiveHttpResponse> 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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<string, string>())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public MockXboxLiveHttpResponse(int httpStatus, Dictionary<string, string> headers) : this(httpStatus, null, null, headers)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonConstructor]
|
|
||||||
public MockXboxLiveHttpResponse(int httpStatus, JObject body, string characterSet = null, Dictionary<string, string> 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<string, string> header in headers)
|
|
||||||
{
|
|
||||||
webHeaders[header.Key] = header.Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.Initialize(httpStatus, bodyStream, bodyStream.Length, characterSet ?? "utf-8", webHeaders);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<XboxLiveHttpRequest>
|
|
||||||
{
|
|
||||||
public static List<string> IgnoredHeaders = new List<string>
|
|
||||||
{
|
|
||||||
"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<string, string> x, IDictionary<string, string> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,8 +12,8 @@ namespace Microsoft.Xbox.Services.Privacy
|
||||||
/// Get the list of Xbox Live Ids the calling user should avoid during multiplayer matchmaking.
|
/// Get the list of Xbox Live Ids the calling user should avoid during multiplayer matchmaking.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A collection of XboxUserIds that correspond to the calling user's avoid list.</returns>
|
/// <returns>A collection of XboxUserIds that correspond to the calling user's avoid list.</returns>
|
||||||
Task<IList<string>> GetAvoidListAsync();
|
Task<IReadOnlyList<string>> GetAvoidListAsync();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check a single permission with a single target user.
|
/// Check a single permission with a single target user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -33,15 +33,15 @@ namespace Microsoft.Xbox.Services.Privacy
|
||||||
/// See Microsoft::Xbox::Services::Privacy::PermissionIdConstants for the latest options.</param>
|
/// See Microsoft::Xbox::Services::Privacy::PermissionIdConstants for the latest options.</param>
|
||||||
/// <param name="targetXboxUserIds">The collection of target Xbox user IDs to check permissions against.</param>
|
/// <param name="targetXboxUserIds">The collection of target Xbox user IDs to check permissions against.</param>
|
||||||
/// <returns>A collection of <see cref="PermissionCheckResult"/> objects containing results of the target xbox user ids.</returns>
|
/// <returns>A collection of <see cref="PermissionCheckResult"/> objects containing results of the target xbox user ids.</returns>
|
||||||
Task<List<MultiplePermissionsCheckResult>> CheckMultiplePermissionsWithMultipleTargetUsersAsync(
|
Task<IReadOnlyList<MultiplePermissionsCheckResult>> CheckMultiplePermissionsWithMultipleTargetUsersAsync(
|
||||||
IList<string> permissionIds,
|
IReadOnlyList<string> permissionIds,
|
||||||
IList<string> targetXboxUserIds
|
IReadOnlyList<string> targetXboxUserIds
|
||||||
);
|
);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the list of Xbox Live Ids that the calling user should not hear (mute) during multiplayer matchmaking.
|
/// Get the list of Xbox Live Ids that the calling user should not hear (mute) during multiplayer matchmaking.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The collection of Xbox user IDs that represent the mute list for a user.</returns>
|
/// <returns>The collection of Xbox user IDs that represent the mute list for a user.</returns>
|
||||||
Task<IList<string>> GetMuteListAsync();
|
Task<IReadOnlyList<string>> GetMuteListAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace Microsoft.Xbox.Services.Privacy
|
||||||
|
|
||||||
public class MultiplePermissionsCheckResult
|
public class MultiplePermissionsCheckResult
|
||||||
{
|
{
|
||||||
public IList<PermissionCheckResult> Items { get; private set; }
|
public IReadOnlyList<PermissionCheckResult> Items { get; private set; }
|
||||||
|
|
||||||
public string XboxUserId { get; private set; }
|
public string XboxUserId { get; private set; }
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ namespace Microsoft.Xbox.Services.Privacy
|
||||||
|
|
||||||
XboxUserId = MarshalingHelpers.Utf8ToString(multiplePermissionsStruct.xboxUserId);
|
XboxUserId = MarshalingHelpers.Utf8ToString(multiplePermissionsStruct.xboxUserId);
|
||||||
|
|
||||||
Items = new List<PermissionCheckResult>((int)multiplePermissionsStruct.itemsCount);
|
var items = new List<PermissionCheckResult>((int)multiplePermissionsStruct.itemsCount);
|
||||||
|
|
||||||
int size = MarshalingHelpers.SizeOf<XSAPI_PRIVACY_PERMISSION_CHECK_RESULT>();
|
int size = MarshalingHelpers.SizeOf<XSAPI_PRIVACY_PERMISSION_CHECK_RESULT>();
|
||||||
IntPtr permissionStructPtr = multiplePermissionsStruct.items;
|
IntPtr permissionStructPtr = multiplePermissionsStruct.items;
|
||||||
|
@ -28,9 +28,10 @@ namespace Microsoft.Xbox.Services.Privacy
|
||||||
for (ulong i = 0; i < multiplePermissionsStruct.itemsCount; ++i)
|
for (ulong i = 0; i < multiplePermissionsStruct.itemsCount; ++i)
|
||||||
{
|
{
|
||||||
var permissionCheckResultStruct = MarshalingHelpers.PtrToStructure<XSAPI_PRIVACY_PERMISSION_CHECK_RESULT>(permissionStructPtr);
|
var permissionCheckResultStruct = MarshalingHelpers.PtrToStructure<XSAPI_PRIVACY_PERMISSION_CHECK_RESULT>(permissionStructPtr);
|
||||||
Items.Add(new PermissionCheckResult(permissionCheckResultStruct));
|
items.Add(new PermissionCheckResult(permissionCheckResultStruct));
|
||||||
permissionStructPtr = permissionStructPtr.Increment(size);
|
permissionStructPtr = permissionStructPtr.Increment(size);
|
||||||
}
|
}
|
||||||
|
Items = items;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Microsoft.Xbox.Services.Privacy
|
||||||
|
|
||||||
public class PermissionCheckResult
|
public class PermissionCheckResult
|
||||||
{
|
{
|
||||||
public IList<PermissionDenyReason> Reasons { get; private set; }
|
public IReadOnlyList<PermissionDenyReason> DenyReasons { get; private set; }
|
||||||
|
|
||||||
public string PermissionRequested { get; private set; }
|
public string PermissionRequested { get; private set; }
|
||||||
|
|
||||||
|
@ -27,17 +27,17 @@ namespace Microsoft.Xbox.Services.Privacy
|
||||||
IsAllowed = permissionCheckResultStruct.isAllowed;
|
IsAllowed = permissionCheckResultStruct.isAllowed;
|
||||||
PermissionRequested = MarshalingHelpers.Utf8ToString(permissionCheckResultStruct.permissionRequested);
|
PermissionRequested = MarshalingHelpers.Utf8ToString(permissionCheckResultStruct.permissionRequested);
|
||||||
|
|
||||||
Reasons = new List<PermissionDenyReason>((int)permissionCheckResultStruct.denyReasonsCount);
|
var denyReasons = new List<PermissionDenyReason>((int)permissionCheckResultStruct.denyReasonsCount);
|
||||||
|
|
||||||
int size = MarshalingHelpers.SizeOf<XSAPI_PRIVACY_PERMISSION_DENY_REASON>();
|
int size = MarshalingHelpers.SizeOf<XSAPI_PRIVACY_PERMISSION_DENY_REASON>();
|
||||||
IntPtr denyReasonPtr = permissionCheckResultStruct.denyReasons;
|
IntPtr denyReasonPtr = permissionCheckResultStruct.denyReasons;
|
||||||
|
|
||||||
for (ulong i = 0; i < permissionCheckResultStruct.denyReasonsCount; ++i)
|
for (ulong i = 0; i < permissionCheckResultStruct.denyReasonsCount; ++i)
|
||||||
{
|
{
|
||||||
Reasons.Add(new PermissionDenyReason(denyReasonPtr));
|
denyReasons.Add(new PermissionDenyReason(denyReasonPtr));
|
||||||
denyReasonPtr = denyReasonPtr.Increment(size);
|
denyReasonPtr = denyReasonPtr.Increment(size);
|
||||||
}
|
}
|
||||||
|
DenyReasons = denyReasons;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,12 +19,12 @@ namespace Microsoft.Xbox.Services.Privacy
|
||||||
this.pCXboxLiveContext = pCXboxLiveContext;
|
this.pCXboxLiveContext = pCXboxLiveContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<IList<string>> GetAvoidListAsync()
|
public Task<IReadOnlyList<string>> GetAvoidListAsync()
|
||||||
{
|
{
|
||||||
var tcs = new TaskCompletionSource<IList<string>>();
|
var tcs = new TaskCompletionSource<IReadOnlyList<string>>();
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
int contextKey = XsapiCallbackContext<object, IList<string>>.CreateContext(null, tcs);
|
int contextKey = XsapiCallbackContext<object, IReadOnlyList<string>>.CreateContext(null, tcs);
|
||||||
|
|
||||||
var xsapiResult = PrivacyGetAvoidList(this.pCXboxLiveContext, GetPrivacyUserListComplete, (IntPtr)contextKey, XboxLive.DefaultTaskGroupId);
|
var xsapiResult = PrivacyGetAvoidList(this.pCXboxLiveContext, GetPrivacyUserListComplete, (IntPtr)contextKey, XboxLive.DefaultTaskGroupId);
|
||||||
if (xsapiResult != XSAPI_RESULT.XSAPI_RESULT_OK)
|
if (xsapiResult != XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
|
@ -35,12 +35,12 @@ namespace Microsoft.Xbox.Services.Privacy
|
||||||
return tcs.Task;
|
return tcs.Task;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<IList<string>> GetMuteListAsync()
|
public Task<IReadOnlyList<string>> GetMuteListAsync()
|
||||||
{
|
{
|
||||||
var tcs = new TaskCompletionSource<IList<string>>();
|
var tcs = new TaskCompletionSource<IReadOnlyList<string>>();
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
int contextKey = XsapiCallbackContext<object, IList<string>>.CreateContext(null, tcs);
|
int contextKey = XsapiCallbackContext<object, IReadOnlyList<string>>.CreateContext(null, tcs);
|
||||||
|
|
||||||
var xsapiResult = PrivacyGetMuteList(this.pCXboxLiveContext, GetPrivacyUserListComplete, (IntPtr)contextKey, XboxLive.DefaultTaskGroupId);
|
var xsapiResult = PrivacyGetMuteList(this.pCXboxLiveContext, GetPrivacyUserListComplete, (IntPtr)contextKey, XboxLive.DefaultTaskGroupId);
|
||||||
if (xsapiResult != XSAPI_RESULT.XSAPI_RESULT_OK)
|
if (xsapiResult != XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
|
@ -58,7 +58,7 @@ namespace Microsoft.Xbox.Services.Privacy
|
||||||
{
|
{
|
||||||
if (result.errorCode == XSAPI_RESULT.XSAPI_RESULT_OK)
|
if (result.errorCode == XSAPI_RESULT.XSAPI_RESULT_OK)
|
||||||
{
|
{
|
||||||
context.TaskCompletionSource.SetResult(MarshalingHelpers.Utf8StringArrayToStringList(xboxUserIdList, (int)count));
|
context.TaskCompletionSource.SetResult(MarshalingHelpers.Utf8StringArrayToStringList(xboxUserIdList, count));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -109,15 +109,15 @@ namespace Microsoft.Xbox.Services.Privacy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<List<MultiplePermissionsCheckResult>> CheckMultiplePermissionsWithMultipleTargetUsersAsync(IList<string> permissionIds, IList<string> targetXboxUserIds)
|
public Task<IReadOnlyList<MultiplePermissionsCheckResult>> CheckMultiplePermissionsWithMultipleTargetUsersAsync(IReadOnlyList<string> permissionIds, IReadOnlyList<string> targetXboxUserIds)
|
||||||
{
|
{
|
||||||
var tcs = new TaskCompletionSource<List<MultiplePermissionsCheckResult>>();
|
var tcs = new TaskCompletionSource<IReadOnlyList<MultiplePermissionsCheckResult>>();
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
var permissionIdsArray = MarshalingHelpers.StringListToHGlobalUtf8StringArray(permissionIds);
|
var permissionIdsArray = MarshalingHelpers.StringListToHGlobalUtf8StringArray(permissionIds);
|
||||||
var xuidsArray = MarshalingHelpers.StringListToHGlobalUtf8StringArray(targetXboxUserIds);
|
var xuidsArray = MarshalingHelpers.StringListToHGlobalUtf8StringArray(targetXboxUserIds);
|
||||||
|
|
||||||
int contextKey = XsapiCallbackContext<CheckMultiplePermissionsContext, List<MultiplePermissionsCheckResult>>.CreateContext(
|
int contextKey = XsapiCallbackContext<CheckMultiplePermissionsContext, IReadOnlyList<MultiplePermissionsCheckResult>>.CreateContext(
|
||||||
new CheckMultiplePermissionsContext
|
new CheckMultiplePermissionsContext
|
||||||
{
|
{
|
||||||
permissionIdsArray = permissionIdsArray,
|
permissionIdsArray = permissionIdsArray,
|
||||||
|
|
|
@ -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<T> : EventArgs
|
|
||||||
{
|
|
||||||
public CallBufferEventArgs(List<T> elements)
|
|
||||||
{
|
|
||||||
this.Elements = elements;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<T> Elements { get; private set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A helper class to throttle calls and buffer call data. One or more calls made to <see cref="Fire"/> will be
|
|
||||||
/// batched together and passed as a single
|
|
||||||
/// </summary>
|
|
||||||
internal class CallBufferTimer<T>
|
|
||||||
{
|
|
||||||
private readonly TimeSpan period;
|
|
||||||
private DateTime previousTime;
|
|
||||||
|
|
||||||
private readonly object elementBufferLock = new object();
|
|
||||||
private readonly HashSet<T> elementBuffer;
|
|
||||||
private TaskCompletionSource<bool> currentCompletionSource = new TaskCompletionSource<bool>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A lock around the current call to prevent multiple callers
|
|
||||||
/// </summary>
|
|
||||||
private readonly object callLock = new object();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A task that represents the current call in progress.
|
|
||||||
/// </summary>
|
|
||||||
private Task inProgressTask = Task.FromResult(true);
|
|
||||||
|
|
||||||
public event EventHandler<CallBufferEventArgs<T>> Completed;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a <see cref="CallBufferTimer{T}"/>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="period">The minimum duration between triggers of the <see cref="Completed"/> event.</param>
|
|
||||||
/// <param name="comparer">If not null, overrides the comparer used to compare elements in the buffer.</param>
|
|
||||||
public CallBufferTimer(TimeSpan period, IEqualityComparer<T> comparer = null)
|
|
||||||
{
|
|
||||||
this.period = period;
|
|
||||||
this.elementBuffer = new HashSet<T>(comparer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task Fire(IList<T> elements)
|
|
||||||
{
|
|
||||||
if (elements == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("elements");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (elements.Count == 0)
|
|
||||||
{
|
|
||||||
return Task.FromResult(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
TaskCompletionSource<bool> 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<bool> 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<T> elements;
|
|
||||||
lock (this.elementBufferLock)
|
|
||||||
{
|
|
||||||
inProgressCompletionSource = this.currentCompletionSource;
|
|
||||||
this.currentCompletionSource = new TaskCompletionSource<bool>();
|
|
||||||
|
|
||||||
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<T>(elements));
|
|
||||||
inProgressCompletionSource.SetResult(true);
|
|
||||||
|
|
||||||
if (this.elementBuffer.Count > 0)
|
|
||||||
{
|
|
||||||
this.FireHelper();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
inProgressCompletionSource.SetException(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnCompleted(CallBufferEventArgs<T> e)
|
|
||||||
{
|
|
||||||
var handler = this.Completed;
|
|
||||||
if (handler != null) handler(this, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<object> Connect(
|
|
||||||
XboxLiveUser xblUser,
|
|
||||||
string uri,
|
|
||||||
string subprotocol);
|
|
||||||
|
|
||||||
void Send(string message, Action<bool> onSendComplete);
|
|
||||||
|
|
||||||
void Close();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -163,7 +163,7 @@ namespace Microsoft.Xbox.Services.Social.Manager
|
||||||
{
|
{
|
||||||
new SocialManagerPresenceTitleRecord
|
new SocialManagerPresenceTitleRecord
|
||||||
{
|
{
|
||||||
TitleId = XboxLiveAppConfiguration.Instance.TitleId,
|
TitleId = XboxLiveAppConfiguration.SingletonInstance.TitleId,
|
||||||
IsTitleActive = true,
|
IsTitleActive = true,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,6 +35,5 @@ namespace Microsoft.Xbox.Services.Social.Manager
|
||||||
return m_instance;
|
return m_instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,101 +9,21 @@ namespace Microsoft.Xbox.Services.Social
|
||||||
|
|
||||||
public class ProfileService
|
public class ProfileService
|
||||||
{
|
{
|
||||||
private readonly string profileEndpoint;
|
|
||||||
|
|
||||||
protected XboxLiveAppConfiguration config;
|
|
||||||
|
|
||||||
internal ProfileService()
|
internal ProfileService()
|
||||||
{
|
{
|
||||||
this.config = XboxLive.Instance.AppConfig;
|
|
||||||
this.profileEndpoint = this.config.GetEndpointForService("profile");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<XboxUserProfile> GetUserProfileAsync(XboxLiveUser user, string xboxUserId)
|
public Task<XboxUserProfile> GetUserProfileAsync(string xboxUserId)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(xboxUserId))
|
throw new NotImplementedException();
|
||||||
{
|
|
||||||
throw new ArgumentException("invalid xboxUserId", "xboxUserId");
|
|
||||||
}
|
|
||||||
|
|
||||||
List<string> profiles = new List<string> { xboxUserId };
|
|
||||||
|
|
||||||
return this.GetUserProfilesAsync(user, profiles).ContinueWith(task => task.Result[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<List<XboxUserProfile>> GetUserProfilesAsync(XboxLiveUser user, List<string> xboxUserIds)
|
public Task<IReadOnlyList<XboxUserProfile>> GetUserProfilesAsync(IReadOnlyList<string> xboxUserIds)
|
||||||
{
|
{
|
||||||
if (xboxUserIds == null)
|
throw new NotImplementedException();
|
||||||
{
|
|
||||||
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<XboxUserProfile> outputUsers = new List<XboxUserProfile>(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<Models.ProfileSettingsResponse>(response.ResponseBodyString);
|
|
||||||
|
|
||||||
List<XboxUserProfile> outputUsers = new List<XboxUserProfile>();
|
|
||||||
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;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<List<XboxUserProfile>> GetUserProfilesForSocialGroupAsync(string socialGroup)
|
public Task<IReadOnlyList<XboxUserProfile>> GetUserProfilesForSocialGroupAsync(string socialGroup)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +1,6 @@
|
||||||
// Copyright (c) Microsoft Corporation
|
// Copyright (c) Microsoft Corporation
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// 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
|
namespace Microsoft.Xbox.Services.System
|
||||||
{
|
{
|
||||||
|
@ -33,5 +29,4 @@ namespace Microsoft.Xbox.Services.System
|
||||||
MultiplayerSessions = 254,
|
MultiplayerSessions = 254,
|
||||||
AddFriend = 255,
|
AddFriend = 255,
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,16 +14,14 @@ namespace Microsoft.Xbox.Services.System
|
||||||
string AgeGroup { get; }
|
string AgeGroup { get; }
|
||||||
string Privileges { get; }
|
string Privileges { get; }
|
||||||
string WebAccountId { get; }
|
string WebAccountId { get; }
|
||||||
AuthConfig AuthConfig { get; }
|
|
||||||
#if WINDOWS_UWP
|
#if WINDOWS_UWP
|
||||||
Windows.System.User CreationContext { get; }
|
Windows.System.User CreationContext { get; }
|
||||||
#endif
|
#endif
|
||||||
#if !UNITY_EDITOR
|
#if !UNITY_EDITOR
|
||||||
IntPtr XboxLiveUserPtr { get; }
|
IntPtr XboxLiveUserPtr { get; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Task<SignInResult> SignInImpl(bool showUI, bool forceRefresh);
|
Task<SignInResult> SignInImpl(bool showUI, bool forceRefresh);
|
||||||
|
|
||||||
Task<TokenAndSignatureResult> InternalGetTokenAndSignatureAsync(string httpMethod, string url, string headers, byte[] body, bool promptForCredentialsIfNeeded, bool forceRefresh);
|
Task<GetTokenAndSignatureResult> InternalGetTokenAndSignatureAsync(string httpMethod, string url, string headers, byte[] body, bool promptForCredentialsIfNeeded, bool forceRefresh);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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<T>(string jsonInput)
|
|
||||||
{
|
|
||||||
return JsonConvert.DeserializeObject<T>(jsonInput);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static string ToJson<T>(T input)
|
|
||||||
{
|
|
||||||
return JsonConvert.SerializeObject(input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,6 +6,7 @@ namespace Microsoft.Xbox.Services
|
||||||
{
|
{
|
||||||
using global::System;
|
using global::System;
|
||||||
using global::System.Collections.Generic;
|
using global::System.Collections.Generic;
|
||||||
|
using global::System.Linq;
|
||||||
using global::System.Runtime.InteropServices;
|
using global::System.Runtime.InteropServices;
|
||||||
using global::System.Text;
|
using global::System.Text;
|
||||||
|
|
||||||
|
@ -51,9 +52,9 @@ namespace Microsoft.Xbox.Services
|
||||||
/// <param name="arrayPtr">Pointer to the C-style string array</param>
|
/// <param name="arrayPtr">Pointer to the C-style string array</param>
|
||||||
/// <param name="length">Number of strings in the array</param>
|
/// <param name="length">Number of strings in the array</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
internal static IList<string> Utf8StringArrayToStringList(IntPtr arrayPtr, int length)
|
internal static IList<string> Utf8StringArrayToStringList(IntPtr arrayPtr, uint length)
|
||||||
{
|
{
|
||||||
var list = new List<string>(length);
|
var list = new List<string>((int)length);
|
||||||
for (int i = 0; i < length; ++i)
|
for (int i = 0; i < length; ++i)
|
||||||
{
|
{
|
||||||
string str = MarshalingHelpers.Utf8ToString(Marshal.ReadIntPtr(arrayPtr));
|
string str = MarshalingHelpers.Utf8ToString(Marshal.ReadIntPtr(arrayPtr));
|
||||||
|
@ -69,9 +70,9 @@ namespace Microsoft.Xbox.Services
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="strings">The array of string to allocate</param>
|
/// <param name="strings">The array of string to allocate</param>
|
||||||
/// <returns>An IntPtr to the first Utf8String pointer</returns>
|
/// <returns>An IntPtr to the first Utf8String pointer</returns>
|
||||||
internal static IntPtr StringListToHGlobalUtf8StringArray(IList<string> strings)
|
internal static IntPtr StringListToHGlobalUtf8StringArray(IEnumerable<string> strings)
|
||||||
{
|
{
|
||||||
var firstString = Marshal.AllocHGlobal(IntPtr.Size * strings.Count);
|
var firstString = Marshal.AllocHGlobal(IntPtr.Size * strings.Count());
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
foreach (var str in strings)
|
foreach (var str in strings)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
// Copyright (c) Microsoft Corporation
|
// Copyright (c) Microsoft Corporation
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// 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
|
namespace Microsoft.Xbox.Services.System
|
||||||
{
|
{
|
||||||
|
using global::System;
|
||||||
|
using global::System.Threading.Tasks;
|
||||||
|
|
||||||
public class StringService
|
public class StringService
|
||||||
{
|
{
|
||||||
|
|
||||||
public Task<VerifyStringResult> VerifyStringAsync(string stringToVerify)
|
public Task<VerifyStringResult> VerifyStringAsync(string stringToVerify)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
|
@ -1,16 +1,11 @@
|
||||||
// Copyright (c) Microsoft Corporation
|
// Copyright (c) Microsoft Corporation
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// 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
|
namespace Microsoft.Xbox.Services.System
|
||||||
{
|
{
|
||||||
public class VerifyStringResult
|
public class VerifyStringResult
|
||||||
{
|
{
|
||||||
|
|
||||||
public string FirstOffendingSubstring
|
public string FirstOffendingSubstring
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
// Copyright (c) Microsoft Corporation
|
// Copyright (c) Microsoft Corporation
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// 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
|
namespace Microsoft.Xbox.Services.System
|
||||||
{
|
{
|
||||||
|
@ -15,5 +11,4 @@ namespace Microsoft.Xbox.Services.System
|
||||||
TooLong = 2,
|
TooLong = 2,
|
||||||
UnknownError = 3,
|
UnknownError = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,6 @@ namespace Microsoft.Xbox.Services.System
|
||||||
|
|
||||||
public static XboxLiveServicesSettings SingletonInstance { get; private set; }
|
public static XboxLiveServicesSettings SingletonInstance { get; private set; }
|
||||||
|
|
||||||
//public event EventHandler<XboxLiveLogCallEventArgs> LogCallRouted;
|
public event EventHandler<XboxLiveLogCallEventArgs> LogCallRouted;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An equality comparer that only uses the XUID property.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This is used in a variety of places in order to perform dictionary lookups efficiently.
|
|
||||||
/// </remarks>
|
|
||||||
public sealed class XboxUserIdEqualityComparer : IEqualityComparer<XboxLiveUser>
|
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An equality comparer that only uses the XUID property.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This is used in a variety of places in order to perform dictionary lookups efficiently.
|
|
||||||
/// </remarks>
|
|
||||||
public sealed class XboxSocialUserIdEqualityComparer : IEqualityComparer<XboxSocialUser>
|
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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.Collections.Generic;
|
||||||
using global::System.Threading.Tasks;
|
using global::System.Threading.Tasks;
|
||||||
|
|
||||||
using Microsoft.Xbox.Services.TitleStorage;
|
using Microsoft.Xbox.Services.TitleStorage;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -72,7 +75,7 @@
|
||||||
/// <param name="etagMatchCondition">The ETag match condition used to determine if the blob data should be uploaded.</param>
|
/// <param name="etagMatchCondition">The ETag match condition used to determine if the blob data should be uploaded.</param>
|
||||||
/// <param name="preferredDownloadBlockSize">The preferred upload block size in bytes for binary blobs. </param>
|
/// <param name="preferredDownloadBlockSize">The preferred upload block size in bytes for binary blobs. </param>
|
||||||
/// <returns>An instance of the <see cref="TitleStorageBlobMetadata"/> class with updated ETag and Length Properties.</returns>
|
/// <returns>An instance of the <see cref="TitleStorageBlobMetadata"/> class with updated ETag and Length Properties.</returns>
|
||||||
Task<TitleStorageBlobMetadata> UploadBlobAsync(TitleStorageBlobMetadata blobMetadata, List<byte> blobBuffer, TitleStorageETagMatchCondition etagMatchCondition, uint preferredUploadBlockSize);
|
Task<TitleStorageBlobMetadata> UploadBlobAsync(TitleStorageBlobMetadata blobMetadata, IReadOnlyList<byte> blobBuffer, TitleStorageETagMatchCondition etagMatchCondition, uint preferredUploadBlockSize);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace Microsoft.Xbox.Services.TitleStorage
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// [optional] Timestamp assigned by the client.
|
/// [optional] Timestamp assigned by the client.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTimeOffset? ClientTimeStamp { get; private set; }
|
public DateTimeOffset ClientTimeStamp { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ETag for the file used in read and write requests.
|
/// 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 displayName = MarshalingHelpers.StringToHGlobalUtf8(this.DisplayName);
|
||||||
var etag = MarshalingHelpers.StringToHGlobalUtf8(this.ETag);
|
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<UInt64>());
|
||||||
|
Marshal.WriteInt64(clientTimePtr, clientTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
TitleStorageCreateBlobMetadata(scid, StorageType, path, BlobType, xuid, displayName, etag, clientTimePtr, out metadataPtr);
|
||||||
|
|
||||||
Marshal.FreeHGlobal(scid);
|
Marshal.FreeHGlobal(scid);
|
||||||
Marshal.FreeHGlobal(path);
|
Marshal.FreeHGlobal(path);
|
||||||
Marshal.FreeHGlobal(xuid);
|
Marshal.FreeHGlobal(xuid);
|
||||||
Marshal.FreeHGlobal(displayName);
|
Marshal.FreeHGlobal(displayName);
|
||||||
Marshal.FreeHGlobal(etag);
|
Marshal.FreeHGlobal(etag);
|
||||||
|
Marshal.FreeHGlobal(clientTimePtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Refresh()
|
internal void Refresh()
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
namespace Microsoft.Xbox.Services.TitleStorage
|
namespace Microsoft.Xbox.Services.TitleStorage
|
||||||
{
|
{
|
||||||
using global::System;
|
using global::System;
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
//
|
//
|
||||||
namespace Microsoft.Xbox.Services.TitleStorage
|
namespace Microsoft.Xbox.Services.TitleStorage
|
||||||
{
|
{
|
||||||
using global::System.Runtime.InteropServices;
|
|
||||||
using global::System;
|
using global::System;
|
||||||
|
using global::System.Runtime.InteropServices;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Blob data returned from the cloud.
|
/// Blob data returned from the cloud.
|
||||||
|
|
|
@ -28,6 +28,15 @@ namespace Microsoft.Xbox.Services.TitleStorage
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TitleStorageType StorageType { get; private set; }
|
public TitleStorageType StorageType { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The ID of the user associated with the storage area
|
||||||
|
/// </summary>
|
||||||
|
public string XboxUserId { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The service configuration ID to get the quota from
|
||||||
|
/// </summary>
|
||||||
|
public string ServiceConfigurationId { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initialze a TitleStorageQuota from the corresponding C object
|
/// Initialze a TitleStorageQuota from the corresponding C object
|
||||||
|
@ -37,6 +46,8 @@ namespace Microsoft.Xbox.Services.TitleStorage
|
||||||
QuotaBytes = quotaStruct.QuotaBytes;
|
QuotaBytes = quotaStruct.QuotaBytes;
|
||||||
UsedBytes = quotaStruct.UsedBytes;
|
UsedBytes = quotaStruct.UsedBytes;
|
||||||
StorageType = quotaStruct.storageType;
|
StorageType = quotaStruct.storageType;
|
||||||
|
XboxUserId = MarshalingHelpers.Utf8ToString(quotaStruct.XboxUserId);
|
||||||
|
ServiceConfigurationId = MarshalingHelpers.Utf8ToString(quotaStruct.ServiceConfigurationId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace Microsoft.Xbox.Services.TitleStorage
|
||||||
{
|
{
|
||||||
using global::System;
|
using global::System;
|
||||||
using global::System.Collections.Generic;
|
using global::System.Collections.Generic;
|
||||||
|
using global::System.Linq;
|
||||||
using global::System.Runtime.InteropServices;
|
using global::System.Runtime.InteropServices;
|
||||||
using global::System.Threading.Tasks;
|
using global::System.Threading.Tasks;
|
||||||
using Microsoft.Xbox.Services.Shared.TitleStorage;
|
using Microsoft.Xbox.Services.Shared.TitleStorage;
|
||||||
|
@ -38,7 +39,7 @@ namespace Microsoft.Xbox.Services.TitleStorage
|
||||||
var tcs = new TaskCompletionSource<TitleStorageQuota>();
|
var tcs = new TaskCompletionSource<TitleStorageQuota>();
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
var scid = MarshalingHelpers.StringToHGlobalUtf8(XboxLive.Instance.AppConfig.PrimaryServiceConfigId);
|
var scid = MarshalingHelpers.StringToHGlobalUtf8(XboxLive.Instance.AppConfig.ServiceConfigurationId);
|
||||||
|
|
||||||
int contextKey;
|
int contextKey;
|
||||||
var context = XsapiCallbackContext<object, TitleStorageQuota>.CreateContext(null, tcs, out contextKey);
|
var context = XsapiCallbackContext<object, TitleStorageQuota>.CreateContext(null, tcs, out contextKey);
|
||||||
|
@ -246,7 +247,7 @@ namespace Microsoft.Xbox.Services.TitleStorage
|
||||||
/// <param name="etagMatchCondition">The ETag match condition used to determine if the blob data should be uploaded.</param>
|
/// <param name="etagMatchCondition">The ETag match condition used to determine if the blob data should be uploaded.</param>
|
||||||
/// <param name="preferredDownloadBlockSize">The preferred upload block size in bytes for binary blobs. </param>
|
/// <param name="preferredDownloadBlockSize">The preferred upload block size in bytes for binary blobs. </param>
|
||||||
/// <returns>An instance of the <see cref="TitleStorageBlobMetadata"/> class with updated ETag and Length Properties.</returns>
|
/// <returns>An instance of the <see cref="TitleStorageBlobMetadata"/> class with updated ETag and Length Properties.</returns>
|
||||||
public Task<TitleStorageBlobMetadata> UploadBlobAsync(TitleStorageBlobMetadata blobMetadata, List<byte> blobBuffer, TitleStorageETagMatchCondition etagMatchCondition, uint preferredUploadBlockSize)
|
public Task<TitleStorageBlobMetadata> UploadBlobAsync(TitleStorageBlobMetadata blobMetadata, IReadOnlyList<byte> blobBuffer, TitleStorageETagMatchCondition etagMatchCondition, uint preferredUploadBlockSize)
|
||||||
{
|
{
|
||||||
var tcs = new TaskCompletionSource<TitleStorageBlobMetadata>();
|
var tcs = new TaskCompletionSource<TitleStorageBlobMetadata>();
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
|
@ -255,7 +256,7 @@ namespace Microsoft.Xbox.Services.TitleStorage
|
||||||
var context = XsapiCallbackContext<TitleStorageBlobMetadata, TitleStorageBlobMetadata>.CreateContext(blobMetadata, tcs, out contextKey);
|
var context = XsapiCallbackContext<TitleStorageBlobMetadata, TitleStorageBlobMetadata>.CreateContext(blobMetadata, tcs, out contextKey);
|
||||||
|
|
||||||
var buffer = Marshal.AllocHGlobal(blobBuffer.Count);
|
var buffer = Marshal.AllocHGlobal(blobBuffer.Count);
|
||||||
Marshal.Copy(blobBuffer.ToArray(), 0, buffer, blobBuffer.Count);
|
Marshal.Copy(Enumerable.ToArray<byte>(blobBuffer), 0, buffer, blobBuffer.Count);
|
||||||
context.PointersToFree = new List<IntPtr> { buffer };
|
context.PointersToFree = new List<IntPtr> { buffer };
|
||||||
|
|
||||||
var xsapiResult = TitleStorageUploadBlob(
|
var xsapiResult = TitleStorageUploadBlob(
|
||||||
|
|
|
@ -219,7 +219,7 @@ namespace UWPIntegration
|
||||||
string resultText = string.Format("Allowed: {0}", result.IsAllowed);
|
string resultText = string.Format("Allowed: {0}", result.IsAllowed);
|
||||||
if (!result.IsAllowed)
|
if (!result.IsAllowed)
|
||||||
{
|
{
|
||||||
foreach (var reason in result.Reasons)
|
foreach (var reason in result.DenyReasons)
|
||||||
{
|
{
|
||||||
resultText += string.Format("\tReason: {0}", reason.Reason);
|
resultText += string.Format("\tReason: {0}", reason.Reason);
|
||||||
}
|
}
|
||||||
|
@ -249,7 +249,7 @@ namespace UWPIntegration
|
||||||
resultText += string.Format("\tPermission {0} allowed: {1}", permissionResult.PermissionRequested, permissionResult.IsAllowed);
|
resultText += string.Format("\tPermission {0} allowed: {1}", permissionResult.PermissionRequested, permissionResult.IsAllowed);
|
||||||
if (!permissionResult.IsAllowed)
|
if (!permissionResult.IsAllowed)
|
||||||
{
|
{
|
||||||
foreach (var reason in permissionResult.Reasons)
|
foreach (var reason in permissionResult.DenyReasons)
|
||||||
{
|
{
|
||||||
resultText += string.Format("\tReason: {0}", reason.Reason);
|
resultText += string.Format("\tReason: {0}", reason.Reason);
|
||||||
}
|
}
|
||||||
|
@ -333,7 +333,7 @@ namespace UWPIntegration
|
||||||
private async void TitleStorageGetQuota_Click(object sender, RoutedEventArgs e)
|
private async void TitleStorageGetQuota_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
var quota = await this.User.Services.TitleStorageService.GetQuotaAsync(
|
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);
|
this.TitleStorageData.Text = string.Format("Used bytes = {0}, Quota bytes = {1}", quota.UsedBytes, quota.QuotaBytes);
|
||||||
}
|
}
|
||||||
|
@ -343,7 +343,7 @@ namespace UWPIntegration
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var metadataResult = await this.User.Services.TitleStorageService.GetBlobMetadataAsync(
|
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;
|
var items = metadataResult.Items;
|
||||||
if (items.Count > 0)
|
if (items.Count > 0)
|
||||||
|
@ -362,7 +362,7 @@ namespace UWPIntegration
|
||||||
{
|
{
|
||||||
try
|
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!");
|
var bytes = System.Text.Encoding.Unicode.GetBytes("Hello, world!");
|
||||||
|
|
||||||
|
@ -403,7 +403,7 @@ namespace UWPIntegration
|
||||||
{
|
{
|
||||||
try
|
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);
|
await this.User.Services.TitleStorageService.DeleteBlobAsync(metadata, false);
|
||||||
|
|
||||||
this.TitleStorageData.Text = string.Format("Successfully deleted blob with path \"path/to/newfile.txt\"", metadata.Length);
|
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)}"));
|
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<SocialEvent> socialEvents = this.SocialManager.DoWork();
|
IList<SocialEvent> socialEvents = this.SocialManager.DoWork();
|
||||||
foreach (SocialEvent ev in socialEvents)
|
foreach (SocialEvent ev in socialEvents)
|
||||||
{
|
{
|
||||||
|
|
|
@ -99,6 +99,9 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<!-- A reference to the entire .Net Framework and Windows SDK are automatically included -->
|
<!-- A reference to the entire .Net Framework and Windows SDK are automatically included -->
|
||||||
<None Include="project.json" />
|
<None Include="project.json" />
|
||||||
|
<Content Include="Microsoft.Xbox.Services.140.UWP.C.dll">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Include="XboxServices.config">
|
<Content Include="XboxServices.config">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Content>
|
</Content>
|
||||||
|
@ -153,8 +156,8 @@
|
||||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||||
<Target Name="CopyCdllToAppx" AfterTargets="Build">
|
<Target Name="CopyCdllToAppx" AfterTargets="Build">
|
||||||
<Message Importance="high" Text="Copying C dll to Appx folder from $(BuildRoot)\..\CppSource\binaries\$(Configuration)\$(CDllPlatform)\Microsoft.Xbox.Services.140.UWP.C\ to $(TargetDir)AppX\" />
|
<Message Importance="high" Text="Copying C dll to Appx folder from $(BuildRoot)\..\CppSource\binaries\$(Configuration)\$(CDllPlatform)\Microsoft.Xbox.Services.140.UWP.C\ to $(TargetDir)AppX\" />
|
||||||
<Exec Command="xcopy /y /d $(BuildRoot)\..\CppSource\binaries\$(Configuration)\$(CDllPlatform)\Microsoft.Xbox.Services.140.UWP.C\*.dll $(TargetDir)AppX\" />
|
<Exec Command="xcopy /y /d $(BuildRoot)\..\CppSource\binaries\$(Configuration)\$(CDllPlatform)\Microsoft.Xbox.Services.140.UWP.C\*.dll $(TargetDir)AppX\" />
|
||||||
<Exec Command="xcopy /y /d $(BuildRoot)\..\CppSource\binaries\$(Configuration)\$(CDllPlatform)\Microsoft.Xbox.Services.140.UWP.C\*.pdb $(TargetDir)AppX\" />
|
<Exec Command="xcopy /y /d $(BuildRoot)\..\CppSource\binaries\$(Configuration)\$(CDllPlatform)\Microsoft.Xbox.Services.140.UWP.C\*.pdb $(TargetDir)AppX\" />
|
||||||
</Target>
|
</Target>
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
|
|
@ -59,16 +59,15 @@ Global
|
||||||
{28AFCA79-691F-4493-B639-D3CAD311189B}.Release|x86.Deploy.0 = Release|x86
|
{28AFCA79-691F-4493-B639-D3CAD311189B}.Release|x86.Deploy.0 = Release|x86
|
||||||
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Debug|Any CPU.ActiveCfg = Debug|x86
|
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||||
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Debug|Any CPU.Build.0 = Debug|x86
|
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Debug|Any CPU.Build.0 = Debug|x86
|
||||||
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||||
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Debug|ARM.Build.0 = Debug|Any CPU
|
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Debug|ARM.Build.0 = Debug|ARM
|
||||||
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Debug|x64.ActiveCfg = Debug|x64
|
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Debug|x64.Build.0 = Debug|x64
|
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Debug|x64.Build.0 = Debug|x64
|
||||||
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Debug|x86.ActiveCfg = Debug|x86
|
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Debug|x86.Build.0 = Debug|x86
|
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Debug|x86.Build.0 = Debug|x86
|
||||||
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Release|Any CPU.ActiveCfg = Release|x86
|
||||||
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Release|Any CPU.Build.0 = Release|Any CPU
|
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Release|ARM.ActiveCfg = Release|ARM
|
||||||
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Release|ARM.ActiveCfg = Release|Any CPU
|
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Release|ARM.Build.0 = Release|ARM
|
||||||
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Release|ARM.Build.0 = Release|Any CPU
|
|
||||||
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Release|x64.ActiveCfg = Release|x64
|
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Release|x64.ActiveCfg = Release|x64
|
||||||
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Release|x64.Build.0 = Release|x64
|
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Release|x64.Build.0 = Release|x64
|
||||||
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Release|x86.ActiveCfg = Release|x86
|
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
"TitleId" : 1798668314,
|
"TitleId" : 1798668314,
|
||||||
"PrimaryServiceConfigId" : "00000000-0000-0000-0000-00006b35801a",
|
"PrimaryServiceConfigId" : "00000000-0000-0000-0000-00006b35801a",
|
||||||
"XboxLiveCreatorsTitle" : true
|
"XboxLiveCreatorsTitle" : true
|
||||||
}
|
}
|
|
@ -64,7 +64,7 @@
|
||||||
<Import Project="..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.ARM.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.ARM.targets" Condition="Exists('..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.ARM.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.ARM.targets')" />
|
<Import Project="..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.ARM.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.ARM.targets" Condition="Exists('..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.ARM.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.ARM.targets')" />
|
||||||
<Import Project="..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x64.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x64.targets" Condition="Exists('..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x64.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x64.targets')" />
|
<Import Project="..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x64.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x64.targets" Condition="Exists('..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x64.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x64.targets')" />
|
||||||
<Import Project="..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x86.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x86.targets" Condition="Exists('..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x86.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x86.targets')" />
|
<Import Project="..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x86.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x86.targets" Condition="Exists('..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x86.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x86.targets')" />
|
||||||
<Import Project="..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.targets" Condition="Exists('..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.targets')" />
|
<Import Project="..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.targets" Condition="Exists('..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.2017.08.20170829.001\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.targets')" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<Import Project="..\..\External\libHttpClient\libHttpClient.props" />
|
<Import Project="..\..\External\libHttpClient\libHttpClient.props" />
|
||||||
|
@ -184,7 +184,6 @@
|
||||||
<ClInclude Include="..\..\Source\Services\Common\pch.h" />
|
<ClInclude Include="..\..\Source\Services\Common\pch.h" />
|
||||||
<ClInclude Include="..\..\Source\Services\Common\pch_common.h" />
|
<ClInclude Include="..\..\Source\Services\Common\pch_common.h" />
|
||||||
<ClInclude Include="..\..\Source\Services\Common\taskargs.h" />
|
<ClInclude Include="..\..\Source\Services\Common\taskargs.h" />
|
||||||
<ClInclude Include="..\..\Source\Services\Common\xbox_live_app_config_impl.h" />
|
|
||||||
<ClInclude Include="..\..\Source\Services\Common\xbox_live_context_impl.h" />
|
<ClInclude Include="..\..\Source\Services\Common\xbox_live_context_impl.h" />
|
||||||
<ClInclude Include="..\..\Source\Services\Leaderboard\leaderboard_helper.h" />
|
<ClInclude Include="..\..\Source\Services\Leaderboard\leaderboard_helper.h" />
|
||||||
<ClInclude Include="..\..\Source\Services\Privacy\privacy_multiple_permissions_check_result_impl.h" />
|
<ClInclude Include="..\..\Source\Services\Privacy\privacy_multiple_permissions_check_result_impl.h" />
|
||||||
|
@ -233,6 +232,6 @@
|
||||||
<Error Condition="!Exists('..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.ARM.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.ARM.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.ARM.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.ARM.targets'))" />
|
<Error Condition="!Exists('..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.ARM.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.ARM.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.ARM.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.ARM.targets'))" />
|
||||||
<Error Condition="!Exists('..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x64.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x64.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x64.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x64.targets'))" />
|
<Error Condition="!Exists('..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x64.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x64.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x64.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x64.targets'))" />
|
||||||
<Error Condition="!Exists('..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x86.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x86.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x86.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x86.targets'))" />
|
<Error Condition="!Exists('..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x86.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x86.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x86.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x86.targets'))" />
|
||||||
<Error Condition="!Exists('..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.2017.11.20171204.01\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.targets'))" />
|
<Error Condition="!Exists('..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.2017.08.20170829.001\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\CSharpSource\external\packages\Microsoft.Xbox.Live.SDK.Cpp.UWP.2017.08.20170829.001\build\native\Microsoft.Xbox.Live.SDK.Cpp.UWP.targets'))" />
|
||||||
</Target>
|
</Target>
|
||||||
</Project>
|
</Project>
|
|
@ -75,9 +75,6 @@
|
||||||
<ClInclude Include="..\..\Include\xsapi\xbox_live_app_config_c.h">
|
<ClInclude Include="..\..\Include\xsapi\xbox_live_app_config_c.h">
|
||||||
<Filter>C++ Public Includes</Filter>
|
<Filter>C++ Public Includes</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\Source\Services\Common\xbox_live_app_config_impl.h">
|
|
||||||
<Filter>C++ Source\Services\Common</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\Source\Shared\utils.h">
|
<ClInclude Include="..\..\Source\Shared\utils.h">
|
||||||
<Filter>C++ Source\Shared</Filter>
|
<Filter>C++ Source\Shared</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче