This repository has been archived on 2023-07-11. You can view files and clone it, but cannot push or open issues or pull requests.
BWMirror-Generator/manual-bwapi-src/Mirror.java

218 lines
6.9 KiB
Java
Raw Normal View History

2014-08-05 04:43:14 -04:00
package bwapi;
import java.io.*;
import java.io.File;
import java.lang.Exception;
import java.lang.UnsupportedOperationException;
import java.util.*;
import java.util.regex.Pattern;
2014-08-05 04:43:14 -04:00
public class Mirror {
public static final String LOG_TAG = "[BWMirror] ";
2014-08-05 04:43:14 -04:00
private Game game;
private AIModule module = new AIModule();
private static void extractResourceFile(String resourceFilename, String outputFilename) throws Exception {
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(resourceFilename);
if (in == null)
throw new FileNotFoundException("Resource file not found: " + resourceFilename);
FileOutputStream out;
try {
out = new FileOutputStream(outputFilename);
} catch (Exception e) {
throw new FileNotFoundException("Could not open output file: " + outputFilename);
}
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = in.read(buffer, 0, buffer.length)) != -1) {
out.write(buffer, 0, bytesRead);
}
out.close();
in.close();
}
2014-08-05 04:43:14 -04:00
private static boolean extractAndLoadNativeLibraries() {
try {
System.out.println(LOG_TAG + "Extracting bwapi_bridge.dll");
extractResourceFile("bwapi_bridge.dll", "./bwapi_bridge.dll");
System.out.println(LOG_TAG + "Extracting libgmp-10.dll");
extractResourceFile("libgmp-10.dll", "./libgmp-10.dll");
System.out.println(LOG_TAG + "Extracting libmpfr-4.dll");
extractResourceFile("libmpfr-4.dll", "./libmpfr-4.dll");
System.out.println(LOG_TAG + "Loading native library bwapi_bridge.dll");
System.load(new File("./bwapi_bridge.dll").getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
return false;
2014-08-05 04:43:14 -04:00
}
return true;
}
private static boolean extractBwtaDataFiles() {
2014-08-05 04:43:14 -04:00
try {
Collection<String> bwtaFilenames = ResourceList.getResources(Pattern.compile("bwapi\\-data/BWTA2/[a-zA-Z0-9]+\\.bwta"));
2014-08-05 04:43:14 -04:00
System.out.println(LOG_TAG + "Creating ./bwapi-data/BWTA2 directory");
new File("./bwapi-data/BWTA2").mkdirs();
2014-08-05 04:43:14 -04:00
System.out.println("Extracting " + bwtaFilenames.size() + " BWTA2 files to ./bwapi-data/BWTA2");
for (String filename : bwtaFilenames) {
String outputFilename = "./" + filename;
extractResourceFile(filename, outputFilename);
2014-08-05 04:43:14 -04:00
}
2014-08-05 04:43:14 -04:00
} catch (Exception e) {
e.printStackTrace();
return false;
2014-08-05 04:43:14 -04:00
}
return true;
}
2014-08-05 04:43:14 -04:00
public static boolean is64BitJRE() {
String bits = System.getProperty("sun.arch.data.model");
if (bits == null)
return System.getProperty("java.vm.name").contains("64");
else
return bits.equals("64");
}
static {
if (is64BitJRE())
throw new UnsupportedOperationException("BWMirror must be run on a 32-bit JRE/JDK.");
if (!extractAndLoadNativeLibraries())
System.exit(1);
if (!extractBwtaDataFiles())
System.exit(1);
initTables();
2014-08-05 04:43:14 -04:00
}
public Game getGame() {
return game;
}
public AIModule getModule() {
return module;
}
/**
* Initializes all BWAPI constant lookup tables.
2014-08-05 04:43:14 -04:00
*/
2017-04-18 21:49:28 -04:00
public static native void initTables();
2014-08-05 04:43:14 -04:00
/**
* Initializes a connection to Broodwar, initializes the a {@link Game} object, and dispatches
2017-04-14 18:07:46 -04:00
* events to your listener as long as Broodwar is in a game. Will automatically attempt to
* reconnect to Broodwar if the connection is lost at any point. If this method is called
* before Broodwar is running, will wait 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 returnOnMatchEnd
* If true, will disconnect from Broodwar and return after the first match ends
2017-04-14 18:07:46 -04:00
* (regardless of how it ended). You can call {@link #startGame} again to run another
* match as needed.
* If false, will run an infinite loop allowing you to keep your bot running as many
2017-04-14 18:07:46 -04:00
* subsequent matches as desired.
*/
public void startGame(boolean returnOnMatchEnd) {
System.out.println(LOG_TAG + "Connecting to Broodwar...");
if (reconnect())
System.out.println(LOG_TAG + "Connection successful, starting match...");
else {
System.out.println(LOG_TAG + "Connection attempt aborted.");
return;
}
game = getInternalGame();
boolean inGame = game.isInGame();
boolean previouslyInGame = inGame;
if (inGame)
System.out.println(LOG_TAG + "Match already running.");
while (true) {
if (!inGame) {
if (previouslyInGame) {
System.out.println(LOG_TAG + "Match ended.");
if (returnOnMatchEnd)
break;
}
update();
} else {
if (!previouslyInGame)
System.out.println(LOG_TAG + "Game ready!!!");
processGameEvents();
update();
}
if (!isConnected()) {
System.out.println(LOG_TAG + "Reconnecting...");
reconnect();
}
if (Thread.interrupted()) {
System.out.println(LOG_TAG + "Interrupted.");
break;
}
previouslyInGame = inGame;
inGame = game.isInGame();
2014-08-05 04:43:14 -04:00
}
System.out.println(LOG_TAG + "Finished.");
System.out.println(LOG_TAG + "Disconnecting from Broodwar...");
if (isConnected())
disconnect();
2014-08-05 04:43:14 -04:00
game = null;
System.out.println(LOG_TAG + "Returning...");
}
2014-08-05 04:43:14 -04:00
private boolean reconnect() {
while (!connect()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// needed to set the interrupt status of this thread.
// else, subsequent calls to Thread.interrupted() will return false.
Thread.currentThread().interrupt();
return false;
}
}
return true;
2014-08-05 04:43:14 -04:00
}
/**
* 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();
}