add: per-world gamerules support for room.

This commit is contained in:
iceBear67 committed 2024-09-18 10:52:22 +08:00
1 parent 0db7b4d00b
commit f3fa16f6fc
4 files changed
+101 -2

No files matched your search

@@ -0,0 +1,29 @@
package io.ib67.sfcraft.mixin.server.subserver;
import com.mojang.brigadier.context.CommandContext;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.GameRuleCommand;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.world.GameRules;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(GameRuleCommand.class)
public abstract class GameRuleCommandMixin {
@Redirect(at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;getGameRules()Lnet/minecraft/world/GameRules;"), method = "executeSet")
private static GameRules sf$redirectSetForPerWorld(MinecraftServer instance, CommandContext<ServerCommandSource> context) {
return getGameRule(instance, context.getSource());
}
@Redirect(at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;getGameRules()Lnet/minecraft/world/GameRules;"), method = "executeQuery")
private static GameRules sf$redirectSetForPerWorld(MinecraftServer instance, ServerCommandSource context) {
return getGameRule(instance, context);
}
private static GameRules getGameRule(MinecraftServer instance, ServerCommandSource source) {
var world = source.getWorld();
if (world == null) return instance.getGameRules();
return world.getGameRules(); // this is same as Server#getGameRule since one GameRules is shared across multiple worlds in vanilla.
}
}
@@ -0,0 +1,57 @@
package io.ib67.sfcraft.mixin.server.subserver;
import com.llamalad7.mixinextras.sugar.Local;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import io.ib67.sfcraft.SFCraft;
import io.ib67.sfcraft.module.RoomModule;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.util.profiler.Profiler;
import net.minecraft.world.GameRules;
import net.minecraft.world.MutableWorldProperties;
import net.minecraft.world.World;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.level.LevelProperties;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.function.Supplier;
@Mixin(World.class)
public abstract class WorldMixin {
@Unique
private GameRules customGameRule;
@Inject(at = @At("TAIL"), method = "<init>")
private void sf$initCustomGameRule(MutableWorldProperties properties,
RegistryKey<World> registryRef,
DynamicRegistryManager registryManager,
RegistryEntry<DimensionType> dimensionEntry,
Supplier<Profiler> profiler,
boolean isClient,
boolean debugWorld,
long biomeAccess,
int maxChainedNeighborUpdates, CallbackInfo ci) {
var id = registryRef.getValue();
if (id.getNamespace().equals("sfcraft")) { // room
customGameRule = SFCraft.getInjector().getInstance(RoomModule.class).readGameRuleForRoom(id);
} else {
customGameRule = properties.getGameRules();
}
}
/**
* @reason for per-world rules
* @author icybear
*/
@Overwrite
public GameRules getGameRules() {
return customGameRule;
}
}
@@ -30,6 +30,7 @@ import net.minecraft.util.Pair;
import net.minecraft.util.Unit; import net.minecraft.util.Unit;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.GameRules;
import net.minecraft.world.World; import net.minecraft.world.World;
import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
@@ -59,6 +60,7 @@ public class RoomModule extends ServerModule {
private Key key; private Key key;
private final List<Pair<RegistryKey<World>, BlockPos>> pregenQueue = new ArrayList<>(); private final List<Pair<RegistryKey<World>, BlockPos>> pregenQueue = new ArrayList<>();
private final Map<UUID, GameProfile> uuidMapper = new ConcurrentHashMap<>(); private final Map<UUID, GameProfile> uuidMapper = new ConcurrentHashMap<>();
private final Map<Identifier, GameRules> gameRulesPerRoom = new HashMap<>();
@Override @Override
public void onInitialize() { public void onInitialize() {
@@ -78,6 +80,11 @@ public class RoomModule extends ServerModule {
} }
} }
@Override
public void onDisable() {
//todo persistence of gameRulesPerRoom
}
private void registerCommand(CommandDispatcher<ServerCommandSource> serverCommandSourceCommandDispatcher, CommandRegistryAccess commandRegistryAccess, CommandManager.RegistrationEnvironment registrationEnvironment) { private void registerCommand(CommandDispatcher<ServerCommandSource> serverCommandSourceCommandDispatcher, CommandRegistryAccess commandRegistryAccess, CommandManager.RegistrationEnvironment registrationEnvironment) {
serverCommandSourceCommandDispatcher.register( serverCommandSourceCommandDispatcher.register(
LiteralArgumentBuilder.<ServerCommandSource>literal("reco") LiteralArgumentBuilder.<ServerCommandSource>literal("reco")
@@ -100,14 +107,14 @@ public class RoomModule extends ServerModule {
} }
@SneakyThrows @SneakyThrows
public byte[] encrypt(byte[] b) { byte[] encrypt(byte[] b) {
var cipher = Cipher.getInstance("AES"); var cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key); cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(b); return cipher.doFinal(b);
} }
@SneakyThrows @SneakyThrows
public byte[] decrypt(byte[] b) { byte[] decrypt(byte[] b) {
var cipher = Cipher.getInstance("AES"); var cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key); cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(b); return cipher.doFinal(b);
@@ -176,4 +183,8 @@ public class RoomModule extends ServerModule {
public GameProfile devirtualize(UUID virtual) { public GameProfile devirtualize(UUID virtual) {
return uuidMapper.get(virtual); return uuidMapper.get(virtual);
} }
public GameRules readGameRuleForRoom(Identifier identifier){
return gameRulesPerRoom.computeIfAbsent(identifier, k -> new GameRules());
}
} }
+2
View File
@@ -34,6 +34,8 @@
"server.subserver.PlayerSaveHandlerMixin", "server.subserver.PlayerSaveHandlerMixin",
"server.subserver.ServerPlayerEntityMixin", "server.subserver.ServerPlayerEntityMixin",
"server.subserver.PlayerListS2CPacket$EntryMixin", "server.subserver.PlayerListS2CPacket$EntryMixin",
"server.subserver.WorldMixin",
"server.subserver.GameRuleCommandMixin",
"server.optimize.LivingEntityMixin" "server.optimize.LivingEntityMixin"
], ],
"injectors": { "injectors": {