From f45bbccfa38622cfa615bbcb213e1ff042548ae6 Mon Sep 17 00:00:00 2001 From: Shirasawa <764798966@qq.com> Date: Wed, 18 Aug 2021 04:20:16 +0800 Subject: [PATCH] Update --- package-lock.json | 4 +- package.json | 2 +- .../java/cn/apisium/nekomaid/NekoMaid.java | 5 +- .../nekomaid/builtin/BuiltinPlugins.java | 5 +- .../apisium/nekomaid/builtin/ItemEditor.java | 2 +- .../cn/apisium/nekomaid/builtin/Options.java | 25 +++ .../apisium/nekomaid/builtin/PlayerList.java | 2 +- .../cn/apisium/nekomaid/builtin/Worlds.java | 179 ++++++++++-------- vscode-material-icon-theme | 2 +- web/Plugin.ts | 5 +- web/pages/Config.tsx | 44 ++++- web/pages/Worlds.tsx | 17 +- 12 files changed, 191 insertions(+), 101 deletions(-) create mode 100644 src/main/java/cn/apisium/nekomaid/builtin/Options.java diff --git a/package-lock.json b/package-lock.json index c4ef5a9a..f85efc32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "nekomaid", - "version": "0.0.8", + "version": "0.0.9", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "nekomaid", - "version": "0.0.8", + "version": "0.0.9", "license": "MIT", "dependencies": { "@emotion/react": "^11.4.1", diff --git a/package.json b/package.json index dd554242..acdfa6fd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nekomaid", - "version": "0.0.8", + "version": "0.0.9", "description": "A plugin can use Web to manage your server.", "main": "index.js", "private": true, diff --git a/src/main/java/cn/apisium/nekomaid/NekoMaid.java b/src/main/java/cn/apisium/nekomaid/NekoMaid.java index 00a36f19..fc42d822 100644 --- a/src/main/java/cn/apisium/nekomaid/NekoMaid.java +++ b/src/main/java/cn/apisium/nekomaid/NekoMaid.java @@ -96,7 +96,6 @@ public void onEnable() { .put("plugins", pluginScripts) .put("version", getServer().getVersion()) .put("onlineMode", getServer().getOnlineMode()) - .put("hasWhitelist", getServer().hasWhitelist()) .put("pluginVersion", getDescription().getVersion()); if (Utils.IS_PAPER) GLOBAL_DATA.put("isPaper", true); try { @@ -167,6 +166,10 @@ public void onEnable() { } catch (Throwable e) {e.printStackTrace();} }); connectListeners.forEach((k, v) -> v.accept(getClient(k, client))); + GLOBAL_DATA + .put("hasWhitelist", getServer().hasWhitelist()) + .put("maxPlayers", getServer().getMaxPlayers()) + .put("spawnRadius", getServer().getSpawnRadius()); client.send("globalData", GLOBAL_DATA); }).on("error", System.out::println); Uniporter.registerHandler("NekoMaid", new MainHandler(), true); diff --git a/src/main/java/cn/apisium/nekomaid/builtin/BuiltinPlugins.java b/src/main/java/cn/apisium/nekomaid/builtin/BuiltinPlugins.java index 611e45f7..13670207 100644 --- a/src/main/java/cn/apisium/nekomaid/builtin/BuiltinPlugins.java +++ b/src/main/java/cn/apisium/nekomaid/builtin/BuiltinPlugins.java @@ -10,7 +10,8 @@ public final class BuiltinPlugins { public BuiltinPlugins(NekoMaid main) { new Dashboard(main); console = new Console(main); - PlayerList.initPlayerList(main); + PlayerList.init(main); + Options.init(main); files = new FilesManager(main); main.getServer().getScheduler().runTask(main, () -> { new Plugins(main); @@ -19,7 +20,7 @@ public BuiltinPlugins(NekoMaid main) { if (pm.getPlugin("Vault") != null) new Vault(main); new OpenInv(main); new Worlds(main); - if (pm.getPlugin("NBTAPI") != null) ItemEditor.initItemEditor(main); + if (pm.getPlugin("NBTAPI") != null) ItemEditor.init(main); }); } public void disable() { diff --git a/src/main/java/cn/apisium/nekomaid/builtin/ItemEditor.java b/src/main/java/cn/apisium/nekomaid/builtin/ItemEditor.java index b6abf6e5..f570d51d 100644 --- a/src/main/java/cn/apisium/nekomaid/builtin/ItemEditor.java +++ b/src/main/java/cn/apisium/nekomaid/builtin/ItemEditor.java @@ -17,7 +17,7 @@ final class ItemEditor { data[1] = Utils.serializeToString(new String[0]); } } - public static void initItemEditor(NekoMaid main) { + public static void init(NekoMaid main) { main.GLOBAL_DATA.put("hasNBTAPI", true); main.onConnected(main, client -> client.onWithMultiArgsAck("item:fetch", () -> data)); } diff --git a/src/main/java/cn/apisium/nekomaid/builtin/Options.java b/src/main/java/cn/apisium/nekomaid/builtin/Options.java new file mode 100644 index 00000000..8156152b --- /dev/null +++ b/src/main/java/cn/apisium/nekomaid/builtin/Options.java @@ -0,0 +1,25 @@ +package cn.apisium.nekomaid.builtin; + +import cn.apisium.nekomaid.NekoMaid; +import org.bukkit.Server; + +final class Options { + private static boolean canSetMaxPlayers; + static { + try { + Server.class.getMethod("setMaxPlayers", int.class); + canSetMaxPlayers = true; + } catch (Throwable ignored) { } + } + public static void init(NekoMaid main) { + if (canSetMaxPlayers) main.GLOBAL_DATA.put("canSetMaxPlayers", true); + main.onConnected(main, client -> client + .on("server:set", args -> main.getServer().getScheduler().runTask(main, () -> { + switch ((String) args[0]) { + case "maxPlayers": if (canSetMaxPlayers) main.getServer().setMaxPlayers((int) args[1]); break; + case "spawnRadius": main.getServer().setSpawnRadius((int) args[1]); break; + case "hasWhitelist": main.getServer().setWhitelist((boolean) args[1]); break; + } + }))); + } +} diff --git a/src/main/java/cn/apisium/nekomaid/builtin/PlayerList.java b/src/main/java/cn/apisium/nekomaid/builtin/PlayerList.java index 2019552c..b91e33aa 100644 --- a/src/main/java/cn/apisium/nekomaid/builtin/PlayerList.java +++ b/src/main/java/cn/apisium/nekomaid/builtin/PlayerList.java @@ -51,7 +51,7 @@ public List(long a, Object[] c) { } } @SuppressWarnings({"deprecation", "ConstantConditions"}) - public static void initPlayerList(NekoMaid main) { + public static void init(NekoMaid main) { Server server = main.getServer(); main.onConnected(main, client -> client.onWithAck("playerList:fetchPage", args -> { Stream list; diff --git a/src/main/java/cn/apisium/nekomaid/builtin/Worlds.java b/src/main/java/cn/apisium/nekomaid/builtin/Worlds.java index 7a9ac441..23958448 100644 --- a/src/main/java/cn/apisium/nekomaid/builtin/Worlds.java +++ b/src/main/java/cn/apisium/nekomaid/builtin/Worlds.java @@ -13,7 +13,6 @@ import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.weather.ThunderChangeEvent; import org.bukkit.event.weather.WeatherChangeEvent; -import org.bukkit.event.world.TimeSkipEvent; import org.bukkit.event.world.WorldLoadEvent; import org.bukkit.event.world.WorldUnloadEvent; import org.bukkit.plugin.Plugin; @@ -22,8 +21,8 @@ import java.util.UUID; import java.util.concurrent.FutureTask; -final class Worlds implements Listener { - private boolean hasWorldGameRuleChangeEvent = false, canSetViewDistance; +final class Worlds { + private boolean hasWorldGameRuleChangeEvent = false, canSetViewDistance, hasSeparateViewDistance; private final Plugin mv; private final NekoMaid main; private final static class World { @@ -38,67 +37,74 @@ public Worlds(NekoMaid main) { this.main = main; mv = main.getServer().getPluginManager().getPlugin("Multiverse-Core"); if (mv != null) main.GLOBAL_DATA.put("hasMultiverse", true); - main.onConnected(main, client -> client.onWithAck("worlds:fetch", this::getWorlds) - .onWithAck("worlds:weather", args -> { - org.bukkit.World world = main.getServer().getWorld(UUID.fromString((String) args[0])); - if (world == null) return; - main.getServer().getScheduler().runTask(main, () -> { - if (world.isThundering()) { - world.setThundering(false); - world.setStorm(false); - } else if (world.hasStorm()) world.setThundering(true); - else world.setStorm(true); - }); - }).onWithAck("worlds:rule", args -> { - org.bukkit.World world = main.getServer().getWorld(UUID.fromString((String) args[0])); - if (world == null) return; - String k = (String) args[1], v = (String) args[2]; - main.getServer().getScheduler().runTask(main, () -> { - world.setGameRuleValue(k, v); - if (!hasWorldGameRuleChangeEvent) update(); - }); - }).onWithAck("worlds:difficulty", args -> { - org.bukkit.World world = main.getServer().getWorld(UUID.fromString((String) args[0])); - if (world == null) return; - String value = (String) args[1]; - Difficulty diff = Difficulty.valueOf(value); - main.getServer().getScheduler().runTask(main, () -> { - world.setDifficulty(diff); - if (mv != null) try { - MVWorldManager wm = ((MultiverseCore) mv).getMVWorldManager(); - wm.getMVWorld(world).setPropertyValue("difficulty", value); - ((MultiverseCore) mv).getMVWorldManager().saveWorldsConfig(); - } catch (Throwable e) { - e.printStackTrace(); - } - update(); - }); - }).onWithAck("worlds:pvp", args -> { + main.onConnected(main, client -> { + client.onWithAck("worlds:fetch", this::getWorlds) + .onWithAck("worlds:weather", args -> { + org.bukkit.World world = main.getServer().getWorld(UUID.fromString((String) args[0])); + if (world == null) return; + main.getServer().getScheduler().runTask(main, () -> { + if (world.isThundering()) { + world.setThundering(false); + world.setStorm(false); + } else if (world.hasStorm()) world.setThundering(true); + else world.setStorm(true); + }); + }).onWithAck("worlds:rule", args -> { + org.bukkit.World world = main.getServer().getWorld(UUID.fromString((String) args[0])); + if (world == null) return; + String k = (String) args[1], v = (String) args[2]; + main.getServer().getScheduler().runTask(main, () -> { + world.setGameRuleValue(k, v); + if (!hasWorldGameRuleChangeEvent) update(); + }); + }).onWithAck("worlds:difficulty", args -> { + org.bukkit.World world = main.getServer().getWorld(UUID.fromString((String) args[0])); + if (world == null) return; + String value = (String) args[1]; + Difficulty diff = Difficulty.valueOf(value); + main.getServer().getScheduler().runTask(main, () -> { + world.setDifficulty(diff); + if (mv != null) try { + MVWorldManager wm = ((MultiverseCore) mv).getMVWorldManager(); + wm.getMVWorld(world).setPropertyValue("difficulty", value); + ((MultiverseCore) mv).getMVWorldManager().saveWorldsConfig(); + } catch (Throwable e) { + e.printStackTrace(); + } + update(); + }); + }).onWithAck("worlds:pvp", args -> { + org.bukkit.World world = main.getServer().getWorld(UUID.fromString((String) args[0])); + if (world == null) return; + boolean value = (boolean) args[1]; + main.getServer().getScheduler().runTask(main, () -> { + world.setPVP(value); + if (mv != null) try { + MVWorldManager wm = ((MultiverseCore) mv).getMVWorldManager(); + wm.getMVWorld(world).setPropertyValue("pvp", String.valueOf(value)); + ((MultiverseCore) mv).getMVWorldManager().saveWorldsConfig(); + } catch (Throwable e) { + e.printStackTrace(); + } + update(); + }); + }).onWithAck("worlds:viewDistance", args -> { + org.bukkit.World world = main.getServer().getWorld(UUID.fromString((String) args[0])); + if (world == null || !canSetViewDistance) return; + main.getServer().getScheduler().runTask(main, () -> { + world.setViewDistance((int) args[1]); + update(); + }); + }).onWithAck("worlds:save", args -> { + org.bukkit.World world = main.getServer().getWorld(UUID.fromString((String) args[0])); + if (world == null) return; + main.getServer().getScheduler().runTask(main, world::save); + }); + if (mv != null) { + MVWorldManager wm = ((MultiverseCore) mv).getMVWorldManager(); + client.onWithAck("worlds:set", args -> { org.bukkit.World world = main.getServer().getWorld(UUID.fromString((String) args[0])); if (world == null) return; - boolean value = (boolean) args[1]; - main.getServer().getScheduler().runTask(main, () -> { - world.setPVP(value); - if (mv != null) try { - MVWorldManager wm = ((MultiverseCore) mv).getMVWorldManager(); - wm.getMVWorld(world).setPropertyValue("pvp", String.valueOf(value)); - ((MultiverseCore) mv).getMVWorldManager().saveWorldsConfig(); - } catch (Throwable e) { - e.printStackTrace(); - } - update(); - }); - }).onWithAck("worlds:viewDistance", args -> { - org.bukkit.World world = main.getServer().getWorld(UUID.fromString((String) args[0])); - if (world == null || !canSetViewDistance) return; - main.getServer().getScheduler().runTask(main, () -> { - world.setViewDistance((int) args[1]); - update(); - }); - }).onWithAck("worlds:set", args -> { - org.bukkit.World world = main.getServer().getWorld(UUID.fromString((String) args[0])); - if (world == null || mv == null) return; - MVWorldManager wm = ((MultiverseCore) mv).getMVWorldManager(); main.getServer().getScheduler().runTask(main, () -> { try { wm.getMVWorld(world).setPropertyValue((String) args[1], (String) args[2]); @@ -108,41 +114,50 @@ public Worlds(NekoMaid main) { e.printStackTrace(); } }); - }).onWithAck("worlds:save", args -> { - org.bukkit.World world = main.getServer().getWorld(UUID.fromString((String) args[0])); - if (world == null) return; - main.getServer().getScheduler().runTask(main, world::save); - })); + }); + } + }); + Events events = new Events(); main.getServer().getScheduler() - .runTask(main, () -> main.getServer().getPluginManager().registerEvents(this, main)); + .runTask(main, () -> main.getServer().getPluginManager().registerEvents(events, main)); try { Class clazz = (Class) Class.forName("io.papermc.paper.event.world.WorldGameRuleChangeEvent"); - main.getServer().getPluginManager().registerEvent(clazz, this, + main.getServer().getPluginManager().registerEvent(clazz, events, EventPriority.MONITOR, (a, b) -> update(), main, true); hasWorldGameRuleChangeEvent = true; } catch (Throwable ignored) { } + try { + Class clazz = (Class) + Class.forName("org.bukkit.event.world.TimeSkipEvent"); + main.getServer().getPluginManager().registerEvent(clazz, events, + EventPriority.MONITOR, (a, b) -> update(), main, true); + } catch (Throwable ignored) { } try { org.bukkit.World.class.getMethod("setViewDistance", int.class); canSetViewDistance = true; main.GLOBAL_DATA.put("canSetViewDistance", true); } catch (Throwable ignored) { } + try { + org.bukkit.World.class.getMethod("getViewDistance"); + hasSeparateViewDistance = true; + } catch (Throwable ignored) { } } private void update() { main.broadcastInPage(main, "worlds", "worlds:update"); } - @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) - public void onWeatherChange(WeatherChangeEvent e) { update(); } - @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) - public void onThunderChange(ThunderChangeEvent e) { update(); } - @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) - public void onTimeSkip(TimeSkipEvent e) { update(); } - @EventHandler - public void onPlayerChangedWorld(PlayerChangedWorldEvent e) { update(); } - @EventHandler - public void onWorldLoad(WorldLoadEvent e) { update(); } - @EventHandler - public void onWorldUnload(WorldUnloadEvent e) { update(); } + private final class Events implements Listener { + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onWeatherChange(WeatherChangeEvent e) { update(); } + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onThunderChange(ThunderChangeEvent e) { update(); } + @EventHandler + public void onPlayerChangedWorld(PlayerChangedWorldEvent e) { update(); } + @EventHandler + public void onWorldLoad(WorldLoadEvent e) { update(); } + @EventHandler + public void onWorldUnload(WorldUnloadEvent e) { update(); } + } @SuppressWarnings("deprecation") private Object[] getWorlds() { @@ -155,7 +170,7 @@ private Object[] getWorlds() { w.players = it.getPlayers().size(); w.chunks = chunks.length; w.weather = it.isThundering() ? 2 : it.hasStorm() ? 1 : 0; - w.viewDistance = it.getViewDistance(); + w.viewDistance = hasSeparateViewDistance ? it.getViewDistance() : main.getServer().getViewDistance(); w.allowMonsters = it.getAllowMonsters(); w.allowAnimals = it.getAllowAnimals(); w.pvp = it.getPVP(); diff --git a/vscode-material-icon-theme b/vscode-material-icon-theme index e5fcd41c..0b40fd80 160000 --- a/vscode-material-icon-theme +++ b/vscode-material-icon-theme @@ -1 +1 @@ -Subproject commit e5fcd41ce3233db5aeefde32cbc2e385f96eefac +Subproject commit 0b40fd805d7b60b447eb1d054c0a63b8a0d65cf1 diff --git a/web/Plugin.ts b/web/Plugin.ts index 569004e5..28df6480 100644 --- a/web/Plugin.ts +++ b/web/Plugin.ts @@ -21,7 +21,7 @@ export interface GlobalInfo { canLoadPlugin: boolean pluginVersion?: string icon?: string - isPaper: boolean + isPaper?: boolean hasVault?: boolean hasVaultPermission?: boolean hasVaultGroups?: boolean @@ -29,7 +29,10 @@ export interface GlobalInfo { hasOpenInv?: boolean hasNBTAPI?: boolean hasMultiverse?: boolean + canSetMaxPlayers?: boolean canSetViewDistance?: boolean + maxPlayers: number + spawnRadius: number plugins: Record vaultEconomy?: { singular: string diff --git a/web/pages/Config.tsx b/web/pages/Config.tsx index 00abc35b..6072e1d4 100644 --- a/web/pages/Config.tsx +++ b/web/pages/Config.tsx @@ -1,16 +1,56 @@ import React, { useState } from 'react' import dayjs from 'dayjs' +import dialog from '../dialog' import * as colors from '@material-ui/core/colors' import { success } from '../toast' import { configs } from '../Plugin' -import { Delete, HelpOutline, Check, Brightness4, Brightness7, SettingsBrightness } from '@material-ui/icons' +import { useGlobalData, usePlugin } from '../Context' +import { Delete, HelpOutline, Check, Brightness4, Brightness7, SettingsBrightness, Edit } from '@material-ui/icons' import { Box, Toolbar, Container, Grid, Card, CardHeader, Divider, List, ListItem, IconButton, ToggleButton, ListItemAvatar, Avatar, ListItemText, Tooltip, CardContent, ToggleButtonGroup, - Paper, ListItemButton } from '@material-ui/core' + Paper, ListItemButton, Switch } from '@material-ui/core' import type { ServerRecord } from '../App' configs.push({ + title: '服务端设置', + component: () => { + const plugin = usePlugin() + const globalData = useGlobalData() + const [flag, update] = useState(0) + const setValue = (field: string, value: any) => { + plugin.emit('server:set', field, ((globalData as any)[field] = value)) + update(flag + 1) + success() + location.reload() + } + const createEditButtom = (field: string) => dialog({ + content: '请输入要修改的值', + input: { + error: true, + type: 'number', + helperText: '值不合法!', + validator: (it: string) => /^\d+$/.test(it) && +it >= 0 + } + }).then(res => res != null && setValue(field, parseInt(res as any)))} + > + return + + + + + + + setValue('hasWhitelist', e.target.checked)} />}> + + + + } +}, +{ title: '连接记录', component: () => { const [cur, update] = useState(0) diff --git a/web/pages/Worlds.tsx b/web/pages/Worlds.tsx index 1d874888..4abd02da 100644 --- a/web/pages/Worlds.tsx +++ b/web/pages/Worlds.tsx @@ -193,6 +193,7 @@ const Worlds: React.FC = () => { {sw.rules.map(([key, value]) => { const isTrue = value === 'true' const isBoolean = isTrue || value === 'false' + const isNumber = /^\d+$/.test(value) return { : dialog({ content: '请输入要修改的值', - input: { - error: true, - type: 'number', - helperText: '值不合法!', - validator: (it: string) => /^\d+$/.test(it) - } + input: isNumber + ? { + error: true, + type: 'number', + helperText: '值不合法!', + validator: (it: string) => /^\d+$/.test(it) + } + : { } }).then(res => { if (res == null) return plugin.emit('worlds:rule', sw.id, key, res) @@ -220,7 +223,7 @@ const Worlds: React.FC = () => { })} >} > - + })}