Tutorial

This tutorial will present a special type of connection to UT server - ObserverConnection (OC). Purpose of OC is to observe other player/bot on the UT game server (always one at a time). With OC you are able to get all the GameBots messages that come for the observed player/bot and some other that export for example whether player/bot started/stoped shooting.

In this tutorial we will show you:

Note: If you are interested specifically in controlling the game server and obtaining global information, consult the ControlConnection tutorial.

Setting up the ObserverConnection

In order to create a ObserverConnection you need to create two classes. First class is your custom ObserverConnection class inheriting UT2004Observer. Second class is a module telling guice that it should instantiate your custom ObserverConnection class (otherwise it would instantiate the default class - UT2004Observer)

ObserverConnection

package observerconnection;

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.SocketConnectionAddress;
import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEventListener;
import cz.cuni.amis.pogamut.base.communication.worldview.object.event.WorldObjectUpdatedEvent;
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.gbcommands.Initialize;
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Self;
import cz.cuni.amis.pogamut.ut2004.communication.worldview.UT2004WorldView;
import cz.cuni.amis.pogamut.ut2004.factory.guice.remoteagent.UT2004ObserverFactory;

import cz.cuni.amis.pogamut.ut2004.observer.impl.UT2004Observer;
import cz.cuni.amis.utils.exception.PogamutException;


/**
 * Custom basic observer class.
 *
 * @author Michal Bida
 */
public class ObserverConnection extends UT2004Observer {

    /** Boolean holding the info that we have already started to observer someone */
    boolean bSetObservedPlayer = false;

    /**
     * Listener for players - we will receive here all players on the server in handshake
     * and then all the players our observed player/bot can see
     */
    IWorldObjectEventListener<Player, WorldObjectUpdatedEvent<Player>> playerListener = new IWorldObjectEventListener<Player, WorldObjectUpdatedEvent<Player>>() {
        public void notify(WorldObjectUpdatedEvent<Player> event) {
            if (!bSetObservedPlayer) {
                //observer first player we get
                getAct().act(new Initialize().setName(event.getObject().getName()));
                bSetObservedPlayer = true;
                System.out.println("Observing: " + event.getObject().getName());
            }

            System.out.println(event.getObject().toString());
        }

    };

    /**
     * Self message of our observed player/bot.
     */
    IWorldObjectEventListener<Self, WorldObjectUpdatedEvent<Self>> selfListener = new IWorldObjectEventListener<Self, WorldObjectUpdatedEvent<Self>>() {

        public void notify(WorldObjectUpdatedEvent<Self> event) {
            System.out.println(event.getObject().toString());
        }

    };

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

    /**
     * We call this method manually - we register listeners here.
     */
    public void initialize() {

        //initialize listeners
        getWorldView().addObjectListener(Player.class, WorldObjectUpdatedEvent.class, playerListener);
        getWorldView().addObjectListener(Self.class, WorldObjectUpdatedEvent.class, selfListener);

        System.out.println("!!!!!!! Initialize");
    }

    /**
     * This method is called when the bot is started either from IDE or from command line.
     * It connects the bot to the game server.
     * @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("ObserverConnection"));
        params.setWorldAddress(new SocketConnectionAddress("127.0.0.1", 3002));

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

        //creating pogamut factory
        UT2004ObserverFactory fac = new UT2004ObserverFactory(module);
        ObserverConnection obs = (ObserverConnection) fac.newAgent(params);

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

ObserverConnectionModule

package observerconnection;

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.base3d.worldview.IVisionWorldView;
import cz.cuni.amis.pogamut.ut2004.communication.translator.observer.ObserverFSM;
import cz.cuni.amis.pogamut.ut2004.communication.worldview.UT2004WorldView;
import cz.cuni.amis.pogamut.ut2004.factory.guice.remoteagent.UT2004ObserverModule;
import cz.cuni.amis.pogamut.ut2004.observer.IUT2004Observer;

/**
 * Class telling guice it should instantiate our custom observer class.
 *
 * @author Michal Bida
 */
public class ObserverConnectionModule extends UT2004ObserverModule {

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

			@Override
			public void configure() {
				bind(IWorldMessageTranslator.class).to(ObserverFSM.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(IUT2004Observer.class);
				bind(IUT2004Observer.class).to(ObserverConnection.class); //THIS tells guice it should instantiate our class and not default one
			}

		});
	}
}
    

Hooking up the observer to start to observe player/bot

To start observing a player or bot you have to issue Initialize command. In this command either set attribute name or Id to name or Id of the player/bot you want to observer. E.g.:

              getAct().act(new Initialize().setName("SomePlayerName"));
          

If the player with supplied name or Id is on the server you will start receive his synchronous messages right away. If it is not, nothing will happen (and you won't receive any warning message).

Note: All the players are exported in a handshake right after your ObserverConnection connects to the server, so you may decide which player to observe in playerListener (as in the big code example above).