Add tab complete support
This commit is contained in:
parent
de13d9876d
commit
3ce2da7f7f
5 changed files with 318 additions and 198 deletions
|
@ -59,6 +59,16 @@
|
||||||
<artifactId>VirtualComputer-MSCOM</artifactId>
|
<artifactId>VirtualComputer-MSCOM</artifactId>
|
||||||
<version>2.1-SNAPSHOT</version>
|
<version>2.1-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- <dependency>
|
||||||
|
<groupId>me.lucko</groupId>
|
||||||
|
<artifactId>commodore</artifactId>
|
||||||
|
<version>1.8</version>
|
||||||
|
</dependency> -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.PandacubeFr</groupId>
|
||||||
|
<artifactId>commodore</artifactId>
|
||||||
|
<version>patch-custom-suggests-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<profiles>
|
<profiles>
|
||||||
<profile>
|
<profile>
|
||||||
|
|
|
@ -1,13 +1,31 @@
|
||||||
package sznp.virtualcomputer;
|
package sznp.virtualcomputer;
|
||||||
|
|
||||||
|
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
||||||
|
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||||
|
import com.mojang.brigadier.builder.ArgumentBuilder;
|
||||||
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
|
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
||||||
|
import com.mojang.brigadier.tree.CommandNode;
|
||||||
|
import lombok.val;
|
||||||
|
import me.lucko.commodore.Commodore;
|
||||||
|
import me.lucko.commodore.CommodoreProvider;
|
||||||
|
import me.lucko.commodore.file.CommodoreFileFormat;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandExecutor;
|
import org.bukkit.command.CommandExecutor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.command.TabCompleter;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.virtualbox_6_1.MouseButtonState;
|
||||||
import org.virtualbox_6_1.VBoxException;
|
import org.virtualbox_6_1.VBoxException;
|
||||||
|
import sznp.virtualcomputer.util.Scancode;
|
||||||
|
|
||||||
public class Commands implements CommandExecutor {
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Commands implements CommandExecutor, TabCompleter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
|
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
|
||||||
|
@ -25,6 +43,9 @@ public class Commands implements CommandExecutor {
|
||||||
}
|
}
|
||||||
Computer.getInstance().Start(sender, c);
|
Computer.getInstance().Start(sender, c);
|
||||||
break;
|
break;
|
||||||
|
case "list":
|
||||||
|
Computer.getInstance().List(sender);
|
||||||
|
break;
|
||||||
case "stop":
|
case "stop":
|
||||||
case "poweroff":
|
case "poweroff":
|
||||||
case "off":
|
case "off":
|
||||||
|
@ -82,11 +103,9 @@ public class Commands implements CommandExecutor {
|
||||||
showusage = false;
|
showusage = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} catch (VBoxException e) {
|
||||||
catch (VBoxException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
} catch (Exception ignored) { //It will show the usage here
|
||||||
catch (Exception ignored) { //It will show the usage here
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (showusage) {
|
if (showusage) {
|
||||||
|
@ -131,7 +150,7 @@ public class Commands implements CommandExecutor {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
MouseLockerPlayerListener.LockedSpeed = Float.parseFloat(args[2]);
|
MouseLockerPlayerListener.LockedSpeed = Float.parseFloat(args[2]);
|
||||||
} catch(NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
sender.sendMessage("§cThe speed must be a number.");
|
sender.sendMessage("§cThe speed must be a number.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -143,6 +162,49 @@ public class Commands implements CommandExecutor {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean tabSetup = true;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||||
|
if (CommodoreProvider.isSupported() && tabSetup) {
|
||||||
|
tabSetup = false;
|
||||||
|
new Object() {
|
||||||
|
private void setup(Command command) {
|
||||||
|
val com = CommodoreProvider.getCommodore(PluginMain.Instance);
|
||||||
|
try {
|
||||||
|
val node = CommodoreFileFormat.parse(PluginMain.Instance.getResource("computer.commodore"));
|
||||||
|
CommandNode<Object> arg = RequiredArgumentBuilder.argument("index", IntegerArgumentType.integer()).build();
|
||||||
|
replaceChildren(node.getChild("start"), arg);
|
||||||
|
replaceChildren(node.getChild("on"), arg);
|
||||||
|
arg = RequiredArgumentBuilder.argument("key", StringArgumentType.word())
|
||||||
|
.suggests((context, builder) -> {
|
||||||
|
Arrays.stream(Scancode.values()).map(Scancode::name)
|
||||||
|
.map(name -> name.replace("sc_", "")).forEach(builder::suggest);
|
||||||
|
return builder.buildFuture();
|
||||||
|
}).build();
|
||||||
|
replaceChildren(node.getChild("key"), arg);
|
||||||
|
replaceChildren(node.getChild("press"), arg);
|
||||||
|
arg = RequiredArgumentBuilder.argument("button", StringArgumentType.word())
|
||||||
|
.suggests((context, builder) -> {
|
||||||
|
Arrays.stream(MouseButtonState.values()).map(MouseButtonState::name).forEach(builder::suggest);
|
||||||
|
return builder.buildFuture();
|
||||||
|
}).build();
|
||||||
|
replaceChildren(node.getChild("mouse"), arg);
|
||||||
|
com.register(command, node);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void replaceChildren(CommandNode<Object> target, CommandNode<Object> node) {
|
||||||
|
target.getChildren().clear();
|
||||||
|
target.addChild(node);
|
||||||
|
}
|
||||||
|
}.setup(command);
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the 2nd parameter
|
* Checks the 2nd parameter
|
||||||
*
|
*
|
||||||
|
|
|
@ -2,6 +2,7 @@ package sznp.virtualcomputer;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.val;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
@ -17,220 +18,228 @@ import javax.annotation.Nullable;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public final class Computer {
|
public final class Computer {
|
||||||
@Getter
|
@Getter
|
||||||
private static Computer instance;
|
private static Computer instance;
|
||||||
|
|
||||||
private final PluginMain plugin;
|
private final PluginMain plugin;
|
||||||
private ISession session;
|
private ISession session;
|
||||||
private IVirtualBox vbox;
|
private IVirtualBox vbox;
|
||||||
private IMachine machine;
|
private IMachine machine;
|
||||||
private MachineEventHandler handler;
|
private MachineEventHandler handler;
|
||||||
private IEventListener listener;
|
private IEventListener listener;
|
||||||
private VirtualBoxManager manager;
|
private VirtualBoxManager manager;
|
||||||
|
|
||||||
@java.beans.ConstructorProperties({"plugin"})
|
@java.beans.ConstructorProperties({"plugin"})
|
||||||
public Computer(PluginMain plugin, VirtualBoxManager manager, IVirtualBox vbox) {
|
public Computer(PluginMain plugin, VirtualBoxManager manager, IVirtualBox vbox) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
session = manager.getSessionObject();
|
session = manager.getSessionObject();
|
||||||
this.vbox = vbox;
|
this.vbox = vbox;
|
||||||
if (instance != null) throw new IllegalStateException("A computer already exists!");
|
if (instance != null) throw new IllegalStateException("A computer already exists!");
|
||||||
instance = this;
|
instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Start(CommandSender sender, int index) {// TODO: Add touchscreen support (#2)
|
public void Start(CommandSender sender, int index) {// TODO: Add touchscreen support (#2)
|
||||||
if (session.getState() == SessionState.Locked) {
|
if (session.getState() == SessionState.Locked) {
|
||||||
sender.sendMessage("§cThe machine is already running!");
|
sender.sendMessage("§cThe machine is already running!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
||||||
if (vbox.getMachines().size() <= index) {
|
if (vbox.getMachines().size() <= index) {
|
||||||
sendMessage(sender, "§cMachine not found!");
|
sendMessage(sender, "§cMachine not found!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
sendMessage(sender, "§eStarting computer...");
|
sendMessage(sender, "§eStarting computer...");
|
||||||
machine = vbox.getMachines().get(index);
|
machine = vbox.getMachines().get(index);
|
||||||
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
|
||||||
VBoxEventHandler.getInstance().setup(machine.getId(), sender); //TODO: Sometimes null
|
VBoxEventHandler.getInstance().setup(machine.getId(), sender); //TODO: Sometimes null
|
||||||
} catch (VBoxException e) {
|
} catch (VBoxException e) {
|
||||||
if (e.getResultCode() == 0x80070005) { //lockMachine: "The object functionality is limited"
|
if (e.getResultCode() == 0x80070005) { //lockMachine: "The object functionality is limited"
|
||||||
sendMessage(sender, "§6Cannot start computer, the machine may be inaccessible");
|
sendMessage(sender, "§6Cannot start computer, the machine may be inaccessible");
|
||||||
sendMessage(sender, "§6Make sure that the server is running as root (sudo)");
|
sendMessage(sender, "§6Make sure that the server is running as root (sudo)");
|
||||||
//TODO: If we have VirtualBox open, it won't close the server's port
|
//TODO: If we have VirtualBox open, it won't close the server's port
|
||||||
//TODO: "The object in question already exists." on second start
|
//TODO: "The object in question already exists." on second start
|
||||||
//machine.launchVMProcess(session, "headless", "").waitForCompletion(10000); //No privileges, start the 'old' way
|
//machine.launchVMProcess(session, "headless", "").waitForCompletion(10000); //No privileges, start the 'old' way
|
||||||
//session.getConsole().getDisplay().attachFramebuffer(0L, new IFramebuffer(new COMFrameBuffer(session.getConsole().getDisplay(), false)));
|
//session.getConsole().getDisplay().attachFramebuffer(0L, new IFramebuffer(new COMFrameBuffer(session.getConsole().getDisplay(), false)));
|
||||||
//sendMessage(sender, "§6Computer started with slower screen. Run as root to use a faster method.");
|
//sendMessage(sender, "§6Computer started with slower screen. Run as root to use a faster method.");
|
||||||
} else {
|
} else {
|
||||||
sendMessage(sender, "§cFailed to start computer: " + e.getMessage());
|
sendMessage(sender, "§cFailed to start computer: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void List(CommandSender sender) {
|
||||||
* Gets called when the machine is locked after {@link #Start(CommandSender, int)}
|
val machines = vbox.getMachines();
|
||||||
*
|
for (int i = 0; i < machines.size(); i++) {
|
||||||
* @param sender The sender which started the machine
|
val m = machines.get(i);
|
||||||
*/
|
sender.sendMessage("[" + i + "] " + m.getName() + " - " + m.getState());
|
||||||
public void onLock(CommandSender sender) {
|
}
|
||||||
machine = session.getMachine(); // This is the Machine object we can work with
|
}
|
||||||
final IConsole console = session.getConsole();
|
|
||||||
if (handler != null)
|
|
||||||
handler.disable();
|
|
||||||
handler = new MachineEventHandler(Computer.this, sender);
|
|
||||||
listener = handler.registerTo(console.getEventSource());
|
|
||||||
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())));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendMessage(@Nullable CommandSender sender, String message) {
|
/**
|
||||||
if (sender != null)
|
* Gets called when the machine is locked after {@link #Start(CommandSender, int)}
|
||||||
sender.sendMessage(message);
|
*
|
||||||
plugin.getLogger().warning((sender == null ? "" : sender.getName() + ": ") + ChatColor.stripColor(message));
|
* @param sender The sender which started the machine
|
||||||
}
|
*/
|
||||||
|
public void onLock(CommandSender sender) {
|
||||||
|
machine = session.getMachine(); // This is the Machine object we can work with
|
||||||
|
final IConsole console = session.getConsole();
|
||||||
|
if (handler != null)
|
||||||
|
handler.disable();
|
||||||
|
handler = new MachineEventHandler(Computer.this, sender);
|
||||||
|
listener = handler.registerTo(console.getEventSource());
|
||||||
|
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())));
|
||||||
|
}
|
||||||
|
|
||||||
public void Stop(CommandSender sender) {
|
private void sendMessage(@Nullable CommandSender sender, String message) {
|
||||||
if (checkMachineNotRunning(sender)) {
|
if (sender != null)
|
||||||
if (session.getState().equals(SessionState.Locked)) {
|
sender.sendMessage(message);
|
||||||
onMachineStop(sender); //Needed for session reset
|
plugin.getLogger().warning((sender == null ? "" : sender.getName() + ": ") + ChatColor.stripColor(message));
|
||||||
sendMessage(sender, "§eComputer was already off, released it.");
|
}
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sendMessage(sender, "§eStopping computer...");
|
|
||||||
session.getConsole().powerDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PowerButton(CommandSender sender, int index) {
|
public void Stop(CommandSender sender) {
|
||||||
sendMessage(sender, "§ePressing powerbutton...");
|
if (checkMachineNotRunning(sender)) {
|
||||||
Bukkit.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() {
|
if (session.getState().equals(SessionState.Locked)) {
|
||||||
@Override
|
onMachineStop(sender); //Needed for session reset
|
||||||
public void run() {
|
sendMessage(sender, "§eComputer was already off, released it.");
|
||||||
if (session.getState() != SessionState.Locked || session.getMachine() == null) {
|
}
|
||||||
Start(sender, index);
|
return;
|
||||||
} else {
|
}
|
||||||
session.getConsole().powerButton();
|
sendMessage(sender, "§eStopping computer...");
|
||||||
sendMessage(sender, "§ePowerbutton pressed.");
|
session.getConsole().powerDown();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Reset(CommandSender sender) {
|
public void PowerButton(CommandSender sender, int index) {
|
||||||
if (checkMachineNotRunning(sender))
|
sendMessage(sender, "§ePressing powerbutton...");
|
||||||
return;
|
Bukkit.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() {
|
||||||
sendMessage(sender, "§eResetting computer...");
|
@Override
|
||||||
session.getConsole().reset();
|
public void run() {
|
||||||
sendMessage(sender, "§eComputer reset.");
|
if (session.getState() != SessionState.Locked || session.getMachine() == null) {
|
||||||
}
|
Start(sender, index);
|
||||||
|
} else {
|
||||||
|
session.getConsole().powerButton();
|
||||||
|
sendMessage(sender, "§ePowerbutton pressed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void FixScreen(CommandSender sender) {
|
public void Reset(CommandSender sender) {
|
||||||
if (checkMachineNotRunning(sender))
|
if (checkMachineNotRunning(sender))
|
||||||
return;
|
return;
|
||||||
sendMessage(sender, "§eFixing screen...");
|
sendMessage(sender, "§eResetting computer...");
|
||||||
session.getConsole().getDisplay().setSeamlessMode(false);
|
session.getConsole().reset();
|
||||||
session.getConsole().getDisplay().setVideoModeHint(0L, true, false, 0, 0, 640L, 480L, 32L, true);
|
sendMessage(sender, "§eComputer reset.");
|
||||||
sendMessage(sender, "§eScreen fixed.");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public boolean checkMachineNotRunning(@Nullable CommandSender sender) {
|
public void FixScreen(CommandSender sender) {
|
||||||
if (session.getState() != SessionState.Locked || machine.getState() != MachineState.Running) {
|
if (checkMachineNotRunning(sender))
|
||||||
if (sender != null)
|
return;
|
||||||
sender.sendMessage("§cMachine isn't running.");
|
sendMessage(sender, "§eFixing screen...");
|
||||||
return true;
|
session.getConsole().getDisplay().setSeamlessMode(false);
|
||||||
}
|
session.getConsole().getDisplay().setVideoModeHint(0L, true, false, 0, 0, 640L, 480L, 32L, true);
|
||||||
return false;
|
sendMessage(sender, "§eScreen fixed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PressKey(CommandSender sender, String key, String stateorduration) {
|
public boolean checkMachineNotRunning(@Nullable CommandSender sender) {
|
||||||
if (checkMachineNotRunning(sender))
|
if (session.getState() != SessionState.Locked || machine.getState() != MachineState.Running) {
|
||||||
return;
|
if (sender != null)
|
||||||
int durationorstate;
|
sender.sendMessage("§cMachine isn't running.");
|
||||||
if (stateorduration.length() == 0)
|
return true;
|
||||||
durationorstate = 0;
|
}
|
||||||
else if (stateorduration.equalsIgnoreCase("down"))
|
return false;
|
||||||
durationorstate = -1;
|
}
|
||||||
else if (stateorduration.equalsIgnoreCase("up"))
|
|
||||||
durationorstate = -2;
|
|
||||||
else
|
|
||||||
durationorstate = Short.parseShort(stateorduration);
|
|
||||||
int code = Scancode.getCode("sc_" + key.toLowerCase());
|
|
||||||
if (code == -1) {
|
|
||||||
sender.sendMessage("§cUnknown key: " + key);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateMouse(CommandSender sender, int x, int y, int z, int w, String mbs, boolean down) throws Exception {
|
public void PressKey(CommandSender sender, String key, String stateorduration) {
|
||||||
if (checkMachineNotRunning(sender))
|
if (checkMachineNotRunning(sender))
|
||||||
return;
|
return;
|
||||||
int state = 0;
|
int durationorstate;
|
||||||
if (mbs.length() > 0 && down)
|
if (stateorduration.length() == 0)
|
||||||
state = Arrays.stream(MouseButtonState.values()).filter(mousebs -> mousebs.name().equalsIgnoreCase(mbs))
|
durationorstate = 0;
|
||||||
.findAny().orElseThrow(() -> new Exception("Unknown mouse button")).value();
|
else if (stateorduration.equalsIgnoreCase("down"))
|
||||||
session.getConsole().getMouse().putMouseEvent(x, y, z, w, state);
|
durationorstate = -1;
|
||||||
}
|
else if (stateorduration.equalsIgnoreCase("up"))
|
||||||
|
durationorstate = -2;
|
||||||
|
else
|
||||||
|
durationorstate = Short.parseShort(stateorduration);
|
||||||
|
int code = Scancode.getCode("sc_" + key.toLowerCase());
|
||||||
|
if (code == -1) {
|
||||||
|
sender.sendMessage("§cUnknown key: " + key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateMouse(CommandSender sender, int x, int y, int z, int w, String mbs) throws Exception {
|
public void UpdateMouse(CommandSender sender, int x, int y, int z, int w, String mbs, boolean down) throws Exception {
|
||||||
if (checkMachineNotRunning(sender))
|
if (checkMachineNotRunning(sender))
|
||||||
return;
|
return;
|
||||||
UpdateMouse(sender, x, y, z, w, mbs, true);
|
int state = 0;
|
||||||
UpdateMouse(sender, x, y, z, w, mbs, false);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateMouse(CommandSender sender, int x, int y, int z, int w, String mbs) throws Exception {
|
||||||
|
if (checkMachineNotRunning(sender))
|
||||||
|
return;
|
||||||
|
UpdateMouse(sender, x, y, z, w, mbs, true);
|
||||||
|
UpdateMouse(sender, x, y, z, w, mbs, false);
|
||||||
|
}
|
||||||
|
|
||||||
public void onMachineStart(CommandSender sender) {
|
public void onMachineStart(CommandSender sender) {
|
||||||
sendMessage(sender, "§eComputer started.");
|
sendMessage(sender, "§eComputer started.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onMachineStop(CommandSender sender) {
|
public void onMachineStop(CommandSender sender) {
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
||||||
if (session.getState() == SessionState.Locked) {
|
if (session.getState() == SessionState.Locked) {
|
||||||
session.unlockMachine(); //Needs to be outside of the event handler
|
session.unlockMachine(); //Needs to be outside of the event handler
|
||||||
handler = null;
|
handler = null;
|
||||||
machine = null;
|
machine = null;
|
||||||
session = manager.getSessionObject();
|
session = manager.getSessionObject();
|
||||||
sendMessage(sender, "§eComputer powered off."); //This block runs later
|
sendMessage(sender, "§eComputer powered off."); //This block runs later
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
GPURenderer.update(new byte[1], 0, 0, 0, 0, 640, 480); //Black screen
|
GPURenderer.update(new byte[1], 0, 0, 0, 0, 640, 480); //Black screen
|
||||||
stopEvents();
|
stopEvents();
|
||||||
MouseLockerPlayerListener.computerStop();
|
MouseLockerPlayerListener.computerStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopEvents() {
|
public void stopEvents() {
|
||||||
/*if(session!=null && listener!=null)
|
/*if(session!=null && listener!=null)
|
||||||
session.getConsole().getEventSource().unregisterListener(listener);*/
|
session.getConsole().getEventSource().unregisterListener(listener);*/
|
||||||
if (listener != null)
|
if (listener != null)
|
||||||
handler.disable();
|
handler.disable();
|
||||||
listener = null;
|
listener = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pluginDisable(CommandSender ccs) {
|
public void pluginDisable(CommandSender ccs) {
|
||||||
stopEvents();
|
stopEvents();
|
||||||
if (session.getState() == SessionState.Locked) {
|
if (session.getState() == SessionState.Locked) {
|
||||||
if (session.getMachine().getState().equals(MachineState.Running)) {
|
if (session.getMachine().getState().equals(MachineState.Running)) {
|
||||||
ccs.sendMessage("§aSaving machine state...");
|
ccs.sendMessage("§aSaving machine state...");
|
||||||
session.getMachine().saveState().waitForCompletion(10000);
|
session.getMachine().saveState().waitForCompletion(10000);
|
||||||
}
|
}
|
||||||
session.unlockMachine();
|
session.unlockMachine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
35
VirtualComputer-Core/src/main/resources/computer.commodore
Normal file
35
VirtualComputer-Core/src/main/resources/computer.commodore
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
computer {
|
||||||
|
start {
|
||||||
|
index brigadier:integer;
|
||||||
|
}
|
||||||
|
on {
|
||||||
|
index brigadier:integer;
|
||||||
|
}
|
||||||
|
list;
|
||||||
|
stop;
|
||||||
|
off;
|
||||||
|
shutdown;
|
||||||
|
kill;
|
||||||
|
powerbutton;
|
||||||
|
reset;
|
||||||
|
restart;
|
||||||
|
fix;
|
||||||
|
fixscreen;
|
||||||
|
key {
|
||||||
|
key brigadier:string single_word;
|
||||||
|
}
|
||||||
|
press {
|
||||||
|
key brigadier:string single_word;
|
||||||
|
}
|
||||||
|
mouse {
|
||||||
|
button brigadier:string single_word;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
key;
|
||||||
|
mouse;
|
||||||
|
}
|
||||||
|
show {
|
||||||
|
key;
|
||||||
|
mouse;
|
||||||
|
}
|
||||||
|
}
|
4
pom.xml
4
pom.xml
|
@ -33,6 +33,10 @@
|
||||||
<id>spigot-repo</id>
|
<id>spigot-repo</id>
|
||||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>jitpack</id>
|
||||||
|
<url>https://jitpack.io/</url>
|
||||||
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
Loading…
Reference in a new issue