Directly using VirtualBox from Java #5
5 changed files with 45 additions and 18 deletions
|
@ -16,6 +16,9 @@ public class BukkitRenderer extends MapRenderer implements IRenderer {
|
||||||
private BufferedImage image;
|
private BufferedImage image;
|
||||||
private int startindex;
|
private int startindex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The raw pixel data from the machine in BGRA format
|
||||||
|
*/
|
||||||
public void setAllPixels(ByteBuffer allpixels) {
|
public void setAllPixels(ByteBuffer allpixels) {
|
||||||
this.allpixels = allpixels;
|
this.allpixels = allpixels;
|
||||||
}
|
}
|
||||||
|
@ -27,8 +30,6 @@ public class BukkitRenderer extends MapRenderer implements IRenderer {
|
||||||
* The ID of the current map
|
* The ID of the current map
|
||||||
* @param world
|
* @param world
|
||||||
* The world to create new maps in
|
* The world to create new maps in
|
||||||
* @param allpixels
|
|
||||||
* The raw pixel data from the machine in BGRA format
|
|
||||||
* @param startindex
|
* @param startindex
|
||||||
* The index to start from in allpixels
|
* The index to start from in allpixels
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -105,17 +105,15 @@ public class MCFrameBuffer implements IFramebuffer {
|
||||||
holder.value.getTypedWrapped().queryBitmapInfo(ptr, w, h, bpp, bpl, pf);
|
holder.value.getTypedWrapped().queryBitmapInfo(ptr, w, h, bpp, bpl, pf);
|
||||||
System.out.println("Arr0:" + ptr[0]);
|
System.out.println("Arr0:" + ptr[0]);
|
||||||
System.out.println("whbppbplpf: " + w[0] + " " + h[0] + " " + bpp[0] + " " + bpl[0] + " " + pf[0]);
|
System.out.println("whbppbplpf: " + w[0] + " " + h[0] + " " + bpp[0] + " " + bpl[0] + " " + pf[0]);
|
||||||
|
if(PluginMain.direct)
|
||||||
|
PluginMain.pxc.setSource(ptr[0], (int)w[0], (int)h[0], PluginMain.MCX, PluginMain.MCY);
|
||||||
|
else {
|
||||||
PluginMain.allpixels = new Pointer(ptr[0]).getByteBuffer(0L, width * height * 4);
|
PluginMain.allpixels = new Pointer(ptr[0]).getByteBuffer(0L, width * height * 4);
|
||||||
if (width * height > 640 * 480)
|
if (width * height > 640 * 480)
|
||||||
PluginMain.allpixels.limit(640 * 480 * 4);
|
PluginMain.allpixels.limit(640 * 480 * 4);
|
||||||
else
|
else
|
||||||
PluginMain.allpixels.limit((int) (width * height * 4));
|
PluginMain.allpixels.limit((int) (width * height * 4));
|
||||||
for (IRenderer r : PluginMain.renderers)
|
}
|
||||||
if (r instanceof BukkitRenderer)
|
|
||||||
((BukkitRenderer) r).setAllPixels(PluginMain.allpixels);
|
|
||||||
else if (r instanceof DirectRenderer)
|
|
||||||
//((DirectRenderer) r).render(PluginMain.allpixels, xOrigin, yOrigin, width, height);
|
|
||||||
((DirectRenderer) r).setAllpixels(PluginMain.allpixels);
|
|
||||||
System.out.println("Change!");
|
System.out.println("Change!");
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
package sznp.virtualcomputer;
|
package sznp.virtualcomputer;
|
||||||
|
|
||||||
|
import jnr.ffi.Pointer;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.nio.Buffer;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public interface PXCLib {
|
public interface PXCLib {
|
||||||
/**
|
/**
|
||||||
|
@ -24,5 +29,5 @@ public interface PXCLib {
|
||||||
* Updates map and returns it's content, where affected
|
* Updates map and returns it's content, where affected
|
||||||
* @return Partial map data [mapc][data]
|
* @return Partial map data [mapc][data]
|
||||||
*/
|
*/
|
||||||
byte[][] updateAndGetMap(int x, int y, int width, int height); //TODO: Only update parts that actually updated and return them per-map (flagDirty)
|
Buffer updateAndGetMap(int x, int y, int width, int height, Pointer out_changed); //TODO: Only update parts that actually updated and return them per-map (flagDirty)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,11 @@ import java.lang.reflect.Field;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public class PluginMain extends JavaPlugin {
|
public class PluginMain extends JavaPlugin {
|
||||||
|
public static final int MCX = 5;
|
||||||
|
public static final int MCY = 4;
|
||||||
private IVirtualBox vbox;
|
private IVirtualBox vbox;
|
||||||
private ISession session;
|
private ISession session;
|
||||||
private IMachine machine;
|
private IMachine machine;
|
||||||
|
@ -25,8 +28,16 @@ public class PluginMain extends JavaPlugin {
|
||||||
|
|
||||||
public static PluginMain Instance;
|
public static PluginMain Instance;
|
||||||
//public static ByteBuffer allpixels = ByteBuffer.allocate(640 * 480 * 4); // It's set on each change
|
//public static ByteBuffer allpixels = ByteBuffer.allocate(640 * 480 * 4); // It's set on each change
|
||||||
|
/**
|
||||||
|
* Only used if {@link #direct} is false.
|
||||||
|
*/
|
||||||
public static ByteBuffer allpixels; // It's set on each change
|
public static ByteBuffer allpixels; // It's set on each change
|
||||||
public static ArrayList<IRenderer> renderers = new ArrayList<>();
|
public static ArrayList<IRenderer> renderers = new ArrayList<>();
|
||||||
|
/**
|
||||||
|
* Only used if {@link #direct} is true.
|
||||||
|
*/
|
||||||
|
public static PXCLib pxc;
|
||||||
|
public static boolean direct;
|
||||||
|
|
||||||
// Fired when plugin is first enabled
|
// Fired when plugin is first enabled
|
||||||
@Override
|
@Override
|
||||||
|
@ -39,10 +50,12 @@ public class PluginMain extends JavaPlugin {
|
||||||
String vbpath = System.getProperty("os.name").toLowerCase().contains("mac")
|
String vbpath = System.getProperty("os.name").toLowerCase().contains("mac")
|
||||||
? "/Applications/VirtualBox.app/Contents/MacOS"
|
? "/Applications/VirtualBox.app/Contents/MacOS"
|
||||||
: "/opt/virtualbox";
|
: "/opt/virtualbox";
|
||||||
File f = new File(vbpath);
|
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
if (!f.isDirectory() || Arrays.stream(f.list()).noneMatch(s -> s.contains("xpcom")))
|
Predicate<File> notGoodDir= ff->!ff.isDirectory() || Arrays.stream(ff.list()).noneMatch(s -> s.contains("xpcom"));
|
||||||
|
if (notGoodDir.test(new File(vbpath)))
|
||||||
vbpath = "/usr/lib/virtualbox";
|
vbpath = "/usr/lib/virtualbox";
|
||||||
|
if(notGoodDir.test(new File(vbpath)))
|
||||||
|
error("Could not find VirtualBox! Download from https://www.virtualbox.org/wiki/Downloads");
|
||||||
if (System.getProperty("vbox.home") == null || System.getProperty("vbox.home").isEmpty())
|
if (System.getProperty("vbox.home") == null || System.getProperty("vbox.home").isEmpty())
|
||||||
System.setProperty("vbox.home", vbpath);
|
System.setProperty("vbox.home", vbpath);
|
||||||
if (System.getProperty("sun.boot.library.path") == null
|
if (System.getProperty("sun.boot.library.path") == null
|
||||||
|
@ -57,24 +70,34 @@ public class PluginMain extends JavaPlugin {
|
||||||
vbox = manager.getVBox();
|
vbox = manager.getVBox();
|
||||||
session = manager.getSessionObject(); // TODO: Events
|
session = manager.getSessionObject(); // TODO: Events
|
||||||
ccs.sendMessage("§bLoading Screen...");
|
ccs.sendMessage("§bLoading Screen...");
|
||||||
|
pxc = LibraryLoader.create(PXCLib.class).search(getDataFolder().getAbsolutePath()).load("pxc");
|
||||||
try {
|
try {
|
||||||
//throw new NoClassDefFoundError("Test error pls ignore");
|
//throw new NoClassDefFoundError("Test error pls ignore");
|
||||||
for (short i = 0; i < 20; i++)
|
for (short i = 0; i < 20; i++)
|
||||||
renderers.add(new DirectRenderer(i, Bukkit.getWorlds().get(0), i * 128 * 128 * 4)); // TODO: The pixels are selected in a horribly wrong way probably
|
renderers.add(new DirectRenderer(i, Bukkit.getWorlds().get(0), i * 128 * 128 * 4)); // TODO: The pixels are selected in a horribly wrong way probably
|
||||||
|
direct=true;
|
||||||
ccs.sendMessage("§bUsing Direct Renderer, all good");
|
ccs.sendMessage("§bUsing Direct Renderer, all good");
|
||||||
} catch (NoClassDefFoundError e) {
|
} catch (NoClassDefFoundError e) {
|
||||||
for (short i = 0; i < 20; i++)
|
for (short i = 0; i < 20; i++)
|
||||||
renderers.add(new BukkitRenderer(i, Bukkit.getWorlds().get(0), i * 128 * 128 * 4));
|
renderers.add(new BukkitRenderer(i, Bukkit.getWorlds().get(0), i * 128 * 128 * 4));
|
||||||
ccs.sendMessage("§6Compability error, using slower renderer");
|
direct=false;
|
||||||
|
ccs.sendMessage("§6Compatibility error, using slower renderer");
|
||||||
}
|
}
|
||||||
ccs.sendMessage("§bLoaded!");
|
ccs.sendMessage("§bLoaded!");
|
||||||
mousetask = getServer().getScheduler().runTaskTimer(this, new MouseLockerPlayerListener(), 0, 0);
|
mousetask = getServer().getScheduler().runTaskTimer(this, new MouseLockerPlayerListener(), 0, 0);
|
||||||
|
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
error(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void error(String message) {
|
||||||
|
getLogger().severe("A fatal error occured, disabling plugin!");
|
||||||
|
Bukkit.getPluginManager().disablePlugin(this);
|
||||||
|
throw new RuntimeException(message);
|
||||||
|
}
|
||||||
|
|
||||||
// Fired when plugin is disabled
|
// Fired when plugin is disabled
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
|
|
|
@ -41,7 +41,7 @@ void setSource(addr address, short w, short h, short mcx, short mcy) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//May return 0
|
//May return 0
|
||||||
void* updateAndGetMap(int x, int y, int w, int h) { //TODO: Support the parameters
|
void* updateAndGetMap(int x, int y, int w, int h, int** out_changed) { //TODO: Support the parameters
|
||||||
if(image==NULL || maps==NULL) return 0;
|
if(image==NULL || maps==NULL) return 0;
|
||||||
char* mapp = maps;
|
char* mapp = maps;
|
||||||
NativeColor* imgp = image;
|
NativeColor* imgp = image;
|
||||||
|
|
Loading…
Reference in a new issue