use of com.microsoft.Malmo.Utils.TCPInputPoller in project malmo by Microsoft.
the class ClientStateMachine method initialiseComms.
/**
* Set up the mission poller.<br>
* This is called during the initialisation episode, but also needs to be
* available for other episodes in case the configuration changes, resulting
* in changes to the ports.
*
* @throws UnknownHostException
*/
protected void initialiseComms() throws UnknownHostException {
// Start polling for missions:
if (this.missionPoller != null) {
this.missionPoller.stopServer();
}
this.missionPoller = new TCPInputPoller(AddressHelper.getMissionControlPortOverride(), AddressHelper.MIN_MISSION_CONTROL_PORT, AddressHelper.MAX_FREE_PORT) {
@Override
public void onError(String error, DataOutputStream dos) {
System.out.println("SENDING ERROR: " + error);
try {
dos.writeInt(error.length());
dos.writeBytes(error);
} catch (IOException e) {
}
}
private void reply(String reply, DataOutputStream dos) {
System.out.println("REPLYING WITH: " + reply);
try {
dos.writeInt(reply.length());
dos.writeBytes(reply);
} catch (IOException e) {
System.out.println("Failed to reply to message!");
}
}
@Override
public boolean onCommand(String command, String ipFrom, DataOutputStream dos) {
System.out.println("Received from " + ipFrom + ":");
System.out.println(command.substring(0, Math.min(command.length(), 1024)));
boolean keepProcessing = false;
// Possible commands:
// 1: MALMO_REQUEST_CLIENT:<malmo version>:<reservation_length(ms)><experiment_id>
// 2: MALMO_CANCEL_REQUEST
// 3: MALMO_FIND_SERVER<experiment_id>
// 4: MissionInit
String reservePrefix = "MALMO_REQUEST_CLIENT:" + Loader.instance().activeModContainer().getVersion() + ":";
String findServerPrefix = "MALMO_FIND_SERVER";
String cancelRequestCommand = "MALMO_CANCEL_REQUEST";
if (command.startsWith(reservePrefix)) {
// Reservation request.
// We either reply with MALMOOK, if we are free, or MALMOBUSY if not.
IState currentState = getStableState();
if (currentState != null && currentState.equals(ClientState.DORMANT) && !isReserved()) {
reserveClient(command.substring(reservePrefix.length()));
reply("MALMOOK", dos);
} else {
// We're busy - we can't be reserved.
reply("MALMOBUSY", dos);
}
} else if (command.equals(cancelRequestCommand)) {
// If we've been reserved, cancel the reservation.
if (isReserved()) {
cancelReservation();
reply("MALMOOK", dos);
} else {
// We weren't reserved in the first place - something is odd.
reply("MALMOERRORAttempt to cancel a reservation that was never made.", dos);
}
} else if (command.startsWith(findServerPrefix)) {
// Request to find the server for the given experiment ID.
String expID = command.substring(findServerPrefix.length());
if (currentMissionInit() != null && currentMissionInit().getExperimentUID().equals(expID)) {
// Our Experiment IDs match, so we are running the same experiment.
// Return the port and server IP address to the caller:
MinecraftServerConnection msc = currentMissionInit().getMinecraftServerConnection();
if (msc == null)
// Mission might be starting up.
reply("MALMONOSERVERYET", dos);
else
reply("MALMOS" + msc.getAddress() + ":" + msc.getPort(), dos);
} else {
// We don't have a MissionInit ourselves, or we're running a different experiment,
// so we can't help.
reply("MALMONOSERVER", dos);
}
} else {
// See if we've been sent a MissionInit message:
MissionInitResult missionInitResult = decodeMissionInit(command);
if (missionInitResult.wasMissionInit && missionInitResult.missionInit == null) {
// Got sent a duff MissionInit xml - pass back the JAXB/SAXB errors.
reply("MALMOERROR" + missionInitResult.error, dos);
} else if (missionInitResult.wasMissionInit && missionInitResult.missionInit != null) {
MissionInit missionInit = missionInitResult.missionInit;
// We've been sent a MissionInit message.
// First, check the version number:
String platformVersion = missionInit.getPlatformVersion();
String ourVersion = Loader.instance().activeModContainer().getVersion();
if (platformVersion == null || !platformVersion.equals(ourVersion)) {
reply("MALMOERRORVERSIONMISMATCH (Got " + platformVersion + ", expected " + ourVersion + " - check your path for old versions of MalmoPython/MalmoJava/Malmo.lib etc)", dos);
} else {
// MissionInit passed to us - this is a request to launch this mission. Can we?
IState currentState = getStableState();
if (currentState != null && currentState.equals(ClientState.DORMANT) && isAvailable(missionInit.getExperimentUID())) {
reply("MALMOOK", dos);
// State machine will now process this MissionInit and start the mission.
keepProcessing = true;
} else {
// We're busy - we can't run this mission.
reply("MALMOBUSY", dos);
}
}
}
}
return keepProcessing;
}
};
this.missionPoller.start();
// Tell the address helper what the actual port is:
AddressHelper.setMissionControlPort(ClientStateMachine.this.missionPoller.getPortBlocking());
if (AddressHelper.getMissionControlPort() == -1) {
// Failed to create a mission control port - nothing will work!
System.out.println("**** NO MISSION CONTROL SOCKET CREATED - WAS THE PORT IN USE? (Check Mod GUI options) ****");
ClientStateMachine.this.getScreenHelper().addFragment("ERROR: Could not open a Mission Control Port - check the Mod GUI options.", TextCategory.TXT_CLIENT_WARNING, MISSING_MCP_PORT_ERROR);
} else {
// Clear the error string, if there was one:
ClientStateMachine.this.getScreenHelper().clearFragment(MISSING_MCP_PORT_ERROR);
}
// Display the port number:
ClientStateMachine.this.getScreenHelper().clearFragment(INFO_MCP_PORT);
if (AddressHelper.getMissionControlPort() != -1)
ClientStateMachine.this.getScreenHelper().addFragment("MCP: " + AddressHelper.getMissionControlPort(), TextCategory.TXT_INFO, INFO_MCP_PORT);
}
Aggregations