Show MineGeo console output and release plugin 0.1.2
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"passed": true,
|
||||
"checks": [
|
||||
"local console help, status and errors produce visible output",
|
||||
"remote console help produces visible output",
|
||||
"missing export guidance",
|
||||
"empty area failure",
|
||||
"real Paper export without a player",
|
||||
@@ -16,5 +18,5 @@
|
||||
"blocks": 10112,
|
||||
"chunks": 16,
|
||||
"viewpoints": 24,
|
||||
"directory": ".cache/plugin-regression-1791186051478"
|
||||
"directory": ".cache/plugin-regression-1791207258927"
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
# Server plugin 0.1.1
|
||||
# Server plugin 0.1.2
|
||||
|
||||
## Update and connect
|
||||
|
||||
1. Stop the Minecraft server, replace its old MineGeo JAR with `public/tools/plugin/minegeo-plugin-1.21.11.jar`, and restart. Run `/version MineGeo` to verify 0.1.1.
|
||||
1. Stop the Minecraft server, replace its old MineGeo JAR with `public/tools/plugin/minegeo-plugin-1.21.11.jar`, and restart. Run `version MineGeo` in the console to verify 0.1.2.
|
||||
2. Open your MineGeo website dashboard, sign in, and generate a plugin token.
|
||||
3. In the Minecraft server console, configure the website and token. Console commands do not need the leading slash:
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
allprojects { group = 'dev.minegeo'; version = '0.1.1'; repositories { mavenCentral() } }
|
||||
allprojects { group = 'dev.minegeo'; version = '0.1.2'; repositories { mavenCentral() } }
|
||||
|
||||
@@ -37,7 +37,10 @@ public final class MineGeoPlugin extends JavaPlugin {
|
||||
}
|
||||
@Override public void onDisable(){cancelled.set(true);}
|
||||
@Override public boolean onCommand(CommandSender sender,Command command,String label,String[] args){
|
||||
if(!sender.hasPermission("minegeo.admin")){sender.sendMessage("MineGeo: administrator permission required.");return true;}
|
||||
// Paper may dispatch hosting-panel commands through a remote console sender
|
||||
// whose permissions differ from the local console. Check permissions here so
|
||||
// every rejected command receives a visible explanation.
|
||||
if(!(sender instanceof ConsoleCommandSender||sender instanceof RemoteConsoleCommandSender||sender instanceof Player&&sender.hasPermission("minegeo.admin"))){sender.sendMessage("MineGeo: administrator permission required.");return true;}
|
||||
try {
|
||||
if(args.length==0||args[0].equalsIgnoreCase("help")) {sender.sendMessage(new String[]{"MineGeo commands:","/minegeo website <http(s)://address:port>","/minegeo server <hostname[:port]> — capture server address","/minegeo link <dashboard token>","/minegeo area <world> <minX> <minZ> <maxX> <maxZ>","/minegeo export <map name> — saves a local export","/minegeo upload — uploads the latest completed export","/minegeo contribute <map ID> — send up to 12 panoramas to its owner","/minegeo status | cancel | reload"});return true;}
|
||||
switch(args[0].toLowerCase(Locale.ROOT)) {
|
||||
@@ -62,7 +65,7 @@ public final class MineGeoPlugin extends JavaPlugin {
|
||||
}catch(Exception ex){sender.sendMessage("MineGeo: "+ex.getMessage());}return true;
|
||||
}
|
||||
private void requireIdle(){if(busy)throw new IllegalArgumentException("An operation is running. Use /minegeo status or /minegeo cancel.");}
|
||||
private void report(CommandSender sender,String message){status=message;getLogger().info(message);if(sender instanceof Player&&isEnabled())Bukkit.getScheduler().runTask(this,()->sender.sendMessage("MineGeo: "+message));}
|
||||
private void report(CommandSender sender,String message){status=message;getLogger().info(message);if(!(sender instanceof ConsoleCommandSender)&&isEnabled())Bukkit.getScheduler().runTask(this,()->sender.sendMessage("MineGeo: "+message));}
|
||||
private void fail(CommandSender sender,String phase,Exception ex){report(sender,cancelled.get()?"Cancelled. Completed exports are kept.":phase+" failed: "+ex.getMessage());if(!cancelled.get())getLogger().log(Level.WARNING,phase+" failure",ex);}
|
||||
private void upload(CommandSender sender,String targetMap)throws Exception {
|
||||
requireIdle();if(latest==null||!Files.isRegularFile(latest.resolve("manifest.json")))throw new IOException("No completed export. Run /minegeo export My World, wait for 'Export complete', then /minegeo upload. Files: "+getDataFolder().toPath().resolve("exports").toAbsolutePath());
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
name: MineGeo
|
||||
version: 0.1.1
|
||||
version: 0.1.2
|
||||
main: dev.minegeo.plugin.MineGeoPlugin
|
||||
api-version: '1.21'
|
||||
description: Bounded terrain export for MineGeo panorama guessing
|
||||
commands:
|
||||
minegeo:
|
||||
description: Link, select, export, upload, status or cancel MineGeo maps
|
||||
permission: minegeo.admin
|
||||
permissions:
|
||||
minegeo.admin:
|
||||
default: op
|
||||
|
||||
Binary file not shown.
@@ -1,4 +1,5 @@
|
||||
import { createServer } from "node:http";
|
||||
import { connect } from "node:net";
|
||||
import { spawn } from "node:child_process";
|
||||
import { mkdir, copyFile, writeFile, readFile } from "node:fs/promises";
|
||||
import { createHash } from "node:crypto";
|
||||
@@ -17,7 +18,7 @@ await copyFile(
|
||||
await writeFile(`${directory}/eula.txt`, "eula=true\n");
|
||||
await writeFile(
|
||||
`${directory}/server.properties`,
|
||||
'server-ip=127.0.0.1\nserver-port=25580\nonline-mode=true\nlevel-type=minecraft:flat\ngenerator-settings={"layers":[{"block":"minecraft:bedrock","height":1},{"block":"minecraft:dirt","height":2},{"block":"minecraft:grass_block","height":1}],"biome":"minecraft:plains"}\ngenerate-structures=false\nview-distance=2\nsimulation-distance=2\nspawn-protection=0\nmax-players=1\n',
|
||||
'server-ip=127.0.0.1\nserver-port=25580\nenable-rcon=true\nrcon.port=25581\nrcon.password=minegeo-fixture\nonline-mode=true\nlevel-type=minecraft:flat\ngenerator-settings={"layers":[{"block":"minecraft:bedrock","height":1},{"block":"minecraft:dirt","height":2},{"block":"minecraft:grass_block","height":1}],"biome":"minecraft:plains"}\ngenerate-structures=false\nview-distance=2\nsimulation-distance=2\nspawn-protection=0\nmax-players=1\n',
|
||||
);
|
||||
let manifest: any,
|
||||
received = Buffer.alloc(0),
|
||||
@@ -164,8 +165,52 @@ const command = async (text: string, pattern: RegExp) => {
|
||||
child.stdin.write(text + "\n");
|
||||
await pending;
|
||||
};
|
||||
const rconCommand = (text: string, expected: RegExp) => new Promise<void>((resolve, reject) => {
|
||||
const socket = connect(25581, "127.0.0.1");
|
||||
let buffer = Buffer.alloc(0);
|
||||
let authenticated = false;
|
||||
const timeout = setTimeout(() => finish(new Error(`RCON timed out waiting for ${expected}`)), 10000);
|
||||
const finish = (error?: Error) => {
|
||||
clearTimeout(timeout);
|
||||
socket.destroy();
|
||||
if (error) reject(error);
|
||||
else resolve();
|
||||
};
|
||||
const packet = (id: number, type: number, body: string) => {
|
||||
const payload = Buffer.from(body);
|
||||
const frame = Buffer.alloc(payload.length + 14);
|
||||
frame.writeInt32LE(payload.length + 10, 0);
|
||||
frame.writeInt32LE(id, 4);
|
||||
frame.writeInt32LE(type, 8);
|
||||
payload.copy(frame, 12);
|
||||
return frame;
|
||||
};
|
||||
socket.on("connect", () => socket.write(packet(1, 3, "minegeo-fixture")));
|
||||
socket.on("error", finish);
|
||||
socket.on("data", (chunk) => {
|
||||
buffer = Buffer.concat([buffer, chunk]);
|
||||
while (buffer.length >= 4 && buffer.length >= buffer.readInt32LE(0) + 4) {
|
||||
const length = buffer.readInt32LE(0);
|
||||
const frame = buffer.subarray(0, length + 4);
|
||||
buffer = buffer.subarray(length + 4);
|
||||
const id = frame.readInt32LE(4);
|
||||
const type = frame.readInt32LE(8);
|
||||
if (id === -1) return finish(new Error("RCON authentication failed"));
|
||||
if (id === 1 && type === 2 && !authenticated) {
|
||||
authenticated = true;
|
||||
socket.write(packet(2, 2, text));
|
||||
} else if (id === 2 && expected.test(frame.toString("utf8", 12, length + 2))) {
|
||||
return finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
try {
|
||||
await wait(/Done \(/, 0, 180000);
|
||||
await command("minegeo help", /MineGeo commands:/);
|
||||
await command("minegeo status", /MineGeo: Idle/);
|
||||
await command("minegeo unknown", /Unknown command\. Use \/minegeo help/);
|
||||
await rconCommand("minegeo help", /MineGeo commands:/);
|
||||
await command("minegeo upload", /No completed export/);
|
||||
await command(
|
||||
"minegeo area world 100000 100000 100032 100032",
|
||||
@@ -266,6 +311,8 @@ try {
|
||||
{
|
||||
passed: true,
|
||||
checks: [
|
||||
"local console help, status and errors produce visible output",
|
||||
"remote console help produces visible output",
|
||||
"missing export guidance",
|
||||
"empty area failure",
|
||||
"real Paper export without a player",
|
||||
|
||||
Reference in New Issue
Block a user