Directly using VirtualBox from Java #5

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

View file

@ -36,7 +36,7 @@ public class BukkitRenderer extends MapRenderer implements IRenderer {
MapView map = IRenderer.prepare(id, world); MapView map = IRenderer.prepare(id, world);
map.addRenderer(this); map.addRenderer(this);
this.startindex = startindex; this.startindex = startindex;
image = new BufferedImage(640, 480, BufferedImage.TYPE_INT_RGB); image = new BufferedImage(128, 128, BufferedImage.TYPE_INT_RGB);
} }
private int progress = 0; private int progress = 0;

View file

@ -115,6 +115,7 @@ public class Commands implements CommandExecutor {
MouseLockerPlayerListener.LockedPlayers.remove(sender); MouseLockerPlayerListener.LockedPlayers.remove(sender);
sender.sendMessage("§bMouse unlocked."); sender.sendMessage("§bMouse unlocked.");
} }
break;
case "mspeed": case "mspeed":
case "mousespeed": case "mousespeed":
if (args.length < 3) { if (args.length < 3) {

View file

@ -3,6 +3,7 @@ package sznp.virtualcomputer;
import java.awt.Color; import java.awt.Color;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Map; import java.util.Map;
import org.bukkit.World; import org.bukkit.World;
@ -61,6 +62,11 @@ public class DirectRenderer implements IRenderer {
WorldMap wmap = (WorldMap) field.get(map); WorldMap wmap = (WorldMap) field.get(map);
wmap.flagDirty(0, 0); wmap.flagDirty(0, 0);
wmap.flagDirty(127, 127); // Send the whole image - TODO: Only send changes wmap.flagDirty(127, 127); // Send the whole image - TODO: Only send changes
/*
* final Field fieldf = map.getClass().getDeclaredField("renderCache"); fieldf.setAccessible(true);
* @SuppressWarnings("unchecked") final Map<CraftPlayer, RenderData> renderCache = (Map<CraftPlayer, RenderData>) fieldf.get(map); RenderData render = renderCache.get(null);
* System.out.println("==: " + (buffer == render.buffer)); System.out.println("equals:" + Arrays.equals(buffer, render.buffer));
*/
} catch (Exception e) { } catch (Exception e) {
if (ex != null && (e.getMessage() == ex.getMessage() if (ex != null && (e.getMessage() == ex.getMessage()
|| (e.getMessage() != null && e.getMessage().equals(ex.getMessage())))) || (e.getMessage() != null && e.getMessage().equals(ex.getMessage()))))

View file

@ -1,6 +1,7 @@
package sznp.virtualcomputer; package sznp.virtualcomputer;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitTask;
import org.mozilla.interfaces.IFramebuffer; import org.mozilla.interfaces.IFramebuffer;
import org.mozilla.interfaces.IFramebufferOverlay; import org.mozilla.interfaces.IFramebufferOverlay;
import org.mozilla.interfaces.nsISupports; import org.mozilla.interfaces.nsISupports;
@ -74,18 +75,28 @@ public class MCFrameBuffer implements IFramebuffer {
public void notify3DEvent(long arg0, byte[] arg1) { public void notify3DEvent(long arg0, byte[] arg1) {
} }
private BukkitTask tt;
@Override @Override
public void notifyChange(long screenId, long xOrigin, long yOrigin, long width, long height) { public void notifyChange(long screenId, long xOrigin, long yOrigin, long width, long height) {
if (width > 640 || height > 480) System.out.println("Change - " + width + "x" + height);
return; // Don't even try to render too large resolutions if (tt != null)
tt.cancel();
/*
* if (width > 640 || height > 480) { tt = Bukkit.getScheduler().runTaskTimerAsynchronously(PluginMain.Instance, () -> display.setVideoModeHint(0L, true, false, 0, 0, 640L, 480L, 32L), 5, 5);
* return; // Don't even try to render too large resolutions }
*/
Bukkit.getScheduler().runTaskLaterAsynchronously(PluginMain.Instance, () -> { Bukkit.getScheduler().runTaskLaterAsynchronously(PluginMain.Instance, () -> {
display.querySourceBitmap(0L, holder); display.querySourceBitmap(0L, holder);
byte[] arr = PluginMain.allpixels.array(); byte[] arr = PluginMain.allpixels.array();
holder.value.getTypedWrapped().queryBitmapInfo(arr, new long[] { width }, new long[] { height }, long[] w = new long[1], h = new long[1], bpp = new long[1], bpl = new long[1], pf = new long[1];
new long[] { getBitsPerPixel() }, new long[] { getBytesPerLine() }, holder.value.getTypedWrapped().queryBitmapInfo(arr, w, h, bpp, bpl, pf);
new long[] { getPixelFormat() }); // These are out params but whatever System.out.println("Arr10:" + arr[10]);
System.out.println("Arr0:" + arr[0]); System.out.println("whbppbplpf: " + w[0] + " " + h[0] + " " + bpp[0] + " " + bpl[0] + " " + pf[0]);
PluginMain.allpixels.limit((int) (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) for (IRenderer r : PluginMain.renderers)
if (r instanceof BukkitRenderer) if (r instanceof BukkitRenderer)
((BukkitRenderer) r).setAllPixels(PluginMain.allpixels); ((BukkitRenderer) r).setAllPixels(PluginMain.allpixels);
@ -100,7 +111,6 @@ public class MCFrameBuffer implements IFramebuffer {
for (IRenderer r : PluginMain.renderers) for (IRenderer r : PluginMain.renderers)
if (r instanceof DirectRenderer) if (r instanceof DirectRenderer)
((DirectRenderer) r).render(PluginMain.allpixels, x, y, width, height); ((DirectRenderer) r).render(PluginMain.allpixels, x, y, width, height);
System.out.println("Update!");
} }
@Override @Override

View file

@ -6,6 +6,7 @@ import java.util.Map.Entry;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
public class MouseLockerPlayerListener implements Runnable { public class MouseLockerPlayerListener implements Runnable {
public static Map<Player, Location> LockedPlayers = new HashMap<>(); public static Map<Player, Location> LockedPlayers = new HashMap<>();
@ -24,7 +25,7 @@ public class MouseLockerPlayerListener implements Runnable {
PluginMain.Instance.UpdateMouse(null, (int) ((yaw2 - yaw1) * LockedSpeed), PluginMain.Instance.UpdateMouse(null, (int) ((yaw2 - yaw1) * LockedSpeed),
(int) ((pitch2 - pitch1) * LockedSpeed), 0, 0, ""); (int) ((pitch2 - pitch1) * LockedSpeed), 0, 0, "");
entry.setValue(entry.getValue()); entry.getKey().teleport(entry.getValue(), TeleportCause.PLUGIN);
} }
} }
} }

View file

@ -25,7 +25,7 @@ public class PluginMain extends JavaPlugin {
private BukkitTask mousetask; private BukkitTask mousetask;
public static PluginMain Instance; public static PluginMain Instance;
public static ByteBuffer allpixels = ByteBuffer.allocate(640 * 480); // It's set on each change public static ByteBuffer allpixels = ByteBuffer.allocate(640 * 480 * 4); // It's set on each change
public static ArrayList<IRenderer> renderers = new ArrayList<>(); public static ArrayList<IRenderer> renderers = new ArrayList<>();
// Fired when plugin is first enabled // Fired when plugin is first enabled
@ -57,9 +57,10 @@ public class PluginMain extends JavaPlugin {
session = manager.getSessionObject(); // TODO: Events session = manager.getSessionObject(); // TODO: Events
ccs.sendMessage("§bLoading Screen..."); ccs.sendMessage("§bLoading Screen...");
try { try {
for (short i = 0; i < 20; i++) 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 renderers.add(new DirectRenderer(i, Bukkit.getWorlds().get(0), i * 128 * 128 * 4)); // TODO: The pixels are selected in a horribly wrong way probably
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));
@ -97,7 +98,6 @@ public class PluginMain extends JavaPlugin {
session.setName("minecraft"); session.setName("minecraft");
// machine.launchVMProcess(session, "headless", "").waitForCompletion(10000); - This creates a *process*, we don't want that anymore // machine.launchVMProcess(session, "headless", "").waitForCompletion(10000); - This creates a *process*, we don't want that anymore
machine.lockMachine(session, LockType.VM); // We want the machine inside *our* process <-- Need the VM type to have console access machine.lockMachine(session, LockType.VM); // We want the machine inside *our* process <-- Need the VM type to have console access
sender.sendMessage("A: " + machine.getState().toString());
final Runnable tr = new Runnable() { final Runnable tr = new Runnable() {
public void run() { public void run() {
if (session.getState() != SessionState.Locked) { // https://www.virtualbox.org/sdkref/_virtual_box_8idl.html#ac82c179a797c0d7c249d1b98a8e3aa8f if (session.getState() != SessionState.Locked) { // https://www.virtualbox.org/sdkref/_virtual_box_8idl.html#ac82c179a797c0d7c249d1b98a8e3aa8f
@ -105,24 +105,18 @@ public class PluginMain extends JavaPlugin {
return; // "This state also occurs as a short transient state during an IMachine::lockMachine call." return; // "This state also occurs as a short transient state during an IMachine::lockMachine call."
} }
machine = session.getMachine(); // This is the Machine object we can work with machine = session.getMachine(); // This is the Machine object we can work with
sender.sendMessage("B: " + machine.getState().toString());
final IConsole console = session.getConsole(); final IConsole console = session.getConsole();
sender.sendMessage("1: " + console.getState().toString());
console.powerUp(); // https://marc.info/?l=vbox-dev&m=142780789819967&w=2 console.powerUp(); // https://marc.info/?l=vbox-dev&m=142780789819967&w=2
sender.sendMessage("2: " + console.getState().toString());
console.getDisplay().attachFramebuffer(0L, console.getDisplay().attachFramebuffer(0L,
new IFramebuffer(new MCFrameBuffer(console.getDisplay()))); new IFramebuffer(new MCFrameBuffer(console.getDisplay())));
sender.sendMessage("3: " + console.getState().toString());
if (screenupdatetask == null) if (screenupdatetask == null)
screenupdatetask = Bukkit.getScheduler().runTaskTimerAsynchronously(PluginMain.this, () -> { screenupdatetask = Bukkit.getScheduler().runTaskTimerAsynchronously(PluginMain.this, () -> {
sender.sendMessage("4: " + console.getState().toString());
if (session.getState().equals(SessionState.Locked) // Don't run until the machine is running if (session.getState().equals(SessionState.Locked) // Don't run until the machine is running
&& console.getState().equals(MachineState.Running)) && console.getState().equals(MachineState.Running))
console.getDisplay().invalidateAndUpdateScreen(0L); console.getDisplay().invalidateAndUpdateScreen(0L);
if (session.getState().equals(SessionState.Unlocked) // Stop if the machine stopped fully if (session.getState().equals(SessionState.Unlocked) // Stop if the machine stopped fully
|| console.getState().equals(MachineState.PoweredOff) || console.getState().equals(MachineState.PoweredOff)
|| console.getState().equals(MachineState.Saved)) { || console.getState().equals(MachineState.Saved)) {
sender.sendMessage("5: " + console.getState().toString());
if (session.getState().equals(SessionState.Locked)) { if (session.getState().equals(SessionState.Locked)) {
session.unlockMachine(); session.unlockMachine();
sender.sendMessage("Computer powered off, released it."); sender.sendMessage("Computer powered off, released it.");
@ -141,8 +135,13 @@ public class PluginMain extends JavaPlugin {
public static int MouseSpeed = 1; public static int MouseSpeed = 1;
public void Stop(CommandSender sender) { public void Stop(CommandSender sender) {
if (!checkMachineRunning(sender)) if (!checkMachineRunning(sender)) {
if (session.getState().equals(SessionState.Locked)) {
session.unlockMachine();
sender.sendMessage("§eComputer powered off, released it.");
}
return; return;
}
sender.sendMessage("§eStopping computer..."); sender.sendMessage("§eStopping computer...");
session.getConsole().powerDown().waitForCompletion(2000); session.getConsole().powerDown().waitForCompletion(2000);
session.unlockMachine(); session.unlockMachine();