Package com.barrybecker4.game.common.online.server

Source Code of com.barrybecker4.game.common.online.server.OnlineGameServer

/** Copyright by Barry G. Becker, 2000-2011. Licensed under MIT License: http://www.opensource.org/licenses/MIT  */
package com.barrybecker4.game.common.online.server;

import com.barrybecker4.common.app.CommandLineOptions;
import com.barrybecker4.game.common.GameContext;
import com.barrybecker4.ui.components.Appendable;

import java.io.IOException;
import java.net.BindException;
import java.net.ServerSocket;
import java.util.LinkedList;
import java.util.List;

/**
* The abstract server for online games.
* This can be run from within a ui or from a command line.
* If running from the command line use:
*       java OnlineGameServer -game <gameName>
* e.g.  java OnlineGameServer -game poker
*
* If running from the UI, see
*   OnlineGameServerFrame
*
* Manages the tables for the game room.
* Has a GameController for each table.
* Consider using executor framework to manage threads.
*
* @author Barry Becker
*/
public class OnlineGameServer  {

    public static final String GAME_OPTION = "game"// NON-NLS

    private Appendable text;
    private ServerSocket server;
    private volatile boolean stopped = false;

    /** keep a list of the threads that we have for each client connection.  */
    private List<ClientWorker> clientConnections;

    /**
     * Create the online game server to serve all online clients.
     * @param gameType - one of the supported games (see plugin file)
     * @param textArea - may be null if not running in UI, else shows traffic messages.
     */
    public OnlineGameServer(String gameType, Appendable textArea) {

        this.text = textArea;
        clientConnections = new LinkedList<ClientWorker>();
        openListenSocket(gameType);
    }

    public void shutDown() {
        stopped = true;
        for (ClientWorker worker : clientConnections) {
            worker.stop();
        }
        try {
            server.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * open a server socket to listen on our assigned port for
     * requests from clients. Updates will be broadcast on this socket.
     * Maintain a list of clientConnections corresponding to the players
     * that we need to broadcast to when something changes.
     */
    void openListenSocket(String gameType) {

        ServerCommandProcessor cmdProcessor = new ServerCommandProcessor(gameType);
        int port = cmdProcessor.getPort();

        server = createServerSocket(port);
        acceptClientConnections(cmdProcessor);
    }

    /**
     * Allows the server to listen for client messages.
     * @param port port to listen on.
     * @return new server socket
     */
    private ServerSocket createServerSocket(int port) {
        ServerSocket socket;
        try {
            socket = new ServerSocket(port);
        }
        catch (BindException e) {
            GameContext.log(0, "Address already in use! " +
                    "Perhaps there is already another game server sunning on this port:" + port);
            throw new RuntimeException(e);
        }
        catch (IOException e) {
            GameContext.log(0, "Could not listen on port " + port);
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return socket;
    }

    private void acceptClientConnections(ServerCommandProcessor cmdProcessor) {

        while (!stopped) {
            try {
                // accept new connections from players wanting to join.
                ClientWorker worker = new ClientWorker(server.accept(), text, cmdProcessor, clientConnections);
                clientConnections.add(worker);
                new Thread(worker).start();
            }
            catch (IOException e) {
                GameContext.log(0, "Accept failed on port " + server.getLocalPort());
                e.printStackTrace();
                break;
            }
        }
    }

    /**
     * Objects created in run method are finalized when
     * program terminates and thread exits.
     * Also shuts down all client workers so they do not keep waiting for commands to process.
     */
    @Override
    protected void finalize() {
        try {
            shutDown();
            super.finalize();
        }
        catch (IOException e) {
            GameContext.log(0, "Could not close socket");
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        catch (Throwable t) {
            t.printStackTrace();
        }
    }

    /**
     * @param options command line options to verify
     * @return true if valid.
     */
    public static boolean verifyCmdLineOptions(CommandLineOptions options) {
        if (options.contains("help") || !options.contains(GAME_OPTION)) {
           GameContext.log(0, "Usage: -game <game name>\n");
            return false;
        }
        if (options.getValueForOption(GAME_OPTION) == null) {
            GameContext.log(0,"You must specify a valid game. See plugins.xml for list of available games.");
            return false;
        }
        return true;
    }

     /**
      * Implements OnlineGameServerInterface which is also implemented by GtpTesujiSoftGoServer.
      * not currently used, but I'm trying to have a consistent game server interface.
      *
     public boolean handleCommand(String cmdLine, StringBuilder response) {
         String[] cmdArray = StringUtils.tokenize(cmdLine);
         String cmdStr = cmdArray[0];
         boolean status = true;
         GameCommand cmd = new GameCommand(GameCommand.Name.valueOf(cmdStr), cmdStr);
         return processCmd(cmd);
    } */

    /**
     * create and show the server.
     */
    public static void main(String[] args) {

        CommandLineOptions options = new CommandLineOptions(args);

        if (verifyCmdLineOptions(options))  {
            String gameName = options.getValueForOption(GAME_OPTION);
            new OnlineGameServer(gameName, null);
        }
    }
}
TOP

Related Classes of com.barrybecker4.game.common.online.server.OnlineGameServer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.