added mdga server controller
This commit is contained in:
		@@ -0,0 +1,209 @@
 | 
			
		||||
package pp.mdga.client.server;
 | 
			
		||||
 | 
			
		||||
import com.jme3.network.ConnectionListener;
 | 
			
		||||
import com.jme3.network.HostedConnection;
 | 
			
		||||
import com.jme3.network.Message;
 | 
			
		||||
import com.jme3.network.MessageListener;
 | 
			
		||||
import com.jme3.network.Network;
 | 
			
		||||
import com.jme3.network.Server;
 | 
			
		||||
import com.jme3.network.serializing.Serializer;
 | 
			
		||||
import pp.mdga.game.Game;
 | 
			
		||||
import pp.mdga.game.Player;
 | 
			
		||||
import pp.mdga.message.client.*;
 | 
			
		||||
import pp.mdga.message.server.*;
 | 
			
		||||
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.lang.System.Logger;
 | 
			
		||||
import java.lang.System.Logger.Level;
 | 
			
		||||
import java.util.concurrent.BlockingQueue;
 | 
			
		||||
import java.util.concurrent.LinkedBlockingQueue;
 | 
			
		||||
import java.util.logging.LogManager;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Server implementing the visitor pattern as MessageReceiver for ClientMessages
 | 
			
		||||
 */
 | 
			
		||||
public class MdgaServer implements MessageListener<HostedConnection>, ConnectionListener, ServerSender {
 | 
			
		||||
    private static final Logger LOGGER = System.getLogger(MdgaServer.class.getName());
 | 
			
		||||
 | 
			
		||||
    private Server myServer;
 | 
			
		||||
    private final ServerGameLogic logic;
 | 
			
		||||
    private final BlockingQueue<ReceivedMessage> pendingMessages = new LinkedBlockingQueue<>();
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        // Configure logging
 | 
			
		||||
        LogManager manager = LogManager.getLogManager();
 | 
			
		||||
        try {
 | 
			
		||||
            manager.readConfiguration(new FileInputStream("logging.properties"));
 | 
			
		||||
            LOGGER.log(Level.INFO, "Successfully read logging properties"); //NON-NLS
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            LOGGER.log(Level.INFO, e.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Starts the Battleships server.
 | 
			
		||||
     */
 | 
			
		||||
    public static void main(String[] args) {
 | 
			
		||||
        new MdgaServer().run();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new MdgaServer.
 | 
			
		||||
     */
 | 
			
		||||
    public MdgaServer() {
 | 
			
		||||
        LOGGER.log(Level.INFO, "Creating MdgaServer"); //NON-NLS
 | 
			
		||||
        logic = new ServerGameLogic(new Game(), this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void run() {
 | 
			
		||||
        startServer();
 | 
			
		||||
        this.connectionAdded(myServer, myServer.getConnection(0));
 | 
			
		||||
        while (true)
 | 
			
		||||
            processNextMessage();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void startServer() {
 | 
			
		||||
        try {
 | 
			
		||||
            LOGGER.log(Level.INFO, "Starting server..."); //NON-NLS
 | 
			
		||||
            myServer = Network.createServer(1234);
 | 
			
		||||
 | 
			
		||||
            initializeSerializables();
 | 
			
		||||
            myServer.start();
 | 
			
		||||
            registerListeners();
 | 
			
		||||
            LOGGER.log(Level.INFO, "Server started: {0}", myServer.isRunning()); //NON-NLS
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            LOGGER.log(Level.ERROR, "Couldn't start server: {0}", e.getMessage()); //NON-NLS
 | 
			
		||||
            exit(1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void processNextMessage() {
 | 
			
		||||
        try {
 | 
			
		||||
            pendingMessages.take().process(logic);
 | 
			
		||||
        } catch (InterruptedException ex) {
 | 
			
		||||
            LOGGER.log(Level.INFO, "Interrupted while waiting for messages"); //NON-NLS
 | 
			
		||||
            Thread.currentThread().interrupt();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initializeSerializables() {
 | 
			
		||||
        Serializer.registerClass(AnimationEnd.class);
 | 
			
		||||
        Serializer.registerClass(ClientStartGame.class);
 | 
			
		||||
        Serializer.registerClass(DeselectTSK.class);
 | 
			
		||||
        Serializer.registerClass(ForceContinueGame.class);
 | 
			
		||||
        Serializer.registerClass(ForceStartGame.class);
 | 
			
		||||
        Serializer.registerClass(JoinServer.class);
 | 
			
		||||
        Serializer.registerClass(LeaveGame.class);
 | 
			
		||||
        Serializer.registerClass(LobbyNotReady.class);
 | 
			
		||||
        Serializer.registerClass(LobbyReady.class);
 | 
			
		||||
        Serializer.registerClass(NoPowerCard.class);
 | 
			
		||||
        Serializer.registerClass(RequestBriefing.class);
 | 
			
		||||
        Serializer.registerClass(RequestDice.class);
 | 
			
		||||
        Serializer.registerClass(RequestMove.class);
 | 
			
		||||
        Serializer.registerClass(RequestPlayCard.class);
 | 
			
		||||
        Serializer.registerClass(SelectCard.class);
 | 
			
		||||
        Serializer.registerClass(SelectedPieces.class);
 | 
			
		||||
        Serializer.registerClass(SelectTSK.class);
 | 
			
		||||
 | 
			
		||||
        Serializer.registerClass(ActivePlayer.class);
 | 
			
		||||
        Serializer.registerClass(AnyPiece.class);
 | 
			
		||||
        Serializer.registerClass(Briefing.class);
 | 
			
		||||
        Serializer.registerClass(CeremonyMessage.class);
 | 
			
		||||
        Serializer.registerClass(Dice.class);
 | 
			
		||||
        Serializer.registerClass(DiceAgain.class);
 | 
			
		||||
        Serializer.registerClass(DiceNow.class);
 | 
			
		||||
        Serializer.registerClass(EndOfTurn.class);
 | 
			
		||||
        Serializer.registerClass(LobbyAccept.class);
 | 
			
		||||
        Serializer.registerClass(LobbyDeny.class);
 | 
			
		||||
        Serializer.registerClass(LobbyPlayerJoin.class);
 | 
			
		||||
        Serializer.registerClass(LobbyPlayerLeave.class);
 | 
			
		||||
        Serializer.registerClass(MoveMessage.class);
 | 
			
		||||
        Serializer.registerClass(NoTurn.class);
 | 
			
		||||
        Serializer.registerClass(PauseGame.class);
 | 
			
		||||
        Serializer.registerClass(PlayCard.class);
 | 
			
		||||
        Serializer.registerClass(PossibleCard.class);
 | 
			
		||||
        Serializer.registerClass(PossiblePiece.class);
 | 
			
		||||
        Serializer.registerClass(RankingResponse.class);
 | 
			
		||||
        Serializer.registerClass(RankingRollAgain.class);
 | 
			
		||||
        Serializer.registerClass(ReconnectBriefing.class);
 | 
			
		||||
        Serializer.registerClass(ResumeGame.class);
 | 
			
		||||
        Serializer.registerClass(ServerStartGame.class);
 | 
			
		||||
        Serializer.registerClass(StartPiece.class);
 | 
			
		||||
        Serializer.registerClass(UpdateReady.class);
 | 
			
		||||
        Serializer.registerClass(UpdateTSK.class);
 | 
			
		||||
        Serializer.registerClass(WaitPiece.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void registerListeners() {
 | 
			
		||||
        myServer.addMessageListener(this, AnimationEnd.class);
 | 
			
		||||
        myServer.addMessageListener(this, ClientStartGame.class);
 | 
			
		||||
        myServer.addMessageListener(this, DeselectTSK.class);
 | 
			
		||||
        myServer.addMessageListener(this, ForceContinueGame.class);
 | 
			
		||||
        myServer.addMessageListener(this, ForceStartGame.class);
 | 
			
		||||
        myServer.addMessageListener(this, JoinServer.class);
 | 
			
		||||
        myServer.addMessageListener(this, LeaveGame.class);
 | 
			
		||||
        myServer.addMessageListener(this, LobbyNotReady.class);
 | 
			
		||||
        myServer.addMessageListener(this, LobbyReady.class);
 | 
			
		||||
        myServer.addMessageListener(this, NoPowerCard.class);
 | 
			
		||||
        myServer.addMessageListener(this, RequestBriefing.class);
 | 
			
		||||
        myServer.addMessageListener(this, RequestDice.class);
 | 
			
		||||
        myServer.addMessageListener(this, RequestMove.class);
 | 
			
		||||
        myServer.addMessageListener(this, RequestPlayCard.class);
 | 
			
		||||
        myServer.addMessageListener(this, SelectCard.class);
 | 
			
		||||
        myServer.addMessageListener(this, SelectedPieces.class);
 | 
			
		||||
        myServer.addMessageListener(this, SelectTSK.class);
 | 
			
		||||
        myServer.addConnectionListener(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void messageReceived(HostedConnection source, Message message) {
 | 
			
		||||
        LOGGER.log(Level.INFO, "message received from {0}: {1}", source.getId(), message); //NON-NLS
 | 
			
		||||
        if (message instanceof ClientMessage clientMessage)
 | 
			
		||||
            pendingMessages.add(new ReceivedMessage(clientMessage, source.getId()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void connectionAdded(Server server, HostedConnection hostedConnection) {
 | 
			
		||||
        LOGGER.log(Level.INFO, "new connection {0}", hostedConnection); //NON-NLS
 | 
			
		||||
        logic.addPlayer(hostedConnection.getId());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void connectionRemoved(Server server, HostedConnection hostedConnection) {
 | 
			
		||||
        LOGGER.log(Level.INFO, "connection closed: {0}", hostedConnection); //NON-NLS
 | 
			
		||||
        final Player player = logic.getPlayerById(hostedConnection.getId());
 | 
			
		||||
        if (player == null)
 | 
			
		||||
            LOGGER.log(Level.INFO, "closed connection does not belong to an active player"); //NON-NLS
 | 
			
		||||
        else { //NON-NLS
 | 
			
		||||
            LOGGER.log(Level.INFO, "closed connection belongs to {0}", player); //NON-NLS
 | 
			
		||||
            exit(0);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void exit(int exitValue) { //NON-NLS
 | 
			
		||||
        LOGGER.log(Level.INFO, "close request"); //NON-NLS
 | 
			
		||||
        if (myServer != null)
 | 
			
		||||
            for (HostedConnection client : myServer.getConnections()) //NON-NLS
 | 
			
		||||
                if (client != null) client.close("Game over"); //NON-NLS
 | 
			
		||||
        System.exit(exitValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Send the specified message to the specified connection.
 | 
			
		||||
     *
 | 
			
		||||
     * @param id      the connection id
 | 
			
		||||
     * @param message the message
 | 
			
		||||
     */
 | 
			
		||||
    public void send(int id, ServerMessage message) {
 | 
			
		||||
        if (myServer == null || !myServer.isRunning()) {
 | 
			
		||||
            LOGGER.log(Level.ERROR, "no server running when trying to send {0}", message); //NON-NLS
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        final HostedConnection connection = myServer.getConnection(id);
 | 
			
		||||
        if (connection != null)
 | 
			
		||||
            connection.send(message);
 | 
			
		||||
        else
 | 
			
		||||
            LOGGER.log(Level.ERROR, "there is no connection with id={0}", id); //NON-NLS
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,10 @@
 | 
			
		||||
package pp.mdga.client.server;
 | 
			
		||||
 | 
			
		||||
import pp.mdga.message.client.ClientInterpreter;
 | 
			
		||||
import pp.mdga.message.client.ClientMessage;
 | 
			
		||||
 | 
			
		||||
public record ReceivedMessage(ClientMessage msg, int from) {
 | 
			
		||||
    void process(ClientInterpreter interpreter) {
 | 
			
		||||
        msg.accept(interpreter, from);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user