Attempts to fix screen on Ubuntu after /c fix
It stops sending updates after running the fix command
This commit is contained in:
parent
3ce2da7f7f
commit
32cea5c384
2 changed files with 115 additions and 46 deletions
|
@ -3,6 +3,7 @@ package sznp.virtualcomputer;
|
|||
import com.google.common.collect.Lists;
|
||||
import lombok.Getter;
|
||||
import lombok.val;
|
||||
import lombok.var;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
@ -28,6 +29,7 @@ public final class Computer {
|
|||
private MachineEventHandler handler;
|
||||
private IEventListener listener;
|
||||
private VirtualBoxManager manager;
|
||||
private MCFrameBuffer framebuffer;
|
||||
|
||||
@java.beans.ConstructorProperties({"plugin"})
|
||||
public Computer(PluginMain plugin, VirtualBoxManager manager, IVirtualBox vbox) {
|
||||
|
@ -45,7 +47,7 @@ public final class Computer {
|
|||
return;
|
||||
}
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
||||
if (vbox.getMachines().size() <= index) {
|
||||
if (index < 0 || vbox.getMachines().size() <= index) {
|
||||
sendMessage(sender, "§cMachine not found!");
|
||||
return;
|
||||
}
|
||||
|
@ -54,7 +56,9 @@ public final class Computer {
|
|||
machine = vbox.getMachines().get(index);
|
||||
session.setName("minecraft");
|
||||
// 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
|
||||
synchronized (session) {
|
||||
machine.lockMachine(session, LockType.VM); // We want the machine inside *our* process <-- Need the VM type to have console access
|
||||
}
|
||||
VBoxEventHandler.getInstance().setup(machine.getId(), sender); //TODO: Sometimes null
|
||||
} catch (VBoxException e) {
|
||||
if (e.getResultCode() == 0x80070005) { //lockMachine: "The object functionality is limited"
|
||||
|
@ -95,8 +99,11 @@ public final class Computer {
|
|||
IProgress progress = console.powerUp(); // https://marc.info/?l=vbox-dev&m=142780789819967&w=2
|
||||
handler.setProgress(progress);
|
||||
handler.registerTo(progress.getEventSource()); //TODO: Show progress bar some way?
|
||||
console.getDisplay().attachFramebuffer(0L,
|
||||
COMUtils.gimmeAFramebuffer(new MCFrameBuffer(console.getDisplay())));
|
||||
val fb = new MCFrameBuffer(console.getDisplay());
|
||||
String fbid = console.getDisplay().attachFramebuffer(0L,
|
||||
COMUtils.gimmeAFramebuffer(fb));
|
||||
fb.setId(fbid);
|
||||
framebuffer = fb;
|
||||
}
|
||||
|
||||
private void sendMessage(@Nullable CommandSender sender, String message) {
|
||||
|
@ -114,7 +121,9 @@ public final class Computer {
|
|||
return;
|
||||
}
|
||||
sendMessage(sender, "§eStopping computer...");
|
||||
session.getConsole().powerDown();
|
||||
synchronized (session) {
|
||||
session.getConsole().powerDown();
|
||||
}
|
||||
}
|
||||
|
||||
public void PowerButton(CommandSender sender, int index) {
|
||||
|
@ -125,7 +134,9 @@ public final class Computer {
|
|||
if (session.getState() != SessionState.Locked || session.getMachine() == null) {
|
||||
Start(sender, index);
|
||||
} else {
|
||||
session.getConsole().powerButton();
|
||||
synchronized (session) {
|
||||
session.getConsole().powerButton();
|
||||
}
|
||||
sendMessage(sender, "§ePowerbutton pressed.");
|
||||
}
|
||||
}
|
||||
|
@ -136,17 +147,36 @@ public final class Computer {
|
|||
if (checkMachineNotRunning(sender))
|
||||
return;
|
||||
sendMessage(sender, "§eResetting computer...");
|
||||
session.getConsole().reset();
|
||||
synchronized (session) {
|
||||
session.getConsole().reset();
|
||||
}
|
||||
sendMessage(sender, "§eComputer reset.");
|
||||
}
|
||||
|
||||
public void FixScreen(CommandSender sender) {
|
||||
if (checkMachineNotRunning(sender))
|
||||
return;
|
||||
if (framebuffer == null) {
|
||||
sender.sendMessage("§cFramebuffer is null...");
|
||||
return;
|
||||
}
|
||||
val lastUpdated = new Holder<Long>();
|
||||
var status = session.getConsole().getGuest().getFacilityStatus(AdditionsFacilityType.Seamless, lastUpdated);
|
||||
sendMessage(sender, "Seamless status: " + status);
|
||||
sendMessage(sender, "§eFixing screen...");
|
||||
session.getConsole().getDisplay().setSeamlessMode(false);
|
||||
session.getConsole().getDisplay().setVideoModeHint(0L, true, false, 0, 0, 640L, 480L, 32L, true);
|
||||
try {
|
||||
synchronized (session) {
|
||||
session.getConsole().getDisplay().setSeamlessMode(false);
|
||||
session.getConsole().getDisplay().detachFramebuffer(0L, framebuffer.getId());
|
||||
session.getConsole().getDisplay().setVideoModeHint(0L, true, false, 0, 0, 640L, 480L, 32L, true);
|
||||
framebuffer.setId(session.getConsole().getDisplay().attachFramebuffer(0L, COMUtils.gimmeAFramebuffer(framebuffer)));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
sendMessage(sender, "§eScreen fixed.");
|
||||
status = session.getConsole().getGuest().getFacilityStatus(AdditionsFacilityType.Seamless, lastUpdated);
|
||||
sendMessage(sender, "Seamless status: " + status);
|
||||
}
|
||||
|
||||
public boolean checkMachineNotRunning(@Nullable CommandSender sender) {
|
||||
|
@ -177,14 +207,16 @@ public final class Computer {
|
|||
}
|
||||
// Release key scan code concept taken from VirtualBox source code (KeyboardImpl.cpp:putCAD())
|
||||
// +128
|
||||
if (durationorstate != -2)
|
||||
session.getConsole().getKeyboard().putScancode(code);
|
||||
Runnable sendrelease = () -> session.getConsole().getKeyboard().putScancodes(Lists.newArrayList(code + 128,
|
||||
Scancode.sc_controlLeft.Code + 128, Scancode.sc_shiftLeft.Code + 128, Scancode.sc_altLeft.Code + 128));
|
||||
if (durationorstate == 0 || durationorstate == -2)
|
||||
sendrelease.run();
|
||||
if (durationorstate > 0) {
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, sendrelease, durationorstate);
|
||||
synchronized (session) {
|
||||
if (durationorstate != -2)
|
||||
session.getConsole().getKeyboard().putScancode(code);
|
||||
Runnable sendrelease = () -> session.getConsole().getKeyboard().putScancodes(Lists.newArrayList(code + 128,
|
||||
Scancode.sc_controlLeft.Code + 128, Scancode.sc_shiftLeft.Code + 128, Scancode.sc_altLeft.Code + 128));
|
||||
if (durationorstate == 0 || durationorstate == -2)
|
||||
sendrelease.run();
|
||||
if (durationorstate > 0) {
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, sendrelease, durationorstate * 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,7 +227,9 @@ public final class Computer {
|
|||
if (mbs.length() > 0 && down)
|
||||
state = Arrays.stream(MouseButtonState.values()).filter(mousebs -> mousebs.name().equalsIgnoreCase(mbs))
|
||||
.findAny().orElseThrow(() -> new Exception("Unknown mouse button")).value();
|
||||
session.getConsole().getMouse().putMouseEvent(x, y, z, w, state);
|
||||
synchronized (session) {
|
||||
session.getConsole().getMouse().putMouseEvent(x, y, z, w, state);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateMouse(CommandSender sender, int x, int y, int z, int w, String mbs) throws Exception {
|
||||
|
@ -212,7 +246,9 @@ public final class Computer {
|
|||
public void onMachineStop(CommandSender sender) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
||||
if (session.getState() == SessionState.Locked) {
|
||||
session.unlockMachine(); //Needs to be outside of the event handler
|
||||
synchronized (session) {
|
||||
session.unlockMachine(); //Needs to be outside of the event handler
|
||||
}
|
||||
handler = null;
|
||||
machine = null;
|
||||
session = manager.getSessionObject();
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package sznp.virtualcomputer.renderer;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.virtualbox_6_1.Holder;
|
||||
|
@ -21,46 +23,77 @@ public class MCFrameBuffer implements IMCFrameBuffer {
|
|||
private Pointer pointer;
|
||||
private int width;
|
||||
private int height;
|
||||
private boolean updating = false;
|
||||
@Getter
|
||||
@Setter
|
||||
private String id;
|
||||
|
||||
@Override
|
||||
public void notifyChange(long screenId, long xOrigin, long yOrigin, long width, long height) {
|
||||
if (tt != null)
|
||||
tt.cancel();
|
||||
tt = Bukkit.getScheduler().runTaskAsynchronously(PluginMain.Instance, () -> {
|
||||
try {
|
||||
display.querySourceBitmap(0L, holder);
|
||||
long[] ptr = new long[1], w = new long[1], h = new long[1], bpp = new long[1], bpl = new long[1], pf = new long[1];
|
||||
COMUtils.queryBitmapInfo(holder.value, ptr, w, h, bpp, bpl, pf);
|
||||
if (PluginMain.direct) {
|
||||
pointer = new Pointer(ptr[0]);
|
||||
this.width = (int) w[0];
|
||||
this.height = (int) h[0];
|
||||
GPURenderer.update(pointer.getByteArray(0L, (int) (w[0] * h[0] * 4)), (int) w[0], (int) h[0], 0, 0, this.width, this.height);
|
||||
} 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));
|
||||
synchronized (this) { //If a change occurs twice, then wait for it
|
||||
try {
|
||||
System.out.println("Change: " + xOrigin + " " + yOrigin + " - " + width + " " + height);
|
||||
display.querySourceBitmap(0L, holder);
|
||||
long[] ptr = new long[1], w = new long[1], h = new long[1], bpp = new long[1], bpl = new long[1], pf = new long[1];
|
||||
COMUtils.queryBitmapInfo(holder.value, ptr, w, h, bpp, bpl, pf);
|
||||
if (PluginMain.direct) {
|
||||
pointer = new Pointer(ptr[0]);
|
||||
this.width = (int) w[0];
|
||||
this.height = (int) h[0];
|
||||
if (this.width > 1024 || this.height > 768)
|
||||
return;
|
||||
GPURenderer.update(pointer.getByteArray(0L, (int) (w[0] * h[0] * 4)), (int) w[0], (int) h[0], 0, 0, this.width, this.height);
|
||||
} 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));
|
||||
}
|
||||
} catch (VBoxException e) {
|
||||
if (e.getResultCode() == 0x80070005)
|
||||
return; // Machine is being powered down
|
||||
if (e.getResultCode() == 0x80004005) //The function "querySourceBitmap" returned an error condition: "Operation failed (NS_ERROR_FAILURE)"
|
||||
System.out.println("I don't know why this happens, but stopping the computer helps.");
|
||||
e.printStackTrace();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
} finally {
|
||||
System.out.println("Change finished");
|
||||
}
|
||||
} catch (VBoxException e) {
|
||||
if (e.getResultCode() == 0x80070005)
|
||||
return; // Machine is being powered down
|
||||
if (e.getResultCode() == 0x80004005) //The function "querySourceBitmap" returned an error condition: "Operation failed (NS_ERROR_FAILURE)"
|
||||
System.out.println("I don't know why this happens, but stopping the computer helps.");
|
||||
e.printStackTrace();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyUpdate(long x, long y, long width, long height) {
|
||||
Timing t = new Timing();
|
||||
GPURenderer.update(pointer.getByteArray(0L, this.width * this.height * 4), this.width, this.height, (int) x, (int) y, (int) width, (int) height);
|
||||
if (t.elapsedMS() > 60) //Typically 1ms max
|
||||
System.out.println("Update took " + t.elapsedMS() + "ms");
|
||||
if (this.width > 1024 || this.height > 768)
|
||||
return;
|
||||
Bukkit.getScheduler().runTaskAsynchronously(PluginMain.Instance, () -> {
|
||||
synchronized (this) {
|
||||
if (updating) {
|
||||
System.out.println("Ignoring update");
|
||||
return;
|
||||
}
|
||||
updating = true;
|
||||
if (pointer == null) {
|
||||
System.out.println("Screen pointer is null");
|
||||
updating = false;
|
||||
return;
|
||||
}
|
||||
System.out.println("Update: " + x + " " + y + " - " + width + " " + height);
|
||||
Timing t = new Timing();
|
||||
GPURenderer.update(pointer.getByteArray(0L, this.width * this.height * 4), this.width, this.height, (int) x, (int) y, (int) width, (int) height);
|
||||
if (t.elapsedMS() > 60) //Typically 1ms max
|
||||
System.out.println("Update took " + t.elapsedMS() + "ms");
|
||||
else
|
||||
System.out.println("Update finished");
|
||||
updating = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in a new issue