public async Task <IActionResult> NewGameAsync(string playerid, string roomid, string roomtype) { // Only accept nonempty alphanumeric usernames under 20 characters long // this should have been handled in javascript, may point to aggressive behavior // also verify no one tries to make a room other than those provided Regex names = new Regex(@"(?i)([a-z?0-9?\-?]\s?){0,10}"); if (!names.IsMatch(playerid)) { return(this.StatusCode(400, this.Json("Invalid username."))); } if (!names.IsMatch(roomid)) { return(this.StatusCode(400, this.Json("Invalid room name."))); } try { Enum.Parse(typeof(RoomTypes), roomtype); } catch { return(this.StatusCode(400, this.Json("This is not a valid room type."))); } int key = Partitioners.GetPlayerPartition(playerid); //Direct query to correct partition string url = this.proxy + $"NewGame/?playerid={playerid}&roomid={roomid}&roomtype={roomtype}&PartitionKind=Int64Range&PartitionKey={key}"; HttpResponseMessage response = await this.httpClient.GetAsync(url); //Send the request and wait for the response // A 404 tells us that our proxy is old, so we renew it if ((int)response.StatusCode == 404) { this.RenewProxy(); url = this.proxy + $"NewGame/?playerid={playerid}&roomid={roomid}&roomtype={roomtype}&PartitionKind=Int64Range&PartitionKey={key}"; response = await this.httpClient.GetAsync(url); //Send the request and wait for the response } // Forward the response we get to the client return(this.StatusCode((int)response.StatusCode, this.Json(await response.Content.ReadAsStringAsync()))); }
public async Task <IActionResult> EndGame(string roomid, string playerid) { try { if (!RoomManager.IsActive) { return new ContentResult { StatusCode = 500, Content = "Service is still starting up. Please retry." } } ; IReliableDictionary <string, Room> roomdict = await this.stateManager.GetOrAddAsync <IReliableDictionary <string, Room> >(RoomDictionaryName); Room room; Player player; //want to maintain this information between our transactions //Transaction one: Send the PlayerManager the updated player data using (ITransaction tx = this.stateManager.CreateTransaction()) { ConditionalValue <Room> roomOption = await roomdict.TryGetValueAsync(tx, roomid); //make sure room exists if (!roomOption.HasValue) { return new ContentResult { StatusCode = 400, Content = "This room does not exist" } } ; //Hand the room data up so that transaction two does not have to gather it again room = roomOption.Value; IReliableDictionary <string, ActivePlayer> activeroomdict = await this.stateManager.GetOrAddAsync <IReliableDictionary <string, ActivePlayer> >(roomid); //try to get the player data ConditionalValue <ActivePlayer> playerOption = await activeroomdict.TryGetValueAsync(tx, playerid); if (!playerOption.HasValue) { return new ContentResult { StatusCode = 400, Content = "This player is not in this room" } } ; player = playerOption.Value.Player; //now that we have it, we are finished with the transaction. await tx.CommitAsync(); } // We send the data to the PlayerManager to update data and mark that player as offline. We do not want to // remove data until we are sure it is stored in the PlayerManager. int key = Partitioners.GetPlayerPartition(playerid); string url = this.proxy + $"EndGame/?playerid={playerid}" + $"&playerdata={JsonConvert.SerializeObject(player)}" + $"&PartitionKind=Int64Range&PartitionKey={key}"; HttpResponseMessage response = await this.httpClient.GetAsync(url); if ((int)response.StatusCode == 404) { this.RenewProxy(); url = this.proxy + $"EndGame/?playerid={playerid}" + $"&playerdata={JsonConvert.SerializeObject(player)}" + $"&PartitionKind=Int64Range&PartitionKey={key}"; response = await this.httpClient.GetAsync(url); } string responseMessage = await response.Content.ReadAsStringAsync(); if ((int)response.StatusCode != 200) { return new ContentResult { StatusCode = 500, Content = responseMessage } } ; //Transaction two: remove the player from the room using (ITransaction tx1 = this.stateManager.CreateTransaction()) { IReliableDictionary <string, ActivePlayer> activeroomdict = await this.stateManager.GetOrAddAsync <IReliableDictionary <string, ActivePlayer> >(roomid); //Remove the player from the active room await activeroomdict.TryRemoveAsync(tx1, playerid); //Deincrement the number of players in the room room.NumPlayers--; // If that number is now 0, remove that room from the room dictionary if (room.NumPlayers == 0) { await roomdict.TryRemoveAsync(tx1, roomid); } else { await roomdict.SetAsync(tx1, roomid, room); } await tx1.CommitAsync(); } return(new ContentResult { StatusCode = 200, Content = "Successfully logged out" }); } catch (Exception e) { return(exceptionHandler(e)); } }