diff options
Diffstat (limited to 'spark-forge/src')
8 files changed, 165 insertions, 123 deletions
diff --git a/spark-forge/src/main/java/me/lucko/spark/forge/ForgeCommandSender.java b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeCommandSender.java index 9ca6f03..f3b746d 100644 --- a/spark-forge/src/main/java/me/lucko/spark/forge/ForgeCommandSender.java +++ b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeCommandSender.java @@ -25,14 +25,14 @@ import me.lucko.spark.forge.plugin.ForgeSparkPlugin; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; -import net.minecraft.Util; import net.minecraft.commands.CommandSource; +import net.minecraft.network.chat.Component.Serializer; import net.minecraft.network.chat.MutableComponent; -import net.minecraft.network.chat.TextComponent; import net.minecraft.server.MinecraftServer; import net.minecraft.server.rcon.RconConsoleSource; import net.minecraft.world.entity.player.Player; +import java.util.Objects; import java.util.UUID; public class ForgeCommandSender extends AbstractCommandSender<CommandSource> { @@ -66,8 +66,9 @@ public class ForgeCommandSender extends AbstractCommandSender<CommandSource> { @Override public void sendMessage(Component message) { - MutableComponent component = TextComponent.Serializer.fromJson(GsonComponentSerializer.gson().serialize(message)); - super.delegate.sendMessage(component, Util.NIL_UUID); + MutableComponent component = Serializer.fromJson(GsonComponentSerializer.gson().serialize(message)); + Objects.requireNonNull(component, "component"); + super.delegate.sendSystemMessage(component); } @Override diff --git a/spark-forge/src/main/java/me/lucko/spark/forge/ForgePlatformInfo.java b/spark-forge/src/main/java/me/lucko/spark/forge/ForgePlatformInfo.java index 60294be..97b3a86 100644 --- a/spark-forge/src/main/java/me/lucko/spark/forge/ForgePlatformInfo.java +++ b/spark-forge/src/main/java/me/lucko/spark/forge/ForgePlatformInfo.java @@ -20,12 +20,12 @@ package me.lucko.spark.forge; -import me.lucko.spark.common.platform.AbstractPlatformInfo; +import me.lucko.spark.common.platform.PlatformInfo; import net.minecraftforge.versions.forge.ForgeVersion; import net.minecraftforge.versions.mcp.MCPVersion; -public class ForgePlatformInfo extends AbstractPlatformInfo { +public class ForgePlatformInfo implements PlatformInfo { private final Type type; public ForgePlatformInfo(Type type) { diff --git a/spark-forge/src/main/java/me/lucko/spark/forge/ForgePlayerPingProvider.java b/spark-forge/src/main/java/me/lucko/spark/forge/ForgePlayerPingProvider.java new file mode 100644 index 0000000..f31cc5b --- /dev/null +++ b/spark-forge/src/main/java/me/lucko/spark/forge/ForgePlayerPingProvider.java @@ -0,0 +1,47 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) <luck@lucko.me> + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package me.lucko.spark.forge; + +import com.google.common.collect.ImmutableMap; + +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerPlayer; + +import java.util.Map; + +public class ForgePlayerPingProvider implements PlayerPingProvider { + private final MinecraftServer server; + + public ForgePlayerPingProvider(MinecraftServer server) { + this.server = server; + } + + @Override + public Map<String, Integer> poll() { + ImmutableMap.Builder<String, Integer> builder = ImmutableMap.builder(); + for (ServerPlayer player : this.server.getPlayerList().getPlayers()) { + builder.put(player.getGameProfile().getName(), player.latency); + } + return builder.build(); + } +} diff --git a/spark-forge/src/main/java/me/lucko/spark/forge/ForgeSparkMod.java b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeSparkMod.java index 02a2ebc..3321d12 100644 --- a/spark-forge/src/main/java/me/lucko/spark/forge/ForgeSparkMod.java +++ b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeSparkMod.java @@ -24,7 +24,7 @@ import me.lucko.spark.forge.plugin.ForgeClientSparkPlugin; import me.lucko.spark.forge.plugin.ForgeServerSparkPlugin; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.RegisterCommandsEvent; +import net.minecraftforge.event.server.ServerAboutToStartEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.IExtensionPoint; import net.minecraftforge.fml.ModContainer; @@ -61,15 +61,15 @@ public class ForgeSparkMod { this.configDirectory = FMLPaths.CONFIGDIR.get().resolve(this.container.getModId()); } - @SubscribeEvent - public void registerCommands(RegisterCommandsEvent e) { - ForgeServerSparkPlugin.register(this, e); - } - public void clientInit(FMLClientSetupEvent e) { ForgeClientSparkPlugin.register(this, e); } + @SubscribeEvent + public void serverInit(ServerAboutToStartEvent e) { + ForgeServerSparkPlugin.register(this, e); + } + public Path getConfigDirectory() { if (this.configDirectory == null) { throw new IllegalStateException("Config directory not set"); diff --git a/spark-forge/src/main/java/me/lucko/spark/forge/plugin/ForgeClientSparkPlugin.java b/spark-forge/src/main/java/me/lucko/spark/forge/plugin/ForgeClientSparkPlugin.java index 95bb2d1..cf5c89b 100644 --- a/spark-forge/src/main/java/me/lucko/spark/forge/plugin/ForgeClientSparkPlugin.java +++ b/spark-forge/src/main/java/me/lucko/spark/forge/plugin/ForgeClientSparkPlugin.java @@ -21,7 +21,6 @@ package me.lucko.spark.forge.plugin; import com.mojang.brigadier.Command; -import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.suggestion.SuggestionProvider; @@ -38,95 +37,64 @@ import me.lucko.spark.forge.ForgeTickHook; import me.lucko.spark.forge.ForgeTickReporter; import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientPacketListener; import net.minecraft.commands.CommandSource; -import net.minecraft.commands.SharedSuggestionProvider; -import net.minecraftforge.client.event.ClientChatEvent; +import net.minecraft.commands.CommandSourceStack; +import net.minecraftforge.client.event.RegisterClientCommandsEvent; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; -import java.util.Arrays; -import java.util.Optional; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; import java.util.stream.Stream; -public class ForgeClientSparkPlugin extends ForgeSparkPlugin implements SuggestionProvider<SharedSuggestionProvider> { +public class ForgeClientSparkPlugin extends ForgeSparkPlugin implements Command<CommandSourceStack>, SuggestionProvider<CommandSourceStack> { public static void register(ForgeSparkMod mod, FMLClientSetupEvent event) { ForgeClientSparkPlugin plugin = new ForgeClientSparkPlugin(mod, Minecraft.getInstance()); plugin.enable(); - - // register listeners - MinecraftForge.EVENT_BUS.register(plugin); - - // ensure commands are registered - plugin.scheduler.scheduleWithFixedDelay(plugin::checkCommandRegistered, 10, 10, TimeUnit.SECONDS); } private final Minecraft minecraft; - private CommandDispatcher<SharedSuggestionProvider> dispatcher; public ForgeClientSparkPlugin(ForgeSparkMod mod, Minecraft minecraft) { super(mod); this.minecraft = minecraft; } - private CommandDispatcher<SharedSuggestionProvider> getPlayerCommandDispatcher() { - return Optional.ofNullable(this.minecraft.player) - .map(player -> player.connection) - .map(ClientPacketListener::getCommands) - .orElse(null); - } - - private void checkCommandRegistered() { - CommandDispatcher<SharedSuggestionProvider> dispatcher = getPlayerCommandDispatcher(); - if (dispatcher == null) { - return; - } + @Override + public void enable() { + super.enable(); - try { - if (dispatcher != this.dispatcher) { - this.dispatcher = dispatcher; - registerCommands(this.dispatcher, context -> Command.SINGLE_SUCCESS, this, "sparkc", "sparkclient"); - } - } catch (Exception e) { - e.printStackTrace(); - } + // register listeners + MinecraftForge.EVENT_BUS.register(this); } @SubscribeEvent - public void onClientChat(ClientChatEvent event) { - String[] args = processArgs(event.getMessage(), false); + public void onCommandRegister(RegisterClientCommandsEvent e) { + registerCommands(e.getDispatcher(), this, this, "sparkc", "sparkclient"); + } + + @Override + public int run(CommandContext<CommandSourceStack> context) throws CommandSyntaxException { + String[] args = processArgs(context, false, "sparkc", "sparkclient"); if (args == null) { - return; + return 0; } this.threadDumper.ensureSetup(); - this.platform.executeCommand(new ForgeCommandSender(this.minecraft.player, this), args); - this.minecraft.gui.getChat().addRecentChat(event.getMessage()); - event.setCanceled(true); + this.platform.executeCommand(new ForgeCommandSender(context.getSource().getEntity(), this), args); + return Command.SINGLE_SUCCESS; } @Override - public CompletableFuture<Suggestions> getSuggestions(CommandContext<SharedSuggestionProvider> context, SuggestionsBuilder builder) throws CommandSyntaxException { - String[] args = processArgs(context.getInput(), true); + public CompletableFuture<Suggestions> getSuggestions(CommandContext<CommandSourceStack> context, SuggestionsBuilder builder) throws CommandSyntaxException { + String[] args = processArgs(context, true, "/sparkc", "/sparkclient"); if (args == null) { return Suggestions.empty(); } - return generateSuggestions(new ForgeCommandSender(this.minecraft.player, this), args, builder); - } - - private static String[] processArgs(String input, boolean tabComplete) { - String[] split = input.split(" ", tabComplete ? -1 : 0); - if (split.length == 0 || !split[0].equals("/sparkc") && !split[0].equals("/sparkclient")) { - return null; - } - - return Arrays.copyOfRange(split, 1, split.length); + return generateSuggestions(new ForgeCommandSender(context.getSource().getEntity(), this), args, builder); } @Override @@ -158,5 +126,4 @@ public class ForgeClientSparkPlugin extends ForgeSparkPlugin implements Suggesti public String getCommandName() { return "sparkc"; } - } diff --git a/spark-forge/src/main/java/me/lucko/spark/forge/plugin/ForgeServerSparkPlugin.java b/spark-forge/src/main/java/me/lucko/spark/forge/plugin/ForgeServerSparkPlugin.java index 4a2416f..e341d6f 100644 --- a/spark-forge/src/main/java/me/lucko/spark/forge/plugin/ForgeServerSparkPlugin.java +++ b/spark-forge/src/main/java/me/lucko/spark/forge/plugin/ForgeServerSparkPlugin.java @@ -29,11 +29,13 @@ import com.mojang.brigadier.suggestion.SuggestionProvider; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import me.lucko.spark.common.monitor.ping.PlayerPingProvider; import me.lucko.spark.common.platform.PlatformInfo; import me.lucko.spark.common.tick.TickHook; import me.lucko.spark.common.tick.TickReporter; import me.lucko.spark.forge.ForgeCommandSender; import me.lucko.spark.forge.ForgePlatformInfo; +import me.lucko.spark.forge.ForgePlayerPingProvider; import me.lucko.spark.forge.ForgeSparkMod; import me.lucko.spark.forge.ForgeTickHook; import me.lucko.spark.forge.ForgeTickReporter; @@ -45,49 +47,61 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.RegisterCommandsEvent; import net.minecraftforge.event.TickEvent; +import net.minecraftforge.event.server.ServerAboutToStartEvent; import net.minecraftforge.event.server.ServerStoppingEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.server.ServerLifecycleHooks; import net.minecraftforge.server.permission.PermissionAPI; import net.minecraftforge.server.permission.events.PermissionGatherEvent; import net.minecraftforge.server.permission.nodes.PermissionNode; import net.minecraftforge.server.permission.nodes.PermissionNode.PermissionResolver; import net.minecraftforge.server.permission.nodes.PermissionTypes; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; -import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; public class ForgeServerSparkPlugin extends ForgeSparkPlugin implements Command<CommandSourceStack>, SuggestionProvider<CommandSourceStack> { - public static void register(ForgeSparkMod mod, RegisterCommandsEvent event) { - ForgeServerSparkPlugin plugin = new ForgeServerSparkPlugin(mod, ServerLifecycleHooks::getCurrentServer); + public static void register(ForgeSparkMod mod, ServerAboutToStartEvent event) { + ForgeServerSparkPlugin plugin = new ForgeServerSparkPlugin(mod, event.getServer()); plugin.enable(); - - // register listeners - MinecraftForge.EVENT_BUS.register(plugin); - - // register commands & permissions - CommandDispatcher<CommandSourceStack> dispatcher = event.getDispatcher(); - registerCommands(dispatcher, plugin, plugin, "spark"); } - private final Supplier<MinecraftServer> server; + private final MinecraftServer server; private Map<String, PermissionNode<Boolean>> registeredPermissions = Collections.emptyMap(); - public ForgeServerSparkPlugin(ForgeSparkMod mod, Supplier<MinecraftServer> server) { + public ForgeServerSparkPlugin(ForgeSparkMod mod, MinecraftServer server) { super(mod); this.server = server; } + @Override + public void enable() { + super.enable(); + + // register commands + registerCommands(this.server.getCommands().getDispatcher()); + + // register listeners + MinecraftForge.EVENT_BUS.register(this); + } + + @Override + public void disable() { + super.disable(); + + // unregister listeners + MinecraftForge.EVENT_BUS.unregister(this); + } + @SubscribeEvent public void onDisable(ServerStoppingEvent event) { - disable(); + if (event.getServer() == this.server) { + disable(); + } } @SubscribeEvent @@ -112,21 +126,31 @@ public class ForgeServerSparkPlugin extends ForgeSparkPlugin implements Command< this.registeredPermissions = builder.build(); } + @SubscribeEvent + public void onCommandRegister(RegisterCommandsEvent e) { + registerCommands(e.getDispatcher()); + } + + private void registerCommands(CommandDispatcher<CommandSourceStack> dispatcher) { + registerCommands(dispatcher, this, this, "spark"); + } + @Override public int run(CommandContext<CommandSourceStack> context) throws CommandSyntaxException { - String[] args = processArgs(context, false); + String[] args = processArgs(context, false, "/spark", "spark"); if (args == null) { return 0; } this.threadDumper.ensureSetup(); - this.platform.executeCommand(new ForgeCommandSender(context.getSource().source, this), args); + CommandSource source = context.getSource().getEntity() != null ? context.getSource().getEntity() : context.getSource().getServer(); + this.platform.executeCommand(new ForgeCommandSender(source, this), args); return Command.SINGLE_SUCCESS; } @Override public CompletableFuture<Suggestions> getSuggestions(CommandContext<CommandSourceStack> context, SuggestionsBuilder builder) throws CommandSyntaxException { - String[] args = processArgs(context, true); + String[] args = processArgs(context, true, "/spark", "spark"); if (args == null) { return Suggestions.empty(); } @@ -134,15 +158,6 @@ public class ForgeServerSparkPlugin extends ForgeSparkPlugin implements Command< return generateSuggestions(new ForgeCommandSender(context.getSource().getPlayerOrException(), this), args, builder); } - private static String [] processArgs(CommandContext<CommandSourceStack> context, boolean tabComplete) { - String[] split = context.getInput().split(" ", tabComplete ? -1 : 0); - if (split.length == 0 || !split[0].equals("/spark") && !split[0].equals("spark")) { - return null; - } - - return Arrays.copyOfRange(split, 1, split.length); - } - @Override public boolean hasPermission(CommandSource sender, String permission) { if (sender instanceof ServerPlayer) { @@ -163,8 +178,8 @@ public class ForgeServerSparkPlugin extends ForgeSparkPlugin implements Command< @Override public Stream<ForgeCommandSender> getCommandSenders() { return Stream.concat( - this.server.get().getPlayerList().getPlayers().stream(), - Stream.of(this.server.get()) + this.server.getPlayerList().getPlayers().stream(), + Stream.of(this.server) ).map(sender -> new ForgeCommandSender(sender, this)); } @@ -179,6 +194,11 @@ public class ForgeServerSparkPlugin extends ForgeSparkPlugin implements Command< } @Override + public PlayerPingProvider createPlayerPingProvider() { + return new ForgePlayerPingProvider(this.server); + } + + @Override public PlatformInfo getPlatformInfo() { return new ForgePlatformInfo(PlatformInfo.Type.SERVER); } diff --git a/spark-forge/src/main/java/me/lucko/spark/forge/plugin/ForgeSparkPlugin.java b/spark-forge/src/main/java/me/lucko/spark/forge/plugin/ForgeSparkPlugin.java index f8b7559..f257e34 100644 --- a/spark-forge/src/main/java/me/lucko/spark/forge/plugin/ForgeSparkPlugin.java +++ b/spark-forge/src/main/java/me/lucko/spark/forge/plugin/ForgeSparkPlugin.java @@ -25,6 +25,7 @@ import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.builder.RequiredArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.suggestion.SuggestionProvider; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; @@ -35,6 +36,7 @@ import me.lucko.spark.common.SparkPlugin; import me.lucko.spark.common.command.sender.CommandSender; import me.lucko.spark.common.sampler.ThreadDumper; import me.lucko.spark.common.util.ClassSourceLookup; +import me.lucko.spark.common.util.SparkThreadFactory; import me.lucko.spark.forge.ForgeClassSourceLookup; import me.lucko.spark.forge.ForgeSparkMod; @@ -44,6 +46,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.nio.file.Path; +import java.util.Arrays; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -51,44 +54,21 @@ import java.util.logging.Level; public abstract class ForgeSparkPlugin implements SparkPlugin { - public static <T> void registerCommands(CommandDispatcher<T> dispatcher, Command<T> executor, SuggestionProvider<T> suggestor, String... aliases) { - if (aliases.length == 0) { - return; - } - - String mainName = aliases[0]; - LiteralArgumentBuilder<T> command = LiteralArgumentBuilder.<T>literal(mainName) - .executes(executor) - .then(RequiredArgumentBuilder.<T, String>argument("args", StringArgumentType.greedyString()) - .suggests(suggestor) - .executes(executor) - ); - - LiteralCommandNode<T> node = dispatcher.register(command); - for (int i = 1; i < aliases.length; i++) { - dispatcher.register(LiteralArgumentBuilder.<T>literal(aliases[i]).redirect(node)); - } - } - private final ForgeSparkMod mod; private final Logger logger; protected final ScheduledExecutorService scheduler; - protected final SparkPlatform platform; + + protected SparkPlatform platform; protected final ThreadDumper.GameThread threadDumper = new ThreadDumper.GameThread(); protected ForgeSparkPlugin(ForgeSparkMod mod) { this.mod = mod; this.logger = LogManager.getLogger("spark"); - this.scheduler = Executors.newSingleThreadScheduledExecutor(r -> { - Thread thread = Executors.defaultThreadFactory().newThread(r); - thread.setName("spark-forge-async-worker"); - thread.setDaemon(true); - return thread; - }); - this.platform = new SparkPlatform(this); + this.scheduler = Executors.newScheduledThreadPool(4, new SparkThreadFactory()); } public void enable() { + this.platform = new SparkPlatform(this); this.platform.enable(); } @@ -154,4 +134,32 @@ public abstract class ForgeSparkPlugin implements SparkPlugin { return suggestions.build(); }); } + + protected static <T> void registerCommands(CommandDispatcher<T> dispatcher, Command<T> executor, SuggestionProvider<T> suggestor, String... aliases) { + if (aliases.length == 0) { + return; + } + + String mainName = aliases[0]; + LiteralArgumentBuilder<T> command = LiteralArgumentBuilder.<T>literal(mainName) + .executes(executor) + .then(RequiredArgumentBuilder.<T, String>argument("args", StringArgumentType.greedyString()) + .suggests(suggestor) + .executes(executor) + ); + + LiteralCommandNode<T> node = dispatcher.register(command); + for (int i = 1; i < aliases.length; i++) { + dispatcher.register(LiteralArgumentBuilder.<T>literal(aliases[i]).redirect(node)); + } + } + + protected static String[] processArgs(CommandContext<?> context, boolean tabComplete, String... aliases) { + String[] split = context.getInput().split(" ", tabComplete ? -1 : 0); + if (split.length == 0 || !Arrays.asList(aliases).contains(split[0])) { + return null; + } + + return Arrays.copyOfRange(split, 1, split.length); + } } diff --git a/spark-forge/src/main/resources/META-INF/accesstransformer.cfg b/spark-forge/src/main/resources/META-INF/accesstransformer.cfg deleted file mode 100644 index a1d1dc8..0000000 --- a/spark-forge/src/main/resources/META-INF/accesstransformer.cfg +++ /dev/null @@ -1 +0,0 @@ -public net.minecraft.commands.CommandSourceStack f_81288_ # source
\ No newline at end of file |