aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlucko <git@lucko.me>2024-07-21 12:44:06 +0100
committerGitHub <noreply@github.com>2024-07-21 12:44:06 +0100
commitb78afab85ee15d809ea4ff0ccb14c2b263ede860 (patch)
treed3d987473aee0b1e71ac6a24ea2f692be78bf14b
parent635800af986351f08dba33aa2e8ec5dd691bbffb (diff)
downloadspark-b78afab85ee15d809ea4ff0ccb14c2b263ede860.tar.gz
spark-b78afab85ee15d809ea4ff0ccb14c2b263ede860.tar.bz2
spark-b78afab85ee15d809ea4ff0ccb14c2b263ede860.zip
Include gamerule settings in metadata (#425)
-rw-r--r--spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitWorldInfoProvider.java29
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/world/AsyncWorldInfoProvider.java8
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/world/WorldInfoProvider.java45
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/platform/world/WorldStatisticsProvider.java12
-rw-r--r--spark-common/src/main/proto/spark/spark.proto7
-rw-r--r--spark-fabric/src/main/java/me/lucko/spark/fabric/FabricWorldInfoProvider.java53
-rw-r--r--spark-forge/src/main/java/me/lucko/spark/forge/ForgeWorldInfoProvider.java54
-rw-r--r--spark-neoforge/src/main/java/me/lucko/spark/neoforge/NeoForgeWorldInfoProvider.java54
-rw-r--r--spark-paper/src/main/java/me/lucko/spark/paper/PaperSparkPlugin.java1
-rw-r--r--spark-paper/src/main/java/me/lucko/spark/paper/PaperWorldInfoProvider.java29
-rw-r--r--spark-sponge7/src/main/java/me/lucko/spark/sponge/Sponge7WorldInfoProvider.java16
-rw-r--r--spark-sponge8/src/main/java/me/lucko/spark/sponge/Sponge8WorldInfoProvider.java18
12 files changed, 318 insertions, 8 deletions
diff --git a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitWorldInfoProvider.java b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitWorldInfoProvider.java
index 8d2ea51..6290391 100644
--- a/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitWorldInfoProvider.java
+++ b/spark-bukkit/src/main/java/me/lucko/spark/bukkit/BukkitWorldInfoProvider.java
@@ -24,6 +24,7 @@ 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 org.bukkit.Chunk;
+import org.bukkit.GameRule;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.block.BlockState;
@@ -32,6 +33,7 @@ import org.bukkit.entity.EntityType;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
public class BukkitWorldInfoProvider implements WorldInfoProvider {
private static final boolean SUPPORTS_PAPER_COUNT_METHODS;
@@ -110,6 +112,33 @@ public class BukkitWorldInfoProvider implements WorldInfoProvider {
return data;
}
+ @Override
+ public GameRulesResult pollGameRules() {
+ GameRulesResult data = new GameRulesResult();
+
+ boolean addDefaults = true; // add defaults in the first iteration
+ for (World world : this.server.getWorlds()) {
+ for (String gameRule : world.getGameRules()) {
+ GameRule<?> ruleObj = GameRule.getByName(gameRule);
+ if (ruleObj == null) {
+ continue;
+ }
+
+ if (addDefaults) {
+ Object defaultValue = world.getGameRuleDefault(ruleObj);
+ data.putDefault(gameRule, Objects.toString(defaultValue));
+ }
+
+ Object value = world.getGameRuleValue(ruleObj);
+ data.put(gameRule, world.getName(), Objects.toString(value));
+ }
+
+ addDefaults = false;
+ }
+
+ return data;
+ }
+
static final class BukkitChunkInfo extends AbstractChunkInfo<EntityType> {
private final CountMap<EntityType> entityCounts;
diff --git a/spark-common/src/main/java/me/lucko/spark/common/platform/world/AsyncWorldInfoProvider.java b/spark-common/src/main/java/me/lucko/spark/common/platform/world/AsyncWorldInfoProvider.java
index 82cddef..0f48b2e 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/platform/world/AsyncWorldInfoProvider.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/platform/world/AsyncWorldInfoProvider.java
@@ -80,6 +80,10 @@ public class AsyncWorldInfoProvider {
return async(WorldInfoProvider::pollChunks);
}
+ public CompletableFuture<WorldInfoProvider.GameRulesResult> pollGameRules() {
+ return async(WorldInfoProvider::pollGameRules);
+ }
+
public WorldInfoProvider.CountsResult getCounts() {
return get(pollCounts());
}
@@ -87,4 +91,8 @@ public class AsyncWorldInfoProvider {
public WorldInfoProvider.ChunksResult<? extends ChunkInfo<?>> getChunks() {
return get(pollChunks());
}
+
+ public WorldInfoProvider.GameRulesResult getGameRules() {
+ return get(pollGameRules());
+ }
}
diff --git a/spark-common/src/main/java/me/lucko/spark/common/platform/world/WorldInfoProvider.java b/spark-common/src/main/java/me/lucko/spark/common/platform/world/WorldInfoProvider.java
index 7fb581d..e360ea4 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/platform/world/WorldInfoProvider.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/platform/world/WorldInfoProvider.java
@@ -39,6 +39,11 @@ public interface WorldInfoProvider {
public ChunksResult<? extends ChunkInfo<?>> pollChunks() {
return null;
}
+
+ @Override
+ public GameRulesResult pollGameRules() {
+ return null;
+ }
};
/**
@@ -55,6 +60,13 @@ public interface WorldInfoProvider {
*/
ChunksResult<? extends ChunkInfo<?>> pollChunks();
+ /**
+ * Polls for game rules.
+ *
+ * @return the game rules
+ */
+ GameRulesResult pollGameRules();
+
default boolean mustCallSync() {
return true;
}
@@ -101,4 +113,37 @@ public interface WorldInfoProvider {
}
}
+ final class GameRulesResult {
+ private final Map<String, GameRule> rules = new HashMap<>();
+
+ private GameRule rule(String name) {
+ return this.rules.computeIfAbsent(name, k -> new GameRule());
+ }
+
+ public void put(String gameRuleName, String worldName, String value) {
+ rule(gameRuleName).worldValues.put(worldName, value);
+ }
+
+ public void putDefault(String gameRuleName, String value) {
+ rule(gameRuleName).defaultValue = value;
+ }
+
+ public Map<String, GameRule> getRules() {
+ return this.rules;
+ }
+
+ public static final class GameRule {
+ Map<String, String> worldValues = new HashMap<>();
+ String defaultValue = null;
+
+ public String getDefaultValue() {
+ return this.defaultValue;
+ }
+
+ public Map<String, String> getWorldValues() {
+ return this.worldValues;
+ }
+ }
+ }
+
}
diff --git a/spark-common/src/main/java/me/lucko/spark/common/platform/world/WorldStatisticsProvider.java b/spark-common/src/main/java/me/lucko/spark/common/platform/world/WorldStatisticsProvider.java
index 7e63222..5d00037 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/platform/world/WorldStatisticsProvider.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/platform/world/WorldStatisticsProvider.java
@@ -38,7 +38,7 @@ public class WorldStatisticsProvider {
}
public WorldStatistics getWorldStatistics() {
- WorldInfoProvider.ChunksResult<? extends ChunkInfo<?>> result = provider.getChunks();
+ WorldInfoProvider.ChunksResult<? extends ChunkInfo<?>> result = this.provider.getChunks();
if (result == null) {
return null;
}
@@ -70,6 +70,16 @@ public class WorldStatisticsProvider {
stats.setTotalEntities(combinedTotal.get());
combined.asMap().forEach((key, value) -> stats.putEntityCounts(key, value.get()));
+ WorldInfoProvider.GameRulesResult gameRules = this.provider.getGameRules();
+ if (gameRules != null) {
+ gameRules.getRules().forEach((ruleName, rule) -> stats.addGameRules(WorldStatistics.GameRule.newBuilder()
+ .setName(ruleName)
+ .setDefaultValue(rule.getDefaultValue())
+ .putAllWorldValues(rule.getWorldValues())
+ .build()
+ ));
+ }
+
return stats.build();
}
diff --git a/spark-common/src/main/proto/spark/spark.proto b/spark-common/src/main/proto/spark/spark.proto
index 53750d7..6ffd4e9 100644
--- a/spark-common/src/main/proto/spark/spark.proto
+++ b/spark-common/src/main/proto/spark/spark.proto
@@ -140,6 +140,7 @@ message WorldStatistics {
int32 total_entities = 1;
map<string, int32> entity_counts = 2;
repeated World worlds = 3;
+ repeated GameRule game_rules = 4;
message World {
string name = 1;
@@ -158,6 +159,12 @@ message WorldStatistics {
int32 total_entities = 3;
map<string, int32> entity_counts = 4;
}
+
+ message GameRule {
+ string name = 1;
+ string default_value = 2;
+ map<string, string> world_values = 3;
+ }
}
message WindowStatistics {
diff --git a/spark-fabric/src/main/java/me/lucko/spark/fabric/FabricWorldInfoProvider.java b/spark-fabric/src/main/java/me/lucko/spark/fabric/FabricWorldInfoProvider.java
index 926e8a3..d7dc7a7 100644
--- a/spark-fabric/src/main/java/me/lucko/spark/fabric/FabricWorldInfoProvider.java
+++ b/spark-fabric/src/main/java/me/lucko/spark/fabric/FabricWorldInfoProvider.java
@@ -37,6 +37,7 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.server.world.ServerEntityManager;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.ChunkPos;
+import net.minecraft.world.GameRules;
import net.minecraft.world.entity.ClientEntityManager;
import net.minecraft.world.entity.EntityIndex;
import net.minecraft.world.entity.EntityTrackingSection;
@@ -101,6 +102,28 @@ public abstract class FabricWorldInfoProvider implements WorldInfoProvider {
return data;
}
+
+ @Override
+ public GameRulesResult pollGameRules() {
+ GameRulesResult data = new GameRulesResult();
+ Iterable<ServerWorld> worlds = this.server.getWorlds();
+
+ GameRules.accept(new GameRules.Visitor() {
+ @Override
+ public <T extends GameRules.Rule<T>> void visit(GameRules.Key<T> key, GameRules.Type<T> type) {
+ String defaultValue = type.createRule().serialize();
+ data.putDefault(key.getName(), defaultValue);
+
+ for (ServerWorld world : worlds) {
+ String worldName = world.getRegistryKey().getValue().getPath();
+
+ String value = world.getGameRules().get(key).serialize();
+ data.put(key.getName(), worldName, value);
+ }
+ }
+ });
+ return data;
+ }
}
public static final class Client extends FabricWorldInfoProvider {
@@ -128,13 +151,13 @@ public abstract class FabricWorldInfoProvider implements WorldInfoProvider {
@Override
public ChunksResult<FabricChunkInfo> pollChunks() {
- ChunksResult<FabricChunkInfo> data = new ChunksResult<>();
-
ClientWorld world = this.client.world;
if (world == null) {
return null;
}
+ ChunksResult<FabricChunkInfo> data = new ChunksResult<>();
+
ClientEntityManager<Entity> entityManager = ((ClientWorldAccessor) world).getEntityManager();
SectionedEntityCache<Entity> cache = ((ClientEntityManagerAccessor) entityManager).getCache();
@@ -143,6 +166,32 @@ public abstract class FabricWorldInfoProvider implements WorldInfoProvider {
return data;
}
+
+ @Override
+ public GameRulesResult pollGameRules() {
+ ClientWorld world = this.client.world;
+ if (world == null) {
+ return null;
+ }
+
+ GameRulesResult data = new GameRulesResult();
+
+ String worldName = world.getRegistryKey().getValue().getPath();
+ GameRules worldRules = world.getGameRules();
+
+ GameRules.accept(new GameRules.Visitor() {
+ @Override
+ public <T extends GameRules.Rule<T>> void visit(GameRules.Key<T> key, GameRules.Type<T> type) {
+ String defaultValue = type.createRule().serialize();
+ data.putDefault(key.getName(), defaultValue);
+
+ String value = worldRules.get(key).serialize();
+ data.put(key.getName(), worldName, value);
+ }
+ });
+
+ return data;
+ }
}
static final class FabricChunkInfo extends AbstractChunkInfo<EntityType<?>> {
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 e10a0c8..286605a 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
@@ -32,6 +32,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.GameRules;
import net.minecraft.world.level.entity.EntityLookup;
import net.minecraft.world.level.entity.EntitySection;
import net.minecraft.world.level.entity.EntitySectionStorage;
@@ -97,6 +98,29 @@ public abstract class ForgeWorldInfoProvider implements WorldInfoProvider {
return data;
}
+
+ @Override
+ public GameRulesResult pollGameRules() {
+ GameRulesResult data = new GameRulesResult();
+ Iterable<ServerLevel> levels = this.server.getAllLevels();
+
+ GameRules.visitGameRuleTypes(new GameRules.GameRuleTypeVisitor() {
+ @Override
+ public <T extends GameRules.Value<T>> void visit(GameRules.Key<T> key, GameRules.Type<T> type) {
+ String defaultValue = type.createRule().serialize();
+ data.putDefault(key.getId(), defaultValue);
+
+ for (ServerLevel level : levels) {
+ String levelName = level.dimension().location().getPath();
+
+ String value = level.getGameRules().getRule(key).serialize();
+ data.put(key.getId(), levelName, value);
+ }
+ }
+ });
+
+ return data;
+ }
}
public static final class Client extends ForgeWorldInfoProvider {
@@ -124,13 +148,13 @@ public abstract class ForgeWorldInfoProvider implements WorldInfoProvider {
@Override
public ChunksResult<ForgeChunkInfo> pollChunks() {
- ChunksResult<ForgeChunkInfo> data = new ChunksResult<>();
-
ClientLevel level = this.client.level;
if (level == null) {
return null;
}
+ ChunksResult<ForgeChunkInfo> data = new ChunksResult<>();
+
TransientEntitySectionManager<Entity> entityManager = level.entityStorage;
EntitySectionStorage<Entity> cache = entityManager.sectionStorage;
@@ -139,6 +163,32 @@ public abstract class ForgeWorldInfoProvider implements WorldInfoProvider {
return data;
}
+
+ @Override
+ public GameRulesResult pollGameRules() {
+ ClientLevel level = this.client.level;
+ if (level == null) {
+ return null;
+ }
+
+ GameRulesResult data = new GameRulesResult();
+
+ String levelName = level.dimension().location().getPath();
+ GameRules levelRules = level.getGameRules();
+
+ GameRules.visitGameRuleTypes(new GameRules.GameRuleTypeVisitor() {
+ @Override
+ public <T extends GameRules.Value<T>> void visit(GameRules.Key<T> key, GameRules.Type<T> type) {
+ String defaultValue = type.createRule().serialize();
+ data.putDefault(key.getId(), defaultValue);
+
+ String value = levelRules.getRule(key).serialize();
+ data.put(key.getId(), levelName, value);
+ }
+ });
+
+ return data;
+ }
}
static final class ForgeChunkInfo extends AbstractChunkInfo<EntityType<?>> {
diff --git a/spark-neoforge/src/main/java/me/lucko/spark/neoforge/NeoForgeWorldInfoProvider.java b/spark-neoforge/src/main/java/me/lucko/spark/neoforge/NeoForgeWorldInfoProvider.java
index ef76646..fe6a6c8 100644
--- a/spark-neoforge/src/main/java/me/lucko/spark/neoforge/NeoForgeWorldInfoProvider.java
+++ b/spark-neoforge/src/main/java/me/lucko/spark/neoforge/NeoForgeWorldInfoProvider.java
@@ -32,6 +32,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.GameRules;
import net.minecraft.world.level.entity.EntityLookup;
import net.minecraft.world.level.entity.EntitySection;
import net.minecraft.world.level.entity.EntitySectionStorage;
@@ -97,6 +98,29 @@ public abstract class NeoForgeWorldInfoProvider implements WorldInfoProvider {
return data;
}
+
+ @Override
+ public GameRulesResult pollGameRules() {
+ GameRulesResult data = new GameRulesResult();
+ Iterable<ServerLevel> levels = this.server.getAllLevels();
+
+ GameRules.visitGameRuleTypes(new GameRules.GameRuleTypeVisitor() {
+ @Override
+ public <T extends GameRules.Value<T>> void visit(GameRules.Key<T> key, GameRules.Type<T> type) {
+ String defaultValue = type.createRule().serialize();
+ data.putDefault(key.getId(), defaultValue);
+
+ for (ServerLevel level : levels) {
+ String levelName = level.dimension().location().getPath();
+
+ String value = level.getGameRules().getRule(key).serialize();
+ data.put(key.getId(), levelName, value);
+ }
+ }
+ });
+
+ return data;
+ }
}
public static final class Client extends NeoForgeWorldInfoProvider {
@@ -124,13 +148,13 @@ public abstract class NeoForgeWorldInfoProvider implements WorldInfoProvider {
@Override
public ChunksResult<ForgeChunkInfo> pollChunks() {
- ChunksResult<ForgeChunkInfo> data = new ChunksResult<>();
-
ClientLevel level = this.client.level;
if (level == null) {
return null;
}
+ ChunksResult<ForgeChunkInfo> data = new ChunksResult<>();
+
TransientEntitySectionManager<Entity> entityManager = level.entityStorage;
EntitySectionStorage<Entity> cache = entityManager.sectionStorage;
@@ -139,6 +163,32 @@ public abstract class NeoForgeWorldInfoProvider implements WorldInfoProvider {
return data;
}
+
+ @Override
+ public GameRulesResult pollGameRules() {
+ ClientLevel level = this.client.level;
+ if (level == null) {
+ return null;
+ }
+
+ GameRulesResult data = new GameRulesResult();
+
+ String levelName = level.dimension().location().getPath();
+ GameRules levelRules = level.getGameRules();
+
+ GameRules.visitGameRuleTypes(new GameRules.GameRuleTypeVisitor() {
+ @Override
+ public <T extends GameRules.Value<T>> void visit(GameRules.Key<T> key, GameRules.Type<T> type) {
+ String defaultValue = type.createRule().serialize();
+ data.putDefault(key.getId(), defaultValue);
+
+ String value = levelRules.getRule(key).serialize();
+ data.put(key.getId(), levelName, value);
+ }
+ });
+
+ return data;
+ }
}
public static final class ForgeChunkInfo extends AbstractChunkInfo<EntityType<?>> {
diff --git a/spark-paper/src/main/java/me/lucko/spark/paper/PaperSparkPlugin.java b/spark-paper/src/main/java/me/lucko/spark/paper/PaperSparkPlugin.java
index eb595cc..eb82f8e 100644
--- a/spark-paper/src/main/java/me/lucko/spark/paper/PaperSparkPlugin.java
+++ b/spark-paper/src/main/java/me/lucko/spark/paper/PaperSparkPlugin.java
@@ -39,7 +39,6 @@ import me.lucko.spark.paper.api.PaperSparkModule;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
-import org.bukkit.plugin.ServicePriority;
import java.nio.file.Path;
import java.util.Arrays;
diff --git a/spark-paper/src/main/java/me/lucko/spark/paper/PaperWorldInfoProvider.java b/spark-paper/src/main/java/me/lucko/spark/paper/PaperWorldInfoProvider.java
index 29ab1ef..feda9a0 100644
--- a/spark-paper/src/main/java/me/lucko/spark/paper/PaperWorldInfoProvider.java
+++ b/spark-paper/src/main/java/me/lucko/spark/paper/PaperWorldInfoProvider.java
@@ -24,6 +24,7 @@ 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 org.bukkit.Chunk;
+import org.bukkit.GameRule;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.entity.Entity;
@@ -31,6 +32,7 @@ import org.bukkit.entity.EntityType;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
public class PaperWorldInfoProvider implements WorldInfoProvider {
private final Server server;
@@ -75,6 +77,33 @@ public class PaperWorldInfoProvider implements WorldInfoProvider {
return data;
}
+ @Override
+ public GameRulesResult pollGameRules() {
+ GameRulesResult data = new GameRulesResult();
+
+ boolean addDefaults = true; // add defaults in the first iteration
+ for (World world : this.server.getWorlds()) {
+ for (String gameRule : world.getGameRules()) {
+ GameRule<?> ruleObj = GameRule.getByName(gameRule);
+ if (ruleObj == null) {
+ continue;
+ }
+
+ if (addDefaults) {
+ Object defaultValue = world.getGameRuleDefault(ruleObj);
+ data.putDefault(gameRule, Objects.toString(defaultValue));
+ }
+
+ Object value = world.getGameRuleValue(ruleObj);
+ data.put(gameRule, world.getName(), Objects.toString(value));
+ }
+
+ addDefaults = false;
+ }
+
+ return data;
+ }
+
static final class PaperChunkInfo extends AbstractChunkInfo<EntityType> {
private final CountMap<EntityType> entityCounts;
diff --git a/spark-sponge7/src/main/java/me/lucko/spark/sponge/Sponge7WorldInfoProvider.java b/spark-sponge7/src/main/java/me/lucko/spark/sponge/Sponge7WorldInfoProvider.java
index 8c2e412..426ad47 100644
--- a/spark-sponge7/src/main/java/me/lucko/spark/sponge/Sponge7WorldInfoProvider.java
+++ b/spark-sponge7/src/main/java/me/lucko/spark/sponge/Sponge7WorldInfoProvider.java
@@ -34,6 +34,7 @@ import org.spongepowered.api.world.World;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
public class Sponge7WorldInfoProvider implements WorldInfoProvider {
private final Server server;
@@ -76,6 +77,21 @@ public class Sponge7WorldInfoProvider implements WorldInfoProvider {
return data;
}
+ @Override
+ public GameRulesResult pollGameRules() {
+ // No way to get defaults info on sponge API 7 :(
+
+ // GameRulesResult data = new GameRulesResult();
+ // for (World world : this.server.getWorlds()) {
+ // for (Map.Entry<String, String> entry : world.getGameRules().entrySet()) {
+ // data.put(entry.getKey(), world.getName(), entry.getValue());
+ // }
+ // }
+ // return data;
+
+ return null;
+ }
+
static final class Sponge7ChunkInfo extends AbstractChunkInfo<EntityType> {
private final CountMap<EntityType> entityCounts;
diff --git a/spark-sponge8/src/main/java/me/lucko/spark/sponge/Sponge8WorldInfoProvider.java b/spark-sponge8/src/main/java/me/lucko/spark/sponge/Sponge8WorldInfoProvider.java
index fadd629..58f9c33 100644
--- a/spark-sponge8/src/main/java/me/lucko/spark/sponge/Sponge8WorldInfoProvider.java
+++ b/spark-sponge8/src/main/java/me/lucko/spark/sponge/Sponge8WorldInfoProvider.java
@@ -30,11 +30,14 @@ import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.entity.EntityType;
import org.spongepowered.api.entity.EntityTypes;
import org.spongepowered.api.world.chunk.WorldChunk;
+import org.spongepowered.api.world.gamerule.GameRule;
+import org.spongepowered.api.world.gamerule.GameRules;
import org.spongepowered.api.world.server.ServerWorld;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.stream.Collectors;
public class Sponge8WorldInfoProvider implements WorldInfoProvider {
private final Server server;
@@ -77,6 +80,21 @@ public class Sponge8WorldInfoProvider implements WorldInfoProvider {
return data;
}
+ @Override
+ public GameRulesResult pollGameRules() {
+ GameRulesResult data = new GameRulesResult();
+
+ List<GameRule<?>> rules = GameRules.registry().stream().collect(Collectors.toList());
+ for (GameRule<?> rule : rules) {
+ data.putDefault(rule.name(), rule.defaultValue().toString());
+ for (ServerWorld world : this.server.worldManager().worlds()) {
+ data.put(rule.name(), world.key().value(), world.properties().gameRule(rule).toString());
+ }
+ }
+
+ return data;
+ }
+
static final class Sponge7ChunkInfo extends AbstractChunkInfo<EntityType<?>> {
private final CountMap<EntityType<?>> entityCounts;