Ejemplo n.º 1
0
        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())));
        }
Ejemplo n.º 2
0
        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));
            }
        }