add: per-world gamerules support for room.
This commit is contained in:
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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": {
|
||||||
|
|||||||
Reference in new issue
Block a user