Forum: PogamutUT2004

Custom ControlServer in 3.1

Hi all,

follow this guide when having troubles with running custom control server in Pogamut 3.1.

Basically you need to write two classes. A module with information for guice and the control server itself.

Guice module


package controlconnection;

import com.google.inject.AbstractModule;
import com.google.inject.name.Names;
import cz.cuni.amis.pogamut.base.agent.IAgent;
import cz.cuni.amis.pogamut.base.communication.translator.IWorldMessageTranslator;
import cz.cuni.amis.pogamut.base.communication.worldview.IWorldView;
import cz.cuni.amis.pogamut.base.component.controller.ComponentDependencies;
import cz.cuni.amis.pogamut.base.server.IWorldServer;
import cz.cuni.amis.pogamut.base3d.worldview.IVisionWorldView;
import cz.cuni.amis.pogamut.ut2004.communication.translator.server.ServerFSM;
import cz.cuni.amis.pogamut.ut2004.communication.worldview.UT2004WorldView;
import cz.cuni.amis.pogamut.ut2004.factory.guice.remoteagent.UT2004ServerModule;

import cz.cuni.amis.pogamut.ut2004.server.IUT2004Server;

/**
 * Class used by UT2004Factory telling the guice that it should instantiate our
 * custom class.
 * 
 * @author Michal Bida
 */
public class ControlConnectionModule extends UT2004ServerModule {

	@Override
	protected void configureModules() {
		super.configureModules();
		addModule(new AbstractModule() {

			@Override
			public void configure() {
				bind(IWorldMessageTranslator.class).to(ServerFSM.class);
				bind(IWorldView.class).to(IVisionWorldView.class);
				bind(IVisionWorldView.class).to(UT2004WorldView.class);
				bind(ComponentDependencies.class).annotatedWith(Names.named(UT2004WorldView.WORLDVIEW_DEPENDENCY)).toProvider(worldViewDependenciesProvider);
				bind(IAgent.class).to(IWorldServer.class);
				bind(IWorldServer.class).to(IUT2004Server.class);
				bind(IUT2004Server.class).to(ControlConnection.class); //Here we tell guice it should create our custom Control server class
			}

		});
	}
}


ControlServer code


package controlconnection;

import com.google.inject.Inject;
import cz.cuni.amis.pogamut.base.agent.impl.AgentId;
import cz.cuni.amis.pogamut.base.communication.command.IAct;
import cz.cuni.amis.pogamut.base.communication.connection.impl.socket.SocketConnection;
import cz.cuni.amis.pogamut.base.communication.connection.impl.socket.SocketConnectionAddress;
import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEvent;
import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectListener;
import cz.cuni.amis.pogamut.base.component.bus.IComponentBus;
import cz.cuni.amis.pogamut.base.utils.logging.IAgentLogger;
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Player;
import cz.cuni.amis.pogamut.ut2004.agent.params.UT2004AgentParameters;
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.BeginMessage;
import cz.cuni.amis.pogamut.ut2004.communication.worldview.UT2004WorldView;
import cz.cuni.amis.pogamut.ut2004.factory.guice.remoteagent.UT2004ServerFactory;

import cz.cuni.amis.pogamut.ut2004.server.IUT2004Server;
import cz.cuni.amis.pogamut.ut2004.server.impl.UT2004Server;
import cz.cuni.amis.utils.exception.PogamutException;

/**
 * Control server connected to UT environment. Through this connection we get global
 * information about the game and can control the game.
 *
 * @author Michal Bida
 */
public class ControlConnection extends UT2004Server implements IUT2004Server {

    private double currentUTTime;

    /*
     * BeginMessage listener - we get current server time here.
     */
    IWorldEventListener<BeginMessage> myBeginMessageListener = new IWorldEventListener<BeginMessage>() {
        public void notify(BeginMessage event) {
            currentUTTime = event.getTime();
            System.out.println("Begin: " + event.toString());
        }
    };

    /*
     * Player listener - we simply print out all player messages we receive.
     */
    IWorldObjectListener<Player> myPlayerListener = new IWorldObjectListener<Player>() {
        public void notify(IWorldObjectEvent<Player> event) {
            System.out.println("Player: " + event.getObject().toString());
        }
    };

    @Inject
    public ControlConnection(UT2004AgentParameters params, IAgentLogger agentLogger, IComponentBus bus, SocketConnection connection, UT2004WorldView worldView, IAct act) {
        super(params, agentLogger, bus, connection, worldView, act);
    }


    /*
     * Our custom hook, where we initialize our listeners. Note that UT2004Server class
     * is just stub, so no helper methods are present (no prepareBot, botInitialized, etc
     as with Bot classes)
     */
    public void initialize() {
        getWorldView().addEventListener(BeginMessage.class, myBeginMessageListener);
        getWorldView().addObjectListener(Player.class, myPlayerListener);
        System.out.println("ControlConnection initialized.");
    }


    /**
     * This method is called when the server is started either from IDE or from command line.
     * It connects the server to the game.
     * @param args
     */
    public static void main(String args[]) throws PogamutException {
        //creating agent parameters - setting module name and connection adress
        UT2004AgentParameters params = new UT2004AgentParameters();
        params.setAgentId(new AgentId("ControlConnection"));
        params.setWorldAddress(new SocketConnectionAddress("127.0.0.1", 3001));

        //create module that tells guice it should instantiate OUR (this) class
        ControlConnectionModule module = new ControlConnectionModule();

        //creating pogamut factory
        UT2004ServerFactory fac = new UT2004ServerFactory(module);
        ControlConnection cts = (ControlConnection) fac.newAgent(params);

        //starting the connection - connecting to the server
        cts.start();
        //launching our custom method
        cts.initialize();
    }
}


This control servers updates its current time variable and is also posting information from synchronous batches about FlagInfo and domination point objects it is receiving as a console log (note that you get FlagInfo only in BotCTFGame and domination points in BotDoubleDomination game type).

Best,
Michal