diff options
6 files changed, 219 insertions, 290 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java index 812aca9d..c5f4317e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java @@ -21,10 +21,7 @@ package io.github.moulberry.notenoughupdates.commands; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.commands.dev.DiagCommand; -import io.github.moulberry.notenoughupdates.commands.dev.DungeonWinTestCommand; import io.github.moulberry.notenoughupdates.commands.dev.PackDevCommand; -import io.github.moulberry.notenoughupdates.commands.dev.ResetRepoCommand; -import io.github.moulberry.notenoughupdates.commands.dev.StatsCommand; import io.github.moulberry.notenoughupdates.commands.dungeon.DhCommand; import io.github.moulberry.notenoughupdates.commands.dungeon.DnCommand; import io.github.moulberry.notenoughupdates.commands.dungeon.JoinDungeonCommand; @@ -54,10 +51,7 @@ public class Commands { // Dev Commands ClientCommandHandler.instance.registerCommand(new PackDevCommand()); - ClientCommandHandler.instance.registerCommand(new DungeonWinTestCommand()); - ClientCommandHandler.instance.registerCommand(new StatsCommand()); ClientCommandHandler.instance.registerCommand(new DiagCommand()); - ClientCommandHandler.instance.registerCommand(new ResetRepoCommand()); // Profile Commands ClientCommandHandler.instance.registerCommand(new PeekCommand()); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DungeonWinTestCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DungeonWinTestCommand.java deleted file mode 100644 index be25e697..00000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DungeonWinTestCommand.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2022 NotEnoughUpdates contributors - * - * This file is part of NotEnoughUpdates. - * - * NotEnoughUpdates is free software: you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation, either - * version 3 of the License, or (at your option) any later version. - * - * NotEnoughUpdates 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. - */ - -package io.github.moulberry.notenoughupdates.commands.dev; - -import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; -import io.github.moulberry.notenoughupdates.dungeons.DungeonWin; -import net.minecraft.command.CommandException; -import net.minecraft.command.ICommandSender; -import net.minecraft.util.ResourceLocation; - -public class DungeonWinTestCommand extends ClientCommandBase { - - public DungeonWinTestCommand() { - super("neudungeonwintest"); - } - - @Override - public void processCommand(ICommandSender sender, String[] args) throws CommandException { - if (args.length > 0) { - DungeonWin.TEAM_SCORE = new ResourceLocation("notenoughupdates:dungeon_win/" + args[0].toLowerCase() + ".png"); - } - - DungeonWin.displayWin(); - } -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/ResetRepoCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/ResetRepoCommand.java deleted file mode 100644 index 3f693898..00000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/ResetRepoCommand.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2022 NotEnoughUpdates contributors - * - * This file is part of NotEnoughUpdates. - * - * NotEnoughUpdates is free software: you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation, either - * version 3 of the License, or (at your option) any later version. - * - * NotEnoughUpdates 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. - */ - -package io.github.moulberry.notenoughupdates.commands.dev; - -import io.github.moulberry.notenoughupdates.NotEnoughUpdates; -import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; -import net.minecraft.command.CommandException; -import net.minecraft.command.ICommandSender; -import net.minecraft.util.ChatComponentText; - -public class ResetRepoCommand extends ClientCommandBase { - - public ResetRepoCommand() { - super("neuresetrepo"); - } - - @Override - public void processCommand(ICommandSender sender, String[] args) throws CommandException { - NotEnoughUpdates.INSTANCE.manager - .userFacingRepositoryReload() - .thenAccept(strings -> - strings.forEach(line -> - sender.addChatMessage(new ChatComponentText("§e[NEU] " + line)))); - } -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java deleted file mode 100644 index ea417977..00000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 2022 NotEnoughUpdates contributors - * - * This file is part of NotEnoughUpdates. - * - * NotEnoughUpdates is free software: you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation, either - * version 3 of the License, or (at your option) any later version. - * - * NotEnoughUpdates 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. - */ - -package io.github.moulberry.notenoughupdates.commands.dev; - -import io.github.moulberry.notenoughupdates.NotEnoughUpdates; -import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; -import io.github.moulberry.notenoughupdates.util.DiscordMarkdownBuilder; -import io.github.moulberry.notenoughupdates.util.HastebinUploader; -import io.github.moulberry.notenoughupdates.util.SBInfo; -import io.github.moulberry.notenoughupdates.util.Utils; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.OpenGlHelper; -import net.minecraft.command.ICommandSender; -import net.minecraft.util.BlockPos; -import net.minecraft.util.EnumChatFormatting; -import net.minecraftforge.common.ForgeVersion; -import net.minecraftforge.fml.client.FMLClientHandler; -import net.minecraftforge.fml.common.Loader; -import org.lwjgl.opengl.Display; -import org.lwjgl.opengl.GL11; - -import javax.management.JMX; -import javax.management.MBeanServer; -import javax.management.ObjectName; -import java.awt.*; -import java.awt.datatransfer.StringSelection; -import java.lang.management.ManagementFactory; -import java.util.List; -import java.util.Locale; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -public class StatsCommand extends ClientCommandBase { - private final ExecutorService threadPool = Executors.newFixedThreadPool(1); - - public StatsCommand() { - super("neustats"); - } - - private static final int activeModCount = Loader.instance().getActiveModList().size(); - - @Override - public void processCommand(ICommandSender sender, String[] args) { - if (args.length > 0) { - switch (args[0].toLowerCase(Locale.ROOT)) { - case "modlist": - if (activeModCount > 15) { - clipboardAndSendMessage(createModList(new DiscordMarkdownBuilder()).toString()); - } else { - clipboardAndSendMessage(createStats()); - } - break; - case "dump": - modPrefixedMessage(EnumChatFormatting.GREEN + - "This will upload a dump of the java classes your game has loaded how big they are and how many there are. This can take a few seconds as it is uploading to HasteBin."); - threadPool.submit(() -> { - try { - final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); - final ObjectName objectName = ObjectName.getInstance("com.sun.management:type=DiagnosticCommand"); - final DiagnosticCommandMXBean proxy = JMX.newMXBeanProxy( - server, - objectName, - DiagnosticCommandMXBean.class - ); - clipboardAndSendMessage(HastebinUploader.upload( - proxy.gcClassHistogram(new String[0]).replace("[", "[]"), - HastebinUploader.Mode.NORMAL - )); - } catch (Exception e) { - clipboardAndSendMessage(null); - } - }); - break; - } - } else { - clipboardAndSendMessage(createStats()); - } - - } - - @Override - public List<String> addTabCompletionOptions(ICommandSender sender, String[] args, BlockPos pos) { - return args.length == 1 ? getListOfStringsMatchingLastWord(args, "modlist", "dump") : null; - } - - public interface DiagnosticCommandMXBean { - String gcClassHistogram(String[] array); - } - - private static void clipboardAndSendMessage(String data) { - if (data == null) { - modPrefixedMessage(EnumChatFormatting.DARK_RED + "Error occurred trying to perform command."); - return; - } - try { - StringSelection clipboard = new StringSelection(data); - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(clipboard, clipboard); - modPrefixedMessage(EnumChatFormatting.GREEN + "Dev info copied to clipboard."); - } catch (Exception ignored) { - modPrefixedMessage(EnumChatFormatting.DARK_RED + "Could not copy to clipboard."); - } - } - - private static void modPrefixedMessage(String message) { - Utils.addChatMessage( - EnumChatFormatting.GOLD + "[" + EnumChatFormatting.RED + "NotEnoughUpdates" + EnumChatFormatting.GOLD + "]: " + message); - } - - private static String createStats() { - DiscordMarkdownBuilder builder = new DiscordMarkdownBuilder(); - long maxMemory = Runtime.getRuntime().maxMemory(); - long totalMemory = Runtime.getRuntime().totalMemory(); - long freeMemory = Runtime.getRuntime().freeMemory(); - long currentMemory = totalMemory - freeMemory; - - builder.category("System Stats"); - builder.append("OS", System.getProperty("os.name")); - builder.append("CPU", OpenGlHelper.getCpu()); - builder.append( - "Display", - String.format("%dx%d (%s)", Display.getWidth(), Display.getHeight(), GL11.glGetString(GL11.GL_VENDOR)) - ); - builder.append("GPU", GL11.glGetString(GL11.GL_RENDERER)); - builder.append("GPU Driver", GL11.glGetString(GL11.GL_VERSION)); - if (getMemorySize() > 0) builder.append("Maximum Memory", (getMemorySize() / 1024L / 1024L) + "MB"); - builder.append("Shaders", ("" + OpenGlHelper.isFramebufferEnabled()).toUpperCase()); - builder.category("Java Stats"); - builder.append( - "Java", - String.format("%s %dbit", System.getProperty("java.version"), Minecraft.getMinecraft().isJava64bit() ? 64 : 32) - ); - builder.append( - "Memory", - String.format( - "% 2d%% %03d/%03dMB", - currentMemory * 100L / maxMemory, - currentMemory / 1024L / 1024L, - maxMemory / 1024L / 1024L - ) - ); - builder.append( - "Memory Allocated", - String.format("% 2d%% %03dMB", totalMemory * 100L / maxMemory, totalMemory / 1024L / 1024L) - ); - builder.category("Game Stats"); - builder.append("FPS", String.valueOf(Minecraft.getDebugFPS())); - builder.append("Loaded Mods", String.valueOf(activeModCount)); - builder.append("Forge", ForgeVersion.getVersion()); - builder.append("Optifine", FMLClientHandler.instance().hasOptifine() ? "TRUE" : "FALSE"); - builder.category("Neu Settings"); - builder.append("API Key", NotEnoughUpdates.INSTANCE.config.apiData.apiKey.isEmpty() ? "FALSE" : "TRUE"); - builder.append("On SkyBlock", NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() ? "TRUE" : "FALSE"); - builder.append( - "Mod Version", - Loader.instance().getIndexedModList().get(NotEnoughUpdates.MODID).getDisplayVersion() - ); - builder.append("SB Profile", SBInfo.getInstance().currentProfile); - builder.append("Has Advanced Tab", SBInfo.getInstance().hasNewTab ? "TRUE" : "FALSE"); - builder.category("Repo Stats"); - builder.append("Last Commit", NotEnoughUpdates.INSTANCE.manager.latestRepoCommit); - builder.append("Loaded Items", String.valueOf(NotEnoughUpdates.INSTANCE.manager.getItemInformation().size())); - if (activeModCount <= 15) createModList(builder); - - return builder.toString(); - } - - private static DiscordMarkdownBuilder createModList(DiscordMarkdownBuilder builder) { - builder.category("Mods Loaded"); - Loader.instance().getActiveModList().forEach(mod -> builder.append(mod.getName(), mod.getSource().getName())); - return builder; - } - - private static long getMemorySize() { - try { - return ((com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getTotalPhysicalMemorySize(); - } catch (Exception e) { - try { - return ((com.sun.management.UnixOperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getTotalPhysicalMemorySize(); - } catch (Exception ignored) {/*IGNORE*/} - } - return -1; - } -} diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/NEUStatsCommand.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/NEUStatsCommand.kt new file mode 100644 index 00000000..97d1edb3 --- /dev/null +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/NEUStatsCommand.kt @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2023 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.commands.dev + +import com.mojang.brigadier.context.CommandContext +import com.sun.management.OperatingSystemMXBean +import com.sun.management.UnixOperatingSystemMXBean +import io.github.moulberry.notenoughupdates.NotEnoughUpdates +import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe +import io.github.moulberry.notenoughupdates.events.RegisterBrigadierCommandEvent +import io.github.moulberry.notenoughupdates.util.DiscordMarkdownBuilder +import io.github.moulberry.notenoughupdates.util.HastebinUploader +import io.github.moulberry.notenoughupdates.util.SBInfo +import io.github.moulberry.notenoughupdates.util.brigadier.reply +import io.github.moulberry.notenoughupdates.util.brigadier.thenExecute +import io.github.moulberry.notenoughupdates.util.brigadier.thenLiteralExecute +import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.OpenGlHelper +import net.minecraft.command.ICommandSender +import net.minecraft.util.EnumChatFormatting.DARK_RED +import net.minecraft.util.EnumChatFormatting.GREEN +import net.minecraftforge.common.ForgeVersion +import net.minecraftforge.fml.client.FMLClientHandler +import net.minecraftforge.fml.common.Loader +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import org.lwjgl.opengl.Display +import org.lwjgl.opengl.GL11 +import java.awt.Toolkit +import java.awt.datatransfer.StringSelection +import java.lang.management.ManagementFactory +import java.util.concurrent.CompletableFuture +import javax.management.JMX +import javax.management.ObjectName + +@NEUAutoSubscribe +class NEUStatsCommand { + @SubscribeEvent + fun onCommands(event: RegisterBrigadierCommandEvent) { + event.command("stats", "neustats") { + thenExecute { + clipboardAndSendMessage( + DiscordMarkdownBuilder() + .also(::appendStats) + .also { + if (Loader.instance().activeModList.size <= 15) appendModList(it) + } + .toString() + ) + } + thenLiteralExecute("modlist") { + clipboardAndSendMessage( + DiscordMarkdownBuilder() + .also(::appendModList) + .toString() + ) + } + thenLiteralExecute("full") { + clipboardAndSendMessage( + DiscordMarkdownBuilder() + .also(::appendStats) + .also(::appendModList) + .toString() + ) + } + thenLiteralExecute("dump") { + reply("${GREEN}This will upload a dump of the java classes your game has loaded how big they are and how many there are. This can take a few seconds as it is uploading to HasteBin.") + uploadDataUsageDump().thenAccept { + clipboardAndSendMessage(it) + } + } + } + } + interface DiagnosticCommandMXBean { + fun gcClassHistogram(array: Array<String>): String + } + + private fun uploadDataUsageDump(): CompletableFuture<String?> { + return CompletableFuture.supplyAsync { + try { + val server = + ManagementFactory.getPlatformMBeanServer() + val objectName = + ObjectName.getInstance("com.sun.management:type=DiagnosticCommand") + val proxy = JMX.newMXBeanProxy( + server, + objectName, + DiagnosticCommandMXBean::class.java + ) + HastebinUploader.upload( + proxy.gcClassHistogram(emptyArray()).replace("[", "[]"), + HastebinUploader.Mode.NORMAL + ) + } catch (e: Exception) { + null + } + } + + } + + + private fun getMemorySize(): Long { + try { + return (ManagementFactory.getOperatingSystemMXBean() as OperatingSystemMXBean).totalPhysicalMemorySize + } catch (e: java.lang.Exception) { + try { + return (ManagementFactory.getOperatingSystemMXBean() as UnixOperatingSystemMXBean).totalPhysicalMemorySize + } catch (ignored: java.lang.Exception) { /*IGNORE*/ + } + } + return -1 + } + + val ONE_MB = 1024L * 1024L + private fun appendStats(builder: DiscordMarkdownBuilder) { + val maxMemory = Runtime.getRuntime().maxMemory() + val totalMemory = Runtime.getRuntime().totalMemory() + val freeMemory = Runtime.getRuntime().freeMemory() + val currentMemory = totalMemory - freeMemory + builder.category("System Stats") + builder.append("OS", System.getProperty("os.name")) + builder.append("CPU", OpenGlHelper.getCpu()) + builder.append( + "Display", + String.format("%dx%d (%s)", Display.getWidth(), Display.getHeight(), GL11.glGetString(GL11.GL_VENDOR)) + ) + builder.append("GPU", GL11.glGetString(GL11.GL_RENDERER)) + builder.append("GPU Driver", GL11.glGetString(GL11.GL_VERSION)) + if (getMemorySize() > 0) + builder.append( + "Maximum Memory", + "${getMemorySize() / ONE_MB}MB" + ) + builder.append("Shaders", ("" + OpenGlHelper.isFramebufferEnabled()).uppercase()) + builder.category("Java Stats") + builder.append( + "Java", + "${System.getProperty("java.version")} ${if (Minecraft.getMinecraft().isJava64bit) 64 else 32}bit", + ) + builder.append( + "Memory", String.format( + "% 2d%% %03d/%03dMB", + currentMemory * 100L / maxMemory, + currentMemory / ONE_MB, + maxMemory / ONE_MB + ) + ) + builder.append( + "Memory Allocated", + String.format("% 2d%% %03dMB", totalMemory * 100L / maxMemory, totalMemory / ONE_MB) + ) + builder.category("Game Stats") + builder.append("FPS", Minecraft.getDebugFPS().toString()) + builder.append("Loaded Mods", Loader.instance().activeModList.size) + builder.append("Forge", ForgeVersion.getVersion()) + builder.append("Optifine", if (FMLClientHandler.instance().hasOptifine()) "TRUE" else "FALSE") + builder.category("Neu Settings") + builder.append("API Key", if (NotEnoughUpdates.INSTANCE.config.apiData.apiKey.isEmpty()) "FALSE" else "TRUE") + builder.append("On SkyBlock", if (NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) "TRUE" else "FALSE") + builder.append( + "Mod Version", + Loader.instance().indexedModList[NotEnoughUpdates.MODID]!!.displayVersion + ) + builder.append("SB Profile", SBInfo.getInstance().currentProfile) + builder.append("Has Advanced Tab", if (SBInfo.getInstance().hasNewTab) "TRUE" else "FALSE") + builder.category("Repo Stats") + builder.append("Last Commit", NotEnoughUpdates.INSTANCE.manager.latestRepoCommit) + builder.append("Loaded Items", NotEnoughUpdates.INSTANCE.manager.itemInformation.size.toString()) + } + + private fun appendModList(builder: DiscordMarkdownBuilder): DiscordMarkdownBuilder { + builder.category("Mods Loaded") + Loader.instance().activeModList.forEach { + builder.append(it.name, "${it.source} (${it.displayVersion})") + } + return builder + } + + fun CommandContext<ICommandSender>.clipboardAndSendMessage(data: String?) { + if (data == null) { + reply("${DARK_RED}Error occurred trying to perform command.") + return + } + try { + val clipboard = StringSelection(data) + Toolkit.getDefaultToolkit().systemClipboard.setContents(clipboard, null) + reply("${GREEN}Dev info copied to clipboard.") + } catch (ignored: Exception) { + reply("${DARK_RED}Could not copy to clipboard.") + } + } +} diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/SimpleDevCommands.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/SimpleDevCommands.kt index a42fc412..2990b24d 100644 --- a/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/SimpleDevCommands.kt +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/SimpleDevCommands.kt @@ -30,8 +30,10 @@ import io.github.moulberry.notenoughupdates.util.brigadier.* import net.minecraft.client.entity.EntityPlayerSP import net.minecraft.event.ClickEvent import net.minecraft.util.BlockPos +import net.minecraft.util.ChatComponentText import net.minecraft.util.ResourceLocation import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.util.function.Consumer @NEUAutoSubscribe class SimpleDevCommands { @@ -95,5 +97,14 @@ class SimpleDevCommands { reply("Set size to ${this[size]}") } } + event.command("neuresetrepo") { + thenExecute { + NotEnoughUpdates.INSTANCE.manager + .userFacingRepositoryReload() + .thenAccept { it + it.forEach(::reply) + } + } + } } } |