From 4d45579d2bf57b417d5d3eca041c2131177183e4 Mon Sep 17 00:00:00 2001 From: Luck Date: Sat, 25 Jun 2022 22:48:55 +0100 Subject: Add providers for world (entity/chunk) statistics --- .../lucko/spark/forge/ForgeWorldInfoProvider.java | 141 +++++++++++++++++++++ .../spark/forge/plugin/ForgeClientSparkPlugin.java | 12 ++ .../spark/forge/plugin/ForgeServerSparkPlugin.java | 12 ++ .../main/resources/META-INF/accesstransformer.cfg | 4 + 4 files changed, 169 insertions(+) create mode 100644 spark-forge/src/main/java/me/lucko/spark/forge/ForgeWorldInfoProvider.java create mode 100644 spark-forge/src/main/resources/META-INF/accesstransformer.cfg (limited to 'spark-forge/src/main') diff --git a/spark-forge/src/main/java/me/lucko/spark/forge/ForgeWorldInfoProvider.java b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeWorldInfoProvider.java new file mode 100644 index 0000000..b17dab5 --- /dev/null +++ b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeWorldInfoProvider.java @@ -0,0 +1,141 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * 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 . + */ + +package me.lucko.spark.forge; + +import it.unimi.dsi.fastutil.longs.LongIterator; +import it.unimi.dsi.fastutil.longs.LongSet; + +import me.lucko.spark.common.platform.world.AbstractChunkInfo; +import me.lucko.spark.common.platform.world.CountMap; +import me.lucko.spark.common.platform.world.WorldInfoProvider; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.entity.EntitySection; +import net.minecraft.world.level.entity.EntitySectionStorage; +import net.minecraft.world.level.entity.PersistentEntitySectionManager; +import net.minecraft.world.level.entity.TransientEntitySectionManager; +import net.minecraft.world.level.storage.ServerLevelData; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.stream.Stream; + +public abstract class ForgeWorldInfoProvider implements WorldInfoProvider { + + protected List getChunksFromCache(EntitySectionStorage cache) { + LongSet loadedChunks = cache.getAllChunksWithExistingSections(); + List list = new ArrayList<>(loadedChunks.size()); + + for (LongIterator iterator = loadedChunks.iterator(); iterator.hasNext(); ) { + long chunkPos = iterator.nextLong(); + Stream> sections = cache.getExistingSectionsInChunk(chunkPos); + + list.add(new ForgeChunkInfo(chunkPos, sections)); + } + + return list; + } + + public static final class Server extends ForgeWorldInfoProvider { + private final MinecraftServer server; + + public Server(MinecraftServer server) { + this.server = server; + } + + @Override + public Result poll() { + Result data = new Result<>(); + + for (ServerLevel level : this.server.getAllLevels()) { + PersistentEntitySectionManager entityManager = level.entityManager; + EntitySectionStorage cache = entityManager.sectionStorage; + + List list = getChunksFromCache(cache); + data.put(((ServerLevelData) level.getLevelData()).getLevelName(), list); + } + + return data; + } + } + + public static final class Client extends ForgeWorldInfoProvider { + private final Minecraft client; + + public Client(Minecraft client) { + this.client = client; + } + + @Override + public Result poll() { + Result data = new Result<>(); + + ClientLevel level = this.client.level; + if (level == null) { + return null; + } + + TransientEntitySectionManager entityManager = level.entityStorage; + EntitySectionStorage cache = entityManager.sectionStorage; + + List list = getChunksFromCache(cache); + data.put(level.dimensionTypeId().location().getPath(), list); + + return data; + } + } + + static final class ForgeChunkInfo extends AbstractChunkInfo> { + private final CountMap> entityCounts; + + ForgeChunkInfo(long chunkPos, Stream> entities) { + super(ChunkPos.getX(chunkPos), ChunkPos.getZ(chunkPos)); + + this.entityCounts = new CountMap.Simple<>(new HashMap<>()); + entities.forEach(section -> { + if (section.getStatus().isAccessible()) { + section.getEntities().forEach(entity -> + this.entityCounts.increment(entity.getType()) + ); + } + }); + } + + @Override + public CountMap> getEntityCounts() { + return this.entityCounts; + } + + @Override + public String entityTypeName(EntityType type) { + return EntityType.getKey(type).toString(); + } + } + + +} 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 cf5c89b..04c8785 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 @@ -28,6 +28,7 @@ import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; import me.lucko.spark.common.platform.PlatformInfo; +import me.lucko.spark.common.platform.world.WorldInfoProvider; import me.lucko.spark.common.tick.TickHook; import me.lucko.spark.common.tick.TickReporter; import me.lucko.spark.forge.ForgeCommandSender; @@ -35,6 +36,7 @@ import me.lucko.spark.forge.ForgePlatformInfo; import me.lucko.spark.forge.ForgeSparkMod; import me.lucko.spark.forge.ForgeTickHook; import me.lucko.spark.forge.ForgeTickReporter; +import me.lucko.spark.forge.ForgeWorldInfoProvider; import net.minecraft.client.Minecraft; import net.minecraft.commands.CommandSource; @@ -107,6 +109,11 @@ public class ForgeClientSparkPlugin extends ForgeSparkPlugin implements Command< return Stream.of(new ForgeCommandSender(this.minecraft.player, this)); } + @Override + public void executeSync(Runnable task) { + this.minecraft.executeIfPossible(task); + } + @Override public TickHook createTickHook() { return new ForgeTickHook(TickEvent.Type.CLIENT); @@ -117,6 +124,11 @@ public class ForgeClientSparkPlugin extends ForgeSparkPlugin implements Command< return new ForgeTickReporter(TickEvent.Type.CLIENT); } + @Override + public WorldInfoProvider createWorldInfoProvider() { + return new ForgeWorldInfoProvider.Client(this.minecraft); + } + @Override public PlatformInfo getPlatformInfo() { return new ForgePlatformInfo(PlatformInfo.Type.CLIENT); 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 e341d6f..03f9952 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 @@ -31,6 +31,7 @@ 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.platform.world.WorldInfoProvider; import me.lucko.spark.common.tick.TickHook; import me.lucko.spark.common.tick.TickReporter; import me.lucko.spark.forge.ForgeCommandSender; @@ -39,6 +40,7 @@ import me.lucko.spark.forge.ForgePlayerPingProvider; import me.lucko.spark.forge.ForgeSparkMod; import me.lucko.spark.forge.ForgeTickHook; import me.lucko.spark.forge.ForgeTickReporter; +import me.lucko.spark.forge.ForgeWorldInfoProvider; import net.minecraft.commands.CommandSource; import net.minecraft.commands.CommandSourceStack; @@ -183,6 +185,11 @@ public class ForgeServerSparkPlugin extends ForgeSparkPlugin implements Command< ).map(sender -> new ForgeCommandSender(sender, this)); } + @Override + public void executeSync(Runnable task) { + this.server.executeIfPossible(task); + } + @Override public TickHook createTickHook() { return new ForgeTickHook(TickEvent.Type.SERVER); @@ -198,6 +205,11 @@ public class ForgeServerSparkPlugin extends ForgeSparkPlugin implements Command< return new ForgePlayerPingProvider(this.server); } + @Override + public WorldInfoProvider createWorldInfoProvider() { + return new ForgeWorldInfoProvider.Server(this.server); + } + @Override public PlatformInfo getPlatformInfo() { return new ForgePlatformInfo(PlatformInfo.Type.SERVER); diff --git a/spark-forge/src/main/resources/META-INF/accesstransformer.cfg b/spark-forge/src/main/resources/META-INF/accesstransformer.cfg new file mode 100644 index 0000000..1e418b8 --- /dev/null +++ b/spark-forge/src/main/resources/META-INF/accesstransformer.cfg @@ -0,0 +1,4 @@ +public net.minecraft.server.level.ServerLevel f_143244_ # entityManager +public net.minecraft.world.level.entity.PersistentEntitySectionManager f_157495_ # sectionStorage +public net.minecraft.client.multiplayer.ClientLevel f_171631_ # entityStorage +public net.minecraft.world.level.entity.TransientEntitySectionManager f_157638_ # sectionStorage -- cgit From f2c2a75bfa73080c9837471c92f96f57c9620c45 Mon Sep 17 00:00:00 2001 From: Luck Date: Wed, 29 Jun 2022 22:36:27 +0100 Subject: Fix entity stats on Fabric/Forge --- .../src/main/java/me/lucko/spark/forge/ForgeWorldInfoProvider.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'spark-forge/src/main') diff --git a/spark-forge/src/main/java/me/lucko/spark/forge/ForgeWorldInfoProvider.java b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeWorldInfoProvider.java index b17dab5..1d65d6a 100644 --- a/spark-forge/src/main/java/me/lucko/spark/forge/ForgeWorldInfoProvider.java +++ b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeWorldInfoProvider.java @@ -38,7 +38,6 @@ import net.minecraft.world.level.entity.EntitySection; import net.minecraft.world.level.entity.EntitySectionStorage; import net.minecraft.world.level.entity.PersistentEntitySectionManager; import net.minecraft.world.level.entity.TransientEntitySectionManager; -import net.minecraft.world.level.storage.ServerLevelData; import java.util.ArrayList; import java.util.HashMap; @@ -77,7 +76,7 @@ public abstract class ForgeWorldInfoProvider implements WorldInfoProvider { EntitySectionStorage cache = entityManager.sectionStorage; List list = getChunksFromCache(cache); - data.put(((ServerLevelData) level.getLevelData()).getLevelName(), list); + data.put(level.dimension().location().getPath(), list); } return data; @@ -104,7 +103,7 @@ public abstract class ForgeWorldInfoProvider implements WorldInfoProvider { EntitySectionStorage cache = entityManager.sectionStorage; List list = getChunksFromCache(cache); - data.put(level.dimensionTypeId().location().getPath(), list); + data.put(level.dimension().location().getPath(), list); return data; } -- cgit From 2b24d42ab2b9a9c28a5929520d9ca565f07724f9 Mon Sep 17 00:00:00 2001 From: Luck Date: Wed, 29 Jun 2022 22:41:42 +0100 Subject: Add server config providers for Fabric/Forge --- .../spark/forge/ForgeServerConfigProvider.java | 57 ++++++++++++++++++++++ .../spark/forge/plugin/ForgeServerSparkPlugin.java | 7 +++ 2 files changed, 64 insertions(+) create mode 100644 spark-forge/src/main/java/me/lucko/spark/forge/ForgeServerConfigProvider.java (limited to 'spark-forge/src/main') diff --git a/spark-forge/src/main/java/me/lucko/spark/forge/ForgeServerConfigProvider.java b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeServerConfigProvider.java new file mode 100644 index 0000000..baa1358 --- /dev/null +++ b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeServerConfigProvider.java @@ -0,0 +1,57 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * 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 . + */ + +package me.lucko.spark.forge; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +import me.lucko.spark.common.platform.serverconfig.AbstractServerConfigProvider; +import me.lucko.spark.common.platform.serverconfig.ConfigParser; +import me.lucko.spark.common.platform.serverconfig.PropertiesConfigParser; + +import java.util.Collection; +import java.util.Map; + +public class ForgeServerConfigProvider extends AbstractServerConfigProvider { + + /** A map of provided files and their type */ + private static final Map FILES; + /** A collection of paths to be excluded from the files */ + private static final Collection HIDDEN_PATHS; + + public ForgeServerConfigProvider() { + super(FILES, HIDDEN_PATHS); + } + + static { + ImmutableSet.Builder hiddenPaths = ImmutableSet.builder() + .add("server-ip") + .add("motd") + .add("resource-pack") + .add("rconpassword") + .add("level-seed") + .addAll(getSystemPropertyList("spark.serverconfigs.hiddenpaths")); + + FILES = ImmutableMap.of("server.properties", PropertiesConfigParser.INSTANCE); + HIDDEN_PATHS = hiddenPaths.build(); + } + +} 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 03f9952..f4a51e0 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 @@ -31,12 +31,14 @@ 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.platform.serverconfig.ServerConfigProvider; import me.lucko.spark.common.platform.world.WorldInfoProvider; 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.ForgeServerConfigProvider; import me.lucko.spark.forge.ForgeSparkMod; import me.lucko.spark.forge.ForgeTickHook; import me.lucko.spark.forge.ForgeTickReporter; @@ -205,6 +207,11 @@ public class ForgeServerSparkPlugin extends ForgeSparkPlugin implements Command< return new ForgePlayerPingProvider(this.server); } + @Override + public ServerConfigProvider createServerConfigProvider() { + return new ForgeServerConfigProvider(); + } + @Override public WorldInfoProvider createWorldInfoProvider() { return new ForgeWorldInfoProvider.Server(this.server); -- cgit From 73dd214ae66bab483ee8b4f0ed03881466da92e8 Mon Sep 17 00:00:00 2001 From: Luck Date: Tue, 12 Jul 2022 22:37:59 +0100 Subject: Improve/fix game thread dumper --- .../java/me/lucko/spark/forge/plugin/ForgeClientSparkPlugin.java | 9 ++++++++- .../java/me/lucko/spark/forge/plugin/ForgeServerSparkPlugin.java | 9 ++++++++- .../main/java/me/lucko/spark/forge/plugin/ForgeSparkPlugin.java | 7 ------- spark-forge/src/main/resources/META-INF/accesstransformer.cfg | 1 + 4 files changed, 17 insertions(+), 9 deletions(-) (limited to 'spark-forge/src/main') 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 04c8785..a4c6bd1 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 @@ -29,6 +29,7 @@ import com.mojang.brigadier.suggestion.SuggestionsBuilder; import me.lucko.spark.common.platform.PlatformInfo; import me.lucko.spark.common.platform.world.WorldInfoProvider; +import me.lucko.spark.common.sampler.ThreadDumper; import me.lucko.spark.common.tick.TickHook; import me.lucko.spark.common.tick.TickReporter; import me.lucko.spark.forge.ForgeCommandSender; @@ -58,10 +59,12 @@ public class ForgeClientSparkPlugin extends ForgeSparkPlugin implements Command< } private final Minecraft minecraft; + private final ThreadDumper gameThreadDumper; public ForgeClientSparkPlugin(ForgeSparkMod mod, Minecraft minecraft) { super(mod); this.minecraft = minecraft; + this.gameThreadDumper = new ThreadDumper.Specific(minecraft.gameThread); } @Override @@ -84,7 +87,6 @@ public class ForgeClientSparkPlugin extends ForgeSparkPlugin implements Command< return 0; } - this.threadDumper.ensureSetup(); this.platform.executeCommand(new ForgeCommandSender(context.getSource().getEntity(), this), args); return Command.SINGLE_SUCCESS; } @@ -114,6 +116,11 @@ public class ForgeClientSparkPlugin extends ForgeSparkPlugin implements Command< this.minecraft.executeIfPossible(task); } + @Override + public ThreadDumper getDefaultThreadDumper() { + return this.gameThreadDumper; + } + @Override public TickHook createTickHook() { return new ForgeTickHook(TickEvent.Type.CLIENT); 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 f4a51e0..1aeb2b1 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 @@ -33,6 +33,7 @@ import me.lucko.spark.common.monitor.ping.PlayerPingProvider; import me.lucko.spark.common.platform.PlatformInfo; import me.lucko.spark.common.platform.serverconfig.ServerConfigProvider; import me.lucko.spark.common.platform.world.WorldInfoProvider; +import me.lucko.spark.common.sampler.ThreadDumper; import me.lucko.spark.common.tick.TickHook; import me.lucko.spark.common.tick.TickReporter; import me.lucko.spark.forge.ForgeCommandSender; @@ -75,11 +76,13 @@ public class ForgeServerSparkPlugin extends ForgeSparkPlugin implements Command< } private final MinecraftServer server; + private final ThreadDumper gameThreadDumper; private Map> registeredPermissions = Collections.emptyMap(); public ForgeServerSparkPlugin(ForgeSparkMod mod, MinecraftServer server) { super(mod); this.server = server; + this.gameThreadDumper = new ThreadDumper.Specific(server.getRunningThread()); } @Override @@ -146,7 +149,6 @@ public class ForgeServerSparkPlugin extends ForgeSparkPlugin implements Command< return 0; } - this.threadDumper.ensureSetup(); CommandSource source = context.getSource().getEntity() != null ? context.getSource().getEntity() : context.getSource().getServer(); this.platform.executeCommand(new ForgeCommandSender(source, this), args); return Command.SINGLE_SUCCESS; @@ -192,6 +194,11 @@ public class ForgeServerSparkPlugin extends ForgeSparkPlugin implements Command< this.server.executeIfPossible(task); } + @Override + public ThreadDumper getDefaultThreadDumper() { + return this.gameThreadDumper; + } + @Override public TickHook createTickHook() { return new ForgeTickHook(TickEvent.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 f257e34..36a7ce8 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 @@ -34,7 +34,6 @@ import com.mojang.brigadier.tree.LiteralCommandNode; import me.lucko.spark.common.SparkPlatform; 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; @@ -59,7 +58,6 @@ public abstract class ForgeSparkPlugin implements SparkPlugin { protected final ScheduledExecutorService scheduler; protected SparkPlatform platform; - protected final ThreadDumper.GameThread threadDumper = new ThreadDumper.GameThread(); protected ForgeSparkPlugin(ForgeSparkMod mod) { this.mod = mod; @@ -107,11 +105,6 @@ public abstract class ForgeSparkPlugin implements SparkPlugin { } } - @Override - public ThreadDumper getDefaultThreadDumper() { - return this.threadDumper.get(); - } - @Override public ClassSourceLookup createClassSourceLookup() { return new ForgeClassSourceLookup(); diff --git a/spark-forge/src/main/resources/META-INF/accesstransformer.cfg b/spark-forge/src/main/resources/META-INF/accesstransformer.cfg index 1e418b8..39e9c1a 100644 --- a/spark-forge/src/main/resources/META-INF/accesstransformer.cfg +++ b/spark-forge/src/main/resources/META-INF/accesstransformer.cfg @@ -2,3 +2,4 @@ public net.minecraft.server.level.ServerLevel f_143244_ # entityManager public net.minecraft.world.level.entity.PersistentEntitySectionManager f_157495_ # sectionStorage public net.minecraft.client.multiplayer.ClientLevel f_171631_ # entityStorage public net.minecraft.world.level.entity.TransientEntitySectionManager f_157638_ # sectionStorage +public net.minecraft.client.Minecraft f_91018_ # gameThread \ No newline at end of file -- cgit From 7079484d428321c9b3db09394577efda4d591a4e Mon Sep 17 00:00:00 2001 From: Luck Date: Mon, 19 Sep 2022 18:57:02 +0100 Subject: Provide extra metadata about sources in sampler data --- .../me/lucko/spark/forge/ForgeClassSourceLookup.java | 2 +- .../me/lucko/spark/forge/plugin/ForgeSparkPlugin.java | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'spark-forge/src/main') diff --git a/spark-forge/src/main/java/me/lucko/spark/forge/ForgeClassSourceLookup.java b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeClassSourceLookup.java index 7900bc3..82d66ca 100644 --- a/spark-forge/src/main/java/me/lucko/spark/forge/ForgeClassSourceLookup.java +++ b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeClassSourceLookup.java @@ -20,7 +20,7 @@ package me.lucko.spark.forge; -import me.lucko.spark.common.util.ClassSourceLookup; +import me.lucko.spark.common.sampler.source.ClassSourceLookup; import cpw.mods.modlauncher.TransformingClassLoader; 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 36a7ce8..56061b9 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 @@ -34,18 +34,22 @@ import com.mojang.brigadier.tree.LiteralCommandNode; import me.lucko.spark.common.SparkPlatform; import me.lucko.spark.common.SparkPlugin; import me.lucko.spark.common.command.sender.CommandSender; -import me.lucko.spark.common.util.ClassSourceLookup; +import me.lucko.spark.common.sampler.source.ClassSourceLookup; +import me.lucko.spark.common.sampler.source.SourceMetadata; import me.lucko.spark.common.util.SparkThreadFactory; import me.lucko.spark.forge.ForgeClassSourceLookup; import me.lucko.spark.forge.ForgeSparkMod; import net.minecraft.commands.CommandSource; +import net.minecraftforge.fml.ModList; +import net.minecraftforge.forgespi.language.IModInfo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.nio.file.Path; import java.util.Arrays; +import java.util.Collection; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -110,6 +114,16 @@ public abstract class ForgeSparkPlugin implements SparkPlugin { return new ForgeClassSourceLookup(); } + @Override + public Collection getKnownSources() { + return SourceMetadata.gather( + ModList.get().getMods(), + IModInfo::getModId, + mod -> mod.getVersion().toString(), + mod -> null // ? + ); + } + protected CompletableFuture generateSuggestions(CommandSender sender, String[] args, SuggestionsBuilder builder) { SuggestionsBuilder suggestions; -- cgit From dbdd3eb1344b837abb13538b9c55d1d99e697e54 Mon Sep 17 00:00:00 2001 From: Luck Date: Thu, 22 Sep 2022 22:06:10 +0100 Subject: Allow platforms to pass extra misc metadata to the viewer --- .../spark/forge/ForgeExtraMetadataProvider.java | 75 ++++++++++++++++++++++ .../spark/forge/ForgeServerConfigProvider.java | 4 +- .../spark/forge/plugin/ForgeClientSparkPlugin.java | 7 ++ .../spark/forge/plugin/ForgeServerSparkPlugin.java | 7 ++ 4 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 spark-forge/src/main/java/me/lucko/spark/forge/ForgeExtraMetadataProvider.java (limited to 'spark-forge/src/main') diff --git a/spark-forge/src/main/java/me/lucko/spark/forge/ForgeExtraMetadataProvider.java b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeExtraMetadataProvider.java new file mode 100644 index 0000000..cac2771 --- /dev/null +++ b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeExtraMetadataProvider.java @@ -0,0 +1,75 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * 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 . + */ + +package me.lucko.spark.forge; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import me.lucko.spark.common.platform.MetadataProvider; + +import net.minecraft.server.packs.repository.Pack; +import net.minecraft.server.packs.repository.PackRepository; +import net.minecraft.server.packs.repository.PackSource; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class ForgeExtraMetadataProvider implements MetadataProvider { + + private final PackRepository resourcePackManager; + + public ForgeExtraMetadataProvider(PackRepository resourcePackManager) { + this.resourcePackManager = resourcePackManager; + } + + @Override + public Map get() { + Map metadata = new LinkedHashMap<>(); + metadata.put("datapacks", datapackMetadata()); + return metadata; + } + + private JsonElement datapackMetadata() { + JsonObject datapacks = new JsonObject(); + for (Pack profile : this.resourcePackManager.getSelectedPacks()) { + JsonObject obj = new JsonObject(); + obj.addProperty("name", profile.getTitle().getString()); + obj.addProperty("description", profile.getDescription().getString()); + obj.addProperty("source", resourcePackSource(profile.getPackSource())); + datapacks.add(profile.getId(), obj); + } + return datapacks; + } + + private static String resourcePackSource(PackSource source) { + if (source == PackSource.DEFAULT) { + return "none"; + } else if (source == PackSource.BUILT_IN) { + return "builtin"; + } else if (source == PackSource.WORLD) { + return "world"; + } else if (source == PackSource.SERVER) { + return "server"; + } else { + return "unknown"; + } + } +} diff --git a/spark-forge/src/main/java/me/lucko/spark/forge/ForgeServerConfigProvider.java b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeServerConfigProvider.java index baa1358..6feba52 100644 --- a/spark-forge/src/main/java/me/lucko/spark/forge/ForgeServerConfigProvider.java +++ b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeServerConfigProvider.java @@ -23,14 +23,14 @@ package me.lucko.spark.forge; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import me.lucko.spark.common.platform.serverconfig.AbstractServerConfigProvider; import me.lucko.spark.common.platform.serverconfig.ConfigParser; import me.lucko.spark.common.platform.serverconfig.PropertiesConfigParser; +import me.lucko.spark.common.platform.serverconfig.ServerConfigProvider; import java.util.Collection; import java.util.Map; -public class ForgeServerConfigProvider extends AbstractServerConfigProvider { +public class ForgeServerConfigProvider extends ServerConfigProvider { /** A map of provided files and their type */ private static final Map FILES; 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 a4c6bd1..a8c7c92 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 @@ -27,12 +27,14 @@ import com.mojang.brigadier.suggestion.SuggestionProvider; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import me.lucko.spark.common.platform.MetadataProvider; import me.lucko.spark.common.platform.PlatformInfo; import me.lucko.spark.common.platform.world.WorldInfoProvider; import me.lucko.spark.common.sampler.ThreadDumper; 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.ForgeExtraMetadataProvider; import me.lucko.spark.forge.ForgePlatformInfo; import me.lucko.spark.forge.ForgeSparkMod; import me.lucko.spark.forge.ForgeTickHook; @@ -136,6 +138,11 @@ public class ForgeClientSparkPlugin extends ForgeSparkPlugin implements Command< return new ForgeWorldInfoProvider.Client(this.minecraft); } + @Override + public MetadataProvider createExtraMetadataProvider() { + return new ForgeExtraMetadataProvider(this.minecraft.getResourcePackRepository()); + } + @Override public PlatformInfo getPlatformInfo() { return new ForgePlatformInfo(PlatformInfo.Type.CLIENT); 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 1aeb2b1..56d30b7 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 @@ -30,6 +30,7 @@ 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.MetadataProvider; import me.lucko.spark.common.platform.PlatformInfo; import me.lucko.spark.common.platform.serverconfig.ServerConfigProvider; import me.lucko.spark.common.platform.world.WorldInfoProvider; @@ -37,6 +38,7 @@ import me.lucko.spark.common.sampler.ThreadDumper; 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.ForgeExtraMetadataProvider; import me.lucko.spark.forge.ForgePlatformInfo; import me.lucko.spark.forge.ForgePlayerPingProvider; import me.lucko.spark.forge.ForgeServerConfigProvider; @@ -219,6 +221,11 @@ public class ForgeServerSparkPlugin extends ForgeSparkPlugin implements Command< return new ForgeServerConfigProvider(); } + @Override + public MetadataProvider createExtraMetadataProvider() { + return new ForgeExtraMetadataProvider(this.server.getPackRepository()); + } + @Override public WorldInfoProvider createWorldInfoProvider() { return new ForgeWorldInfoProvider.Server(this.server); -- cgit From 4545bbffd95d27e4e72aaad1a481af9d91094a64 Mon Sep 17 00:00:00 2001 From: Luck Date: Fri, 21 Oct 2022 21:59:27 +0100 Subject: Fix exception from Forge permission registration (#255) --- .../me/lucko/spark/forge/plugin/ForgeServerSparkPlugin.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'spark-forge/src/main') 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 56d30b7..a047538 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 @@ -66,6 +66,7 @@ import net.minecraftforge.server.permission.nodes.PermissionTypes; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -127,7 +128,18 @@ public class ForgeServerSparkPlugin extends ForgeSparkPlugin implements Command< // register permissions with forge & keep a copy for lookup ImmutableMap.Builder> builder = ImmutableMap.builder(); + + Set alreadyRegistered = e.getNodes().stream() + .map(PermissionNode::getNodeName) + .collect(Collectors.toSet()); + for (String permission : permissions) { + // there's a weird bug where it seems that this listener can be called twice, causing an + // IllegalArgumentException to be thrown the second time e.addNodes is called. + if (alreadyRegistered.contains("spark." + permission)) { + continue; + } + PermissionNode node = new PermissionNode<>("spark", permission, PermissionTypes.BOOLEAN, defaultValue); e.addNodes(node); builder.put("spark." + permission, node); -- cgit From 4314cdf23be38f75297c406ca48900c3dd80eec5 Mon Sep 17 00:00:00 2001 From: Luck Date: Sat, 29 Oct 2022 21:53:50 +0100 Subject: Fix Forge permission checks --- .../lucko/spark/forge/plugin/ForgeServerSparkPlugin.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'spark-forge/src/main') 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 a047538..8ac0c7c 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 @@ -66,8 +66,8 @@ import net.minecraftforge.server.permission.nodes.PermissionTypes; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.CompletableFuture; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -129,20 +129,23 @@ public class ForgeServerSparkPlugin extends ForgeSparkPlugin implements Command< // register permissions with forge & keep a copy for lookup ImmutableMap.Builder> builder = ImmutableMap.builder(); - Set alreadyRegistered = e.getNodes().stream() - .map(PermissionNode::getNodeName) - .collect(Collectors.toSet()); + Map> alreadyRegistered = e.getNodes().stream().collect(Collectors.toMap(PermissionNode::getNodeName, Function.identity())); for (String permission : permissions) { + String permissionString = "spark." + permission; + // there's a weird bug where it seems that this listener can be called twice, causing an // IllegalArgumentException to be thrown the second time e.addNodes is called. - if (alreadyRegistered.contains("spark." + permission)) { + PermissionNode existing = alreadyRegistered.get(permissionString); + if (existing != null) { + //noinspection unchecked + builder.put(permissionString, (PermissionNode) existing); continue; } PermissionNode node = new PermissionNode<>("spark", permission, PermissionTypes.BOOLEAN, defaultValue); e.addNodes(node); - builder.put("spark." + permission, node); + builder.put(permissionString, node); } this.registeredPermissions = builder.build(); } -- cgit From 65f9460a1a27e930b3749525766fd44d57b65300 Mon Sep 17 00:00:00 2001 From: Luck Date: Sat, 26 Nov 2022 23:00:53 +0000 Subject: Include player/entity/chunk counts in window statistics --- .../lucko/spark/forge/ForgeWorldInfoProvider.java | 42 +++++++++++++++++++--- .../main/resources/META-INF/accesstransformer.cfg | 4 ++- 2 files changed, 41 insertions(+), 5 deletions(-) (limited to 'spark-forge/src/main') diff --git a/spark-forge/src/main/java/me/lucko/spark/forge/ForgeWorldInfoProvider.java b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeWorldInfoProvider.java index 1d65d6a..4750c08 100644 --- a/spark-forge/src/main/java/me/lucko/spark/forge/ForgeWorldInfoProvider.java +++ b/spark-forge/src/main/java/me/lucko/spark/forge/ForgeWorldInfoProvider.java @@ -34,6 +34,7 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.entity.EntityLookup; import net.minecraft.world.level.entity.EntitySection; import net.minecraft.world.level.entity.EntitySectionStorage; import net.minecraft.world.level.entity.PersistentEntitySectionManager; @@ -68,8 +69,25 @@ public abstract class ForgeWorldInfoProvider implements WorldInfoProvider { } @Override - public Result poll() { - Result data = new Result<>(); + public CountsResult pollCounts() { + int players = this.server.getPlayerCount(); + int entities = 0; + int chunks = 0; + + for (ServerLevel level : this.server.getAllLevels()) { + PersistentEntitySectionManager entityManager = level.entityManager; + EntityLookup entityIndex = entityManager.visibleEntityStorage; + + entities += entityIndex.count(); + chunks += level.getChunkSource().getLoadedChunksCount(); + } + + return new CountsResult(players, entities, -1, chunks); + } + + @Override + public ChunksResult pollChunks() { + ChunksResult data = new ChunksResult<>(); for (ServerLevel level : this.server.getAllLevels()) { PersistentEntitySectionManager entityManager = level.entityManager; @@ -91,8 +109,24 @@ public abstract class ForgeWorldInfoProvider implements WorldInfoProvider { } @Override - public Result poll() { - Result data = new Result<>(); + public CountsResult pollCounts() { + ClientLevel level = this.client.level; + if (level == null) { + return null; + } + + TransientEntitySectionManager entityManager = level.entityStorage; + EntityLookup entityIndex = entityManager.entityStorage; + + int entities = entityIndex.count(); + int chunks = level.getChunkSource().getLoadedChunksCount(); + + return new CountsResult(-1, entities, -1, chunks); + } + + @Override + public ChunksResult pollChunks() { + ChunksResult data = new ChunksResult<>(); ClientLevel level = this.client.level; if (level == null) { diff --git a/spark-forge/src/main/resources/META-INF/accesstransformer.cfg b/spark-forge/src/main/resources/META-INF/accesstransformer.cfg index 39e9c1a..2699a0e 100644 --- a/spark-forge/src/main/resources/META-INF/accesstransformer.cfg +++ b/spark-forge/src/main/resources/META-INF/accesstransformer.cfg @@ -1,5 +1,7 @@ public net.minecraft.server.level.ServerLevel f_143244_ # entityManager public net.minecraft.world.level.entity.PersistentEntitySectionManager f_157495_ # sectionStorage +public net.minecraft.world.level.entity.PersistentEntitySectionManager f_157494_ # visibleEntityStorage public net.minecraft.client.multiplayer.ClientLevel f_171631_ # entityStorage public net.minecraft.world.level.entity.TransientEntitySectionManager f_157638_ # sectionStorage -public net.minecraft.client.Minecraft f_91018_ # gameThread \ No newline at end of file +public net.minecraft.world.level.entity.TransientEntitySectionManager f_157637_ # entityStorage +public net.minecraft.client.Minecraft f_91018_ # gameThread -- cgit From 521cf8889ea4938b93691233178640fea06db69e Mon Sep 17 00:00:00 2001 From: Luck Date: Sat, 10 Dec 2022 10:01:58 +0000 Subject: Give integrated server host all permissions --- .../spark/forge/plugin/ForgeServerSparkPlugin.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'spark-forge/src/main') 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 8ac0c7c..8737057 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 @@ -78,6 +78,19 @@ public class ForgeServerSparkPlugin extends ForgeSparkPlugin implements Command< plugin.enable(); } + private static final PermissionResolver DEFAULT_PERMISSION_VALUE = (player, playerUUID, context) -> { + if (player == null) { + return false; + } + + MinecraftServer server = player.getServer(); + if (server != null && server.isSingleplayerOwner(player.getGameProfile())) { + return true; + } + + return player.hasPermissions(4); + }; + private final MinecraftServer server; private final ThreadDumper gameThreadDumper; private Map> registeredPermissions = Collections.emptyMap(); @@ -116,8 +129,6 @@ public class ForgeServerSparkPlugin extends ForgeSparkPlugin implements Command< @SubscribeEvent public void onPermissionGather(PermissionGatherEvent.Nodes e) { - PermissionResolver defaultValue = (player, playerUUID, context) -> player != null && player.hasPermissions(4); - // collect all possible permissions List permissions = this.platform.getCommands().stream() .map(me.lucko.spark.common.command.Command::primaryAlias) @@ -143,7 +154,7 @@ public class ForgeServerSparkPlugin extends ForgeSparkPlugin implements Command< continue; } - PermissionNode node = new PermissionNode<>("spark", permission, PermissionTypes.BOOLEAN, defaultValue); + PermissionNode node = new PermissionNode<>("spark", permission, PermissionTypes.BOOLEAN, DEFAULT_PERMISSION_VALUE); e.addNodes(node); builder.put(permissionString, node); } -- cgit