diff --git a/CHANGELOG.md b/CHANGELOG.md index 8137ac0..8112266 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1 +1 @@ -- Makes use of API version 4.0.0, allowing for marginal performance increases as API calls are now Async \ No newline at end of file +- Add client side command /mclogsc \ No newline at end of file diff --git a/LICENSE b/LICENSE index 036c6a5..ea8ea84 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020-2023 Aternos GmbH +Copyright (c) 2020-2024 Aternos GmbH Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/build.gradle b/build.gradle index 74da9de..a780b0b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' id 'fabric-loom' version '1.2.7' - id "com.modrinth.minotaur" version "2.8.1" + id "com.modrinth.minotaur" version "2.8.7" id "net.darkhax.curseforgegradle" version "1.1.15" } diff --git a/src/main/java/gs/mclo/fabric/CommandMclogs.java b/src/main/java/gs/mclo/fabric/CommandMclogs.java deleted file mode 100644 index 12d945c..0000000 --- a/src/main/java/gs/mclo/fabric/CommandMclogs.java +++ /dev/null @@ -1,15 +0,0 @@ -package gs.mclo.fabric; - -import com.mojang.brigadier.CommandDispatcher; -import net.minecraft.server.command.ServerCommandSource; - -import static net.minecraft.server.command.CommandManager.literal; - -public class CommandMclogs { - static void register(CommandDispatcher dispatcher) { - dispatcher.register(literal("mclogs") - .requires(source -> source.hasPermissionLevel(2)) - .executes(context -> MclogsFabricLoader.share(context.getSource(), "latest.log")) - ); - } -} diff --git a/src/main/java/gs/mclo/fabric/CommandMclogsList.java b/src/main/java/gs/mclo/fabric/CommandMclogsList.java deleted file mode 100644 index 5365be4..0000000 --- a/src/main/java/gs/mclo/fabric/CommandMclogsList.java +++ /dev/null @@ -1,73 +0,0 @@ -package gs.mclo.fabric; - -import com.mojang.brigadier.CommandDispatcher; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.text.ClickEvent; -import net.minecraft.text.LiteralText; -import net.minecraft.text.MutableText; -import net.minecraft.text.Style; -import net.minecraft.util.Formatting; - -import static net.minecraft.server.command.CommandManager.literal; - -public class CommandMclogsList { - static void register(CommandDispatcher dispatcher) { - dispatcher.register(literal("mclogs").then(literal("list") - .requires(source -> source.hasPermissionLevel(2)) - .executes((context) -> { - ServerCommandSource source = context.getSource(); - - try { - int total = 0; - - MutableText message = new LiteralText(""); - - message.append(new LiteralText("Available logs:") - .setStyle(Style.EMPTY - .withColor(Formatting.GREEN) - .withBold(true) - )); - for (String log : MclogsFabricLoader.getLogs(context)) { - MutableText tempText = new LiteralText("\n" + log) - .setStyle( - Style.EMPTY - .withClickEvent( - new ClickEvent(ClickEvent.Action.RUN_COMMAND,"/mclogs share " + log) - ) - ); - message.append(tempText); - total ++; - } - - message.append(new LiteralText("\nAvailable crash reports:") - .setStyle(Style.EMPTY - .withColor(Formatting.GREEN) - .withBold(true) - )); - for (String report : MclogsFabricLoader.getCrashReports(context)) { - MutableText tempText = new LiteralText("\n" + report) - .setStyle( - Style.EMPTY - .withClickEvent( - new ClickEvent(ClickEvent.Action.RUN_COMMAND,"/mclogs share " + report) - ) - ); - message.append(tempText); - total ++; - } - - - source.sendFeedback(message, false); - return total; - } - catch (Exception e) { - MclogsFabricLoader.logger.error("An error occurred when listing your logs."); - MclogsFabricLoader.logger.error(e); - LiteralText error = new LiteralText("An error occurred. Check your log for more details."); - source.sendError(error); - return -1; - } - }) - )); - } -} diff --git a/src/main/java/gs/mclo/fabric/CommandMclogsShare.java b/src/main/java/gs/mclo/fabric/CommandMclogsShare.java deleted file mode 100644 index 15a5bb2..0000000 --- a/src/main/java/gs/mclo/fabric/CommandMclogsShare.java +++ /dev/null @@ -1,55 +0,0 @@ -package gs.mclo.fabric; - -import com.google.common.collect.ImmutableList; -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.arguments.StringArgumentType; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.context.StringRange; -import com.mojang.brigadier.suggestion.Suggestion; -import com.mojang.brigadier.suggestion.Suggestions; -import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import net.minecraft.server.command.CommandManager; -import net.minecraft.server.command.ServerCommandSource; - -import java.io.IOException; -import java.util.concurrent.CompletableFuture; - -import static net.minecraft.server.command.CommandManager.literal; - -public class CommandMclogsShare { - static void register(CommandDispatcher dispatcher) { - dispatcher.register(literal("mclogs").then(literal("share") - .requires(source -> source.hasPermissionLevel(2)) - .then(CommandManager.argument("filename", StringArgumentType.greedyString()) - .suggests(CommandMclogsShare::suggest) - .executes(context -> MclogsFabricLoader.share(context.getSource(), context.getArgument("filename",String.class)))) - )); - } - - private static CompletableFuture suggest(CommandContext context, SuggestionsBuilder builder) { - ImmutableList.Builder suggestions = ImmutableList.builder(); - String[] logs, reports; - try { - logs = MclogsFabricLoader.getLogs(context); - reports = MclogsFabricLoader.getCrashReports(context); - } catch (IOException e) { - MclogsFabricLoader.logger.error("Failed to suggest log files", e); - return Suggestions.empty(); - } - - String argument = context.getArgument("filename", String.class); - int start = "/mclogs share ".length(); - - for (String log: logs) { - if (!log.startsWith(argument)) continue; - suggestions.add(new Suggestion(StringRange.between(start, context.getInput().length()), log)); - } - - for (String report: reports) { - if (!report.startsWith(argument)) continue; - suggestions.add(new Suggestion(StringRange.between(start, context.getInput().length()), report)); - } - - return CompletableFuture.completedFuture(Suggestions.create("mclogs", suggestions.build())); - } -} diff --git a/src/main/java/gs/mclo/fabric/MclogsFabricLoader.java b/src/main/java/gs/mclo/fabric/MclogsFabric.java similarity index 56% rename from src/main/java/gs/mclo/fabric/MclogsFabricLoader.java rename to src/main/java/gs/mclo/fabric/MclogsFabric.java index 12cfc6d..7cee7d6 100644 --- a/src/main/java/gs/mclo/fabric/MclogsFabricLoader.java +++ b/src/main/java/gs/mclo/fabric/MclogsFabric.java @@ -1,13 +1,23 @@ package gs.mclo.fabric; -import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; import gs.mclo.api.Log; import gs.mclo.api.MclogsClient; import gs.mclo.api.response.UploadLogResponse; +import gs.mclo.fabric.commands.Command; +import gs.mclo.fabric.commands.MclogsCommand; +import gs.mclo.fabric.commands.MclogsListCommand; +import gs.mclo.fabric.commands.MclogsShareCommand; +import gs.mclo.fabric.commands.source.Source; +import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.DedicatedServerModInitializer; +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.client.command.v1.ClientCommandManager; +import net.fabricmc.fabric.api.client.command.v1.FabricClientCommandSource; import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.ModContainer; +import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.text.ClickEvent; import net.minecraft.text.LiteralText; @@ -24,34 +34,39 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; -public class MclogsFabricLoader implements DedicatedServerModInitializer { +public class MclogsFabric implements DedicatedServerModInitializer, ClientModInitializer, ModInitializer { public static final Logger logger = LogManager.getLogger(); private static final MclogsClient client = new MclogsClient("Mclogs-fabric"); + private static final Command[] COMMANDS = new Command[]{ + new MclogsCommand(), + new MclogsListCommand(), + new MclogsShareCommand() + }; /** - * @param context command context + * @param source command source * @return log files * @throws IOException io exception */ - public static String[] getLogs(CommandContext context) throws IOException { - return client.listLogsInDirectory(context.getSource().getServer().getRunDirectory().getCanonicalPath()); + public static String[] getLogs(Source source) throws IOException { + return client.listLogsInDirectory(source.getRunDirectory().toString()); } /** - * @param context command context + * @param source command source * @return crash reports * @throws IOException io exception */ - public static String[] getCrashReports(CommandContext context) throws IOException { - return client.listCrashReportsInDirectory(context.getSource().getServer().getRunDirectory().getCanonicalPath()); + public static String[] getCrashReports(Source source) throws IOException { + return client.listCrashReportsInDirectory(source.getRunDirectory().toString()); } - public static int share(ServerCommandSource source, String filename) { - client.setMinecraftVersion(source.getServer().getVersion()); - logger.log(Level.INFO,"Sharing "+filename); + public static int share(Source source, String filename) { + client.setMinecraftVersion(source.getMinecraftVersion()); + logger.log(Level.INFO, "Sharing {}", filename); source.sendFeedback(new LiteralText("Sharing " + filename), false); - Path directory = source.getServer().getRunDirectory().toPath(); + Path directory = source.getRunDirectory(); Path logs = directory.resolve("logs"); Path crashReports = directory.resolve("crash-reports"); Path log = directory.resolve("logs").resolve(filename); @@ -65,8 +80,8 @@ public static int share(ServerCommandSource source, String filename) { Path logPath = log.toRealPath(); isInAllowedDirectory = (logs.toFile().exists() && logPath.startsWith(logs.toRealPath())) || (crashReports.toFile().exists() && logPath.startsWith(crashReports.toRealPath())); + } catch (IOException ignored) { } - catch (IOException ignored) {} if (!log.toFile().exists() || !isInAllowedDirectory || !log.getFileName().toString().matches(Log.ALLOWED_FILE_NAME_PATTERN.pattern())) { @@ -81,30 +96,27 @@ public static int share(ServerCommandSource source, String filename) { res.setClient(client); if (res.isSuccess()) { LiteralText feedback = new LiteralText("Your log has been uploaded: "); - feedback.setStyle(Style.EMPTY.withColor(Formatting.GREEN)); LiteralText link = new LiteralText(res.getUrl()); - Style linkStyle = Style.EMPTY.withColor(Formatting.BLUE); - linkStyle = linkStyle.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL,res.getUrl())); + Style linkStyle = Style.EMPTY + .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, res.getUrl())) + .withFormatting(Formatting.UNDERLINE); link.setStyle(linkStyle); - source.sendFeedback(feedback.append(link),true); + source.sendFeedback(feedback.append(link), true); return 1; - } - else { + } else { logger.error("An error occurred when uploading your log: "); logger.error(res.getError()); LiteralText error = new LiteralText("An error occurred. Check your log for more details"); source.sendError(error); return 0; } - } - catch (FileNotFoundException|IllegalArgumentException e) { - LiteralText error = new LiteralText("The log file "+filename+" doesn't exist. Use '/mclogs list' to list all logs."); + } catch (FileNotFoundException | IllegalArgumentException e) { + LiteralText error = new LiteralText("The log file " + filename + " doesn't exist. Use '/mclogs list' to list all logs."); source.sendError(error); return -1; - } - catch (IOException | InterruptedException | ExecutionException e) { + } catch (IOException | InterruptedException | ExecutionException e) { source.sendError(new LiteralText("An error occurred. Check your log for more details")); logger.error("Could not get log file!"); logger.error(e); @@ -113,13 +125,33 @@ public static int share(ServerCommandSource source, String filename) { } @Override - public void onInitializeServer() { + public void onInitialize() { Optional mclogs = FabricLoader.getInstance().getModContainer("mclogs"); client.setProjectVersion(mclogs.isPresent() ? mclogs.get().getMetadata().getVersion().getFriendlyString() : "unknown"); + } + + @Override + public void onInitializeServer() { CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> { - CommandMclogs.register(dispatcher); - CommandMclogsList.register(dispatcher); - CommandMclogsShare.register(dispatcher); + if (!dedicated) { + return; + } + + logger.info("Registering server commands"); + LiteralArgumentBuilder mclogs = CommandManager.literal("mclogs"); + for (Command command : COMMANDS) { + dispatcher.register(command.buildServer(mclogs)); + } }); } + + @Override + public void onInitializeClient() { + logger.info("Registering client commands"); + LiteralArgumentBuilder mclogsc = ClientCommandManager.literal("mclogsc"); + for (Command command : COMMANDS) { + ClientCommandManager.DISPATCHER.register(command.buildClient(mclogsc)); + } + } + } diff --git a/src/main/java/gs/mclo/fabric/commands/Command.java b/src/main/java/gs/mclo/fabric/commands/Command.java new file mode 100644 index 0000000..3d36566 --- /dev/null +++ b/src/main/java/gs/mclo/fabric/commands/Command.java @@ -0,0 +1,10 @@ +package gs.mclo.fabric.commands; + +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import net.fabricmc.fabric.api.client.command.v1.FabricClientCommandSource; +import net.minecraft.server.command.ServerCommandSource; + +public interface Command { + LiteralArgumentBuilder buildClient(LiteralArgumentBuilder builder); + LiteralArgumentBuilder buildServer(LiteralArgumentBuilder builder); +} diff --git a/src/main/java/gs/mclo/fabric/commands/MclogsCommand.java b/src/main/java/gs/mclo/fabric/commands/MclogsCommand.java new file mode 100644 index 0000000..d8e79f6 --- /dev/null +++ b/src/main/java/gs/mclo/fabric/commands/MclogsCommand.java @@ -0,0 +1,23 @@ +package gs.mclo.fabric.commands; + +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import gs.mclo.fabric.MclogsFabric; +import gs.mclo.fabric.commands.source.ClientSource; +import gs.mclo.fabric.commands.source.ServerSource; +import net.fabricmc.fabric.api.client.command.v1.FabricClientCommandSource; +import net.minecraft.server.command.ServerCommandSource; + + +public class MclogsCommand implements Command { + @Override + public LiteralArgumentBuilder buildClient(LiteralArgumentBuilder builder) { + return builder.executes(context -> MclogsFabric.share(new ClientSource(context.getSource()), "latest.log")); + } + + @Override + public LiteralArgumentBuilder buildServer(LiteralArgumentBuilder builder) { + return builder + .requires(source -> source.hasPermissionLevel(2)) + .executes(context -> MclogsFabric.share(new ServerSource(context.getSource()), "latest.log")); + } +} diff --git a/src/main/java/gs/mclo/fabric/commands/MclogsListCommand.java b/src/main/java/gs/mclo/fabric/commands/MclogsListCommand.java new file mode 100644 index 0000000..6df3cee --- /dev/null +++ b/src/main/java/gs/mclo/fabric/commands/MclogsListCommand.java @@ -0,0 +1,80 @@ +package gs.mclo.fabric.commands; + +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import gs.mclo.fabric.MclogsFabric; +import gs.mclo.fabric.commands.source.ClientSource; +import gs.mclo.fabric.commands.source.ServerSource; +import gs.mclo.fabric.commands.source.Source; +import net.fabricmc.fabric.api.client.command.v1.ClientCommandManager; +import net.fabricmc.fabric.api.client.command.v1.FabricClientCommandSource; +import net.minecraft.server.command.CommandManager; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.text.*; +import net.minecraft.util.Formatting; + + +public class MclogsListCommand implements Command { + @Override + public LiteralArgumentBuilder buildClient(LiteralArgumentBuilder builder) { + return builder.then(ClientCommandManager + .literal("list") + .executes((context) -> execute(new ClientSource(context.getSource()), "mclogsc")) + ); + } + + @Override + public LiteralArgumentBuilder buildServer(LiteralArgumentBuilder builder) { + return builder.then(CommandManager + .literal("list") + .requires(source -> source.hasPermissionLevel(2)) + .executes((context) -> execute(new ServerSource(context.getSource()), "mclogs")) + ); + } + + private int execute(Source source, String command) { + try { + int total = 0; + + MutableText message = new LiteralText(""); + + + total += list(message, MclogsFabric.getLogs(source), "Available Logs:", command); + message.append("\n"); + total += list(message, MclogsFabric.getCrashReports(source), "Available Crash Reports:", command); + + if (total == 0) { + message = new LiteralText("No logs or crash reports found.").formatted(Formatting.RED); + } + + source.sendFeedback(message, false); + return total; + } catch (Exception e) { + MclogsFabric.logger.error("An error occurred when listing your logs."); + MclogsFabric.logger.error(e); + LiteralText error = new LiteralText("An error occurred. Check your log for more details."); + source.sendError(error); + return -1; + } + } + + private int list(MutableText message, String[] items, String title, String command) { + if (items.length > 0) { + message.append(title(title)); + for (String log : items) { + message.append(item(log, command)); + } + } + return items.length; + } + + private MutableText title(String title) { + return new LiteralText(title).setStyle(Style.EMPTY.withFormatting(Formatting.UNDERLINE)); + } + + private MutableText item(String filename, String command) { + return new LiteralText("\n" + filename) + .setStyle(Style.EMPTY.withClickEvent( + new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/"+ command + " share " + filename) + )); + } +} diff --git a/src/main/java/gs/mclo/fabric/commands/MclogsShareCommand.java b/src/main/java/gs/mclo/fabric/commands/MclogsShareCommand.java new file mode 100644 index 0000000..8a4bd7c --- /dev/null +++ b/src/main/java/gs/mclo/fabric/commands/MclogsShareCommand.java @@ -0,0 +1,85 @@ +package gs.mclo.fabric.commands; + +import com.google.common.collect.ImmutableList; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.context.StringRange; +import com.mojang.brigadier.suggestion.Suggestion; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import gs.mclo.fabric.MclogsFabric; +import gs.mclo.fabric.commands.source.ClientSource; +import gs.mclo.fabric.commands.source.ServerSource; +import gs.mclo.fabric.commands.source.Source; +import net.fabricmc.fabric.api.client.command.v1.ClientCommandManager; +import net.fabricmc.fabric.api.client.command.v1.FabricClientCommandSource; +import net.minecraft.client.network.ClientCommandSource; +import net.minecraft.server.command.CommandManager; +import net.minecraft.server.command.ServerCommandSource; + +import java.io.IOException; +import java.util.Locale; +import java.util.concurrent.CompletableFuture; + +import static net.minecraft.server.command.CommandManager.literal; + +public class MclogsShareCommand implements Command { + @Override + public LiteralArgumentBuilder buildClient(LiteralArgumentBuilder builder) { + return builder.then(ClientCommandManager + .literal("share") + .then(ClientCommandManager + .argument("filename", StringArgumentType.greedyString()) + .suggests((x, y) -> this.suggest(x, y, new ClientSource(x.getSource()))) + .executes(context -> MclogsFabric.share( + new ClientSource(context.getSource()), + context.getArgument("filename", String.class) + )) + ) + ); + } + + @Override + public LiteralArgumentBuilder buildServer(LiteralArgumentBuilder builder) { + return builder.then(CommandManager + .literal("share") + .requires(source -> source.hasPermissionLevel(2)) + .then(CommandManager.argument("filename", StringArgumentType.greedyString()) + .suggests((x, y) -> this.suggest(x, y, new ServerSource(x.getSource()))) + .executes(context -> MclogsFabric.share( + new ServerSource(context.getSource()), + context.getArgument("filename", String.class) + )) + ) + ); + } + + private CompletableFuture suggest(CommandContext context, SuggestionsBuilder builder, Source source) { + ImmutableList.Builder suggestions = ImmutableList.builder(); + String[] logs, reports; + try { + logs = MclogsFabric.getLogs(source); + reports = MclogsFabric.getCrashReports(source); + } catch (IOException e) { + MclogsFabric.logger.error("Failed to suggest log files", e); + return Suggestions.empty(); + } + + String argument = builder.getRemaining(); + int start = "/mclogs share ".length(); + + for (String log : logs) { + if (!log.startsWith(argument)) continue; + suggestions.add(new Suggestion(StringRange.between(start, context.getInput().length()), log)); + } + + for (String report : reports) { + if (!report.startsWith(argument)) continue; + suggestions.add(new Suggestion(StringRange.between(start, context.getInput().length()), report)); + } + + return CompletableFuture.completedFuture(Suggestions.create("mclogs", suggestions.build())); + } +} diff --git a/src/main/java/gs/mclo/fabric/commands/source/ClientSource.java b/src/main/java/gs/mclo/fabric/commands/source/ClientSource.java new file mode 100644 index 0000000..075991c --- /dev/null +++ b/src/main/java/gs/mclo/fabric/commands/source/ClientSource.java @@ -0,0 +1,34 @@ +package gs.mclo.fabric.commands.source; + +import net.fabricmc.fabric.api.client.command.v1.FabricClientCommandSource; +import net.minecraft.text.Text; + +import java.nio.file.Path; + +public class ClientSource implements Source { + private final FabricClientCommandSource parent; + + public ClientSource(FabricClientCommandSource parent) { + this.parent = parent; + } + + @Override + public String getMinecraftVersion() { + return parent.getClient().getGameVersion(); + } + + @Override + public void sendFeedback(Text message, boolean broadcastToOps) { + parent.sendFeedback(message); + } + + @Override + public void sendError(Text message) { + parent.sendError(message); + } + + @Override + public Path getRunDirectory() { + return parent.getClient().runDirectory.toPath(); + } +} diff --git a/src/main/java/gs/mclo/fabric/commands/source/ServerSource.java b/src/main/java/gs/mclo/fabric/commands/source/ServerSource.java new file mode 100644 index 0000000..e21546f --- /dev/null +++ b/src/main/java/gs/mclo/fabric/commands/source/ServerSource.java @@ -0,0 +1,34 @@ +package gs.mclo.fabric.commands.source; + +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.text.Text; + +import java.nio.file.Path; + +public class ServerSource implements Source { + private final ServerCommandSource parent; + + public ServerSource(ServerCommandSource parent) { + this.parent = parent; + } + + @Override + public String getMinecraftVersion() { + return parent.getServer().getVersion(); + } + + @Override + public void sendFeedback(Text message, boolean broadcastToOps) { + parent.sendFeedback(message, broadcastToOps); + } + + @Override + public void sendError(Text message) { + parent.sendError(message); + } + + @Override + public Path getRunDirectory() { + return parent.getServer().getRunDirectory().toPath(); + } +} diff --git a/src/main/java/gs/mclo/fabric/commands/source/Source.java b/src/main/java/gs/mclo/fabric/commands/source/Source.java new file mode 100644 index 0000000..b2c87cb --- /dev/null +++ b/src/main/java/gs/mclo/fabric/commands/source/Source.java @@ -0,0 +1,12 @@ +package gs.mclo.fabric.commands.source; + +import net.minecraft.text.Text; + +import java.nio.file.Path; + +public interface Source { + String getMinecraftVersion(); + void sendFeedback(Text message, boolean broadcastToOps); + void sendError(Text message); + Path getRunDirectory(); +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 3b36fae..1c1935d 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -20,10 +20,16 @@ "license": "MIT", "icon": "assets/mclogs/logo.png", - "environment": "server", + "environment": "*", "entrypoints": { + "main": [ + "gs.mclo.fabric.MclogsFabric" + ], "server": [ - "gs.mclo.fabric.MclogsFabricLoader" + "gs.mclo.fabric.MclogsFabric" + ], + "client": [ + "gs.mclo.fabric.MclogsFabric" ] }, "depends": {