Online-TicTacToe

Log | Files | Refs | README | LICENSE

TicTacToeWS.java (20696B)


      1 /*
      2  * Implements the Tic Tac Toe Web Service.
      3  */
      4 package com.tttws;
      5 
      6 import jakarta.jws.WebMethod;
      7 import jakarta.jws.WebParam;
      8 import jakarta.jws.WebService;
      9 import jakarta.jws.soap.SOAPBinding;
     10 
     11 /*
     12  * Tic Tac Toe Web Service
     13  */
     14 
     15 /**
     16  *
     17  * @author petar
     18  */
     19 
     20 @WebService(serviceName = "TicTacToeWebService")
     21 @SOAPBinding(style = SOAPBinding.Style.RPC)
     22 public class TicTacToeWS {
     23     
     24     private final TTT_MySQL dao; 
     25     
     26     /**
     27      * Web Service constructor
     28      */
     29     public TicTacToeWS() {
     30         dao = new TTT_MySQL("localhost", "root", "", "tictactoe");
     31     }
     32 
     33     /**
     34      * Used to login to the system
     35      * @param username the username of the user logging in.
     36      * @param password the password of the user logging in.
     37      * @return either 0 if incorrect details, an integer greater than 0 (which is the users id) if correct details, -1 if there is a general error.
     38      */
     39     @WebMethod(operationName = "login")
     40     public int login(@WebParam(name = "username") String username, @WebParam(name = "password") String password) {
     41         try {
     42             String sqlCmd = "SELECT autokey FROM users WHERE username = '" + username;
     43             sqlCmd += "' AND password = SHA1('" + password + "') AND isactive = 1;";
     44             String result = dao.retrieve(sqlCmd);
     45             if("ERROR".equals(result)) {
     46                 return 0;
     47             } else {
     48                 return Integer.parseInt(result);
     49             }
     50         } catch(Exception e) {
     51             System.out.println("Error is : " + e.getMessage());
     52             return -1;
     53         }
     54     }
     55 
     56     /**
     57      * Used to register a new user on the system.
     58      * @param username the username of the new user.
     59      * @param password the password of the new user.
     60      * @param name - the name of the new user.
     61      * @param surname the surname of the new user.
     62      * @return The user provides their username, password, name and surname. If successful, the method returns the users id on the system (the autokey 
     63      * field from the users table). If unsuccessful, it returns either “ERROR-REPEAT” if a user with that username already exists, “ERROR-INSERT” if the 
     64      * method could not add the data to the users table, “ERROR-RETRIEVE “ if the method cannot retrieve the newly inserted data from the users table, or
     65      * “ERROR-DB” if the method cannot find the DB.
     66      */
     67     @WebMethod(operationName = "register")
     68     public String register(@WebParam(name = "username") String username, @WebParam(name = "password") String password, @WebParam(name = "name") String name, @WebParam(name = "surname") String surname) {
     69         String sqlCmd = "";
     70         
     71         sqlCmd = "SELECT COUNT(*) FROM users WHERE username = '" + username + "';";
     72         try {
     73             String result = "";
     74             result = dao.retrieve(sqlCmd);
     75             if(result.equals("0")) {
     76                 sqlCmd = "INSERT INTO users VALUES (default, '";
     77                 sqlCmd += name + "', '" + surname + "', '" + username + "', SHA1('";
     78                 sqlCmd += password + "'), 1, default);";
     79                 System.out.println(sqlCmd);
     80                 try {
     81                     result = dao.insert(sqlCmd);
     82                     if(!"INSERTED 1 ROWS.".equals(result)) {
     83                         return "ERROR-INSERT";
     84                     } else {
     85                         sqlCmd = "SELECT autokey FROM users WHERE username = '" + username;
     86                         sqlCmd += "' AND password = SHA1('" + password + "') AND isactive = 1;";
     87 
     88                         try {
     89                             result = dao.retrieve(sqlCmd);
     90                             return result;
     91                         } catch(Exception g) {
     92                             return "ERROR-RETRIEVE";
     93                         }
     94                     }
     95                 } catch(Exception e) {
     96                     return "ERROR-DB";
     97                 }
     98             } else {
     99                 return "ERROR-REPEAT";
    100             }
    101         } catch(Exception u) {
    102             return "ERROR-DB";
    103         }        
    104     }
    105 
    106     /**
    107      * Used to create a new game.
    108      * @param uid the user id of the user creating the new game.
    109      * @return either the id of the new game (returned as a string), or "ERROR-NOTFOUND", "ERROR-RETRIEVE", or "ERROR-INSERT" if the game couldn't be created, or "ERROR-DB" if unable to talk to the DB or DBMS.
    110      */
    111     @WebMethod(operationName = "newGame")
    112     public String newGame(@WebParam(name = "uid") int uid) {
    113         String sqlCmd = "INSERT INTO games VALUES(default, " + uid + ", NULL, -1, default);";
    114         try {
    115             String result = dao.insert(sqlCmd);
    116             if(result.equals("INSERTED 1 ROWS.")) {
    117                 sqlCmd = "SELECT autokey FROM games WHERE gamestate = -1 AND p1 = " + uid + " AND p2 IS NULL ORDER BY autokey DESC LIMIT 1;";
    118                 try {
    119                     result = dao.retrieve(sqlCmd);
    120                     if(result.length() > 0) {
    121                         return result;
    122                     } else {
    123                         return "ERROR-NOTFOUND";
    124                     }
    125                 } catch(Exception g) {
    126                     return "ERROR-RETRIEVE";
    127                 }
    128             } else {
    129                 return "ERROR-INSERT";
    130             }
    131         } catch(Exception e) {
    132             return "ERROR-DB";
    133         }
    134     }
    135 
    136     /**
    137      * Used to join an existing game.
    138      * @param uid the user id of the person joining the game.
    139      * @param gid the game id of the game the player wants to join.
    140      * @return 1 (as a string) if able to join, 0 (as a string) if unable to join, or "ERROR-DB" if unable to talk to the DB or DBMS.
    141      */
    142     @WebMethod(operationName = "joinGame")
    143     public String joinGame(@WebParam(name = "uid") int uid, @WebParam(name = "gid") int gid) {
    144         String sqlCmd = "UPDATE games SET p2 = " + uid + ", gamestate = 0 WHERE autokey = " + gid + ";";
    145         try {
    146             String result = dao.update(sqlCmd);
    147             if(result.equals("UPDATED 1 ROWS.")) {
    148                 return "1";
    149             } else {
    150                 return "0";
    151             }
    152         } catch(Exception e) {
    153             return "ERROR-DB";
    154         }
    155     }
    156     
    157     /**
    158      * Returns the current board as a formatted string.
    159      * @param gid the game id of the game whose board we want to see.
    160      * @return Used to return all moves taken to date for a particular game. If successful, the method returns the moves taken as a string as follows {pId, x, y} for each row, each row separated by \n. The moves are returned in order of play (i.e. first move will be first row returned etc.). Using this we can evaluate how many moves have been taken (i.e. the number of rows), the last player to take a move (pId of the final row), plus all the moves taken to date. 
    161      * The method returns "ERROR-NOMOVES" if no moves have yet been made for that game, or "ERROR-DB" if unable to talk to the DB or DBMS.
    162      */
    163     @WebMethod(operationName = "getBoard")
    164     public String getBoard(@WebParam(name = "gid") int gid) {
    165         String sqlCmd = "SELECT pId, x, y FROM moves WHERE gId = " + gid + " ORDER BY played ASC;";
    166         try {
    167             String result = dao.retrieve(sqlCmd);
    168             if(result.length() > 0) {
    169                 return result;
    170             } else {
    171                 return "ERROR-NOMOVES";
    172             }
    173         } catch(Exception e) {
    174             return "ERROR-DB";
    175         }
    176     }
    177 
    178     /**
    179      * Returns the state of the game.
    180      * @param gid the game id of the game whose state we wish to check.
    181      * @return -1 (as a string) if waiting for a second player to join, 0 (as a string) if the game is in progress, 1 (as a string) if player 1 has won, 
    182      * 2 (as a string) if player 2 has won, 3 (as a string) if a draw, or "ERROR-NOGAME" if a game matching the game id cannot be found, or "ERROR-DB" if
    183      * unable to talk to the DB or DBMS.
    184      */
    185     @WebMethod(operationName = "getGameState")
    186     public String getGameState(@WebParam(name = "gid") int gid) {
    187         String sqlCmd = "SELECT gamestate FROM games WHERE autokey = " + gid + ";";
    188         try {
    189             String result = dao.retrieve(sqlCmd);
    190             if(result.length() > 0) {
    191                 return result;
    192             } else {
    193                 return "ERROR-NOGAME";
    194             }
    195         } catch(Exception e) {
    196             return "ERROR-DB";
    197         }
    198     }
    199 
    200     /**
    201      * Sets the state of a game.
    202      * @param gid the game id of the game whose state we wish to set.
    203      * @param gstate the state we wish to set the game to.
    204      * @return 1 (as a string) if successful, "ERROR-NOGAME" if unable to find a game matching gid, "ERROR-DB" if unable to talk the the DB or DBMS.
    205      */
    206     @WebMethod(operationName = "setGameState")
    207     public String setGameState(@WebParam(name = "gid") int gid, @WebParam(name = "gstate") int gstate) {
    208         String sqlCmd = "UPDATE games SET gamestate = " + gstate + " WHERE autokey = " + gid + ";";
    209         try {
    210             String result = dao.update(sqlCmd);
    211             if(result.equals("UPDATED 1 ROWS.")) {
    212                 return "1";
    213             } else {
    214                 return "ERROR-NOGAME";
    215             }
    216         } catch(Exception e) {
    217             return "ERROR-DB";
    218         }
    219     }
    220 
    221     /**
    222      * Checks a particular square in a game to see if it has been or can be taken.
    223      * @param x the columns position of the square.
    224      * @param y the row position of the square.
    225      * @param gid the game we are playing/checking.
    226      * @return 1 (as a string) if the square is taken, 0 (as a string) if the square is available, "ERROR-DB" if there is a problem talking to the DB or DBMS.
    227      */
    228     @WebMethod(operationName = "checkSquare")
    229     public String checkSquare(@WebParam(name = "x") int x, @WebParam(name = "y") int y, @WebParam(name = "gid") int gid) {
    230         String sqlCmd = "SELECT COUNT(*) FROM moves WHERE x = " + x + " AND y = " + y + " AND ";
    231         sqlCmd += " gId = " + gid + ";";
    232         try {
    233             String result = dao.retrieve(sqlCmd);
    234             return result;
    235         } catch (Exception e) {
    236             return "ERROR-DB";
    237         }
    238     }
    239 
    240     /**
    241      * Takes a square in a particular game for a particular player.
    242      * @param x the column position of the square.
    243      * @param y the row position of the square.
    244      * @param gid the game we are playing.
    245      * @param pid the user id of the player taking the square.
    246      * @return 1 (as a string) if successful, 0 (as a string) if unsuccessful, "ERROR-TAKEN" if the square is unavailable, "ERROR-DB" if there is a problem
    247      * talking to the DB or DBMS, "ERROR" if there is a general error.
    248      */
    249     @WebMethod(operationName = "takeSquare")
    250     public String takeSquare(@WebParam(name = "x") int x, @WebParam(name = "y") int y, @WebParam(name = "gid") int gid, @WebParam(name = "pid") int pid) {
    251         int count = Integer.parseInt(checkSquare(x, y, gid));
    252         String flag = "";
    253         switch(count) {
    254             case 1:
    255                 flag = "ERROR-TAKEN";
    256             break;
    257             case 0:
    258                 String sqlCmd = "INSERT INTO moves VALUES(default, " + pid + ", " + x + ", " + y;
    259                 sqlCmd += ", default, " + gid + ");";
    260                 try {
    261                     String result = dao.insert(sqlCmd);
    262                     if(result.equals("INSERTED 1 ROWS.")) {
    263                         flag = "1";
    264                     } else {
    265                         flag = "0";
    266                     }
    267                 } catch(Exception e) {
    268                     flag = "ERROR-DB";
    269                 }
    270             break;
    271             default: 
    272                 flag = "ERROR";
    273         }
    274         return flag;
    275     }
    276 
    277     /**
    278      * Used to see if the game is over or not, and who has won if it is over.
    279      * @param gid the game id of the game we are checking.
    280      * @return 0 (as a string) if the game hasn’t been won but can continue to be played, 1 (as a string) if player 1 has won, 
    281      * 2 (as a string) if player 2 has won, or 3 (as a string) if the game is a draw. The method will return “ERROR-RETRIEVE” if there is an issue 
    282      * getting details about the game, “ERROR-NOGAME” if no game can be found matching the gid, “ERROR-DB” if there is a problem accessing the DB or DBMS.
    283      */
    284     @WebMethod(operationName = "checkWin")
    285     public String checkWin(@WebParam(name = "gid") int gid) {
    286         String result = getBoard(gid);
    287         int winner = 0;
    288         if(result.length() > 0) {
    289             String[] rows = result.split("\n");
    290             int num_moves = rows.length;
    291             int[][] table = new int[3][3];
    292             for(int a = 0; a < 3; a++) {
    293                 for(int b = 0; b < 3; b++) {
    294                     table[a][b] = 0;
    295                 }
    296             }
    297             for(int i = 0; i < num_moves; i++) {
    298                 String[] cells = rows[i].split(",");
    299                 int pid = Integer.parseInt(cells[0]);
    300                 int x = Integer.parseInt(cells[1]);
    301                 int y = Integer.parseInt(cells[2]);
    302                 table[x][y] = pid;
    303             }
    304             
    305             //check rows and cols
    306             for(int t = 0; t < 3; t++) {
    307                 if(table[t][0] == table[t][1] && table[t][1] == table[t][2] && table[t][0] != 0) {
    308                     winner = table[t][0];
    309                 }
    310                 if(table[0][t] == table[1][t] && table[1][t] == table[2][t] && table[0][t] != 0) {
    311                     winner = table[0][t];
    312                 }
    313             }
    314             
    315             //Check diagonals
    316             if(table[0][0] == table[1][1] && table[1][1] == table[2][2] && table[0][0] != 0) {
    317                 winner = table[0][0];
    318             }
    319             if(table[0][2] == table[1][1] && table[1][1] == table[2][0] && table[0][2] != 0) {
    320                 winner = table[0][2];
    321             }
    322             
    323             if(winner > 0) {
    324                 try {
    325                     // check is winner p1 or p2;
    326                     String sqlCmd = "SELECT * FROM games WHERE autokey = " + gid + ";";
    327                     String gDetails = dao.retrieve(sqlCmd);
    328                     if(gDetails.length() > 0) {
    329                         String[] details = gDetails.split(",");
    330                         if(details.length > 0) {
    331                             int p1 = Integer.parseInt(details[1]);
    332                             int p2 = Integer.parseInt(details[2]);
    333                             if(winner == p1) {
    334                                 return "1";
    335                             } else {
    336                                 return "2";
    337                             }
    338                         } else {
    339                             return "ERROR-RETRIEVE";
    340                         }
    341                     } else {
    342                         return "ERROR-RETRIEVE";
    343                     }
    344                 } catch(Exception e) {
    345                     return "ERROR-DB";
    346                 }
    347             } else {
    348                 if(num_moves < 9) {
    349                     return "0";
    350                 } else {
    351                     return "3";
    352                 }
    353             }
    354         } else {
    355             return "ERROR-NOGAME";
    356         }
    357     }
    358 
    359     /**
    360      * Used to remove un-started games from the DB.
    361      * @param gid the game id of the game you wish to remove.
    362      * @param uid the user id of the person making the request (can only delete games you created).
    363      * @return If the game has already started or the user is not the creator of the game, the method returns “ERROR-GAMESTARTED”, 
    364      * otherwise it returns 1 (as a string). The method returns “ERROR-DB” if it cannot access the DBMS.
    365      */
    366     @WebMethod(operationName = "deleteGame")
    367     public String deleteGame(@WebParam(name = "gid") int gid, @WebParam(name = "uid") int uid) {
    368         String sqlCmd = "SELECT COUNT(*) FROM games WHERE autokey = " + gid + " AND p1 = ";
    369         sqlCmd += uid + " AND p2 IS NULL;";
    370         try {
    371             String result = dao.retrieve(sqlCmd);
    372             if(result.equals("1")) {
    373                 sqlCmd = "DELETE FROM moves WHERE gID = " + gid + ";"; // delete moves first
    374                 result = dao.remove(sqlCmd);                      // run the SQL statement 
    375                 sqlCmd = "DELETE FROM games WHERE autokey = " + gid + ";";
    376                 result = dao.remove(sqlCmd);
    377                 return "1";
    378             } else {
    379                 return "ERROR-GAMESTARTED";
    380             }
    381         } catch(Exception e) {
    382             return "ERROR-DB";
    383         }
    384     }
    385 
    386     /**
    387      * Used to show games you have created but that have not yet started.
    388      * @param uid the user id of the player making the request.
    389      * @return If the method is successful it returns a string as follows {{g.autokey, u.username, g.started}\n}*. If unsuccessful, the method returns 
    390      * “ERROR-NOGAMES” if it can find no games, or “ERROR-DB” if it cannot access the DBMS.
    391      */
    392     @WebMethod(operationName = "showMyOpenGames")
    393     public String showMyOpenGames(@WebParam(name = "uid") int uid) {
    394         String sqlCmd = "SELECT g.autokey, u.username, g.started FROM games g, users u WHERE g.p1 = " + uid + " AND g.p2 IS NULL AND g.p1 = u.autokey ORDER BY g.started ASC;";
    395         try {
    396             String result = dao.retrieve(sqlCmd);
    397             if(result.length() > 0) {
    398                 return result;
    399             } else {
    400                 return "ERROR-NOGAMES";
    401             }
    402         } catch(Exception e) {
    403             return "ERROR-DB";
    404         }
    405     }
    406 
    407     /**
    408      * Retrieves all games the user has played/is playing.
    409      * @param uid the user id of the player making the request.
    410      * @return If successful it returns a string as follows {{g.autokey, h.username, o.username, g.started}\n}*. h.username and o.username are the 
    411      * usernames of player 1 and player 2 respectively. If unsuccessful, the method returns “ERROR-NOGAMES” if it can find no games, or “ERROR-DB” 
    412      * if it cannot access the DBMS.
    413      */
    414     @WebMethod(operationName = "showAllMyGames")
    415     public String showAllMyGames(@WebParam(name = "uid") int uid) {
    416         String sqlCmd = "SELECT g.autokey, h.username, o.username, g.started FROM games g, users h, users o WHERE (g.p1 = " + uid + " OR g.p2 = " + uid + ") AND g.p1 = h.autokey AND g.p2 = o.autokey ORDER BY g.started ASC;";
    417         try {
    418             String result = dao.retrieve(sqlCmd);
    419             if(result.length() > 0) {
    420                 return result;
    421             } else {
    422                 return "ERROR-NOGAMES";
    423             }
    424         } catch(Exception e) {
    425             return "ERROR-DB";
    426         }
    427     }
    428 
    429     /**
    430      * Used to generate the content for a league table.
    431      * @return If successful it returns a string as follows {{g.autokey, h.username, o.username, g.gamestate, g.started}\n}*. h.username and o.username 
    432      * are the usernames of player 1 and player 2 respectively. If unsuccessful, the method returns “ERROR-NOGAMES” if it can find no games, or “ERROR-DB”
    433      * if it cannot access the DBMS.
    434      */
    435     @WebMethod(operationName = "leagueTable")
    436     public String leagueTable() {
    437         String sqlCmd = "SELECT g.autokey, h.username, o.username, g.gamestate, g.started FROM games g, users h, users o WHERE g.p1 = h.autokey AND g.p2 = o.autokey ORDER BY g.started ASC;";
    438         try {
    439             String result = dao.retrieve(sqlCmd);
    440             if(result.length() > 0) {
    441                 return result;
    442             } else {
    443                 return "ERROR-NOGAMES";
    444             }
    445         } catch(Exception e) {
    446             return "ERROR-DB";
    447         }
    448     }
    449 
    450     /**
    451      * The list of open games (those with a p1 but no p2).
    452      * @return If successful it returns a string as follows {{g.autokey, h.username, g.started}\n}*. h.username is the usernames of the player who started
    453      * the game. If unsuccessful, the method returns “ERROR-NOGAMES” if it can find no games, or “ERROR-DB” if it cannot access the DBMS.
    454      */
    455     @WebMethod(operationName = "showOpenGames")
    456     public String showOpenGames() {
    457         String sqlCmd = "SELECT g.autokey, h.username, g.started FROM games g, users h WHERE g.p2 IS NULL AND g.p1 = h.autokey ORDER BY g.started ASC;";
    458         try {
    459             String result = dao.retrieve(sqlCmd);
    460             if(result.length() > 0) {
    461                 return result;
    462             } else {
    463                 return "ERROR-NOGAMES";
    464             }
    465         } catch(Exception e) {
    466             return "ERROR-DB";
    467         }
    468     }
    469     
    470     /**
    471      * Closes the connection to the database (before exiting the application).
    472      */
    473     @WebMethod(operationName = "closeConnection")
    474     public void closeConnection() {
    475         dao.close();
    476     }
    477 }