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

189 lines
6.1 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 {
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("Extracting bwapi_bridge.dll");
extractResourceFile("bwapi_bridge.dll", "./bwapi_bridge.dll");
System.out.println("Extracting libgmp-10.dll");
extractResourceFile("libgmp-10.dll", "./libgmp-10.dll");
System.out.println("Extracting libmpfr-4.dll");
extractResourceFile("libmpfr-4.dll", "./libmpfr-4.dll");
System.out.println("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("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:");
for (String filename : bwtaFilenames) {
System.out.println(filename);
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
static {
String arch = System.getProperty("os.arch");
if(!arch.equals("x86")){
throw new UnsupportedOperationException("BWMirror API supports only x86 architecture.");
2014-08-05 04:43:14 -04:00
}
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
*/
private 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
* 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 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...");
2014-08-05 04:43:14 -04:00
}
if (isConnected())
disconnect();
2014-08-05 04:43:14 -04:00
game = null;
}
2014-08-05 04:43:14 -04:00
private void reconnect() throws InterruptedException {
while (!connect()) {
Thread.sleep(1000);
}
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();
}