internal MockStatsManager() { this.LocalUsers = new List <XboxLiveUser>(); Dictionary <string, Models.Stat> statMap = new Dictionary <string, Models.Stat> { { "DefaultNum", new Models.Stat() { Value = 1.5f } }, { "DefaultString", new Models.Stat() { Value = "stringVal" } }, { "Default", new Models.Stat() { Value = 1 } } }; this.statValueDocument = new StatsValueDocument(statMap); this.statEventList = new List <StatEvent>(); }
public Task UpdateStatsValueDocument(XboxLiveUser user, StatsValueDocument statValuePostDocument) { string pathAndQuery = PathAndQueryStatSubpath( user.XboxUserId, this.config.PrimaryServiceConfigId, false ); XboxLiveHttpRequest req = XboxLiveHttpRequest.Create(HttpMethod.Post, this.statsWriteEndpoint, pathAndQuery); var svdModel = new Models.StatsValueDocumentModel() { Revision = ++statValuePostDocument.Revision, Timestamp = DateTime.Now, Stats = new Models.Stats() { Title = new Dictionary <string, Models.Stat>() } }; svdModel.Stats.Title = statValuePostDocument.Stats.ToDictionary( stat => stat.Key, stat => new Models.Stat() { Value = stat.Value.Value }); req.RequestBody = JsonConvert.SerializeObject(svdModel, serializerSettings); return(req.GetResponseWithAuth(user)); }
internal void MergeStatDocument(StatsValueDocument mergeStatDocument) { switch (this.State) { case StatValueDocumentState.NotLoaded: this.Revision = mergeStatDocument.Revision; this.Stats = mergeStatDocument.Stats; break; // for offline the stat values local override any service values // only add any undefined stats into our list case StatValueDocumentState.OfflineNotLoaded: case StatValueDocumentState.OfflineLoaded: foreach (var stat in mergeStatDocument.Stats) { if (this.Stats.ContainsKey(stat.Key)) { this.Stats.Add(stat.Key, stat.Value); } } break; case StatValueDocumentState.Loaded: throw new Exception("MergeStatDocument called with state: StatValueDocumentState.Loaded"); default: break; } this.State = StatValueDocumentState.Loaded; }
public void AddLocalUser(XboxLiveUser user) { if (user == null) { throw new ArgumentException("user"); } string xboxUserId = user.XboxUserId; if (this.userDocumentMap.ContainsKey(xboxUserId)) { throw new ArgumentException("User already in map"); } this.userDocumentMap.Add(xboxUserId, new StatsValueDocument(null)); this.statsService.GetStatsValueDocument(user).ContinueWith(statsValueDocTask => { if (user.IsSignedIn) { lock (this.userDocumentMap) { if (this.userDocumentMap.ContainsKey(xboxUserId)) { StatsValueDocument document = statsValueDocTask.Result; if (statsValueDocTask.IsFaulted) // if there was an error, but the user is signed in, we assume offline sign in { this.userDocumentMap[xboxUserId].State = StatsValueDocument.StatValueDocumentState.OfflineNotLoaded; } else { this.userDocumentMap[xboxUserId].MergeStatDocument(document); } document.FlushEvent += (sender, e) => { if (this.userDocumentMap.ContainsKey(xboxUserId)) { this.FlushToService(user, document); } }; this.userDocumentMap[xboxUserId] = document; } } } this.AddEvent(new StatEvent(StatEventType.LocalUserAdded, user, statsValueDocTask.Exception, new StatEventArgs())); }); }
public Task UpdateStatsValueDocument(StatsValueDocument statValuePostDocument) { string endpoint = XboxLiveEndpoint.GetEndpointForService("statswrite", this.config); string pathAndQuery = PathAndQueryStatSubpath( this.context.User.XboxUserId, this.config.ServiceConfigurationId, false ); XboxLiveHttpRequest req = XboxLiveHttpRequest.Create(this.settings, "POST", endpoint, pathAndQuery); var svdModel = new Models.StatsValueDocumentModel() { Revision = statValuePostDocument.Revision, Timestamp = DateTime.Now, Stats = new Models.Stats() { Title = new Dictionary <string, Models.Stat>() } }; svdModel.Stats.Title = statValuePostDocument.Stats.ToDictionary( stat => stat.Key, stat => new Models.Stat() { Value = stat.Value.Value }); req.RequestBody = JsonConvert.SerializeObject(svdModel, new JsonSerializerSettings { }); return(req.GetResponseWithAuth(this.context.User, HttpCallResponseBodyType.JsonBody).ContinueWith(task => { XboxLiveHttpResponse response = task.Result; if (response.ErrorCode == 0) { ++statValuePostDocument.Revision; } })); }
public Task <StatsValueDocument> GetStatsValueDocument() { string endpoint = XboxLiveEndpoint.GetEndpointForService("statsread", this.config); string pathAndQuery = PathAndQueryStatSubpath( this.context.User.XboxUserId, this.config.ServiceConfigurationId, false ); XboxLiveHttpRequest req = XboxLiveHttpRequest.Create(this.settings, "GET", endpoint, pathAndQuery); return(req.GetResponseWithAuth(this.context.User, HttpCallResponseBodyType.JsonBody).ContinueWith(task => { XboxLiveHttpResponse response = task.Result; var svdModel = JsonConvert.DeserializeObject <Models.StatsValueDocumentModel>(response.ResponseBodyJson); var svd = new StatsValueDocument(svdModel.Stats.Title) { Revision = svdModel.Revision }; return svd; })); }
public Task <StatsValueDocument> GetStatsValueDocument(XboxLiveUser user) { string pathAndQuery = PathAndQueryStatSubpath( user.XboxUserId, this.config.PrimaryServiceConfigId, false ); XboxLiveHttpRequest req = XboxLiveHttpRequest.Create(HttpMethod.Get, this.statsReadEndpoint, pathAndQuery); return(req.GetResponseWithAuth(user).ContinueWith(task => { XboxLiveHttpResponse response = task.Result; var svdModel = JsonConvert.DeserializeObject <Models.StatsValueDocumentModel>(response.ResponseBodyString); var svd = new StatsValueDocument(svdModel.Stats.Title, svdModel.Revision) { State = StatsValueDocument.StatValueDocumentState.Loaded, User = user }; return svd; })); }
private void FlushToService(XboxLiveUser user, StatsValueDocument document) { if (user == null) { // User could have been removed. return; } document.ClearDirtyState(); if (document.State != StatsValueDocument.StatValueDocumentState.Loaded) // if not loaded, try and get the SVD from the service { this.statsService.GetStatsValueDocument(user).ContinueWith((continuationTask) => { lock (this.userDocumentMap) { if (this.userDocumentMap.ContainsKey(user.XboxUserId)) { if (!continuationTask.IsFaulted) { var updatedSvd = continuationTask.Result; this.userDocumentMap[user.XboxUserId].MergeStatDocument(updatedSvd); UpdateStatsValueDocument(user, updatedSvd); } // How do you handle if this failed? } else { // log error: User not found in flush_to_service lambda } } }); } else { UpdateStatsValueDocument(user, document); } }
private void UpdateStatsValueDocument(XboxLiveUser user, StatsValueDocument document) { if (user == null) { // User could have been removed. return; } this.statsService.UpdateStatsValueDocument(user, document).ContinueWith((continuationTask) => { lock (this.userDocumentMap) { if (this.userDocumentMap.ContainsKey(user.XboxUserId)) { if (continuationTask.IsFaulted) { if (this.ShouldWriteOffline(continuationTask.Exception)) { var userSvd = this.userDocumentMap[user.XboxUserId]; if (userSvd.State == StatsValueDocument.StatValueDocumentState.Loaded) { userSvd.State = StatsValueDocument.StatValueDocumentState.OfflineLoaded; } this.WriteOffline(user, userSvd); } else { // log error: Stats manager could not write stats value document } } this.AddEvent(new StatEvent(StatEventType.StatUpdateComplete, user, continuationTask.Exception, new StatEventArgs())); } } }); }
private void WriteOffline(XboxLiveUser user, StatsValueDocument document) { // TODO: implement }