paxos.GameServer.java Source code

Java tutorial

Introduction

Here is the source code for paxos.GameServer.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package paxos;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.json.JSONException;
import org.json.JSONObject;

public class GameServer {
    public static JSONObject tempJSONmsg = null;

    final static int port = 9876;

    public static void main(String args[]) {
        Game myGame = new Game();
        Socket socket = null;
        ServerSocket GameServer = null;
        System.out.println("Server Listening......");
        try {
            GameServer = new ServerSocket(port);
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("Server error");
        }

        while (true) {
            try {
                socket = GameServer.accept();
                String clientAddress = socket.getRemoteSocketAddress().toString();
                int clientPort = socket.getPort();
                System.out.println("Connection established. Client: " + clientAddress + "on port " + clientPort);

                ServerThread st = new ServerThread(socket, myGame);
                st.start();
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("Connection Error");
            }
        }
    }
}

class ServerThread extends Thread {

    String line = null;
    BufferedReader is = null;
    PrintWriter os = null;
    Socket s = null;
    Game myGame = null;

    public ServerThread(Socket s, Game myGame) {
        this.s = s;
        this.myGame = myGame;
    }

    public void run() {
        String username = null;
        String address = null;
        int port = 0;
        int id_player = -1;
        String method = null;
        JSONObject jsonMessage;
        try {
            is = new BufferedReader(new InputStreamReader(s.getInputStream()));
            os = new PrintWriter(s.getOutputStream());
        } catch (IOException e) {
            System.out.println("IO error in server thread");
        }

        try {
            //JOINGAME
            //check whether or not the game is waiting
            boolean isAllowedToJoin = false;
            if (myGame.getStatus() == 0) {
                System.out.println("Game status is 0");
                //game is waiting -> check client's username
                try {
                    jsonMessage = new JSONObject(is.readLine());
                    username = jsonMessage.optString("username");
                    port = jsonMessage.optInt("udp_port");
                    address = jsonMessage.optString("udp_address");
                    System.out.println("Client username is " + username);
                    if (username.length() > 0) {
                        //check whether or not username exists
                        if (!myGame.isUsernameExist(username)) {
                            System.out.println("Username not exist");
                            isAllowedToJoin = true;
                            int new_id = myGame.getNewID();
                            id_player = new_id;
                            System.out.println("Id player is : " + new_id);
                            Player newP = new Player(new_id, address, port, username);
                            myGame.addPlayer(newP);
                            System.out.println("Send to client: " + ServerResponse.joinGameOK(new_id).toString());
                            os.println(ServerResponse.joinGameOK(new_id).toString());
                            os.flush();
                        } else {
                            os.println(ServerResponse.statusFail("user exists"));
                            os.flush();
                        }
                    } else {
                        os.println(ServerResponse.statusFail("username not valid"));
                        os.flush();
                    }
                } catch (JSONException e) {
                    //send wrongRequestError
                    os.println(ServerResponse.wrongRequestError().toString());
                    os.flush();
                    e.printStackTrace();
                }
            } else {
                //the game already has already started
                os.println(ServerResponse.statusFail("please wait, game is currently running").toString());
                os.flush();
            }
            if (!isAllowedToJoin)
                return; //close connection
            //END-JOINGAME

            //READY
            //waiting ready message from client
            //check whether or not the game is waiting
            boolean isReady = false;
            System.out.println("Waiting ready message from client");
            while (!isReady) {
                if (myGame.getStatus() == 0) {
                    System.out.println("Game status is 0");
                    //game is waiting -> check client's username
                    try {
                        String temp_ = is.readLine();

                        jsonMessage = new JSONObject(temp_);
                        System.out.println("Message in !isReady : " + temp_);
                        method = jsonMessage.optString("method");
                        if (method.equals("ready")) {
                            if (myGame.getStatus() != 0) {
                                os.println(ServerResponse.statusFail("please wait, game is currently running"));
                                os.flush();
                                myGame.setPlayerReady(id_player);

                            } else {
                                os.println(ServerResponse.statusOK());
                                os.flush();
                                myGame.setPlayerReady(id_player);//else if error, send error response to client, blm dibuat
                                isReady = true;
                            }
                        } else if (method.equals("leave")) {
                            //leave();
                            myGame.removePlayerWithID(id_player);
                            os.println(ServerResponse.statusOK());
                            os.flush();
                            myGame.removePlayerWithID(id_player);
                            return; //exit
                        } else {
                            os.println(ServerResponse.statusError("Method not allowed"));
                            os.flush();
                        }
                    } catch (JSONException e) {
                        //send wrongRequestError
                        os.println(ServerResponse.wrongRequestError().toString());
                        os.flush();
                        e.printStackTrace();
                    }
                } else {
                    //the game already has already started
                    System.out.println("the game has already started");
                    os.println(ServerResponse.statusFail("please wait, game is currently running").toString());
                    os.flush();
                    break;
                }
            }
            //END-READY
            System.out.println("End-ready. Wait until other players ready");
            //WAIT UNTIL OTHER PLAYERS READY

            while (myGame.getStatus() != 1) {
                System.out.println("status : " + myGame.getStatus());
                try {
                    sleep(100);
                } catch (InterruptedException ex) {
                    Logger.getLogger(ServerThread.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            /*** START GAME (ROLE) ***/
            if (myGame.findPlayerWithID(id_player).getRole().equals("werewolf")) {

                os.println(ServerResponse.startGame("werewolf", myGame.getWerewolfFriends()));
                os.flush();
                System.out.println("Send werewolf role");
            } else { //civilian
                os.println(ServerResponse.startGame("civilian", null));
                os.flush();
                System.out.println("Send civilian role");
            }
            /*** END-START GAME (ROLE) ***/
            System.out.println("End start game (role)");

            /***** NIGHT 1 *****/
            int targetDay = 1;

            /***** DAILY LOOP *****/
            while (myGame.getStatus() == 1) {

                if (myGame.getDay() < targetDay)
                    nextDay();

                int cur_day = myGame.getDay();
                /*** DAY ***/
                /*** LIST CLIENT ***/
                boolean requestListClient = false;
                while (!requestListClient) {
                    try {
                        jsonMessage = new JSONObject(is.readLine());
                        method = jsonMessage.optString("method");
                        if (method.equals("client_address")) {
                            os.println(ServerResponse.listClient(myGame.getPlayers()));
                            os.flush();
                            requestListClient = true;
                        } else {
                            os.println(ServerResponse.statusError("Method not allowed"));
                            os.flush();
                        }
                    } catch (JSONException e) {
                        //send wrongRequestError
                        os.println(ServerResponse.wrongRequestError().toString());
                        os.flush();
                        e.printStackTrace();
                    }
                }
                /*** END-LIST CLIENT ***/

                os.println(ServerResponse.changePhase("day", myGame.getDay(), ""));
                os.flush();
                System.out.println(
                        "after send change phase" + ServerResponse.changePhase("day", myGame.getDay(), ""));
                /* PAXOS */
                /* proposer dan client menjalankan paxos */
                int kpu_id = -1;

                /* MENERIMA JAWABAN DARI ACCEPTOR */
                boolean getLeaderVote = false;
                while (!getLeaderVote) {
                    //                    long start = System.currentTimeMillis();
                    //                    VoteLeaderListener3 main = new VoteLeaderListener3("vll",is);
                    //                    main.start();
                    //                    try {
                    //                        while (main.isRunning) {
                    //                            synchronized (main) {
                    //                                main.wait(1000);
                    //                            }
                    //                        }
                    //                        long stop = System.currentTimeMillis();
                    //
                    //                        if (main.everythingDone)
                    //                            System.out.println("all done in " + (stop - start) + " ms.");
                    //                        else {
                    //                            System.out.println("could not do everything in "
                    //                                    + (stop - start) + " ms.");
                    //                            if (main.endedWithException != null)
                    //                                main.endedWithException.printStackTrace();
                    //                        }
                    //                    } catch (InterruptedException e) {
                    //                        System.out.println("You've killed me!");
                    //                    }
                    //                    jsonMessage = main.getJSONMessage() ;
                    //                    System.out.println("acceptor vll " + jsonMessage.toString());

                    //                    VoteLeaderListener VLL = new VoteLeaderListener("vll",is);
                    //                    System.out.println("gil " + id_player);
                    //                    VLL.start();
                    //                    System.out.println("gila " + id_player);
                    //                    Thread.sleep(20000);
                    //                    System.out.println("gila2" + id_player);
                    //                    //VLL.closeSocket();
                    //                    
                    //                    VLL.interrupt();

                    //                    System.out.println("after join " + id_player);
                    jsonMessage = new JSONObject(is.readLine());
                    System.out.println("acceptor vll " + jsonMessage.toString());

                    try {
                        System.out.println("after set timeout");
                        //jsonMessage = new JSONObject(is.readLine());
                        if (jsonMessage == null) {
                            System.out.println("client send null");
                        } else {
                            method = jsonMessage.optString("method");
                            System.out.println("method " + method);
                            if (method.equals("accepted_proposal")) {
                                os.println(ServerResponse.statusOK());
                                os.flush();
                                System.out.println("after send OK" + id_player);
                                kpu_id = Integer.parseInt(jsonMessage.optString("kpu_id"));
                                myGame.voteLeader(kpu_id);

                            } else if (method.equals("leave")) {
                                myGame.removePlayerWithID(id_player);
                                os.println(ServerResponse.statusOK());
                                os.flush();
                                myGame.removePlayerWithID(id_player);
                                return;
                            }
                        }
                        Thread.sleep(15000);
                        if (myGame.getVoteLeaderFinish() != true) {//ada yg ga ngirim atau ga ada yg n/2
                            System.out.println("kpuselected finsih false " + id_player + " " + myGame.getLeader());
                            os.println(ServerResponse.KPUSelected(myGame.getLeader()));
                            os.flush();
                        } else {
                            System.out.println("kpuselected finsih true" + id_player + " " + myGame.getLeader());
                            os.println(ServerResponse.KPUSelected(myGame.getLeader()));
                            os.flush();
                            getLeaderVote = true;
                        }

                    } /* catch (JSONException e) {
                      e.printStackTrace();
                      }*/ catch (InterruptedException ex) {
                        Logger.getLogger(ServerThread.class.getName()).log(Level.SEVERE, null, ex);
                    }

                    /*while(myGame.getVoteLeaderFinish() == false) {}
                    if (kpu_id == myGame.getLeader()) {
                    os.println(ServerResponse.statusOK());
                    } else {
                    os.println(ServerResponse.statusFail("KPU incorrect"));
                    }*/
                    //os.flush();
                }
                s.setSoTimeout(0);

                /* END-MENERIMA JAWABAN DARI ACCEPTOR */
                os.println(ServerResponse.KPUSelected(myGame.getLeader()));
                os.flush();
                /* MENGIRIM INFORMASI LEADER KE CLIENT */

                /* END-MENGIRIM INFORMASI LEADER KE CLIENT */

                /* SEND VOTE NOW DAY */
                boolean voteCivilianNow = false;
                while (!voteCivilianNow) {
                    System.out.println("Send civilian now" + id_player);
                    os.println(ServerResponse.voteNow("day"));
                    os.flush();
                    String response = is.readLine();
                    try {
                        System.out.println("Client get civilian now" + id_player);
                        JSONObject jsonResponse = new JSONObject(response);
                        String status = jsonResponse.optString("status");
                        if (status.equals("ok")) {
                            System.out.println("Client has got kpu_id");
                            //                            os.println(ServerResponse.listClient(myGame.getPlayers()));
                            //                            os.flush();
                            voteCivilianNow = true;
                        } else if (jsonResponse.optString("method").equals("leave")) {
                            return;
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
                /* END-SEND VOTE NOW DAY */

                /* KILL CIVILIAN VOTE */
                if (myGame.getLeader() == id_player) {//if the client is leader
                    boolean killCivilianVote = false;
                    while (!killCivilianVote) {
                        try {
                            System.out.println("Waiting client civilian vote" + id_player);
                            jsonMessage = new JSONObject(is.readLine());
                            System.out.println("Diterima : " + jsonMessage.toString() + id_player);
                            method = jsonMessage.optString("method");
                            if ((method.equals("vote_result_civilian")) || (method.equals("vote_result"))) {
                                int vote_status = Integer.parseInt(jsonMessage.optString("vote_status"));
                                if (vote_status == 1) {
                                    int player_to_kill = Integer.parseInt(jsonMessage.optString("player_killed"));
                                    System.out.println("Player Killed = " + player_to_kill);
                                    myGame.voteKillCivilian(player_to_kill);
                                    myGame.setVoteCivilianSuccess(true);
                                    os.println(ServerResponse.statusOK());
                                    killCivilianVote = true;
                                } else { //vote_status = -1
                                    os.println(ServerResponse.statusFail("Tie"));
                                }
                                os.flush();
                            } else if (method.equals("leave")) {
                                myGame.removePlayerWithID(id_player);
                                os.println(ServerResponse.statusOK());
                                os.flush();
                                myGame.removePlayerWithID(id_player);
                                return;
                            }
                            try {
                                sleep(5000);
                            } catch (InterruptedException ex) {
                                Logger.getLogger(ServerThread.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                }
                /* END-KILL CIVILIAN VOTE */

                /* WAITING VOTE FINISH */
                while (!myGame.getVoteCivilianFinish()) {
                    try {
                        sleep(100);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }
                /*** END WAITING VOTE FINISH ***/

                /*** SEND LIST CLIENT ***/
                requestListClient = false;
                while (!requestListClient) {
                    try {
                        jsonMessage = new JSONObject(is.readLine());
                        method = jsonMessage.optString("method");
                        if (method.equals("client_address")) {
                            os.println(ServerResponse.listClient(myGame.getPlayers()));
                            os.flush();
                            requestListClient = true;
                        } else {
                            os.println(ServerResponse.statusError("Method not allowed"));
                            os.flush();
                        }
                    } catch (JSONException e) {
                        //send wrongRequestError
                        os.println(ServerResponse.wrongRequestError().toString());
                        os.flush();
                        e.printStackTrace();
                    }

                }
                /*** END SEND LIST CLIENT ***/

                /*** START REVOTE ***/
                if (!myGame.getVoteCivilianSuccess()) {
                    myGame.setVoteCivilianFinish(false);
                    /*** WAITING REVOTE ***/
                    if (myGame.getLeader() == id_player) {//if the client is leader
                        boolean killCivilianVote = false;
                        while (!killCivilianVote) {
                            try {
                                System.out.println("Waiting client civilian vote" + id_player);
                                jsonMessage = new JSONObject(is.readLine());
                                System.out.println("Diterima : " + jsonMessage.toString());
                                method = jsonMessage.optString("method");
                                if ((method.equals("vote_result_civilian")) || (method.equals("vote_result"))) {
                                    int vote_status = Integer.parseInt(jsonMessage.optString("vote_status"));
                                    if (vote_status == 1) {
                                        int player_to_kill = Integer
                                                .parseInt(jsonMessage.optString("player_killed"));
                                        System.out.println("Killed: " + player_to_kill);
                                        myGame.voteKillCivilian(player_to_kill);
                                        myGame.setVoteCivilianSuccess(true);
                                        os.println(ServerResponse.statusOK());
                                        killCivilianVote = true;
                                    } else { //vote_status = -1
                                        os.println(ServerResponse.statusFail("Tie"));
                                    }
                                    os.flush();
                                } else if (method.equals("leave")) {
                                    myGame.removePlayerWithID(id_player);
                                    os.println(ServerResponse.statusOK());
                                    os.flush();
                                    myGame.removePlayerWithID(id_player);
                                    return;
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    /*** END WAITING REVOTE ***/

                    /*** WAITING RE-VOTE FINISH ***/
                    while (!myGame.getVoteCivilianFinish()) {
                        try {
                            sleep(100);
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }
                    /*** END WAITING RE-VOTE FINISH ***/

                    /*** SEND LIST CLIENT ***/
                    requestListClient = false;
                    while (!requestListClient) {
                        try {
                            jsonMessage = new JSONObject(is.readLine());
                            method = jsonMessage.optString("method");
                            if (method.equals("client_address")) {
                                os.println(ServerResponse.listClient(myGame.getPlayers()));
                                os.flush();
                                requestListClient = true;
                            } else {
                                os.println(ServerResponse.statusError("Method not allowed"));
                                os.flush();
                            }
                        } catch (JSONException e) {
                            //send wrongRequestError
                            os.println(ServerResponse.wrongRequestError().toString());
                            os.flush();
                            e.printStackTrace();
                        }

                    }
                    /*** END SEND LIST CLIENT ***/
                }
                /*** END REVOTE ***/
                /*** END-DAY ***/

                /*** NIGHT ***/
                /*** LIST CLIENT ***/
                //                requestListClient = false;
                //                while(!requestListClient){
                //                    try {
                //                        jsonMessage = new JSONObject(is.readLine());
                //                        method = jsonMessage.optString("method");
                //                        if(method.equals("client_address")){
                //                            os.println(ServerResponse.listClient(myGame.getPlayers()));
                //                            os.flush();
                //                            requestListClient = true;
                //                        } else {
                //                            os.println(ServerResponse.statusError("Method not allowed"));
                //                            os.flush();
                //                        }
                //                    } catch (JSONException e) {
                //                        //send wrongRequestError
                //                        os.println(ServerResponse.wrongRequestError().toString());
                //                        os.flush();
                //                        e.printStackTrace();
                //                    }
                //
                //                }
                /*** END-LIST CLIENT ***/

                /* CHANGE PHASE */
                os.println(ServerResponse.changePhase("night", myGame.getDay(), ""));
                os.flush();

                /* SEND VOTE NOW NIGHT */
                boolean voteWerewolfNow = false;
                while (!voteWerewolfNow) {
                    os.println(ServerResponse.voteNow("night"));
                    os.flush();
                    String response = is.readLine();
                    try {
                        JSONObject jsonResponse = new JSONObject(response);
                        String status = jsonResponse.optString("status");
                        if (status.equals("ok")) {
                            os.println(ServerResponse.listClient(myGame.getPlayers()));
                            os.flush();
                            voteWerewolfNow = true;
                        } else if (jsonResponse.optString("method").equals("leave")) {
                            return;
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
                /* END-SEND VOTE NOW NIGHT */

                boolean someoneKilled = false;
                while (!someoneKilled) {
                    myGame.setVoteWerewolfFinish(false);
                    myGame.setVoteWerewolfSuccess(false);
                    /* KILL WEREWOLF VOTE */
                    if (myGame.getLeader() == id_player) {//if the client is leader
                        int vote_attempt = 0;
                        boolean killWerewolfVote = false;
                        while (!killWerewolfVote && vote_attempt < 2) {
                            try {
                                jsonMessage = new JSONObject(is.readLine());
                                System.out.println("Vote Night from leader " + jsonMessage);
                                method = jsonMessage.optString("method");
                                if ((method.equals("vote_result_werewolf")) || (method.equals("vote_result"))) {
                                    int vote_status = Integer.parseInt(jsonMessage.optString("vote_status"));
                                    if (vote_status == 1) {
                                        int player_to_kill = Integer
                                                .parseInt(jsonMessage.optString("player_killed"));
                                        System.out.println("player_killed = " + player_to_kill);
                                        myGame.voteKillWerewolf(player_to_kill);
                                        os.println(ServerResponse.statusOK());
                                        killWerewolfVote = true;
                                    } else { //vote_status = -1
                                        os.println(ServerResponse.statusFail("Tie"));
                                        vote_attempt++;
                                    }
                                    os.flush();
                                } else if (method.equals("leave")) {
                                    myGame.removePlayerWithID(id_player);
                                    os.println(ServerResponse.statusOK());
                                    os.flush();
                                    myGame.removePlayerWithID(id_player);
                                    return;
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    /* END-KILL WEREWOLF VOTE */

                    /*** WAITING RE-VOTE FINISH ***/
                    while (!myGame.getVoteWerewolfFinish()) {
                        try {
                            sleep(100);
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }
                    /*** END WAITING RE-VOTE FINISH ***/

                    /*** SEND LIST CLIENT ***/
                    requestListClient = false;
                    while (!requestListClient) {
                        try {
                            jsonMessage = new JSONObject(is.readLine());
                            method = jsonMessage.optString("method");
                            if (method.equals("client_address")) {
                                os.println(ServerResponse.listClient(myGame.getPlayers()));
                                os.flush();
                                requestListClient = true;
                            } else {
                                os.println(ServerResponse.statusError("Method not allowed"));
                                os.flush();
                            }
                        } catch (JSONException e) {
                            //send wrongRequestError
                            os.println(ServerResponse.wrongRequestError().toString());
                            os.flush();
                            e.printStackTrace();
                        }

                    }
                    /*** END SEND LIST CLIENT ***/

                    if (myGame.getVoteWerewolfSuccess()) {
                        someoneKilled = true;
                    }
                }
                /*** END-NIGHT ***/
                targetDay = cur_day + 1;
            }
            /***** END-DAILY LOOP *****/

            //get Game Input From Client
            /*line = is.readLine();
            while (line.compareTo("QUIT")!=0) {
            os.println(line + " from server");
            os.flush();
            System.out.println("Response to Client  :  " + line);
            line=is.readLine();
            }*/
        } catch (IOException e) {
            line = this.getName(); //reused String line for getting thread name
            System.out.println("IO Error/ Client " + line + " terminated abruptly");
        } catch (NullPointerException e) {
            line = this.getName(); //reused String line for getting thread name
            System.out.println("Client " + line + " Closed");
        } catch (JSONException ex) {
            Logger.getLogger(ServerThread.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                System.out.println("Connection Closing..");
                if (is != null) {
                    is.close();
                    System.out.println(" Socket Input Stream Closed");
                }

                if (os != null) {
                    os.close();
                    System.out.println("Socket Out Closed");
                }
                if (s != null) {
                    s.close();
                    System.out.println("Socket Closed");
                }
            } catch (IOException ie) {
                System.out.println("Socket Close Error");
            }
        }
    }

    public static void leave(int id_player) {

    }

    public synchronized void nextDay() {
        myGame.nextDay();
    }

}