Skip to content

Commit

Permalink
Include gamerule settings in metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
lucko committed Jul 20, 2024
1 parent c0ffb19 commit ac36661
Show file tree
Hide file tree
Showing 12 changed files with 237 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
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;
Expand All @@ -32,6 +33,7 @@

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;
Expand Down Expand Up @@ -110,6 +112,22 @@ public ChunksResult<BukkitChunkInfo> pollChunks() {
return data;
}

@Override
public GameRulesResult pollGameRules() {
GameRulesResult data = new GameRulesResult();
for (World world : this.server.getWorlds()) {
for (String gameRule : world.getGameRules()) {
GameRule<?> ruleObj = GameRule.getByName(gameRule);
if (ruleObj == null) {
continue;
}
Object value = world.getGameRuleValue(ruleObj);
data.put(world.getName(), gameRule, Objects.toString(value));
}
}
return data;
}

static final class BukkitChunkInfo extends AbstractChunkInfo<EntityType> {
private final CountMap<EntityType> entityCounts;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,19 @@ public CompletableFuture<WorldInfoProvider.ChunksResult<? extends ChunkInfo<?>>>
return async(WorldInfoProvider::pollChunks);
}

public CompletableFuture<WorldInfoProvider.GameRulesResult> pollGameRules() {
return async(WorldInfoProvider::pollGameRules);
}

public WorldInfoProvider.CountsResult getCounts() {
return get(pollCounts());
}

public WorldInfoProvider.ChunksResult<? extends ChunkInfo<?>> getChunks() {
return get(pollChunks());
}

public WorldInfoProvider.GameRulesResult getGameRules() {
return get(pollGameRules());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ public CountsResult pollCounts() {
public ChunksResult<? extends ChunkInfo<?>> pollChunks() {
return null;
}

@Override
public GameRulesResult pollGameRules() {
return null;
}
};

/**
Expand All @@ -55,6 +60,13 @@ public ChunksResult<? extends ChunkInfo<?>> pollChunks() {
*/
ChunksResult<? extends ChunkInfo<?>> pollChunks();

/**
* Polls for game rules.
*
* @return the game rules
*/
GameRulesResult pollGameRules();

default boolean mustCallSync() {
return true;
}
Expand Down Expand Up @@ -101,4 +113,17 @@ public int chunks() {
}
}

final class GameRulesResult {
// game rule --> world name --> value
private final Map<String, Map<String, String>> rules = new HashMap<>();

public void put(String worldName, String gameRuleName, String value) {
this.rules.computeIfAbsent(gameRuleName, k -> new HashMap<>()).put(worldName, value);
}

public Map<String, Map<String, String>> getRules() {
return this.rules;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public WorldStatisticsProvider(AsyncWorldInfoProvider provider) {
}

public WorldStatistics getWorldStatistics() {
WorldInfoProvider.ChunksResult<? extends ChunkInfo<?>> result = provider.getChunks();
WorldInfoProvider.ChunksResult<? extends ChunkInfo<?>> result = this.provider.getChunks();
if (result == null) {
return null;
}
Expand Down Expand Up @@ -70,6 +70,16 @@ public WorldStatistics getWorldStatistics() {
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, worldValues) -> {
WorldStatistics.GameRule.Builder builder = WorldStatistics.GameRule.newBuilder();
builder.setName(ruleName);
worldValues.forEach(builder::putWorldValues);
stats.addGameRules(builder.build());
});
}

return stats.build();
}

Expand Down
6 changes: 6 additions & 0 deletions spark-common/src/main/proto/spark/spark.proto
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -158,6 +159,11 @@ message WorldStatistics {
int32 total_entities = 3;
map<string, int32> entity_counts = 4;
}

message GameRule {
string name = 1;
map<string, string> world_values = 2;
}
}

message WindowStatistics {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
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;
Expand Down Expand Up @@ -101,6 +102,23 @@ public ChunksResult<FabricChunkInfo> pollChunks() {

return data;
}

@Override
public GameRulesResult pollGameRules() {
GameRulesResult data = new GameRulesResult();
for (ServerWorld world : this.server.getWorlds()) {
String worldName = world.getRegistryKey().getValue().getPath();
GameRules gameRules = 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 value = gameRules.get(key).serialize();
data.put(worldName, key.getName(), value);
}
});
}
return data;
}
}

public static final class Client extends FabricWorldInfoProvider {
Expand Down Expand Up @@ -128,13 +146,13 @@ public CountsResult pollCounts() {

@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();

Expand All @@ -143,6 +161,28 @@ public ChunksResult<FabricChunkInfo> pollChunks() {

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 gameRules = 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 value = gameRules.get(key).serialize();
data.put(worldName, key.getName(), value);
}
});

return data;
}
}

static final class FabricChunkInfo extends AbstractChunkInfo<EntityType<?>> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
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;
Expand Down Expand Up @@ -97,6 +98,23 @@ public ChunksResult<ForgeChunkInfo> pollChunks() {

return data;
}

@Override
public GameRulesResult pollGameRules() {
GameRulesResult data = new GameRulesResult();
for (ServerLevel level : this.server.getAllLevels()) {
String levelName = level.dimension().location().getPath();
GameRules gameRules = 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 value = gameRules.getRule(key).serialize();
data.put(levelName, key.getId(), value);
}
});
}
return data;
}
}

public static final class Client extends ForgeWorldInfoProvider {
Expand Down Expand Up @@ -124,13 +142,13 @@ public CountsResult pollCounts() {

@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;

Expand All @@ -139,6 +157,28 @@ public ChunksResult<ForgeChunkInfo> pollChunks() {

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 gameRules = 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 value = gameRules.getRule(key).serialize();
data.put(levelName, key.getId(), value);
}
});

return data;
}
}

static final class ForgeChunkInfo extends AbstractChunkInfo<EntityType<?>> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
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;
Expand Down Expand Up @@ -97,6 +98,23 @@ public ChunksResult<ForgeChunkInfo> pollChunks() {

return data;
}

@Override
public GameRulesResult pollGameRules() {
GameRulesResult data = new GameRulesResult();
for (ServerLevel level : this.server.getAllLevels()) {
String levelName = level.dimension().location().getPath();
GameRules gameRules = 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 value = gameRules.getRule(key).serialize();
data.put(levelName, key.getId(), value);
}
});
}
return data;
}
}

public static final class Client extends NeoForgeWorldInfoProvider {
Expand Down Expand Up @@ -124,13 +142,13 @@ public CountsResult pollCounts() {

@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;

Expand All @@ -139,6 +157,28 @@ public ChunksResult<ForgeChunkInfo> pollChunks() {

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 gameRules = 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 value = gameRules.getRule(key).serialize();
data.put(levelName, key.getId(), value);
}
});

return data;
}
}

public static final class ForgeChunkInfo extends AbstractChunkInfo<EntityType<?>> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
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;
Expand Down
Loading

0 comments on commit ac36661

Please sign in to comment.