Tons of cleanup working preperation for preview release (#178)

This commit is contained in:
John L 2017-12-15 11:37:26 -08:00 коммит произвёл GitHub
Родитель d75ae9d4d4
Коммит a0570b8eef
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
106 изменённых файлов: 491 добавлений и 3975 удалений

Просмотреть файл

@ -56,7 +56,7 @@ public class XboxLiveConfigurationEditor : EditorWindow
if (this.configuration != null)
{
if (string.IsNullOrEmpty(this.configuration.PrimaryServiceConfigId) || this.configuration.TitleId == 0 || string.IsNullOrEmpty(this.configuration.AppId))
if (string.IsNullOrEmpty(this.configuration.ServiceConfigurationId) || this.configuration.TitleId == 0 || string.IsNullOrEmpty(this.configuration.AppId))
{
EditorGUILayout.HelpBox("Your Xbox Live configuration appears invalid. You will need to re-associate your game before you can create a finished build.", MessageType.Warning, true);
}
@ -67,7 +67,7 @@ public class XboxLiveConfigurationEditor : EditorWindow
PropertyLabel("Publisher", this.configuration.PublisherDisplayName);
PropertyLabel("App ID", this.configuration.AppId);
PropertyLabel("Product Family Name", this.configuration.ProductFamilyName);
PropertyLabel("SCID", this.configuration.PrimaryServiceConfigId);
PropertyLabel("SCID", this.configuration.ServiceConfigurationId);
PropertyLabel("Title ID", this.configuration.TitleId.ToString());
PropertyLabel("Sandbox", this.configuration.Sandbox);
}

Просмотреть файл

@ -35,7 +35,7 @@ namespace Microsoft.Xbox.Services.ConnectedStorage
if (resultCallBack != null)
{
#if ENABLE_WINMD_SUPPORT
var configId = XboxLive.Instance.AppConfig.PrimaryServiceConfigId;
var configId = XboxLive.Instance.AppConfig.ServiceConfigurationId;
var initTask = GameSaveProvider.GetForUserAsync(xboxLiveUser.WindowsSystemUser, configId).AsTask();
if (initTask.Result.Status == GameSaveErrorStatus.Ok)
{

Просмотреть файл

@ -64,7 +64,7 @@ public class UserProfile : MonoBehaviour
public void Start()
{
// Disable the sign-in button if there's no configuration available.
if (XboxLive.Instance.AppConfig == null || XboxLive.Instance.AppConfig.AppId == null)
if (XboxLive.Instance.AppConfig == null || XboxLive.Instance.AppConfig.ServiceConfigurationId == null)
{
this.ConfigAvailable = false;
@ -86,7 +86,7 @@ public class UserProfile : MonoBehaviour
{
XboxLiveUserManager.Instance.UserForSingleUserMode = Instantiate(this.XboxLiveUserPrefab);
this.XboxLiveUser = XboxLiveUserManager.Instance.UserForSingleUserMode;
if (XboxLive.Instance.AppConfig != null && XboxLive.Instance.AppConfig.AppId != null)
if (XboxLive.Instance.AppConfig != null && XboxLive.Instance.AppConfig.ServiceConfigurationId != null)
{
this.SignIn();
}

Просмотреть файл

@ -44,8 +44,6 @@ public class XboxLiveUserInfo : MonoBehaviour
}
}
}
MockXboxLiveData.Load(Path.Combine(Application.dataPath, "MockData.json"));
}
public void Initialize()

1
CSharpSource/.gitignore поставляемый
Просмотреть файл

@ -49,6 +49,7 @@ External/**/lib/
External/**/bin/
External/**/Debug/
External/**/Release/
Tests/**/*.dll
**/*.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*{b7130c4b-b36b-4449-80b0-60037fc2e0cd}*SharedItemsImports = 4
api\Microsoft.Xbox.Services.Shared.projitems*{cbd81e44-f37f-47d6-b71b-a43a748ae09c}*SharedItemsImports = 4
api\Microsoft.Xbox.Services.Shared.projitems*{cfb2ca8f-6611-4dca-981c-4b7afcca19a8}*SharedItemsImports = 4
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
@ -165,6 +166,54 @@ Global
{4C1806D5-7279-4DFC-8874-13D66D52A31B}.ReleaseNET35|ARM.ActiveCfg = Release|ARM
{4C1806D5-7279-4DFC-8874-13D66D52A31B}.ReleaseNET35|x64.ActiveCfg = Release|x64
{4C1806D5-7279-4DFC-8874-13D66D52A31B}.ReleaseNET35|x86.ActiveCfg = Release|x86
{8F96710E-5169-4917-8874-7DE248F4D243}.Debug|ARM.ActiveCfg = Debug|ARM
{8F96710E-5169-4917-8874-7DE248F4D243}.Debug|ARM.Build.0 = Debug|ARM
{8F96710E-5169-4917-8874-7DE248F4D243}.Debug|x64.ActiveCfg = Debug|x64
{8F96710E-5169-4917-8874-7DE248F4D243}.Debug|x64.Build.0 = Debug|x64
{8F96710E-5169-4917-8874-7DE248F4D243}.Debug|x86.ActiveCfg = Debug|Win32
{8F96710E-5169-4917-8874-7DE248F4D243}.Debug|x86.Build.0 = Debug|Win32
{8F96710E-5169-4917-8874-7DE248F4D243}.DebugNET35|ARM.ActiveCfg = Debug|ARM
{8F96710E-5169-4917-8874-7DE248F4D243}.DebugNET35|ARM.Build.0 = Debug|ARM
{8F96710E-5169-4917-8874-7DE248F4D243}.DebugNET35|x64.ActiveCfg = Debug|x64
{8F96710E-5169-4917-8874-7DE248F4D243}.DebugNET35|x64.Build.0 = Debug|x64
{8F96710E-5169-4917-8874-7DE248F4D243}.DebugNET35|x86.ActiveCfg = Debug|Win32
{8F96710E-5169-4917-8874-7DE248F4D243}.DebugNET35|x86.Build.0 = Debug|Win32
{8F96710E-5169-4917-8874-7DE248F4D243}.Release|ARM.ActiveCfg = Release|ARM
{8F96710E-5169-4917-8874-7DE248F4D243}.Release|ARM.Build.0 = Release|ARM
{8F96710E-5169-4917-8874-7DE248F4D243}.Release|x64.ActiveCfg = Release|x64
{8F96710E-5169-4917-8874-7DE248F4D243}.Release|x64.Build.0 = Release|x64
{8F96710E-5169-4917-8874-7DE248F4D243}.Release|x86.ActiveCfg = Release|Win32
{8F96710E-5169-4917-8874-7DE248F4D243}.Release|x86.Build.0 = Release|Win32
{8F96710E-5169-4917-8874-7DE248F4D243}.ReleaseNET35|ARM.ActiveCfg = Release|ARM
{8F96710E-5169-4917-8874-7DE248F4D243}.ReleaseNET35|ARM.Build.0 = Release|ARM
{8F96710E-5169-4917-8874-7DE248F4D243}.ReleaseNET35|x64.ActiveCfg = Release|x64
{8F96710E-5169-4917-8874-7DE248F4D243}.ReleaseNET35|x64.Build.0 = Release|x64
{8F96710E-5169-4917-8874-7DE248F4D243}.ReleaseNET35|x86.ActiveCfg = Release|Win32
{8F96710E-5169-4917-8874-7DE248F4D243}.ReleaseNET35|x86.Build.0 = Release|Win32
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Debug|ARM.ActiveCfg = Debug|ARM
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Debug|ARM.Build.0 = Debug|ARM
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Debug|x64.ActiveCfg = Debug|x64
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Debug|x64.Build.0 = Debug|x64
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Debug|x86.ActiveCfg = Debug|Win32
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Debug|x86.Build.0 = Debug|Win32
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.DebugNET35|ARM.ActiveCfg = Debug|ARM
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.DebugNET35|ARM.Build.0 = Debug|ARM
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.DebugNET35|x64.ActiveCfg = Debug|x64
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.DebugNET35|x64.Build.0 = Debug|x64
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.DebugNET35|x86.ActiveCfg = Debug|Win32
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.DebugNET35|x86.Build.0 = Debug|Win32
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Release|ARM.ActiveCfg = Release|ARM
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Release|ARM.Build.0 = Release|ARM
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Release|x64.ActiveCfg = Release|x64
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Release|x64.Build.0 = Release|x64
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Release|x86.ActiveCfg = Release|Win32
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.Release|x86.Build.0 = Release|Win32
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.ReleaseNET35|ARM.ActiveCfg = Release|ARM
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.ReleaseNET35|ARM.Build.0 = Release|ARM
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.ReleaseNET35|x64.ActiveCfg = Release|x64
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.ReleaseNET35|x64.Build.0 = Release|x64
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.ReleaseNET35|x86.ActiveCfg = Release|Win32
{1B0DFB7F-2CD5-48DE-80D4-5CC56C22AEEE}.ReleaseNET35|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Просмотреть файл

@ -29,7 +29,6 @@ namespace Microsoft.Xbox.Services.System
public string AgeGroup { get; set; }
public string Privileges { get; set; }
public string WebAccountId { get; set; }
public AuthConfig AuthConfig { get; set; }
public IntPtr XboxLiveUserPtr { get; }
public Task<SignInResult> SignInImpl(bool showUI, bool forceRefresh)
@ -37,10 +36,10 @@ namespace Microsoft.Xbox.Services.System
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(';');
return Task.FromResult(new TokenAndSignatureResult
return Task.FromResult(new GetTokenAndSignatureResult
{
Gamertag = this.Gamertag,
XboxUserId = this.XboxUserId,

Просмотреть файл

@ -3,17 +3,11 @@
//
namespace Microsoft.Xbox.Services
{
public partial class XboxLive
{
public static bool UseMockServices
{
get { return false; }
}
public static bool UseMockHttp
{
get { return true; }
}
}
}

Просмотреть файл

@ -5,11 +5,11 @@ namespace Microsoft.Xbox.Services
{
public partial class XboxLiveAppConfiguration
{
public static XboxLiveAppConfiguration Load(string path)
private static XboxLiveAppConfiguration Load()
{
return new XboxLiveAppConfiguration
{
PrimaryServiceConfigId = "00000000-0000-0000-0000-0000694f5acb",
ServiceConfigurationId = "00000000-0000-0000-0000-0000694f5acb",
TitleId = 1766808267,
Environment = string.Empty,
Sandbox = "JDTDWX.0",

Просмотреть файл

@ -9,10 +9,5 @@ namespace Microsoft.Xbox.Services
{
get { return false; }
}
public static bool UseMockHttp
{
get { return false; }
}
}
}

Просмотреть файл

@ -4,28 +4,43 @@
namespace Microsoft.Xbox.Services
{
using global::System.IO;
using global::Microsoft.Xbox.Services.System;
using global::System;
using global::System.Runtime.InteropServices;
public partial class XboxLiveAppConfiguration
{
public static XboxLiveAppConfiguration Load(string path)
private static XboxLiveAppConfiguration Load()
{
Windows.ApplicationModel.Package package = Windows.ApplicationModel.Package.Current;
Windows.Storage.StorageFolder installedLocation = package.InstalledLocation;
string fullPath = Path.Combine(installedLocation.Path, path);
if (!File.Exists(fullPath))
IntPtr appConfigPtr;
var result = GetXboxLiveAppConfigSingleton(out appConfigPtr);
if (result != XSAPI_RESULT.XSAPI_RESULT_OK)
{
throw new FileNotFoundException(string.Format("Unable to find Xbox Live app configuration file '{0}'.", path));
throw new XboxException(result);
}
string content = File.ReadAllText(fullPath);
if (string.IsNullOrWhiteSpace(content))
{
throw new XboxException(string.Format("Xbox Live app configeration file '{0}' was empty.", path));
}
var appConfigStruct = Marshal.PtrToStructure<XSAPI_XBOX_LIVE_APP_CONFIG>(appConfigPtr);
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
{
using global::System.Threading.Tasks;
using Microsoft.Xbox.Services.System;
public partial class XboxLiveUser
@ -14,41 +13,51 @@ namespace Microsoft.Xbox.Services
public XboxLiveUser(Windows.System.User systemUser)
{
var user = new UserImpl(systemUser);
var userImpl = new UserImpl(systemUser);
this.userImpl = userImpl;
// The UserImpl monitors the underlying system for sign out events
// and notifies us that a user has been signed out. We can then
// pass that event on the application with a concrete reference.
user.SignInCompleted += (sender, args) =>
userImpl.SignInCompleted += (sender, args) =>
{
OnSignInCompleted(this);
if (SignInCompleted != null)
{
SignInCompleted(null, new SignInCompletedEventArgs(this));
}
};
user.SignOutCompleted += (sender, args) =>
userImpl.SignOutCompleted += (sender, args) =>
{
OnSignOutCompleted(this);
if (SignOutCompleted != null)
{
SignOutCompleted(null, new SignOutCompletedEventArgs(this));
}
};
this.userImpl = user;
}
internal XboxLiveUser(global::System.IntPtr xboxLiveUserPtr)
{
var user = new UserImpl(xboxLiveUserPtr);
var userImpl = new UserImpl(xboxLiveUserPtr);
this.userImpl = userImpl;
// The UserImpl monitors the underlying system for sign out events
// and notifies us that a user has been signed out. We can then
// pass that event on the application with a concrete reference.
user.SignInCompleted += (sender, args) =>
userImpl.SignInCompleted += (sender, args) =>
{
OnSignInCompleted(this);
if (SignInCompleted != null)
{
SignInCompleted(null, new SignInCompletedEventArgs(this));
}
};
user.SignOutCompleted += (sender, args) =>
userImpl.SignOutCompleted += (sender, args) =>
{
OnSignOutCompleted(this);
if (SignOutCompleted != null)
{
SignOutCompleted(null, new SignOutCompletedEventArgs(this));
}
};
this.userImpl = user;
user.UpdatePropertiesFromXboxLiveUserPtr();
userImpl.UpdatePropertiesFromXboxLiveUserPtr();
}
public Windows.System.User WindowsSystemUser
@ -63,20 +72,5 @@ namespace Microsoft.Xbox.Services
{
get { return (this.userImpl as UserImpl); }
}
internal static void CleanupEventHandler()
{
foreach (var eh in signInDelegates)
{
InternalSignInCompleted -= eh;
}
signInDelegates.Clear();
foreach (var eh in signOutDelegates)
{
InternalSignOutCompleted -= eh;
}
signOutDelegates.Clear();
}
}
}

Просмотреть файл

@ -100,7 +100,6 @@
<Compile Include="Statistics\Manager\StatisticEvent.cs" />
<Compile Include="Statistics\Manager\StatisticManager.cs" />
<Compile Include="System\TitleCallableUI.cs" />
<Compile Include="System\TokenRequestResult.cs" />
<Compile Include="System\UserImpl.cs" />
<Compile Include="Common\XboxLiveUser.cs" />
<Compile Include="Common\XboxLiveAppConfiguration.cs" />

Просмотреть файл

@ -6,7 +6,6 @@ namespace Microsoft.Xbox.Services.Social.Manager
using global::System;
using global::System.Collections.Generic;
using global::System.Runtime.InteropServices;
using Microsoft.Xbox.Services.Presence;
using System;
public partial class SocialManager : ISocialManager
@ -26,19 +25,14 @@ namespace Microsoft.Xbox.Services.Social.Manager
{
if (user == null) throw new ArgumentNullException("user");
// Allocates memory for returned objects
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cErrMessage;
// Invokes the c method
XSAPI_RESULT errCode = SocialManagerAddLocalUser(user.Impl.XboxLiveUserPtr, extraDetailLevel, cErrMessage);
XSAPI_RESULT errCode = SocialManagerAddLocalUser(user.Impl.XboxLiveUserPtr, extraDetailLevel, out cErrMessage);
// Handles error
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
Marshal.FreeHGlobal(cErrMessage);
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
{
// todo do something
throw new XboxException(errCode, cErrMessage);
}
m_localUsers.Add(user);
@ -48,19 +42,13 @@ namespace Microsoft.Xbox.Services.Social.Manager
{
if (user == null) throw new ArgumentNullException("user");
// Allocates memory for returned objects
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cErrMessage;
// Invokes the c method
XSAPI_RESULT errCode = SocialManagerRemoveLocalUser(user.Impl.XboxLiveUserPtr, cErrMessage);
// Handles error
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
Marshal.FreeHGlobal(cErrMessage);
XSAPI_RESULT errCode = SocialManagerRemoveLocalUser(user.Impl.XboxLiveUserPtr, out cErrMessage);
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
{
// todo do something
throw new XboxException(errCode, cErrMessage);
}
m_localUsers.Remove(user);
@ -70,25 +58,18 @@ namespace Microsoft.Xbox.Services.Social.Manager
{
if (user == null) throw new ArgumentNullException("user");
// Allocates memory for returned objects
IntPtr cGroupPtr = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cGroupPtr;
IntPtr cErrMessage;
// Invokes the c method
XSAPI_RESULT errCode = SocialManagerCreateSocialUserGroupFromFilters(user.Impl.XboxLiveUserPtr, presenceFilter, relationshipFilter, cGroupPtr, cErrMessage);
// Handles error
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
Marshal.FreeHGlobal(cErrMessage);
XSAPI_RESULT errCode = SocialManagerCreateSocialUserGroupFromFilters(user.Impl.XboxLiveUserPtr, presenceFilter, relationshipFilter, out cGroupPtr, out cErrMessage);
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
{
// todo do something
throw new XboxException(errCode, cErrMessage);
}
// Handles returned objects
XboxSocialUserGroup socialUserGroup = new XboxSocialUserGroup(Marshal.ReadIntPtr(cGroupPtr));
Marshal.FreeHGlobal(cGroupPtr);
XboxSocialUserGroup socialUserGroup = new XboxSocialUserGroup(cGroupPtr);
m_groups.Add(socialUserGroup);
return socialUserGroup;
@ -100,41 +81,23 @@ namespace Microsoft.Xbox.Services.Social.Manager
if (xboxUserIdList == null) throw new ArgumentNullException("xboxUserIdList");
// Allocates memory for parameters
List<IntPtr> userIdPtrs = new List<IntPtr>();
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);
IntPtr cUserIds = MarshalingHelpers.StringListToHGlobalUtf8StringArray(xboxUserIdList);
// Allocates memory for returned objects
IntPtr cGroupPtr = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cGroupPtr;
IntPtr cErrMessage;
// Invokes the c method
XSAPI_RESULT errCode = SocialManagerCreateSocialUserGroupFromList(user.Impl.XboxLiveUserPtr, cUserIds, (uint)xboxUserIdList.Count, cGroupPtr, cErrMessage);
// Handles error
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
Marshal.FreeHGlobal(cErrMessage);
XSAPI_RESULT errCode = SocialManagerCreateSocialUserGroupFromList(user.Impl.XboxLiveUserPtr, cUserIds, (uint)xboxUserIdList.Count, out cGroupPtr, out cErrMessage);
MarshalingHelpers.FreeHGlobalUtf8StringArray(cUserIds, xboxUserIdList.Count);
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
{
// todo do something
throw new XboxException(errCode, cErrMessage);
}
// Cleans up parameters
foreach (IntPtr ptr in userIdPtrs)
{
Marshal.FreeHGlobal(ptr);
}
Marshal.FreeHGlobal(cUserIds);
// Handles returned objects
XboxSocialUserGroup socialUserGroup = new XboxSocialUserGroup(Marshal.ReadIntPtr(cGroupPtr));
Marshal.FreeHGlobal(cGroupPtr);
XboxSocialUserGroup socialUserGroup = new XboxSocialUserGroup(cGroupPtr);
m_groups.Add(socialUserGroup);
return socialUserGroup;
@ -146,37 +109,20 @@ namespace Microsoft.Xbox.Services.Social.Manager
if (users == null) throw new ArgumentNullException("users");
// Allocates memory for parameters
List<IntPtr> userIdPtrs = new List<IntPtr>();
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);
IntPtr cUserIds = MarshalingHelpers.StringListToHGlobalUtf8StringArray(users);
// Allocates memory for returned objects
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cErrMessage;
// Invokes the c method
XSAPI_RESULT errCode = SocialManagerUpdateSocialUserGroup(socialGroup.GetPtr(), cUserIds, (uint)users.Count, cErrMessage);
// Handles error
string errMessage = Marshal.PtrToStringUni(Marshal.ReadIntPtr(cErrMessage));
Marshal.FreeHGlobal(cErrMessage);
XSAPI_RESULT errCode = SocialManagerUpdateSocialUserGroup(socialGroup.GetPtr(), cUserIds, (uint)users.Count, out cErrMessage);
MarshalingHelpers.FreeHGlobalUtf8StringArray(cUserIds, users.Count);
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
{
// todo do something
throw new XboxException(errCode, cErrMessage);
}
// Cleans up parameters
foreach (IntPtr ptr in userIdPtrs)
{
Marshal.FreeHGlobal(ptr);
}
Marshal.FreeHGlobal(cUserIds);
// Does local work
socialGroup.Refresh();
}
@ -184,39 +130,27 @@ namespace Microsoft.Xbox.Services.Social.Manager
public void DestroySocialUserGroup(XboxSocialUserGroup xboxSocialUserGroup)
{
if (xboxSocialUserGroup == null) throw new ArgumentNullException("xboxSocialUserGroup");
// Allocates memory for returned objects
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cErrMessage;
// Invokes the c method
XSAPI_RESULT errCode = SocialManagerDestroySocialUserGroup(xboxSocialUserGroup.GetPtr(), cErrMessage);
// Handles error
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
Marshal.FreeHGlobal(cErrMessage);
XSAPI_RESULT errCode = SocialManagerDestroySocialUserGroup(xboxSocialUserGroup.GetPtr(), out cErrMessage);
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
{
// todo do something
throw new XboxException(errCode, cErrMessage);
}
// Does local work
m_groups.Remove(xboxSocialUserGroup);
}
public IList<SocialEvent> DoWork()
{
// Allocates memory for returned objects
IntPtr cEventsCount = Marshal.AllocHGlobal(Marshal.SizeOf<Int32>());
UInt32 eventsCount;
// Invokes the c method
IntPtr eventsPtr = SocialManagerDoWork(cEventsCount);
// Does local work
uint eventsCount = (uint)Marshal.ReadInt32(cEventsCount);
Marshal.FreeHGlobal(cEventsCount);
IntPtr eventsPtr = SocialManagerDoWork(out eventsCount);
// Does local work
List<SocialEvent> events = new List<SocialEvent>();
if (eventsCount > 0)
@ -250,19 +184,13 @@ namespace Microsoft.Xbox.Services.Social.Manager
{
if (user == null) throw new ArgumentNullException("user");
// Allocates memory for returned objects
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cErrMessage;
// Invokes the c method
XSAPI_RESULT errCode = SocialManagerSetRichPresencePollingStatus(user.Impl.XboxLiveUserPtr, shouldEnablePolling, cErrMessage);
// Handles error
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
Marshal.FreeHGlobal(cErrMessage);
XSAPI_RESULT errCode = SocialManagerSetRichPresencePollingStatus(user.Impl.XboxLiveUserPtr, shouldEnablePolling, out cErrMessage);
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
{
// todo do something
throw new XboxException(errCode, cErrMessage);
}
// Does local work
@ -271,28 +199,28 @@ namespace Microsoft.Xbox.Services.Social.Manager
// Marshaling
[DllImport(XboxLive.FlatCDllName)]
private static extern XSAPI_RESULT SocialManagerAddLocalUser(IntPtr user, SocialManagerExtraDetailLevel extraDetailLevel, IntPtr errMessage);
private static extern XSAPI_RESULT SocialManagerAddLocalUser(IntPtr user, SocialManagerExtraDetailLevel extraDetailLevel, out IntPtr errMessage);
[DllImport(XboxLive.FlatCDllName)]
private static extern XSAPI_RESULT SocialManagerRemoveLocalUser(IntPtr user, IntPtr errMessage);
private static extern XSAPI_RESULT SocialManagerRemoveLocalUser(IntPtr user, out IntPtr errMessage);
[DllImport(XboxLive.FlatCDllName)]
private static extern XSAPI_RESULT SocialManagerCreateSocialUserGroupFromFilters(IntPtr user, PresenceFilter presenceDetailFilter, RelationshipFilter filter, IntPtr returnGroup, IntPtr errMessage);
private static extern XSAPI_RESULT SocialManagerCreateSocialUserGroupFromFilters(IntPtr user, PresenceFilter presenceDetailFilter, RelationshipFilter filter, out IntPtr returnGroup, out IntPtr errMessage);
[DllImport(XboxLive.FlatCDllName)]
private static extern XSAPI_RESULT SocialManagerCreateSocialUserGroupFromList(IntPtr group, IntPtr users, UInt32 usersCount, IntPtr returnGroup, IntPtr errMessage);
private static extern XSAPI_RESULT SocialManagerCreateSocialUserGroupFromList(IntPtr group, IntPtr users, UInt32 usersCount, out IntPtr returnGroup, out IntPtr errMessage);
[DllImport(XboxLive.FlatCDllName)]
private static extern XSAPI_RESULT SocialManagerUpdateSocialUserGroup(IntPtr group, IntPtr users, UInt32 usersCount, IntPtr errMessage);
private static extern XSAPI_RESULT SocialManagerUpdateSocialUserGroup(IntPtr group, IntPtr users, UInt32 usersCount, out IntPtr errMessage);
[DllImport(XboxLive.FlatCDllName)]
private static extern XSAPI_RESULT SocialManagerDestroySocialUserGroup(IntPtr group, IntPtr errMessage);
private static extern XSAPI_RESULT SocialManagerDestroySocialUserGroup(IntPtr group, out IntPtr errMessage);
[DllImport(XboxLive.FlatCDllName)]
private static extern IntPtr SocialManagerDoWork(IntPtr numOfEvents);
private static extern IntPtr SocialManagerDoWork(out UInt32 numOfEvents);
[DllImport(XboxLive.FlatCDllName)]
private static extern XSAPI_RESULT SocialManagerSetRichPresencePollingStatus(IntPtr user, bool shouldEnablePolling, IntPtr errMessage);
private static extern XSAPI_RESULT SocialManagerSetRichPresencePollingStatus(IntPtr user, bool shouldEnablePolling, out IntPtr errMessage);
[StructLayout(LayoutKind.Sequential)]

Просмотреть файл

@ -12,7 +12,6 @@ namespace Microsoft.Xbox.Services.Social.Manager
TITLE_HISTORY cTitleHistory = Marshal.PtrToStructure<TITLE_HISTORY>(titleHistoryPtr);
HasUserPlayed = cTitleHistory.UserHasPlayed;
// todo test
LastTimeUserPlayed = DateTimeOffset.FromUnixTimeSeconds(cTitleHistory.LastTimeUserPlayed);
}

Просмотреть файл

@ -15,24 +15,18 @@ namespace Microsoft.Xbox.Services.Statistics.Manager
private readonly List<XboxLiveUser> m_localUsers = new List<XboxLiveUser>();
[DllImport(XboxLive.FlatCDllName)]
private static extern XSAPI_RESULT StatsManagerAddLocalUser(IntPtr user, IntPtr errMessage);
private static extern XSAPI_RESULT StatsManagerAddLocalUser(IntPtr user, out IntPtr errMessage);
public void AddLocalUser(XboxLiveUser user)
{
if (user == null) throw new ArgumentNullException("user");
// Allocates memory for returned objects
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cErrMessage;
// Invokes the c method
XSAPI_RESULT errCode = StatsManagerAddLocalUser(user.Impl.XboxLiveUserPtr, cErrMessage);
// Handles error
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
Marshal.FreeHGlobal(cErrMessage);
XSAPI_RESULT errCode = StatsManagerAddLocalUser(user.Impl.XboxLiveUserPtr, out cErrMessage);
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
{
// todo do something
throw new XboxException(errCode, cErrMessage);
}
// Does local work
@ -40,24 +34,18 @@ namespace Microsoft.Xbox.Services.Statistics.Manager
}
[DllImport(XboxLive.FlatCDllName)]
private static extern XSAPI_RESULT StatsManagerRemoveLocalUser(IntPtr user, IntPtr errMessage);
private static extern XSAPI_RESULT StatsManagerRemoveLocalUser(IntPtr user, out IntPtr errMessage);
public void RemoveLocalUser(XboxLiveUser user)
{
if (user == null) throw new ArgumentNullException("user");
// Allocates memory for returned objects
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cErrMessage;
// Invokes the c method
XSAPI_RESULT errCode = StatsManagerRemoveLocalUser(user.Impl.XboxLiveUserPtr, cErrMessage);
// Handles error
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
Marshal.FreeHGlobal(cErrMessage);
XSAPI_RESULT errCode = StatsManagerRemoveLocalUser(user.Impl.XboxLiveUserPtr, out cErrMessage);
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
{
// todo do something
throw new XboxException(errCode, cErrMessage);
}
// Does local work
@ -65,40 +53,29 @@ namespace Microsoft.Xbox.Services.Statistics.Manager
}
[DllImport(XboxLive.FlatCDllName)]
private static extern XSAPI_RESULT StatsManagerRequestFlushToService(IntPtr user, bool isHighPriority, IntPtr errMessage);
private static extern XSAPI_RESULT StatsManagerRequestFlushToService(IntPtr user, bool isHighPriority, out IntPtr errMessage);
public void RequestFlushToService(XboxLiveUser user, bool isHighPriority = false)
{
if (user == null) throw new ArgumentNullException("user");
// Allocates memory for returned objects
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cErrMessage;
// Invokes the c method
XSAPI_RESULT errCode = StatsManagerRequestFlushToService(user.Impl.XboxLiveUserPtr, isHighPriority, cErrMessage);
// Handles error
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
Marshal.FreeHGlobal(cErrMessage);
XSAPI_RESULT errCode = StatsManagerRequestFlushToService(user.Impl.XboxLiveUserPtr, isHighPriority, out cErrMessage);
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
{
// todo do something
throw new XboxException(errCode, cErrMessage);
}
}
[DllImport(XboxLive.FlatCDllName)]
private static extern IntPtr StatsManagerDoWork(IntPtr numOfEvents);
private static extern IntPtr StatsManagerDoWork(out Int32 numOfEvents);
public IList<StatisticEvent> DoWork()
{
// Allocates memory for returned objects
IntPtr cEventsCount = Marshal.AllocHGlobal(Marshal.SizeOf<Int32>());
Int32 eventsCount;
// Invokes the c method
IntPtr eventsPtr = StatsManagerDoWork(cEventsCount);
// Does local work
uint eventsCount = (uint)Marshal.ReadInt32(cEventsCount);
Marshal.FreeHGlobal(cEventsCount);
IntPtr eventsPtr = StatsManagerDoWork(out eventsCount);
List<StatisticEvent> events = new List<StatisticEvent>();
@ -123,176 +100,134 @@ namespace Microsoft.Xbox.Services.Statistics.Manager
}
[DllImport(XboxLive.FlatCDllName)]
private static extern XSAPI_RESULT StatsManagerSetStatisticNumberData(IntPtr user, string statName, double value, IntPtr errMessage);
private static extern XSAPI_RESULT StatsManagerSetStatisticNumberData(IntPtr user, string statName, double value, out IntPtr errMessage);
public void SetStatisticNumberData(XboxLiveUser user, string statName, double value)
{
if (user == null) throw new ArgumentNullException("user");
// Allocates memory for returned objects
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cErrMessage;
// Invokes the c method
XSAPI_RESULT errCode = StatsManagerSetStatisticNumberData(user.Impl.XboxLiveUserPtr, statName, value, cErrMessage);
// Handles error
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
Marshal.FreeHGlobal(cErrMessage);
XSAPI_RESULT errCode = StatsManagerSetStatisticNumberData(user.Impl.XboxLiveUserPtr, statName, value, out cErrMessage);
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
{
// todo do something
throw new XboxException(errCode, cErrMessage);
}
}
[DllImport(XboxLive.FlatCDllName)]
private static extern XSAPI_RESULT StatsManagerSetStatisticIntegerData(IntPtr user, string statName, long value, IntPtr errMessage);
private static extern XSAPI_RESULT StatsManagerSetStatisticIntegerData(IntPtr user, string statName, long value, out IntPtr errMessage);
public void SetStatisticIntegerData(XboxLiveUser user, string statName, long value)
{
// Allocates memory for returned objects
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cErrMessage;
// Invokes the c method
XSAPI_RESULT errCode = StatsManagerSetStatisticIntegerData(user.Impl.XboxLiveUserPtr, statName, value, cErrMessage);
// Handles error
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
Marshal.FreeHGlobal(cErrMessage);
XSAPI_RESULT errCode = StatsManagerSetStatisticIntegerData(user.Impl.XboxLiveUserPtr, statName, value, out cErrMessage);
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
{
// todo do something
throw new XboxException(errCode, cErrMessage);
}
}
[DllImport(XboxLive.FlatCDllName)]
private static extern XSAPI_RESULT StatsManagerSetStatisticStringData(IntPtr user, string statName, string value, IntPtr errMessage);
private static extern XSAPI_RESULT StatsManagerSetStatisticStringData(IntPtr user, string statName, string value, out IntPtr errMessage);
public void SetStatisticStringData(XboxLiveUser user, string statName, string value)
{
// Allocates memory for returned objects
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cErrMessage;
// Invokes the c method
XSAPI_RESULT errCode = StatsManagerSetStatisticStringData(user.Impl.XboxLiveUserPtr, statName, value, cErrMessage);
// Handles error
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
Marshal.FreeHGlobal(cErrMessage);
XSAPI_RESULT errCode = StatsManagerSetStatisticStringData(user.Impl.XboxLiveUserPtr, statName, value, out cErrMessage);
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
{
// todo do something
throw new XboxException(errCode, cErrMessage);
}
}
[DllImport(XboxLive.FlatCDllName)]
private static extern XSAPI_RESULT StatsManagerDeleteStat(IntPtr user, string statName, IntPtr errMessage);
private static extern XSAPI_RESULT StatsManagerDeleteStat(IntPtr user, string statName, out IntPtr errMessage);
public void DeleteStatistic(XboxLiveUser user, string statName)
{
if (user == null) throw new ArgumentNullException("user");
// Allocates memory for returned objects
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cErrMessage;
// Invokes the c method
XSAPI_RESULT errCode = StatsManagerDeleteStat(user.Impl.XboxLiveUserPtr, statName, cErrMessage);
// Handles error
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
Marshal.FreeHGlobal(cErrMessage);
XSAPI_RESULT errCode = StatsManagerDeleteStat(user.Impl.XboxLiveUserPtr, statName, out cErrMessage);
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
{
// todo do something
throw new XboxException(errCode, cErrMessage);
}
}
[DllImport(XboxLive.FlatCDllName)]
private static extern XSAPI_RESULT StatsManagerGetLeaderboard(IntPtr user, string statName, IntPtr query, IntPtr errMessage);
private static extern XSAPI_RESULT StatsManagerGetLeaderboard(IntPtr user, string statName, IntPtr query, out IntPtr errMessage);
public void GetLeaderboard(XboxLiveUser user, string statName, LeaderboardQuery query)
{
if (user == null) throw new ArgumentNullException("user");
// Allocates memory for returned objects
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cErrMessage;
// Invokes the c method
XSAPI_RESULT errCode = StatsManagerGetLeaderboard(user.Impl.XboxLiveUserPtr, statName, query.GetPtr(), cErrMessage);
// Handles error
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
Marshal.FreeHGlobal(cErrMessage);
XSAPI_RESULT errCode = StatsManagerGetLeaderboard(user.Impl.XboxLiveUserPtr, statName, query.GetPtr(), out cErrMessage);
if (errCode > 0)
{
// todo do something
throw new XboxException(errCode, cErrMessage);
}
}
[DllImport(XboxLive.FlatCDllName)]
private static extern XSAPI_RESULT StatsManagerGetSocialLeaderboard(IntPtr user, string statName, string socialGroup, IntPtr query, IntPtr errMessage);
private static extern XSAPI_RESULT StatsManagerGetSocialLeaderboard(IntPtr user, string statName, string socialGroup, IntPtr query, out IntPtr errMessage);
public void GetSocialLeaderboard(XboxLiveUser user, string statName, string socialGroup, LeaderboardQuery query)
{
if (user == null) throw new ArgumentNullException("user");
// Allocates memory for returned objects
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cErrMessage;
// Invokes the c method
XSAPI_RESULT errCode = StatsManagerGetSocialLeaderboard(user.Impl.XboxLiveUserPtr, statName, socialGroup, query.GetPtr(), cErrMessage);
// Handles error
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
Marshal.FreeHGlobal(cErrMessage);
XSAPI_RESULT errCode = StatsManagerGetSocialLeaderboard(user.Impl.XboxLiveUserPtr, statName, socialGroup, query.GetPtr(), out cErrMessage);
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
{
// todo do something
throw new XboxException(errCode, cErrMessage);
}
}
[DllImport(XboxLive.FlatCDllName)]
private static extern XSAPI_RESULT StatsManagerGetStat(IntPtr user, IntPtr statName, IntPtr statValue, IntPtr errMessage);
private static extern XSAPI_RESULT StatsManagerGetStat(IntPtr user, IntPtr statName, out IntPtr statValue, out IntPtr errMessage);
public StatisticValue GetStatistic(XboxLiveUser user, string statName)
{
if (user == null) throw new ArgumentNullException("user");
// Allocates memory for returned objects
IntPtr cStatValue = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cStatName = Marshal.StringToHGlobalAnsi(statName);
IntPtr cStatValue;
IntPtr cErrMessage;
IntPtr cStatName = MarshalingHelpers.StringToHGlobalUtf8(statName);
// Invokes the c method
XSAPI_RESULT errCode = StatsManagerGetStat(user.Impl.XboxLiveUserPtr, cStatName, cStatValue, cErrMessage);
// Handles error
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
Marshal.FreeHGlobal(cErrMessage);
XSAPI_RESULT errCode = StatsManagerGetStat(user.Impl.XboxLiveUserPtr, cStatName, out cStatValue, out cErrMessage);
Marshal.FreeHGlobal(cStatName);
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
{
// todo do something
throw new XboxException(errCode, cErrMessage);
}
// Handles returned objects
StatisticValue statValue = new StatisticValue(Marshal.ReadIntPtr(cStatValue));
Marshal.FreeHGlobal(cStatValue);
StatisticValue statValue = new StatisticValue(cStatValue);
return statValue;
}
[DllImport(XboxLive.FlatCDllName)]
private static extern XSAPI_RESULT StatsManagerGetStatNames(IntPtr user, IntPtr statNameList, IntPtr statNameListCount, IntPtr errMessage);
private static extern XSAPI_RESULT StatsManagerGetStatNames(IntPtr user, out IntPtr statNameList, out UInt32 statNameListCount, out IntPtr errMessage);
public IList<string> GetStatisticNames(XboxLiveUser user)
{
if (user == null) throw new ArgumentNullException("user");
// Allocates memory for returned objects
IntPtr cStatListPtr = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cStatListCount = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cErrMessage = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
IntPtr cStatListPtr;
UInt32 statListCount;
IntPtr cErrMessage;
// Invokes the c method
XSAPI_RESULT errCode = StatsManagerGetStatNames(user.Impl.XboxLiveUserPtr, cStatListPtr, cStatListCount, cErrMessage);
XSAPI_RESULT errCode = StatsManagerGetStatNames(user.Impl.XboxLiveUserPtr, out cStatListPtr, out statListCount, out cErrMessage);
// Handles error
string errMessage = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(cErrMessage));
@ -300,29 +235,9 @@ namespace Microsoft.Xbox.Services.Statistics.Manager
if (errCode != XSAPI_RESULT.XSAPI_RESULT_OK)
{
// todo do something
throw new XboxException(errCode, cErrMessage);
}
// Handles returned objects
uint statListCount = (uint)Marshal.ReadInt32(cStatListCount);
Marshal.FreeHGlobal(cStatListCount);
List<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;
return MarshalingHelpers.Utf8StringArrayToStringList(cStatListPtr, statListCount);
}
}
}

Просмотреть файл

@ -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 Privileges { get; private set; }
public string WebAccountId { get; private set; }
public AuthConfig AuthConfig { get; private set; } // TODO remove this
public User CreationContext { get; private set; }
public IntPtr XboxLiveUserPtr { get; private set; }
@ -48,7 +47,6 @@ namespace Microsoft.Xbox.Services.System
{
throw new XboxException(result);
}
Init();
}
@ -62,16 +60,7 @@ namespace Microsoft.Xbox.Services.System
{
signOutHandlerContext = AddSignOutCompletedHandler(OnSignOutCompleted);
xboxLiveUserInstanceMap[XboxLiveUserPtr] = this;
// TODO: This config is broken.
var appConfig = XboxLiveAppConfiguration.Instance;
this.AuthConfig = new AuthConfig
{
Sandbox = appConfig.Sandbox,
EnvironmentPrefix = appConfig.EnvironmentPrefix,
Environment = appConfig.Environment,
UseCompactTicket = appConfig.UseFirstPartyToken
};
var appConfig = XboxLiveAppConfiguration.SingletonInstance;
}
~UserImpl()
@ -177,9 +166,9 @@ namespace Microsoft.Xbox.Services.System
}
}
public Task<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(() =>
{
@ -196,7 +185,7 @@ namespace Microsoft.Xbox.Services.System
}
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 };
var result = XboxLiveUserGetTokenAndSignature(
@ -223,12 +212,12 @@ namespace Microsoft.Xbox.Services.System
{
int contextKey = context.ToInt32();
XsapiCallbackContext<UserImpl, TokenAndSignatureResult> contextObject;
if (XsapiCallbackContext<UserImpl, TokenAndSignatureResult>.TryRemove(contextKey, out contextObject))
XsapiCallbackContext<UserImpl, GetTokenAndSignatureResult> contextObject;
if (XsapiCallbackContext<UserImpl, GetTokenAndSignatureResult>.TryRemove(contextKey, out contextObject))
{
if (result.errorCode == XSAPI_RESULT.XSAPI_RESULT_OK)
{
contextObject.TaskCompletionSource.SetResult(new TokenAndSignatureResult
contextObject.TaskCompletionSource.SetResult(new GetTokenAndSignatureResult
{
WebAccountId = MarshalingHelpers.Utf8ToString(payload.WebAccountId),
Privileges = MarshalingHelpers.Utf8ToString(payload.Privileges),
@ -237,7 +226,6 @@ namespace Microsoft.Xbox.Services.System
XboxUserId = MarshalingHelpers.Utf8ToString(payload.XboxUserId),
Signature = MarshalingHelpers.Utf8ToString(payload.Signature),
Token = MarshalingHelpers.Utf8ToString(payload.Token)
//TokenRequestResultStatus = tokenResult.ResponseStatus // TODO
});
}
else
@ -333,7 +321,7 @@ namespace Microsoft.Xbox.Services.System
[StructLayout(LayoutKind.Sequential)]
private struct XSAPI_SIGN_IN_RESULT
{
{
public SignInStatus status;
}

Просмотреть файл

@ -4,16 +4,10 @@
namespace Microsoft.Xbox.Services.UWP.UnitTests
{
using global::System;
using Windows.System;
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using Microsoft.Xbox.Services.System;
using global::System.Linq;
using Moq;
using global::System.Threading.Tasks;
using UITestMethod = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.AppContainer.UITestMethodAttribute;
using Windows.Security.Authentication.Web.Core;
using global::System.Collections.Generic;
using global::System.Threading;
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using Windows.System;
[TestClass]
public class UserTest
@ -30,28 +24,9 @@ namespace Microsoft.Xbox.Services.UWP.UnitTests
private const int mockErrorcode = 9999;
private const string mockErrorMessage = "mock error message";
private TokenRequestResult CreateSuccessTokenResponse()
{
var result = new TokenRequestResult(null);
result.ResponseStatus = WebTokenRequestStatus.Success;
result.Token = mockToken;
result.WebAccountId = mockWebAccountId;
result.Properties = new Dictionary<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]
public void Cleanup()
{
XboxLiveUser.CleanupEventHandler();
}
[TestCategory("XboxLiveUser")]
@ -71,156 +46,5 @@ namespace Microsoft.Xbox.Services.UWP.UnitTests
var xbluser = new XboxLiveUser(systemUser);
Assert.AreEqual(systemUser.NonRoamableId, xbluser.WindowsSystemUser.NonRoamableId);
}
[TestCategory("XboxLiveUser")]
[TestMethod]
public async Task UserSigninSilentlySuccess()
{
var user = new XboxLiveUser();
Assert.IsFalse(user.IsSignedIn);
AutoResetEvent signinEvent = new AutoResetEvent(false);
XboxLiveUser.SignInCompleted += (Object o, SignInCompletedEventArgs args) =>
{
Assert.AreEqual(args.User, user);
signinEvent.Set();
};
var response = CreateSuccessTokenResponse();
// Create xbl user with system user
var silentResult = await user.SignInSilentlyAsync();
Assert.AreEqual(silentResult.Status, SignInStatus.Success);
Assert.IsTrue(user.IsSignedIn);
Assert.AreEqual(user.Gamertag, mockGamerTag);
Assert.AreEqual(user.XboxUserId, mockXuid);
Assert.AreEqual(user.AgeGroup, mockAgeGroup);
Assert.AreEqual(user.Privileges, mockPrivileges);
Assert.AreEqual(user.WebAccountId, mockWebAccountId);
Assert.IsTrue(signinEvent.WaitOne(100), "wait signin event time out");
}
[TestCategory("XboxLiveUser")]
[TestMethod]
public async Task UserSigninWithUiSuccess()
{
var user = new XboxLiveUser();
Assert.IsFalse(user.IsSignedIn);
AutoResetEvent signinEvent = new AutoResetEvent(false);
XboxLiveUser.SignInCompleted += ((Object o, SignInCompletedEventArgs args) =>
{
Assert.AreEqual(args.User, user);
signinEvent.Set();
});
var response = CreateSuccessTokenResponse();
var signinResult = await user.SignInAsync();
Assert.AreEqual(signinResult.Status, SignInStatus.Success);
Assert.IsTrue(user.IsSignedIn);
Assert.AreEqual(user.Gamertag, mockGamerTag);
Assert.AreEqual(user.XboxUserId, mockXuid);
Assert.AreEqual(user.AgeGroup, mockAgeGroup);
Assert.AreEqual(user.Privileges, mockPrivileges);
Assert.AreEqual(user.WebAccountId, mockWebAccountId);
Assert.IsTrue(signinEvent.WaitOne(100), "wait signin event time out");
}
[TestCategory("XboxLiveUser")]
[TestMethod]
public async Task UserSigninSilentlyUserInteractionRequired()
{
var user = new XboxLiveUser();
var result = new TokenRequestResult(null);
result.ResponseStatus = WebTokenRequestStatus.UserInteractionRequired;
var signinResult = await user.SignInSilentlyAsync();
Assert.AreEqual(signinResult.Status, SignInStatus.UserInteractionRequired);
Assert.IsFalse(user.IsSignedIn);
}
[TestCategory("XboxLiveUser")]
[TestMethod]
public async Task UserSigninUIUserCancel()
{
var user = new XboxLiveUser();
var result = new TokenRequestResult(null);
result.ResponseStatus = WebTokenRequestStatus.UserCancel;
var signinResult = await user.SignInAsync();
Assert.AreEqual(signinResult.Status, SignInStatus.UserCancel);
Assert.IsFalse(user.IsSignedIn);
}
[TestCategory("XboxLiveUser")]
[TestMethod]
public async Task UserSigninProviderError()
// provider error
{
var user = new XboxLiveUser();
var result = new TokenRequestResult(null);
result.ResponseStatus = WebTokenRequestStatus.ProviderError;
result.ResponseError = new WebProviderError(mockErrorcode, mockErrorMessage);
// ProviderError will convert to exception
try
{
var silentResult = await user.SignInSilentlyAsync();
}
catch (XboxException ex)
{
Assert.AreEqual(ex.HResult, mockErrorcode);
Assert.IsFalse(string.IsNullOrEmpty(ex.Message));
Assert.IsFalse(user.IsSignedIn);
return;
}
Assert.Fail("No exception was thrown.");
}
[TestCategory("XboxLiveUser")]
[TestMethod]
public async Task UserSignOut()
// provider error
{
var user = new XboxLiveUser();
Assert.IsFalse(user.IsSignedIn);
AutoResetEvent signoutEvent = new AutoResetEvent(false);
XboxLiveUser.SignOutCompleted += ((Object o, SignOutCompletedEventArgs args) =>
{
Assert.AreEqual(args.User, user);
signoutEvent.Set();
});
var successResponse = CreateSuccessTokenResponse();
var errorResponse = new TokenRequestResult(null);
errorResponse.ResponseStatus = WebTokenRequestStatus.UserInteractionRequired;
var silentResult = await user.SignInSilentlyAsync();
Assert.AreEqual(silentResult.Status, SignInStatus.Success);
Assert.IsTrue(user.IsSignedIn);
try
{
var token = await user.GetTokenAndSignatureAsync("GET", "", "");
}
catch(XboxException ex)
{
Assert.IsFalse(string.IsNullOrEmpty(ex.Message));
Assert.IsFalse(user.IsSignedIn);
Assert.IsTrue(signoutEvent.WaitOne(100), "wait signout event time out");
return;
}
Assert.Fail("No exception was thrown.");
}
}
}

Просмотреть файл

@ -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>
</Choose>
<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="Properties\AssemblyInfo.cs" />
<Compile Include="Stats\StatsManagerTests.cs" />
@ -73,22 +69,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="Leaderboards\MockDataForLeaderboardTests.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="TitleStorage\TitleStorageUT.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<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">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</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()
{
base.TestInitialize();
MockXboxLiveData.Load(Environment.CurrentDirectory + "\\Social\\SocialManagerUT.json");
}
[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; }
}
public static bool UseMockHttp
{
get { return false; }
}
}
}

Просмотреть файл

@ -4,10 +4,30 @@
namespace Microsoft.Xbox.Services
{
using Newtonsoft.Json;
using global::System.IO;
public partial class XboxLiveAppConfiguration
{
public string PublisherId { get; set; }
public string PublisherDisplayName { get; set; }
public string PackageIdentityName { get; set; }
public string DisplayName { get; set; }
public string AppId { get; set; }
public string ProductFamilyName { get; set; }
public bool XboxLiveCreatorsTitle { get; set; }
private static XboxLiveAppConfiguration Load()
{
return XboxLiveAppConfiguration.Load(FileName);
}
public static XboxLiveAppConfiguration Load(string path)
{
if (!File.Exists(path))
@ -21,7 +41,7 @@ namespace Microsoft.Xbox.Services
throw new XboxException(string.Format("Xbox Live app configeration file '{0}' was empty.", path));
}
return JsonSerialization.FromJson<XboxLiveAppConfiguration>(content);
return JsonConvert.DeserializeObject<XboxLiveAppConfiguration>(content);
}
}
}

Просмотреть файл

@ -1,5 +1,6 @@
// Copyright (c) Microsoft Corporation
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
namespace Microsoft.Xbox.Services.Leaderboard
{

Просмотреть файл

@ -1,12 +1,15 @@

using System;
// Copyright (c) Microsoft Corporation
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
namespace Microsoft.Xbox.Services.Leaderboard
{
using global::System;
class LeaderboardQueryUnityEditorImpl : ILeaderboardQueryImpl
{
public IntPtr GetPtr() { return IntPtr.Zero; }
uint m_maxItems;
public uint GetMaxItems()
{

Просмотреть файл

@ -16,11 +16,10 @@ namespace Microsoft.Xbox.Services.System
public string AgeGroup { get; set; }
public string Privileges { get; set; }
public string WebAccountId { get; set; }
public AuthConfig AuthConfig { get; set; }
private static int numberOfInstances;
private static Random random = new Random();
public Task<SignInResult> SignInImpl(bool showUI, bool forceRefresh)
{
if (XboxLive.UseMockServices)
@ -36,11 +35,11 @@ namespace Microsoft.Xbox.Services.System
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)
{
return Task.FromResult(new TokenAndSignatureResult
return Task.FromResult(new GetTokenAndSignatureResult
{
Gamertag = this.Gamertag,
XboxUserId = this.XboxUserId,

Просмотреть файл

@ -1,33 +1,17 @@
// Copyright (c) Microsoft Corporation
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Microsoft.Xbox.Services
{
using global::System;
public class HttpCallRequestMessage
{
public HttpRequestMessageType GetHttpRequestMessageType { get; private set; }
public HttpRequestMessageType GetHttpRequestMessageType
{
get;
private set;
}
public Byte[] RequestMessageVector
{
get;
private set;
}
public string RequestMessageString
{
get;
private set;
}
public Byte[] RequestMessageVector { get; private set; }
public string RequestMessageString { get; private set; }
}
}

Просмотреть файл

@ -3,8 +3,6 @@
//
namespace Microsoft.Xbox.Services
{
using global::System;
public enum HttpCallResponseBodyType : uint
{
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;
public interface IXboxLiveUser
internal interface IXboxLiveUser
{
string WebAccountId { get; }
@ -29,10 +29,10 @@ namespace Microsoft.Xbox.Services
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 SignInCompletedEventArgs(IXboxLiveUser user)
public SignInCompletedEventArgs(XboxLiveUser 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 SignOutCompletedEventArgs(IXboxLiveUser user)
public SignOutCompletedEventArgs(XboxLiveUser user)
{
this.User = user;
}
// TODO change this to XboxLiveUser instead of IXboxLive user to match WinRT projections
public IXboxLiveUser User { get; private set; }
public XboxLiveUser User { get; private set; }
}
}

Просмотреть файл

@ -8,7 +8,7 @@ using Windows.Security.Authentication.Web.Core;
namespace Microsoft.Xbox.Services
{
public class TokenAndSignatureResult
public class GetTokenAndSignatureResult
{
public string WebAccountId { get; set; }
@ -25,10 +25,5 @@ namespace Microsoft.Xbox.Services
public string Signature { get; set; }
public string Token { get; set; }
internal string Reserved { get; set; }
#if WINDOWS_UWP
internal WebTokenRequestStatus TokenRequestResultStatus { get; set; }
#endif
}
}

Просмотреть файл

@ -30,6 +30,11 @@ namespace Microsoft.Xbox.Services
{
}
internal XboxException(XSAPI_RESULT result, IntPtr errorMessagePtr)
: base(string.Format("Xbox Services flat C API return error code {0} with message \"{1}\"", result.ToString("g"), MarshalingHelpers.Utf8ToString(errorMessagePtr)))
{
}
internal XboxException(XSAPI_RESULT_INFO resultInfo)
: base (string.Format("Xbox Services flat C API return error code {0} with message \"{1}\"", resultInfo.errorCode.ToString("g"), MarshalingHelpers.Utf8ToString(resultInfo.errorMessage)))
{

Просмотреть файл

@ -5,9 +5,7 @@ namespace Microsoft.Xbox.Services
{
using global::System;
using global::System.IO;
using global::System.ComponentModel;
using global::System.Runtime.InteropServices;
using Microsoft.Xbox.Services.Presence;
using Microsoft.Xbox.Services.Social.Manager;
using Microsoft.Xbox.Services.Statistics.Manager;
using Microsoft.Xbox.Services.System;
@ -16,7 +14,6 @@ namespace Microsoft.Xbox.Services
{
private bool disposed;
private static XboxLive instance;
private XboxLiveSettings settings;
private IStatisticManager statsManager;
private ISocialManager socialManager;
@ -32,24 +29,23 @@ namespace Microsoft.Xbox.Services
private XboxLive()
{
this.settings = new XboxLiveSettings();
try
{
this.appConfig = XboxLiveAppConfiguration.Instance;
#if WINDOWS_UWP
var result = XBLGlobalInitialize();
if (result != XSAPI_RESULT.XSAPI_RESULT_OK)
{
throw new XboxException(result);
}
#endif
// TODO flat C APIs for settings
//this.Settings = null;
this.appConfig = XboxLiveAppConfiguration.SingletonInstance;
}
catch (FileLoadException)
{
this.appConfig = null;
}
#if WINDOWS_UWP
var result = XBLGlobalInitialize();
if (result != XSAPI_RESULT.XSAPI_RESULT_OK)
{
throw new XboxException(result);
}
#endif
}
~XboxLive()
@ -104,15 +100,14 @@ namespace Microsoft.Xbox.Services
}
}
public XboxLiveSettings Settings
{
get { return Instance.settings; }
set { Instance.settings = value; }
}
//public XboxLiveContextSettings Settings { get; private set; }
public XboxLiveAppConfiguration AppConfig
{
get { return Instance.appConfig; }
get
{
return Instance.appConfig;
}
}
protected virtual void Dispose(bool disposing)
@ -134,7 +129,7 @@ namespace Microsoft.Xbox.Services
GC.SuppressFinalize(this);
}
public static Int64 DefaultTaskGroupId
internal static Int64 DefaultTaskGroupId
{
get
{

Просмотреть файл

@ -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
{
using global::System;
using Newtonsoft.Json;
#if UNITY_EDITOR
using global::Newtonsoft.Json;
#endif
public partial class XboxLiveAppConfiguration
{
@ -14,45 +15,10 @@ namespace Microsoft.Xbox.Services
private static readonly object instanceLock = new object();
private static XboxLiveAppConfiguration instance;
public static XboxLiveAppConfiguration Instance
{
get
{
if (instance == null)
{
lock (instanceLock)
{
if (instance == null)
{
instance = Load();
}
}
}
return instance;
}
}
private XboxLiveAppConfiguration()
{
}
public string PublisherId { get; set; }
public string PublisherDisplayName { get; set; }
public string PackageIdentityName { get; set; }
public string DisplayName { get; set; }
public string AppId { get; set; }
public string ProductFamilyName { get; set; }
internal string EnvironmentPrefix { get; set; }
internal bool UseFirstPartyToken { get; set; }
public string PrimaryServiceConfigId { get; set; }
#if UNITY_EDITOR
[JsonProperty("PrimaryServiceConfigId")]
#endif
public string ServiceConfigurationId { get; set; }
public uint TitleId { get; set; }
@ -60,30 +26,34 @@ namespace Microsoft.Xbox.Services
public string Environment { get; set; }
public bool XboxLiveCreatorsTitle { get; set; }
public string GetEndpointForService(string serviceName, string protocol = "https")
public static XboxLiveAppConfiguration SingletonInstance
{
return string.Format("{0}://{1}{2}.xboxlive.com", protocol, serviceName, string.IsNullOrEmpty(this.Environment) ? string.Empty : ("." + this.Environment));
}
public static XboxLiveAppConfiguration Load()
{
try
get
{
// Attempt to load it from a file
return Load(FileName);
}
catch (Exception e)
{
// If we're unable to load the file for some reason, we can just use an empty file
// if mock data is enable.
if (XboxLive.UseMockServices || XboxLive.UseMockHttp)
if (instance == null)
{
return new XboxLiveAppConfiguration();
lock (instanceLock)
{
try
{
if (instance == null)
{
instance = XboxLiveAppConfiguration.Load();
}
}
catch(Exception e)
{
// If we're unable to load the file for some reason, we can just use an empty file
// if mock data is enable.
if (XboxLive.UseMockServices)
{
return new XboxLiveAppConfiguration();
}
throw new XboxException(string.Format("Unable to find or load Xbox Live configuration. Make sure a properly configured Xboxservices.config exists."), e);
}
}
}
throw new XboxException(string.Format("Unable to find or load Xbox Live configuration. Make sure a properly configured {0} exists.", FileName), e);
return instance;
}
}
}

Просмотреть файл

@ -1,10 +1,6 @@
// Copyright (c) Microsoft Corporation
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Microsoft.Xbox.Services
{
@ -12,5 +8,4 @@ namespace Microsoft.Xbox.Services
{
ThisCodeNeedsToBeChangedToFollowBestPractices = 0,
}
}
}

Просмотреть файл

@ -1,10 +1,6 @@
// Copyright (c) Microsoft Corporation
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Microsoft.Xbox.Services
{
@ -12,5 +8,4 @@ namespace Microsoft.Xbox.Services
{
ThisCodeNeedsToBeChangedToAvoidThrottling = 0,
}
}
}

Просмотреть файл

@ -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
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Microsoft.Xbox.Services
{
using global::System;
public class XboxLiveLogCallEventArgs : EventArgs
{
public string Message { get; private set; }
public string Message
{
get;
private set;
}
public string Category
{
get;
private set;
}
public XboxServicesDiagnosticsTraceLevel Level
{
get;
private set;
}
public string Category { get; private set; }
public XboxServicesDiagnosticsTraceLevel Level { get; private set; }
}
}
}

Просмотреть файл

@ -16,11 +16,7 @@ namespace Microsoft.Xbox.Services
public XboxLiveServices(XboxLiveUser user)
{
#if UNITY_EDITOR
// TODO Implement mock title storage service for unity editor
this.TitleStorageService = null;
this.PrivacyService = null;
#else
#if WINDOWS_UWP
IntPtr xboxLiveContext;
var xsapiResult = XboxLiveContextCreate(user.PCXboxLiveUser, out xboxLiveContext);
@ -32,6 +28,10 @@ namespace Microsoft.Xbox.Services
this.TitleStorageService = new TitleStorageService(XboxLiveContextPtr);
this.PrivacyService = new PrivacyService(XboxLiveContextPtr);
#else
// TODO MockServices and/or MockHttp
this.TitleStorageService = null;
this.PrivacyService = null;
#endif
}

Просмотреть файл

@ -5,22 +5,16 @@ namespace Microsoft.Xbox.Services
{
using global::System;
public class XboxLiveSettings
public class XboxLiveContextSettings
{
private const int DefaultHttpTimeoutWindowInSeconds = 20;
private const int DefaultLongHttpTimeoutInSeconds = 5 * 60;
private const int DefaultRetryDelayInSeconds = 2;
public XboxLiveSettings()
public XboxLiveContextSettings()
{
this.DiagnosticsTraceLevel = XboxServicesDiagnosticsTraceLevel.Off;
this.HttpTimeoutWindow = TimeSpan.FromSeconds(DefaultHttpTimeoutWindowInSeconds);
this.LongHttpTimeout = TimeSpan.FromSeconds(DefaultLongHttpTimeoutInSeconds);
this.HttpRetryDelay = TimeSpan.FromSeconds(DefaultRetryDelayInSeconds);
}
public bool UseCoreDispatcherForEventRouting { get; set; }
public TimeSpan HttpTimeout { get; set; }
public TimeSpan HttpTimeoutWindow { get; set; }
public TimeSpan HttpRetryDelay { get; set; }
@ -39,15 +33,15 @@ namespace Microsoft.Xbox.Services
}
}
//public TimeSpan WebsocketTimeoutWindow { get; set; }
public TimeSpan WebsocketTimeoutWindow { get; set; }
//public event EventHandler<XboxLiveLogCallEventArgs> LogCallRouted;
public event EventHandler<XboxLiveLogCallEventArgs> LogCallRouted;
//public bool EnableServiceCallRoutedEvents { get; set; }
public bool EnableServiceCallRoutedEvents { get; set; }
//public void DisableAssertsForMaximumNumberOfWebsocketsActivated(XboxLiveContextRecommendedSetting setting)
//{
// throw new NotImplementedException();
//}
public void DisableAssertsForMaximumNumberOfWebsocketsActivated(XboxLiveContextRecommendedSetting setting)
{
throw new NotImplementedException();
}
}
}

Просмотреть файл

@ -4,10 +4,8 @@
namespace Microsoft.Xbox.Services
{
using global::System;
using global::System.Collections.Generic;
using global::System.Text;
using global::System.Threading.Tasks;
using Microsoft.Xbox.Services.System;
public partial class XboxLiveUser : IXboxLiveUser
@ -17,38 +15,9 @@ namespace Microsoft.Xbox.Services
private readonly IUserImpl userImpl;
private XboxLiveServices xboxLiveServices;
private static event EventHandler<SignInCompletedEventArgs> InternalSignInCompleted;
private static List<EventHandler<SignInCompletedEventArgs>> signInDelegates = new List<EventHandler<SignInCompletedEventArgs>>();
public static event EventHandler<SignInCompletedEventArgs> SignInCompleted
{
add
{
InternalSignInCompleted += value;
signInDelegates.Add(value);
}
remove
{
InternalSignInCompleted -= value;
signInDelegates.Remove(value);
}
}
public static event EventHandler<SignInCompletedEventArgs> SignInCompleted;
public static event EventHandler<SignOutCompletedEventArgs> SignOutCompleted;
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
{
get
@ -136,36 +105,19 @@ namespace Microsoft.Xbox.Services
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);
}
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));
}
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);
}
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
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Microsoft.Xbox.Services
{
using global::System;
public class XboxServiceCallRoutedEventArgs : EventArgs
{
public string XboxUserId
{
get;
private set;
}
public string XboxUserId { get; private set; }
public TimeSpan ElapsedCallTime
{
get;
private set;
}
public TimeSpan ElapsedCallTime { get; private set; }
public DateTimeOffset ResponseTimeUTC
{
get;
private set;
}
public DateTimeOffset ResponseTimeUTC { get; private set; }
public DateTimeOffset RequestTimeUTC
{
get;
private set;
}
public DateTimeOffset RequestTimeUTC { get; private set; }
public string FullResponseToString
{
get;
private set;
}
public string FullResponseToString { get; private set; }
public uint HttpStatus
{
get;
private set;
}
public uint HttpStatus { get; private set; }
public string Signature
{
get;
private set;
}
public string Signature { get; private set; }
public string Token
{
get;
private set;
}
public string Token { get; private set; }
public string ETag
{
get;
private set;
}
public string ETag { get; private set; }
public string ResponseBody
{
get;
private set;
}
public string ResponseBody { get; private set;}
public string ResponseHeaders
{
get;
private set;
}
public string ResponseHeaders { get; private set; }
public uint ResponseCount
{
get;
private set;
}
public uint ResponseCount { get; private set; }
public HttpCallRequestMessage RequestBody
{
get;
private set;
}
public HttpCallRequestMessage RequestBody { get; private set; }
public string RequestHeaders
{
get;
private set;
}
public string RequestHeaders { get; private set; }
public Uri Url
{
get;
private set;
}
public string HttpMethod
{
get;
private set;
}
public Uri Url { get; private set; }
public string HttpMethod { get; private set; }
}
}

Просмотреть файл

@ -1,10 +1,6 @@
// Copyright (c) Microsoft Corporation
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Microsoft.Xbox.Services
{
@ -16,5 +12,4 @@ namespace Microsoft.Xbox.Services
Info = 3,
Verbose = 4,
}
}
}

Просмотреть файл

@ -6,7 +6,7 @@ namespace Microsoft.Xbox.Services.Leaderboard
internal interface ILeaderboardQueryImpl
{
IntPtr GetPtr();
uint GetSkipResultToRank();
void SetSkipResultToRank(uint skipResultToRank);

Просмотреть файл

@ -4,138 +4,17 @@
namespace Microsoft.Xbox.Services.Leaderboard
{
using global::System;
using global::System.Collections.Generic;
using global::System.Text;
using global::System.Threading.Tasks;
public class LeaderboardService : ILeaderboardService
{
private const string leaderboardApiContract = "4";
private static readonly Uri leaderboardsBaseUri = new Uri("https://leaderboards.xboxlive.com");
private readonly XboxLiveAppConfiguration appConfig;
internal LeaderboardService()
{
this.appConfig = XboxLive.Instance.AppConfig;
}
/// <inheritdoc />
public Task<LeaderboardResult> GetLeaderboardAsync(XboxLiveUser user, LeaderboardQuery query)
{
string skipToXboxUserId = null;
if (query.SkipResultToMe)
{
skipToXboxUserId = user.XboxUserId;
}
string requestPath = "";
//if (string.IsNullOrEmpty(query.SocialGroup))
//{
// requestPath = CreateLeaderboardUrlPath(this.appConfig.PrimaryServiceConfigId, query.StatName, query.MaxItems, skipToXboxUserId, query.SkipResultToRank, query.ContinuationToken);
//}
//else
//{
// requestPath = CreateSocialLeaderboardUrlPath(this.appConfig.PrimaryServiceConfigId, query.StatName, user.XboxUserId, query.MaxItems, skipToXboxUserId, query.SkipResultToRank, query.ContinuationToken, query.SocialGroup);
//}
XboxLiveHttpRequest request = XboxLiveHttpRequest.Create(HttpMethod.Get, leaderboardsBaseUri.ToString(), requestPath);
request.ContractVersion = leaderboardApiContract;
request.XboxLiveAPI = XboxLiveAPIName.GetLeaderboardInternal;
return request.GetResponseWithAuth(user)
.ContinueWith(
responseTask =>
{
return this.HandleLeaderboardResponse(responseTask, query);
});
}
internal LeaderboardResult HandleLeaderboardResponse(Task<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("&");
throw new NotImplementedException();
}
}
}

Просмотреть файл

@ -3,6 +3,7 @@
namespace Microsoft.Xbox.Services.Leaderboard
{
using global::Newtonsoft.Json;
using global::System.Collections.Generic;
using global::System.Linq;
using global::System.Threading.Tasks;
@ -20,7 +21,7 @@ namespace Microsoft.Xbox.Services.Leaderboard
internal LeaderboardResult CreateLeaderboardResponse(LeaderboardQuery query)
{
LeaderboardResponse lbResponse = JsonSerialization.FromJson<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 };
@ -34,7 +35,7 @@ namespace Microsoft.Xbox.Services.Leaderboard
Values = row.Value != null ? new List<string> { row.Value } : row.Values
}).ToList();
// Create a result with an 'empty' next query so that it won't have paiging.
// Create a result with an 'empty' next query so that it won't have paging.
LeaderboardResult result = new LeaderboardResult(rows, columns, lbResponse.LeaderboardInfo.TotalCount);
return result;
}

Просмотреть файл

@ -25,11 +25,8 @@
<Compile Include="$(MSBuildThisFileDirectory)Achievements\AchievementTitleAssociation.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Achievements\AchievementType.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\HttpRetryAfterApiState.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Common\HttpRetryAfterManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Common\HttpCallResponseBodyType.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Common\IXboxLiveUser.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Common\ServiceCallLoggingConfig.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Common\SignInCompletedEventArgs.cs" />
@ -39,12 +36,9 @@
<Compile Include="$(MSBuildThisFileDirectory)Common\TokenAndSignatureResult.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLive.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLiveAPIName.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLiveAppConfiguration.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLiveContextRecommendedSetting.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\XboxLiveServices.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Common\XboxLiveSettings.cs" />
@ -79,16 +73,19 @@
<Compile Include="$(MSBuildThisFileDirectory)GameServerPlatform\QualityOfServiceServer.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\ILeaderboardQueryImpl.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\ILeaderboardResultImpl.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\ILeaderboardService.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardQueryImpl.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardResultImpl.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardService.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardStatType.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\MockLeaderboardResultImpl.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\MockLeaderboardService.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Privacy\IPrivacyService.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\IXboxSocialUserGroup.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\LeaderboardResultEventArgs.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Statistics\Manager\MockStatisticManager.cs" />
@ -98,31 +95,24 @@
<Compile Include="$(MSBuildThisFileDirectory)Statistics\Manager\StatisticEventType.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Statistics\Manager\StatisticManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Statistics\Manager\StatisticValue.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\AuthConfig.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IUserImpl.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\MarshallingHelpers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\XboxLiveCallbackContext.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\XboxLiveResult.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\XboxLiveServicesSettings.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\XsapiCallbackContext.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\XsapiResult.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\LeaderboardQuery.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardResponse.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardColumn.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardResult.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardRow.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Leaderboard\LeaderboardService.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Matchmaking\CreateMatchTicketResponse.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Matchmaking\HopperStatisticsResponse.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Matchmaking\MatchmakingService.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Matchmaking\MatchTicketDetailsResponse.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Matchmaking\PreserveSessionMode.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\HostChangedEventArgs.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Multiplayer\Manager\Joinability.cs" />
@ -195,7 +185,6 @@
<Compile Include="$(MSBuildThisFileDirectory)RealTimeActivity\RealTimeActivitySubscriptionError.cs" />
<Compile Include="$(MSBuildThisFileDirectory)RealTimeActivity\RealTimeActivitySubscriptionErrorEventArgs.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\MockSocialManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Social\Manager\PreferredColor.cs" />
@ -214,7 +203,6 @@
<Compile Include="$(MSBuildThisFileDirectory)Social\Manager\XboxSocialUserGroup.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Social\Models\ProfileSettingsRequest.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Social\Models\ProfileSettingsResponse.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Social\ProfileService.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Social\ReputationFeedbackItem.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Social\ReputationFeedbackType.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Social\ReputationService.cs" />
@ -228,13 +216,9 @@
<Compile Include="$(MSBuildThisFileDirectory)Social\XboxSocialRelationshipResult.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Social\XboxUserProfile.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\GamingPrivilege.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\JsonSerialization.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\StringService.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\VerifyStringResult.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\TitleStorageBlobMetadataResult.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.
/// </summary>
/// <returns>A collection of XboxUserIds that correspond to the calling user's avoid list.</returns>
Task<IList<string>> GetAvoidListAsync();
Task<IReadOnlyList<string>> GetAvoidListAsync();
/// <summary>
/// Check a single permission with a single target user.
/// </summary>
@ -33,15 +33,15 @@ namespace Microsoft.Xbox.Services.Privacy
/// 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>
/// <returns>A collection of <see cref="PermissionCheckResult"/> objects containing results of the target xbox user ids.</returns>
Task<List<MultiplePermissionsCheckResult>> CheckMultiplePermissionsWithMultipleTargetUsersAsync(
IList<string> permissionIds,
IList<string> targetXboxUserIds
Task<IReadOnlyList<MultiplePermissionsCheckResult>> CheckMultiplePermissionsWithMultipleTargetUsersAsync(
IReadOnlyList<string> permissionIds,
IReadOnlyList<string> targetXboxUserIds
);
/// <summary>
/// Get the list of Xbox Live Ids that the calling user should not hear (mute) during multiplayer matchmaking.
/// </summary>
/// <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 IList<PermissionCheckResult> Items { get; private set; }
public IReadOnlyList<PermissionCheckResult> Items { get; private set; }
public string XboxUserId { get; private set; }
@ -20,7 +20,7 @@ namespace Microsoft.Xbox.Services.Privacy
XboxUserId = MarshalingHelpers.Utf8ToString(multiplePermissionsStruct.xboxUserId);
Items = new List<PermissionCheckResult>((int)multiplePermissionsStruct.itemsCount);
var items = new List<PermissionCheckResult>((int)multiplePermissionsStruct.itemsCount);
int size = MarshalingHelpers.SizeOf<XSAPI_PRIVACY_PERMISSION_CHECK_RESULT>();
IntPtr permissionStructPtr = multiplePermissionsStruct.items;
@ -28,9 +28,10 @@ namespace Microsoft.Xbox.Services.Privacy
for (ulong i = 0; i < multiplePermissionsStruct.itemsCount; ++i)
{
var permissionCheckResultStruct = MarshalingHelpers.PtrToStructure<XSAPI_PRIVACY_PERMISSION_CHECK_RESULT>(permissionStructPtr);
Items.Add(new PermissionCheckResult(permissionCheckResultStruct));
items.Add(new PermissionCheckResult(permissionCheckResultStruct));
permissionStructPtr = permissionStructPtr.Increment(size);
}
Items = items;
}
}

Просмотреть файл

@ -11,7 +11,7 @@ namespace Microsoft.Xbox.Services.Privacy
public class PermissionCheckResult
{
public IList<PermissionDenyReason> Reasons { get; private set; }
public IReadOnlyList<PermissionDenyReason> DenyReasons { get; private set; }
public string PermissionRequested { get; private set; }
@ -27,17 +27,17 @@ namespace Microsoft.Xbox.Services.Privacy
IsAllowed = permissionCheckResultStruct.isAllowed;
PermissionRequested = MarshalingHelpers.Utf8ToString(permissionCheckResultStruct.permissionRequested);
Reasons = new List<PermissionDenyReason>((int)permissionCheckResultStruct.denyReasonsCount);
var denyReasons = new List<PermissionDenyReason>((int)permissionCheckResultStruct.denyReasonsCount);
int size = MarshalingHelpers.SizeOf<XSAPI_PRIVACY_PERMISSION_DENY_REASON>();
IntPtr denyReasonPtr = permissionCheckResultStruct.denyReasons;
for (ulong i = 0; i < permissionCheckResultStruct.denyReasonsCount; ++i)
{
Reasons.Add(new PermissionDenyReason(denyReasonPtr));
denyReasons.Add(new PermissionDenyReason(denyReasonPtr));
denyReasonPtr = denyReasonPtr.Increment(size);
}
DenyReasons = denyReasons;
}
}

Просмотреть файл

@ -19,12 +19,12 @@ namespace Microsoft.Xbox.Services.Privacy
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(() =>
{
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);
if (xsapiResult != XSAPI_RESULT.XSAPI_RESULT_OK)
@ -35,12 +35,12 @@ namespace Microsoft.Xbox.Services.Privacy
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(() =>
{
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);
if (xsapiResult != XSAPI_RESULT.XSAPI_RESULT_OK)
@ -58,7 +58,7 @@ namespace Microsoft.Xbox.Services.Privacy
{
if (result.errorCode == XSAPI_RESULT.XSAPI_RESULT_OK)
{
context.TaskCompletionSource.SetResult(MarshalingHelpers.Utf8StringArrayToStringList(xboxUserIdList, (int)count));
context.TaskCompletionSource.SetResult(MarshalingHelpers.Utf8StringArrayToStringList(xboxUserIdList, count));
}
else
{
@ -109,15 +109,15 @@ namespace Microsoft.Xbox.Services.Privacy
}
}
public Task<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(() =>
{
var permissionIdsArray = MarshalingHelpers.StringListToHGlobalUtf8StringArray(permissionIds);
var xuidsArray = MarshalingHelpers.StringListToHGlobalUtf8StringArray(targetXboxUserIds);
int contextKey = XsapiCallbackContext<CheckMultiplePermissionsContext, List<MultiplePermissionsCheckResult>>.CreateContext(
int contextKey = XsapiCallbackContext<CheckMultiplePermissionsContext, IReadOnlyList<MultiplePermissionsCheckResult>>.CreateContext(
new CheckMultiplePermissionsContext
{
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
{
TitleId = XboxLiveAppConfiguration.Instance.TitleId,
TitleId = XboxLiveAppConfiguration.SingletonInstance.TitleId,
IsTitleActive = true,
}
};

Просмотреть файл

@ -35,6 +35,5 @@ namespace Microsoft.Xbox.Services.Social.Manager
return m_instance;
}
}
}
}

Просмотреть файл

@ -9,101 +9,21 @@ namespace Microsoft.Xbox.Services.Social
public class ProfileService
{
private readonly string profileEndpoint;
protected XboxLiveAppConfiguration config;
internal ProfileService()
{
this.config = XboxLive.Instance.AppConfig;
this.profileEndpoint = this.config.GetEndpointForService("profile");
}
public Task<XboxUserProfile> GetUserProfileAsync(XboxLiveUser user, string xboxUserId)
public Task<XboxUserProfile> GetUserProfileAsync(string xboxUserId)
{
if (string.IsNullOrEmpty(xboxUserId))
{
throw new ArgumentException("invalid xboxUserId", "xboxUserId");
}
List<string> profiles = new List<string> { xboxUserId };
return this.GetUserProfilesAsync(user, profiles).ContinueWith(task => task.Result[0]);
throw new NotImplementedException();
}
public Task<List<XboxUserProfile>> GetUserProfilesAsync(XboxLiveUser user, List<string> xboxUserIds)
public Task<IReadOnlyList<XboxUserProfile>> GetUserProfilesAsync(IReadOnlyList<string> xboxUserIds)
{
if (xboxUserIds == null)
{
throw new ArgumentNullException("xboxUserIds");
}
if (xboxUserIds.Count == 0)
{
throw new ArgumentOutOfRangeException("xboxUserIds", "Empty list of user ids");
}
if (XboxLive.UseMockServices)
{
Random rand = new Random();
List<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;
});
}
throw new NotImplementedException();
}
public Task<List<XboxUserProfile>> GetUserProfilesForSocialGroupAsync(string socialGroup)
public Task<IReadOnlyList<XboxUserProfile>> GetUserProfilesForSocialGroupAsync(string socialGroup)
{
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
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Microsoft.Xbox.Services.System
{
@ -33,5 +29,4 @@ namespace Microsoft.Xbox.Services.System
MultiplayerSessions = 254,
AddFriend = 255,
}
}

Просмотреть файл

@ -14,16 +14,14 @@ namespace Microsoft.Xbox.Services.System
string AgeGroup { get; }
string Privileges { get; }
string WebAccountId { get; }
AuthConfig AuthConfig { get; }
#if WINDOWS_UWP
Windows.System.User CreationContext { get; }
#endif
#if !UNITY_EDITOR
IntPtr XboxLiveUserPtr { get; }
#endif
Task<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.Collections.Generic;
using global::System.Linq;
using global::System.Runtime.InteropServices;
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="length">Number of strings in the array</param>
/// <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)
{
string str = MarshalingHelpers.Utf8ToString(Marshal.ReadIntPtr(arrayPtr));
@ -69,9 +70,9 @@ namespace Microsoft.Xbox.Services
/// </summary>
/// <param name="strings">The array of string to allocate</param>
/// <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;
foreach (var str in strings)
{

Просмотреть файл

@ -1,16 +1,14 @@
// Copyright (c) Microsoft Corporation
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Microsoft.Xbox.Services.System
{
using global::System;
using global::System.Threading.Tasks;
public class StringService
{
public Task<VerifyStringResult> VerifyStringAsync(string stringToVerify)
{
throw new NotImplementedException();

Просмотреть файл

@ -1,16 +1,11 @@
// Copyright (c) Microsoft Corporation
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Microsoft.Xbox.Services.System
{
public class VerifyStringResult
{
public string FirstOffendingSubstring
{
get;

Просмотреть файл

@ -1,10 +1,6 @@
// Copyright (c) Microsoft Corporation
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Microsoft.Xbox.Services.System
{
@ -15,5 +11,4 @@ namespace Microsoft.Xbox.Services.System
TooLong = 2,
UnknownError = 3,
}
}

Просмотреть файл

@ -11,6 +11,6 @@ namespace Microsoft.Xbox.Services.System
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.Threading.Tasks;
using Microsoft.Xbox.Services.TitleStorage;
/// <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="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>
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>
/// [optional] Timestamp assigned by the client.
/// </summary>
public DateTimeOffset? ClientTimeStamp { get; private set; }
public DateTimeOffset ClientTimeStamp { get; private set; }
/// <summary>
/// ETag for the file used in read and write requests.
@ -157,13 +157,22 @@ namespace Microsoft.Xbox.Services.TitleStorage
var displayName = MarshalingHelpers.StringToHGlobalUtf8(this.DisplayName);
var etag = MarshalingHelpers.StringToHGlobalUtf8(this.ETag);
TitleStorageCreateBlobMetadata(scid, StorageType, path, BlobType, xuid, displayName, etag, IntPtr.Zero, /*TODO client timestamp*/ out metadataPtr);
IntPtr clientTimePtr = IntPtr.Zero;
if (this.ClientTimeStamp != null)
{
var clientTime = this.ClientTimeStamp.ToUnixTimeMilliseconds();
clientTimePtr = Marshal.AllocHGlobal(MarshalingHelpers.SizeOf<UInt64>());
Marshal.WriteInt64(clientTimePtr, clientTime);
}
TitleStorageCreateBlobMetadata(scid, StorageType, path, BlobType, xuid, displayName, etag, clientTimePtr, out metadataPtr);
Marshal.FreeHGlobal(scid);
Marshal.FreeHGlobal(path);
Marshal.FreeHGlobal(xuid);
Marshal.FreeHGlobal(displayName);
Marshal.FreeHGlobal(etag);
Marshal.FreeHGlobal(clientTimePtr);
}
internal void Refresh()

Просмотреть файл

@ -2,7 +2,6 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
namespace Microsoft.Xbox.Services.TitleStorage
{
using global::System;

Просмотреть файл

@ -3,8 +3,8 @@
//
namespace Microsoft.Xbox.Services.TitleStorage
{
using global::System.Runtime.InteropServices;
using global::System;
using global::System.Runtime.InteropServices;
/// <summary>
/// Blob data returned from the cloud.

Просмотреть файл

@ -28,6 +28,15 @@ namespace Microsoft.Xbox.Services.TitleStorage
/// </summary>
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>
/// Initialze a TitleStorageQuota from the corresponding C object
@ -37,6 +46,8 @@ namespace Microsoft.Xbox.Services.TitleStorage
QuotaBytes = quotaStruct.QuotaBytes;
UsedBytes = quotaStruct.UsedBytes;
StorageType = quotaStruct.storageType;
XboxUserId = MarshalingHelpers.Utf8ToString(quotaStruct.XboxUserId);
ServiceConfigurationId = MarshalingHelpers.Utf8ToString(quotaStruct.ServiceConfigurationId);
}
}

Просмотреть файл

@ -5,6 +5,7 @@ namespace Microsoft.Xbox.Services.TitleStorage
{
using global::System;
using global::System.Collections.Generic;
using global::System.Linq;
using global::System.Runtime.InteropServices;
using global::System.Threading.Tasks;
using Microsoft.Xbox.Services.Shared.TitleStorage;
@ -38,7 +39,7 @@ namespace Microsoft.Xbox.Services.TitleStorage
var tcs = new TaskCompletionSource<TitleStorageQuota>();
Task.Run(() =>
{
var scid = MarshalingHelpers.StringToHGlobalUtf8(XboxLive.Instance.AppConfig.PrimaryServiceConfigId);
var scid = MarshalingHelpers.StringToHGlobalUtf8(XboxLive.Instance.AppConfig.ServiceConfigurationId);
int 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="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>
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>();
Task.Run(() =>
@ -255,7 +256,7 @@ namespace Microsoft.Xbox.Services.TitleStorage
var context = XsapiCallbackContext<TitleStorageBlobMetadata, TitleStorageBlobMetadata>.CreateContext(blobMetadata, tcs, out contextKey);
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 };
var xsapiResult = TitleStorageUploadBlob(

Просмотреть файл

@ -219,7 +219,7 @@ namespace UWPIntegration
string resultText = string.Format("Allowed: {0}", result.IsAllowed);
if (!result.IsAllowed)
{
foreach (var reason in result.Reasons)
foreach (var reason in result.DenyReasons)
{
resultText += string.Format("\tReason: {0}", reason.Reason);
}
@ -249,7 +249,7 @@ namespace UWPIntegration
resultText += string.Format("\tPermission {0} allowed: {1}", permissionResult.PermissionRequested, permissionResult.IsAllowed);
if (!permissionResult.IsAllowed)
{
foreach (var reason in permissionResult.Reasons)
foreach (var reason in permissionResult.DenyReasons)
{
resultText += string.Format("\tReason: {0}", reason.Reason);
}
@ -333,7 +333,7 @@ namespace UWPIntegration
private async void TitleStorageGetQuota_Click(object sender, RoutedEventArgs e)
{
var quota = await this.User.Services.TitleStorageService.GetQuotaAsync(
XboxLive.Instance.AppConfig.PrimaryServiceConfigId, TitleStorageType.Universal);
XboxLive.Instance.AppConfig.ServiceConfigurationId, TitleStorageType.Universal);
this.TitleStorageData.Text = string.Format("Used bytes = {0}, Quota bytes = {1}", quota.UsedBytes, quota.QuotaBytes);
}
@ -343,7 +343,7 @@ namespace UWPIntegration
try
{
var metadataResult = await this.User.Services.TitleStorageService.GetBlobMetadataAsync(
XboxLive.Instance.AppConfig.PrimaryServiceConfigId, TitleStorageType.Universal, "path/to/", this.User.XboxUserId);
XboxLive.Instance.AppConfig.ServiceConfigurationId, TitleStorageType.Universal, "path/to/", this.User.XboxUserId);
var items = metadataResult.Items;
if (items.Count > 0)
@ -362,7 +362,7 @@ namespace UWPIntegration
{
try
{
var metadata = new TitleStorageBlobMetadata(XboxLive.Instance.AppConfig.PrimaryServiceConfigId, TitleStorageType.Universal, "path/to/newfile.txt", TitleStorageBlobType.Binary, this.user.XboxUserId);
var metadata = new TitleStorageBlobMetadata(XboxLive.Instance.AppConfig.ServiceConfigurationId, TitleStorageType.Universal, "path/to/newfile.txt", TitleStorageBlobType.Binary, this.user.XboxUserId);
var bytes = System.Text.Encoding.Unicode.GetBytes("Hello, world!");
@ -403,7 +403,7 @@ namespace UWPIntegration
{
try
{
var metadata = new TitleStorageBlobMetadata(XboxLive.Instance.AppConfig.PrimaryServiceConfigId, TitleStorageType.Universal, "path/to/newfile.txt", TitleStorageBlobType.Binary, this.user.XboxUserId);
var metadata = new TitleStorageBlobMetadata(XboxLive.Instance.AppConfig.ServiceConfigurationId, TitleStorageType.Universal, "path/to/newfile.txt", TitleStorageBlobType.Binary, this.user.XboxUserId);
await this.User.Services.TitleStorageService.DeleteBlobAsync(metadata, false);
this.TitleStorageData.Text = string.Format("Successfully deleted blob with path \"path/to/newfile.txt\"", metadata.Length);
@ -457,7 +457,7 @@ namespace UWPIntegration
}
this.StatsData.Text = string.Join(Environment.NewLine, statNames.Select(n => this.StatsManager.GetStatistic(this.User, n)).Select(s => $"{s.Name} ({s.DataType}) = {GetStatValue(s)}"));
}
IList<SocialEvent> socialEvents = this.SocialManager.DoWork();
foreach (SocialEvent ev in socialEvents)
{

Просмотреть файл

@ -99,6 +99,9 @@
<ItemGroup>
<!-- A reference to the entire .Net Framework and Windows SDK are automatically included -->
<None Include="project.json" />
<Content Include="Microsoft.Xbox.Services.140.UWP.C.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="XboxServices.config">
<SubType>Designer</SubType>
</Content>
@ -153,8 +156,8 @@
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
<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\" />
<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\*.dll $(TargetDir)AppX\" />
<Exec Command="xcopy /y /d $(BuildRoot)\..\CppSource\binaries\$(Configuration)\$(CDllPlatform)\Microsoft.Xbox.Services.140.UWP.C\*.pdb $(TargetDir)AppX\" />
</Target>
<!-- 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.

Просмотреть файл

@ -59,16 +59,15 @@ Global
{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.Build.0 = Debug|x86
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Debug|ARM.ActiveCfg = Debug|Any CPU
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Debug|ARM.Build.0 = Debug|Any CPU
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Debug|ARM.ActiveCfg = Debug|ARM
{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.Build.0 = Debug|x64
{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}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Release|Any CPU.Build.0 = Release|Any CPU
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Release|ARM.ActiveCfg = Release|Any CPU
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Release|ARM.Build.0 = Release|Any CPU
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Release|Any CPU.ActiveCfg = Release|x86
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Release|ARM.ActiveCfg = Release|ARM
{CFB2CA8F-6611-4DCA-981C-4B7AFCCA19A8}.Release|ARM.Build.0 = Release|ARM
{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|x86.ActiveCfg = Release|x86

Просмотреть файл

@ -2,4 +2,4 @@
"TitleId" : 1798668314,
"PrimaryServiceConfigId" : "00000000-0000-0000-0000-00006b35801a",
"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.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.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 Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="..\..\External\libHttpClient\libHttpClient.props" />
@ -184,7 +184,6 @@
<ClInclude Include="..\..\Source\Services\Common\pch.h" />
<ClInclude Include="..\..\Source\Services\Common\pch_common.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\Leaderboard\leaderboard_helper.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.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.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>
</Project>

Просмотреть файл

@ -75,9 +75,6 @@
<ClInclude Include="..\..\Include\xsapi\xbox_live_app_config_c.h">
<Filter>C++ Public Includes</Filter>
</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">
<Filter>C++ Source\Shared</Filter>
</ClInclude>

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше