Directly using VirtualBox from Java #5

Merged
NorbiPeti merged 60 commits from directvb into master 2019-04-18 23:29:21 +00:00
5 changed files with 45 additions and 18 deletions
Showing only changes of commit aa6d7bc236 - Show all commits

View file

@ -16,6 +16,9 @@ public class BukkitRenderer extends MapRenderer implements IRenderer {
private BufferedImage image;
private int startindex;
/**
* The raw pixel data from the machine in BGRA format
*/
public void setAllPixels(ByteBuffer allpixels) {
this.allpixels = allpixels;
}
@ -27,8 +30,6 @@ public class BukkitRenderer extends MapRenderer implements IRenderer {
* The ID of the current map
* @param world
* The world to create new maps in
* @param allpixels
* The raw pixel data from the machine in BGRA format
* @param startindex
* The index to start from in allpixels
*/

View file

@ -105,17 +105,15 @@ public class MCFrameBuffer implements IFramebuffer {
holder.value.getTypedWrapped().queryBitmapInfo(ptr, w, h, bpp, bpl, pf);
System.out.println("Arr0:" + ptr[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);
if (width * height > 640 * 480)
PluginMain.allpixels.limit(640 * 480 * 4);
else
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!");
} catch (Throwable t) {
t.printStackTrace();

View file

@ -1,5 +1,10 @@
package sznp.virtualcomputer;
import jnr.ffi.Pointer;
import java.awt.*;
import java.nio.Buffer;
@SuppressWarnings("unused")
public interface PXCLib {
/**
@ -24,5 +29,5 @@ public interface PXCLib {
* Updates map and returns it's content, where affected
* @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)
}

View file

@ -15,8 +15,11 @@ import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.function.Predicate;
public class PluginMain extends JavaPlugin {
public static final int MCX = 5;
public static final int MCY = 4;
private IVirtualBox vbox;
private ISession session;
private IMachine machine;
@ -25,8 +28,16 @@ public class PluginMain extends JavaPlugin {
public static PluginMain Instance;
//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 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
@Override
@ -39,10 +50,12 @@ public class PluginMain extends JavaPlugin {
String vbpath = System.getProperty("os.name").toLowerCase().contains("mac")
? "/Applications/VirtualBox.app/Contents/MacOS"
: "/opt/virtualbox";
File f = new File(vbpath);
//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";
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())
System.setProperty("vbox.home", vbpath);
if (System.getProperty("sun.boot.library.path") == null
@ -57,24 +70,34 @@ public class PluginMain extends JavaPlugin {
vbox = manager.getVBox();
session = manager.getSessionObject(); // TODO: Events
ccs.sendMessage("§bLoading Screen...");
pxc = LibraryLoader.create(PXCLib.class).search(getDataFolder().getAbsolutePath()).load("pxc");
try {
//throw new NoClassDefFoundError("Test error pls ignore");
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
direct=true;
ccs.sendMessage("§bUsing Direct Renderer, all good");
} catch (NoClassDefFoundError e) {
for (short i = 0; i < 20; i++)
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!");
mousetask = getServer().getScheduler().runTaskTimer(this, new MouseLockerPlayerListener(), 0, 0);
} catch (final Exception e) {
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
@Override
public void onDisable() {

View file

@ -41,7 +41,7 @@ void setSource(addr address, short w, short h, short mcx, short mcy) {
}
//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;
char* mapp = maps;
NativeColor* imgp = image;