convert majority of Mirror.startGame to Java code

This commit is contained in:
gered 2017-04-12 21:45:14 -04:00
parent c754784c67
commit 927ac86c9d
2 changed files with 224 additions and 174 deletions

View file

@ -30,165 +30,152 @@ public class Bind {
this.context = context;
}
private void implementConnectionRoutine() {
out.println("\t\t\t\tprintln(\"Waiting...\");\n" +
"while ( !Broodwar->isInGame() )\n" +
" {\n" +
" BWAPI::BWAPIClient.update();\n" +
" if (!BWAPI::BWAPIClient.isConnected())\n" +
" {\n" +
" println(\"Reconnecting...\");\n" +
" reconnect();\n" +
" }\n" +
" }");
}
private void implementGameStart() {
out.println("println(\"Connecting to Broodwar...\");\n" +
"\t\treconnect();\n" +
"\t\tprintln(\"Connection successful, starting match...\");\n" +
"\n" +
"\t\tcls = env->GetObjectClass(obj);\n" +
"\t\tjclass gamecls = env->FindClass(\"L" + context.getPackageName() + "/Game;\");\n" +
"\t\tjclass unitCls = env->FindClass(\"L" + context.getPackageName() + "/Unit;\");\n" +
"\t\tjclass playerCls = env->FindClass(\"L" + context.getPackageName() + "/Player;\");\n" +
"\t\tjclass posCls = env->FindClass(\"L" + context.getPackageName() + "/Position;\");\n" +
"\t\tjobject moduleObj = env->GetObjectField(obj, env->GetFieldID(cls, \"module\", \"L" + context.getPackageName() + "/AIModule;\"));\n" +
"\t\tjclass moduleCls = env->GetObjectClass(moduleObj);\n" +
"\t\tenv->SetObjectField(obj, env->GetFieldID(cls, \"game\", \"L" + context.getPackageName() + "/Game;\"), " +
"env->CallStaticObjectMethod(gamecls, env->GetStaticMethodID(gamecls, \"get\", \"(J)L" + context.getPackageName() + "/Game;\"), (long)BroodwarPtr));\n" +
"\n" +
"\t\tjmethodID updateMethodID = env->GetMethodID(env->GetObjectClass(obj), \"update\", \"()V\");");
out.println("\t\tjmethodID matchStartCallback = env->GetMethodID(moduleCls, \"onStart\", \"()V\");\n" +
"\t\tjmethodID matchEndCallback = env->GetMethodID(moduleCls, \"onEnd\", \"(Z)V\");\n" +
"\t\tjmethodID matchFrameCallback = env->GetMethodID(moduleCls, \"onFrame\", \"()V\");\n" +
"\t\tjmethodID sendTextCallback = env->GetMethodID(moduleCls, \"onSendText\", \"(Ljava/lang/String;)V\");\n" +
"\t\tjmethodID receiveTextCallback = env->GetMethodID(moduleCls, \"onReceiveText\", \"(L" + context.getPackageName() + "/Player;Ljava/lang/String;)V\");\n" +
"\t\tjmethodID playerLeftCallback = env->GetMethodID(moduleCls, \"onPlayerLeft\", \"(L" + context.getPackageName() + "/Player;)V\");\n" +
"\t\tjmethodID nukeDetectCallback = env->GetMethodID(moduleCls, \"onNukeDetect\", \"(L" + context.getPackageName() + "/Position;)V\");\n" +
"\t\tjmethodID unitDiscoverCallback = env->GetMethodID(moduleCls, \"onUnitDiscover\", \"(L" + context.getPackageName() + "/Unit;)V\");\n" +
"\t\tjmethodID unitEvadeCallback = env->GetMethodID(moduleCls, \"onUnitEvade\", \"(L" + context.getPackageName() + "/Unit;)V\");\n" +
"\t\tjmethodID unitShowCallback = env->GetMethodID(moduleCls, \"onUnitShow\", \"(L" + context.getPackageName() + "/Unit;)V\");\n" +
"\t\tjmethodID unitHideCallback = env->GetMethodID(moduleCls, \"onUnitHide\", \"(L" + context.getPackageName() + "/Unit;)V\");\n" +
"\t\tjmethodID unitCreateCallback = env->GetMethodID(moduleCls, \"onUnitCreate\", \"(L" + context.getPackageName() + "/Unit;)V\");\n" +
"\t\tjmethodID unitDestroyCallback = env->GetMethodID(moduleCls, \"onUnitDestroy\", \"(L" + context.getPackageName() + "/Unit;)V\");\n" +
"\t\tjmethodID unitMorphCallback = env->GetMethodID(moduleCls, \"onUnitMorph\", \"(L" + context.getPackageName() + "/Unit;)V\");\n" +
"\t\tjmethodID unitRenegadeCallback = env->GetMethodID(moduleCls, \"onUnitRenegade\", \"(L" + context.getPackageName() + "/Unit;)V\");\n" +
"\t\tjmethodID saveGameCallback = env->GetMethodID(moduleCls, \"onSaveGame\", \"(Ljava/lang/String;)V\");\n" +
"\t\tjmethodID unitCompleteCallback = env->GetMethodID(moduleCls, \"onUnitComplete\", \"(L" + context.getPackageName() + "/Unit;)V\");\n" +
"\t\tjmethodID playerDroppedCallback = env->GetMethodID(moduleCls, \"onPlayerDropped\", \"(L" + context.getPackageName() + "/Player;)V\");");
out.println("\t\twhile (true) {\n");
implementConnectionRoutine();
out.println("\t\t\tprintln(\"Game ready!!!\");\n" +
"\n" +
"\t\t\twhile (Broodwar->isInGame()) {\n" +
"\t\t\t\t\n" +
"\t\t\t\tenv->CallVoidMethod(obj, updateMethodID);\n");
out.println("\n" +
"\t\t\t\tfor(std::list<Event>::const_iterator it = Broodwar->getEvents().begin(); it!=Broodwar->getEvents().end(); it++)\n" +
"\t\t\t\t {\n" +
"\t\t\t\t\t switch (it->getType()) {\n" +
"\t\t\t\t\t\t case EventType::MatchStart:\n" +
"\t\t\t\t\t\t\t env->CallVoidMethod(moduleObj, matchStartCallback);\n" +
"\t\t\t\t\t\t break;\n" +
"\t\t\t\t\t\t case EventType::MatchEnd:\n" +
"\t\t\t\t\t\t\t env->CallVoidMethod(moduleObj, matchEndCallback, it->isWinner());\n" +
"\t\t\t\t\t\t break;\n" +
"\t\t\t\t\t\t case EventType::MatchFrame:\n" +
"\t\t\t\t\t\t\t env->CallVoidMethod(moduleObj, matchFrameCallback);\n" +
"\t\t\t\t\t\t break;\n" +
"\t\t\t\t\t\t case EventType::SendText:\n" +
"\t\t\t\t\t\t\t env->CallVoidMethod(moduleObj, sendTextCallback, env->NewStringUTF(it->getText().c_str()));\n" +
"\t\t\t\t\t\t break;\n" +
"\t\t\t\t\t\t case EventType::ReceiveText:\n" +
"\t\t\t\t\t\t\t env->CallVoidMethod(moduleObj, receiveTextCallback, env->CallStaticObjectMethod(playerCls, env->GetStaticMethodID(playerCls, \"get\", \"(J)L" + context.getPackageName() + "/Player;\"), (jlong)it->getPlayer()), env->NewStringUTF(it->getText().c_str()));\n" +
"\t\t\t\t\t\t break;\n" +
"\t\t\t\t\t\t case EventType::PlayerLeft:\n" +
"\t\t\t\t\t\t\t env->CallVoidMethod(moduleObj, playerLeftCallback, env->CallStaticObjectMethod(playerCls, env->GetStaticMethodID(playerCls, \"get\", \"(J)L" + context.getPackageName() + "/Player;\"), (jlong)it->getPlayer()));\n" +
"\t\t\t\t\t\t break;\n" +
"\t\t\t\t\t\t case EventType::NukeDetect:\n" +
"\t\t\t\t\t\t\t env->CallVoidMethod(moduleObj, nukeDetectCallback, env->NewObject(posCls, env->GetMethodID(posCls,\"<init>\", \"(II)V\"), it->getPosition().x, it->getPosition().y));\n" +
"\t\t\t\t\t\t break;\n" +
"\t\t\t\t\t\t case EventType::UnitDiscover:\n" +
"\t\t\t\t\t\t\t env->CallVoidMethod(moduleObj, unitDiscoverCallback, env->CallStaticObjectMethod(unitCls, env->GetStaticMethodID(unitCls, \"get\", \"(J)L" + context.getPackageName() + "/Unit;\"), (jlong)it->getUnit()));\n" +
"\t\t\t\t\t\t break;\n" +
"\t\t\t\t\t\t case EventType::UnitEvade:\n" +
"\t\t\t\t\t\t\t env->CallVoidMethod(moduleObj, unitEvadeCallback, env->CallStaticObjectMethod(unitCls, env->GetStaticMethodID(unitCls, \"get\", \"(J)L" + context.getPackageName() + "/Unit;\"), (jlong)it->getUnit()));\n" +
"\t\t\t\t\t\t break;\n" +
"\t\t\t\t\t\t case EventType::UnitShow:\n" +
"\t\t\t\t\t\t\t env->CallVoidMethod(moduleObj, unitShowCallback, env->CallStaticObjectMethod(unitCls, env->GetStaticMethodID(unitCls, \"get\", \"(J)L" + context.getPackageName() + "/Unit;\"), (jlong)it->getUnit()));\n" +
"\t\t\t\t\t\t break;\n" +
"\t\t\t\t\t\t case EventType::UnitHide:\n" +
"\t\t\t\t\t\t\t env->CallVoidMethod(moduleObj, unitHideCallback, env->CallStaticObjectMethod(unitCls, env->GetStaticMethodID(unitCls, \"get\", \"(J)L" + context.getPackageName() + "/Unit;\"), (jlong)it->getUnit()));\n" +
"\t\t\t\t\t\t break;\n" +
"\t\t\t\t\t\t case EventType::UnitCreate:\n" +
"\t\t\t\t\t\t\t env->CallVoidMethod(moduleObj, unitCreateCallback, env->CallStaticObjectMethod(unitCls, env->GetStaticMethodID(unitCls, \"get\", \"(J)L" + context.getPackageName() + "/Unit;\"), (jlong)it->getUnit()));\n" +
"\t\t\t\t\t\t break;\n" +
"\t\t\t\t\t\t case EventType::UnitDestroy:\n" +
"\t\t\t\t\t\t\t env->CallVoidMethod(moduleObj, unitDestroyCallback, env->CallStaticObjectMethod(unitCls, env->GetStaticMethodID(unitCls, \"get\", \"(J)L" + context.getPackageName() + "/Unit;\"), (jlong)it->getUnit()));\n" +
"\t\t\t\t\t\t break;\n" +
"\t\t\t\t\t\t case EventType::UnitMorph:\n" +
"\t\t\t\t\t\t\t env->CallVoidMethod(moduleObj, unitMorphCallback, env->CallStaticObjectMethod(unitCls, env->GetStaticMethodID(unitCls, \"get\", \"(J)L" + context.getPackageName() + "/Unit;\"), (jlong)it->getUnit()));\n" +
"\t\t\t\t\t\t break;\n" +
"\t\t\t\t\t\t case EventType::UnitRenegade:\n" +
"\t\t\t\t\t\t\t env->CallVoidMethod(moduleObj, unitRenegadeCallback, env->CallStaticObjectMethod(unitCls, env->GetStaticMethodID(unitCls, \"get\", \"(J)L" + context.getPackageName() + "/Unit;\"), (jlong)it->getUnit()));\n" +
"\t\t\t\t\t\t break;\n" +
"\t\t\t\t\t\t case EventType::SaveGame:\n" +
"\t\t\t\t\t\t\t env->CallVoidMethod(moduleObj, saveGameCallback, env->NewStringUTF(it->getText().c_str()));\n" +
"\t\t\t\t\t\t break;\n" +
"\t\t\t\t\t\t case EventType::UnitComplete:\n" +
"\t\t\t\t\t\t\t env->CallVoidMethod(moduleObj, unitCompleteCallback, env->CallStaticObjectMethod(unitCls, env->GetStaticMethodID(unitCls, \"get\", \"(J)L" + context.getPackageName() + "/Unit;\"), (jlong)it->getUnit()));\n" +
"\t\t\t\t\t\t break;\n" +
"\n" +
"\t\t\t\t\t }\n" +
"\t\t\t\t }");
out.println(
"\t\t\t\tBWAPIClient.update();\n" +
"\t\t\t\tif (!BWAPI::BWAPIClient.isConnected()) {\n" +
"\t\t\t\t\t\tprintln(\"Reconnecting...\");\n" +
"\t\t\t\t\t\treconnect();\n" +
"\t\t\t\t}\n" +
"\t\t\t}\n" +
"println(\"Match ended.\");" +
"\t\t}");
}
private void implementHelpers() {
out.println("void reconnect()\n" +
"{\n" +
"\twhile (!BWAPIClient.connect()) {\n" +
" std::this_thread::sleep_for(std::chrono::milliseconds{ 1000 });\n" +
" }\n" +
"}\n" +
"\n" +
"\n");
out.println(
"void flushPrint(const char * text){\n" +
"\tprintf(text);\n" +
"\tfflush(stdout); \n" +
" printf(text);\n" +
" fflush(stdout); \n" +
"}\n" +
"\n" +
"void println(const char * text){\n" +
"\tprintf(text);\n" +
"\tflushPrint(\"\\n\");\n" +
"}\n");
" printf(text);\n" +
" flushPrint(\"\\n\");\n" +
"}\n"
);
out.println();
}
private void implementMirrorInit(List<CDeclaration> declarationList) {
implementHelpers();
out.println("JNIEXPORT void JNICALL Java_" + context.getPackageName() + "_Mirror_startGame(JNIEnv * env, jobject obj){");
private void implementMirror_initTables(List<CDeclaration> declarationList) {
out.println("JNIEXPORT void JNICALL Java_" + context.getPackageName() + "_Mirror_initTables(JNIEnv * env, jclass jclz){");
out.println(" println(\"Initializing constants tables\");");
implementVariablesBind(declarationList);
implementGameStart();
out.println("}");
out.println();
}
private void implementMirror_getInternalGame() {
out.println(
"JNIEXPORT jobject JNICALL Java_" + context.getPackageName() + "_Mirror_getInternalGame(JNIEnv * env, jobject obj){\n" +
" jclass gamecls = env->FindClass(\"Lbwapi/Game;\");\n" +
" jmethodID getMethodID = env->GetStaticMethodID(gamecls, \"get\", \"(J)Lbwapi/Game;\");\n" +
" return env->CallStaticObjectMethod(gamecls, getMethodID, (long)BroodwarPtr);\n" +
"}\n"
);
out.println();
}
private void implementMirror_processGameEvents() {
out.println(
"JNIEXPORT void JNICALL Java_" + context.getPackageName() + "_Mirror_processGameEvents(JNIEnv * env, jobject obj){\n" +
" jclass cls = env->GetObjectClass(obj);\n" +
" jobject moduleObj = env->GetObjectField(obj, env->GetFieldID(cls, \"module\", \"Lbwapi/AIModule;\"));\n" +
" jclass moduleCls = env->GetObjectClass(moduleObj);\n" +
"\n" +
" jclass unitCls = env->FindClass(\"Lbwapi/Unit;\");\n" +
" jclass playerCls = env->FindClass(\"Lbwapi/Player;\");\n" +
" jclass posCls = env->FindClass(\"Lbwapi/Position;\");\n" +
"\n" +
" jmethodID matchStartCallback = env->GetMethodID(moduleCls, \"onStart\", \"()V\");\n" +
" jmethodID matchEndCallback = env->GetMethodID(moduleCls, \"onEnd\", \"(Z)V\");\n" +
" jmethodID matchFrameCallback = env->GetMethodID(moduleCls, \"onFrame\", \"()V\");\n" +
" jmethodID sendTextCallback = env->GetMethodID(moduleCls, \"onSendText\", \"(Ljava/lang/String;)V\");\n" +
" jmethodID receiveTextCallback = env->GetMethodID(moduleCls, \"onReceiveText\", \"(Lbwapi/Player;Ljava/lang/String;)V\");\n" +
" jmethodID playerLeftCallback = env->GetMethodID(moduleCls, \"onPlayerLeft\", \"(Lbwapi/Player;)V\");\n" +
" jmethodID nukeDetectCallback = env->GetMethodID(moduleCls, \"onNukeDetect\", \"(Lbwapi/Position;)V\");\n" +
" jmethodID unitDiscoverCallback = env->GetMethodID(moduleCls, \"onUnitDiscover\", \"(Lbwapi/Unit;)V\");\n" +
" jmethodID unitEvadeCallback = env->GetMethodID(moduleCls, \"onUnitEvade\", \"(Lbwapi/Unit;)V\");\n" +
" jmethodID unitShowCallback = env->GetMethodID(moduleCls, \"onUnitShow\", \"(Lbwapi/Unit;)V\");\n" +
" jmethodID unitHideCallback = env->GetMethodID(moduleCls, \"onUnitHide\", \"(Lbwapi/Unit;)V\");\n" +
" jmethodID unitCreateCallback = env->GetMethodID(moduleCls, \"onUnitCreate\", \"(Lbwapi/Unit;)V\");\n" +
" jmethodID unitDestroyCallback = env->GetMethodID(moduleCls, \"onUnitDestroy\", \"(Lbwapi/Unit;)V\");\n" +
" jmethodID unitMorphCallback = env->GetMethodID(moduleCls, \"onUnitMorph\", \"(Lbwapi/Unit;)V\");\n" +
" jmethodID unitRenegadeCallback = env->GetMethodID(moduleCls, \"onUnitRenegade\", \"(Lbwapi/Unit;)V\");\n" +
" jmethodID saveGameCallback = env->GetMethodID(moduleCls, \"onSaveGame\", \"(Ljava/lang/String;)V\");\n" +
" jmethodID unitCompleteCallback = env->GetMethodID(moduleCls, \"onUnitComplete\", \"(Lbwapi/Unit;)V\");\n" +
"\n" +
" for (std::list<Event>::const_iterator it = Broodwar->getEvents().begin(); it != Broodwar->getEvents().end(); it++)\n" +
" {\n" +
" switch (it->getType()) {\n" +
" case EventType::MatchStart:\n" +
" env->CallVoidMethod(moduleObj, matchStartCallback);\n" +
" break;\n" +
" case EventType::MatchEnd:\n" +
" env->CallVoidMethod(moduleObj, matchEndCallback, it->isWinner());\n" +
" break;\n" +
" case EventType::MatchFrame:\n" +
" env->CallVoidMethod(moduleObj, matchFrameCallback);\n" +
" break;\n" +
" case EventType::SendText:\n" +
" env->CallVoidMethod(moduleObj, sendTextCallback, env->NewStringUTF(it->getText().c_str()));\n" +
" break;\n" +
" case EventType::ReceiveText:\n" +
" env->CallVoidMethod(moduleObj, receiveTextCallback, env->CallStaticObjectMethod(playerCls, env->GetStaticMethodID(playerCls, \"get\", \"(J)Lbwapi/Player;\"), (jlong)it->getPlayer()), env->NewStringUTF(it->getText().c_str()));\n" +
" break;\n" +
" case EventType::PlayerLeft:\n" +
" env->CallVoidMethod(moduleObj, playerLeftCallback, env->CallStaticObjectMethod(playerCls, env->GetStaticMethodID(playerCls, \"get\", \"(J)Lbwapi/Player;\"), (jlong)it->getPlayer()));\n" +
" break;\n" +
" case EventType::NukeDetect:\n" +
" env->CallVoidMethod(moduleObj, nukeDetectCallback, env->NewObject(posCls, env->GetMethodID(posCls, \"<init>\", \"(II)V\"), it->getPosition().x, it->getPosition().y));\n" +
" break;\n" +
" case EventType::UnitDiscover:\n" +
" env->CallVoidMethod(moduleObj, unitDiscoverCallback, env->CallStaticObjectMethod(unitCls, env->GetStaticMethodID(unitCls, \"get\", \"(J)Lbwapi/Unit;\"), (jlong)it->getUnit()));\n" +
" break;\n" +
" case EventType::UnitEvade:\n" +
" env->CallVoidMethod(moduleObj, unitEvadeCallback, env->CallStaticObjectMethod(unitCls, env->GetStaticMethodID(unitCls, \"get\", \"(J)Lbwapi/Unit;\"), (jlong)it->getUnit()));\n" +
" break;\n" +
" case EventType::UnitShow:\n" +
" env->CallVoidMethod(moduleObj, unitShowCallback, env->CallStaticObjectMethod(unitCls, env->GetStaticMethodID(unitCls, \"get\", \"(J)Lbwapi/Unit;\"), (jlong)it->getUnit()));\n" +
" break;\n" +
" case EventType::UnitHide:\n" +
" env->CallVoidMethod(moduleObj, unitHideCallback, env->CallStaticObjectMethod(unitCls, env->GetStaticMethodID(unitCls, \"get\", \"(J)Lbwapi/Unit;\"), (jlong)it->getUnit()));\n" +
" break;\n" +
" case EventType::UnitCreate:\n" +
" env->CallVoidMethod(moduleObj, unitCreateCallback, env->CallStaticObjectMethod(unitCls, env->GetStaticMethodID(unitCls, \"get\", \"(J)Lbwapi/Unit;\"), (jlong)it->getUnit()));\n" +
" break;\n" +
" case EventType::UnitDestroy:\n" +
" env->CallVoidMethod(moduleObj, unitDestroyCallback, env->CallStaticObjectMethod(unitCls, env->GetStaticMethodID(unitCls, \"get\", \"(J)Lbwapi/Unit;\"), (jlong)it->getUnit()));\n" +
" break;\n" +
" case EventType::UnitMorph:\n" +
" env->CallVoidMethod(moduleObj, unitMorphCallback, env->CallStaticObjectMethod(unitCls, env->GetStaticMethodID(unitCls, \"get\", \"(J)Lbwapi/Unit;\"), (jlong)it->getUnit()));\n" +
" break;\n" +
" case EventType::UnitRenegade:\n" +
" env->CallVoidMethod(moduleObj, unitRenegadeCallback, env->CallStaticObjectMethod(unitCls, env->GetStaticMethodID(unitCls, \"get\", \"(J)Lbwapi/Unit;\"), (jlong)it->getUnit()));\n" +
" break;\n" +
" case EventType::SaveGame:\n" +
" env->CallVoidMethod(moduleObj, saveGameCallback, env->NewStringUTF(it->getText().c_str()));\n" +
" break;\n" +
" case EventType::UnitComplete:\n" +
" env->CallVoidMethod(moduleObj, unitCompleteCallback, env->CallStaticObjectMethod(unitCls, env->GetStaticMethodID(unitCls, \"get\", \"(J)Lbwapi/Unit;\"), (jlong)it->getUnit()));\n" +
" break;\n" +
" }\n" +
" }\n" +
"}\n"
);
out.println();
}
private void implementMirror_BWAPIClientGetters() {
out.println(
"JNIEXPORT jboolean JNICALL Java_bwapi_Mirror_isConnected(JNIEnv * env, jclass jclz){\n" +
" return BWAPI::BWAPIClient.isConnected();\n" +
"}\n" +
"\n" +
"JNIEXPORT jboolean JNICALL Java_bwapi_Mirror_connect(JNIEnv * env, jclass jclz){\n" +
" return BWAPI::BWAPIClient.connect();\n" +
"}\n" +
"\n" +
"JNIEXPORT void JNICALL Java_bwapi_Mirror_disconnect(JNIEnv * env, jclass jclz){\n" +
" BWAPI::BWAPIClient.disconnect();\n" +
"}\n" +
"\n" +
"JNIEXPORT void JNICALL Java_bwapi_Mirror_update(JNIEnv * env, jclass jclz){\n" +
" BWAPI::BWAPIClient.update();\n" +
"}\n"
);
out.println();
}
private void implementVariablesBind(List<CDeclaration> declarationList) {
out.println("jclass cls;");
out.println("jmethodID getId;");
@ -251,7 +238,12 @@ public class Bind {
}
public void implementBind(List<CDeclaration> declarationList) {
implementMirrorInit(declarationList);
implementHelpers();
implementMirror_initTables(declarationList);
implementMirror_getInternalGame();
implementMirror_processGameEvents();
implementMirror_BWAPIClientGetters();
}
}

View file

@ -1,15 +1,11 @@
package bwapi;
import bwapi.AIModule;
import bwapi.BWEventListener;
import java.io.*;
import java.io.File;
import java.lang.Exception;
import java.lang.UnsupportedOperationException;
import java.util.*;
import java.util.regex.Pattern;
import java.util.zip.*;
public class Mirror {
@ -17,10 +13,6 @@ public class Mirror {
private AIModule module = new AIModule();
private FrameCallback frameCallback;
private static final boolean EXTRACT_JAR = true;
private static void extractResourceFile(String resourceFilename, String outputFilename) throws Exception {
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(resourceFilename);
if (in == null)
@ -94,6 +86,8 @@ public class Mirror {
System.exit(1);
if (!extractBwtaDataFiles())
System.exit(1);
initTables();
}
public Game getGame() {
@ -105,26 +99,90 @@ public class Mirror {
}
/**
* Starts the API, initializes all constants ( {@link UnitType}, {@link WeaponType} ) and the {@link Game} object.
* This method blocks until the end of game.
* Initializes all BWAPI constant lookup tables.
*/
public native void startGame();
private void update() {
if (frameCallback != null) {
frameCallback.update();
}
}
/*public void setFrameCallback(bwapi.Mirror.FrameCallback frameCallback) {
this.frameCallback = frameCallback;
} */
private static native void initTables();
/**
* The simplest interface to receive update event from Broodwar. The {@link #update()} method is called once each frame.
* For a simple bot and implementation of this interface is enough, to receive all in game events, implement {@link BWEventListener}.
* Initializes a connection to Broodwar, initializes the a {@link Game} object, and dispatches
* events to your listener as long as Broodwar is in a game. If this method is called before
* Broodwar is running, it will keep retrying until an initial connection can be established.
*
* The {@link Game} instance returned by {@link #getGame()} is only valid while this method
* is running. If your code holds a copy of this object anywhere else, do not try to use it
* again after this method returns.
*
* @param autoReconnect
* If true, will run an infinite loop allowing you to keep your bot running as many
* subsequent matches as desired. Will automatically reconnect to a Broodwar instance
* if the connection is interrupted.
* If false, will disconnect from Broodwar and return after the first match ends
* (regardless of how it ended). Will not attempt to reconnect to Broodwar if the
* connection is interrupted once the first match has been started. You can call
* {@link #startGame} again to run another match as needed.
*/
/*public*/ private interface FrameCallback {
public void update();
public void startGame(boolean autoReconnect) {
try
{
System.out.println("Connecting to Broodwar...");
reconnect();
System.out.println("Connection successful, starting match...");
game = getInternalGame();
do {
System.out.println("Waiting...");
while (!game.isInGame()) {
update();
if (!isConnected()) {
System.out.println("Reconnecting...");
reconnect();
}
}
System.out.println("Game ready!!!");
while (game.isInGame()) {
processGameEvents();
update();
if (!isConnected()) {
System.out.println("Reconnecting...");
reconnect();
}
}
System.out.println("Match ended.");
} while(autoReconnect);
System.out.println("Finished. Disconnecting from Broodwar...");
} catch (InterruptedException e) {
System.out.println("Interrupted. Disconnecting from Broodwar...");
}
if (isConnected())
disconnect();
game = null;
}
private void reconnect() throws InterruptedException {
while (!connect()) {
Thread.sleep(1000);
}
}
/**
* Returns the current connection state to a running Broodwar instance.
*/
public static native boolean isConnected();
private static native boolean connect();
private static native void disconnect();
private static native void update();
private native Game getInternalGame();
private native void processGameEvents();
}