Parkquiz

Uppgift i Programmering 2 och Webbserverprogrammering 1

Denna uppgift är ett samarbete mellan kurserna Programmering 2 och Webbserverprogrammering 1.


Se steg 1
Vi ska bygga ett javaprogram som pratar mot ett REST-api, programmet ska vara en förenklad version av Quizkampen. För de elever som är snabba och jobbar hårt kan man ha som mål att bygga en bättre variant :-)

Programmering 2

GUI… mer info kommer!

Webbserverprogrammering 1

I denna kurs ska vi bygga API:et som programmet ska prata med, vi ska alltså hantera all lagring av data och tillhandahålla den via ett REST-api. Vi ska implementera ett antal endpoints.

Ni ska göra göra en projektplan (projektupplägg) för hela denna uppgift, alltså både Java-programmet och REST-api:et. Vi ska börja med att skriva ner alla “Use Cases”. I projektplanen beskriver ni hela applikationens funktion. Utifrån projektplanen ska ni utveckla applikationen där presentations­logiken ligger i java-programmet och den övriga logiken i REST-api:et. All kod ska naturligtvis följa uppsatt standard när det gäller läsbarhet och kommentarer.

När arbetet är utfört ska ni göra en dokumentation och utvärdering av ert arbeta. Ni ska även muntligt presentera ert resultat. I er dokumentation bör ni identifierar sårbarheter eller hot som kan utnyttjas. Ni ska beskriva tekniken bakom denna webbapplikation och samspelet av olika tekniker som har används.

Om användarnamnet inte finns skapas det, annars kollas det mot lösen. → token.
Starta spel genom att välja spelare. Den andre blir intvingad och spelet hamnar i listan över pågående spel.

Extra när ni har gjort klart alla end-points kan ni lägga in lite felkotroll. Om man skickar något som är i konfilkt med spelet, tex att man begär ut en fråga utan att det är min tur kan man skicka ett annat svar. Mitt förslag är att man skickar ett 409: Conflict

// Ex. på data att retunera.
$data = [
  'status_code' => 409,
  'status_message' => 'Confict: Not your turn to get a question',
];

https://student.oedu.se/~jf/quiz-api/index.php?e=

måste endpoints (*=ej klara):

  • e=get-token
    Skickar login och password för att få en token som kan användas för alla endpoints som kräver detta.
    • skickar:
      • login
      • password
    • svar:
      • status_code
      • auth_token
      • user_id (mitt eget)
      • [status_message]
  • e=get-users
    • skickar:
      • auth_token
    • svar:
      • status_code
      • lista med {user_id, login}
      • [status_message]
  • e=get-game-state
    Hämtar status på ett spel, används för att kunna presentera hur och vad man har svarat på de olika frågorna i spelet.
    • skickar:
      • auth_token
      • game_id
    • svar:
      • status_code,
      • opponent_login
      • me[] (status på alla frågor 1-18 för me) (-1 = ej svarat, 0 = fel, 1 = rätt)
      • op[] (status på alla frågor 1-18 för op) (-1 = ej svarat, 0 = fel, 1 = rätt)
      • [status_message]
  • e=get-games
    • skickar:
      • auth_token
    • svar:
      • status_code
      • lista med egna pågående spel {game_id, opponent_id, opponent_login, my_question, my_turn} där game_id, opponent_id är id:n, opponent_login är en sträng och my_question, my_turn är 1 eller 0.
      • [status_message]
  • e=new-game
    Startar ett nytt spel
    • skickar:
      • auth_token
      • opponent_id (för motspelare)
    • svar:
      • status_code
      • game_id
      • [status_message]
  • e=get-next-turn-categories
    • skickar:
      • auth_token
      • game_id
    • svar:
      • List med 3 st {category_id, category}
      • [status_message]
  • e=new-turn
    Anger att man ska lägga in frågor för nästa omgång utifrån vald kategori. *Lite tips!.
    • skickar:
      • auth_token
      • game_id
      • category_id
    • svar:
      • status_code
      • [status_message]
  • e=get-question
    Här ska man hämta ut en ny fråga, man vill ju inte att man ska kunna hämta samma fråga två gånger. Den lösning vi har valt är att man lägger in en rad i answers med answered = 0 och answer = -1 när man hämtar ut frågan. Om man hämtar ut en fråga och det finns en rad med answered = 0 i aktuellt game så ska man markera detta svar som felaktigt och sätta answered = 1, tex att tiden har gått ut för att svara. Alltså om tiden har gått ut kommer man ha svarat answer = -1.
    • skickar:
      • auth_token
      • game_id
    • svar:
      • status_code
      • category_id
      • question
      • option1
      • option2
      • option3
      • option4
      • [status_message]
  • e=my-question
    Returnerar my_question = 1 om den är den spelaren som gör anropet som är den som ska svara på nästa fråga, annars blir my_question = 0.
    • skickar:
      • auth_token
      • game_id
    • svar:
      • status_code
      • my_question (1 eller 0)
  • e=my-turn
    Returnerar my_turn = 1 om den är spelaren som gör anropet som ska välja kategori, annars blir my_turn = 0.
    • skickar:
      • auth_token
      • game_id
    • svar:
      • status_code
      • my_turn (1 eller 0)
        <?php
         
        /**
         * @file
         * Check i my turn.
         */
         
        if (empty($_POST['game_id'])) {
          $data = [
            'status_code' => 400,
            'status_message' => 'no game_id',
          ];
          quiz_response($data);
        }
         
        // Get the game.
        $query = "SELECT * FROM `games` WHERE `id` = '" . $_POST['game_id'] . "'";
        $result = query($query);
        $game = mysqli_fetch_assoc($result);
        // Check if $user_id is in the game.
        if (!($user_id == $game['me'] || $user_id == $game['opponent'])) {
          $data = [
            'status_code' => 400,
            'status_message' => 'user not in game',
          ];
          quiz_response($data);
        }
         
        $query = "SELECT COUNT(*) as N FROM `answers` WHERE `game_id` = '" . $_POST['game_id'] . "' AND `user_id` = '" . $game['me'] . "'";
        $result = query($query);
        $row_me = mysqli_fetch_assoc($result);
        $me = $row_me['N'];
         
        $query = "SELECT COUNT(*) as N FROM `answers` WHERE `game_id` = '" . $_POST['game_id'] . "' AND `user_id` = '" . $game['opponent'] . "'";
        $result = query($query);
        $row_op = mysqli_fetch_assoc($result);
        $op = $row_op['N'];
         
        // Decide whether or not it is your turn to start new-turn.
        $my_turn = 0;
        if ($me == $op) {
          if ($user_id == $game['me']) {
            if (in_array($me, [0, 6, 12])) {
              $my_turn = 1;
            }
          }
          else {
            if (in_array($op, [3, 9, 15])) {
              $my_turn = 1;
            }
          }
        }
         
        $data = [
          'status_code' => 200,
          'my_turn' => $my_turn,
        ];
        quiz_response($data);
  • e=check-answer
    Eftersom e=get-question fungerar som det gör borde man kunna uppdatera den enda rad ur answers till detta spel med mitt user_id som har answered = 0
    • skickar:
      • auth_token
      • game_id
      • option (1,4)
    • svar:
      • status_code
      • correct (0,1)
      • [status_message]

extra endpoints:

  • hämta statistik för en användare (kräver token)
  • ge upp (kräver token)
  • toplista rätta svar - den andres rätta svar (kräver token)
  • toplista vunna-förlorade matcher (kräver token)