mirror of
https://github.com/lucko/LuckPerms.git
synced 2025-09-02 19:02:33 +02:00
Update to Minecraft 1.21.6
This commit is contained in:
@@ -39,7 +39,6 @@ import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
|
@@ -28,7 +28,6 @@ package me.lucko.luckperms.common.sender;
|
||||
import com.google.common.collect.Iterables;
|
||||
import me.lucko.luckperms.common.command.access.CommandPermission;
|
||||
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||
import me.lucko.luckperms.common.config.generic.key.ConfigKey;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.JoinConfiguration;
|
||||
|
@@ -25,9 +25,9 @@
|
||||
|
||||
package me.lucko.luckperms.common.sender;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import me.lucko.luckperms.common.locale.Message;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
@@ -13,8 +13,8 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
// https://modmuss50.me/fabric.html
|
||||
minecraft 'com.mojang:minecraft:1.21.5'
|
||||
mappings 'net.fabricmc:yarn:1.21.5+build.1:v2'
|
||||
minecraft 'com.mojang:minecraft:1.21.6'
|
||||
mappings 'net.fabricmc:yarn:1.21.6+build.1:v2'
|
||||
modImplementation 'net.fabricmc:fabric-loader:0.16.14'
|
||||
|
||||
Set<String> apiModules = [
|
||||
@@ -26,10 +26,10 @@ dependencies {
|
||||
]
|
||||
|
||||
apiModules.forEach {
|
||||
modImplementation(fabricApi.module(it, '0.123.0+1.21.5'))
|
||||
modImplementation(fabricApi.module(it, '0.127.0+1.21.6'))
|
||||
}
|
||||
|
||||
include(modImplementation('me.lucko:fabric-permissions-api:0.3.3'))
|
||||
include(modImplementation('me.lucko:fabric-permissions-api:0.4.0'))
|
||||
|
||||
implementation project(':common')
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
package me.lucko.luckperms.fabric;
|
||||
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import me.lucko.fabric.api.permissions.v0.Permissions;
|
||||
import me.lucko.luckperms.common.locale.TranslationManager;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
@@ -39,6 +40,7 @@ import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.rcon.RconCommandOutput;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TextCodecs;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
@@ -118,6 +120,9 @@ public class FabricSenderFactory extends SenderFactory<LPFabricPlugin, ServerCom
|
||||
}
|
||||
|
||||
public static Text toNativeText(Component component) {
|
||||
return Text.Serialization.fromJsonTree(GsonComponentSerializer.gson().serializeToTree(component), DynamicRegistryManager.EMPTY);
|
||||
return TextCodecs.CODEC.decode(
|
||||
DynamicRegistryManager.EMPTY.getOps(JsonOps.INSTANCE),
|
||||
GsonComponentSerializer.gson().serializeToTree(component)
|
||||
).getOrThrow(IllegalArgumentException::new).getFirst();
|
||||
}
|
||||
}
|
||||
|
@@ -78,7 +78,7 @@ public class FabricPlayerCalculator implements ContextCalculator<ServerPlayerEnt
|
||||
}
|
||||
|
||||
// TODO: figure out dimension type context too
|
||||
ServerWorld world = target.getServerWorld();
|
||||
ServerWorld world = target.getWorld();
|
||||
if (this.world) {
|
||||
this.plugin.getConfiguration().get(ConfigKeys.WORLD_REWRITES).rewriteAndSubmit(getContextKey(world.getRegistryKey().getValue()), consumer);
|
||||
}
|
||||
|
@@ -35,9 +35,7 @@ import me.lucko.luckperms.fabric.model.MixinUser;
|
||||
import net.luckperms.api.query.QueryOptions;
|
||||
import net.luckperms.api.util.Tristate;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
@@ -63,9 +61,6 @@ public abstract class ServerPlayerEntityMixin implements MixinUser {
|
||||
@Unique
|
||||
private QueryOptionsSupplier luckperms$queryOptions;
|
||||
|
||||
// Used by PlayerChangeWorldCallback hook below.
|
||||
@Shadow public abstract ServerWorld getServerWorld();
|
||||
|
||||
@Override
|
||||
public User luckperms$getUser() {
|
||||
return this.luckperms$user;
|
||||
|
@@ -18,6 +18,7 @@ minecraft {
|
||||
|
||||
dependencies {
|
||||
minecraft "net.minecraftforge:forge:${minecraftVersion}-${forgeVersion}"
|
||||
annotationProcessor 'net.minecraftforge:eventbus-validator:7.0-beta.7'
|
||||
implementation project(':common')
|
||||
compileOnly project(':common:loader-utils')
|
||||
compileOnly project(':forge:forge-api')
|
||||
|
@@ -1,2 +1,2 @@
|
||||
minecraftVersion=1.21.5
|
||||
forgeVersion=55.0.12
|
||||
minecraftVersion=1.21.6
|
||||
forgeVersion=56.0.3
|
@@ -29,16 +29,14 @@ import me.lucko.luckperms.common.loader.JarInJarClassLoader;
|
||||
import me.lucko.luckperms.common.loader.LoaderBootstrap;
|
||||
import net.minecraftforge.fml.IExtensionPoint;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLModContainer;
|
||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mod(value = "luckperms")
|
||||
@@ -48,15 +46,14 @@ public class ForgeLoaderPlugin implements Supplier<ModContainer> {
|
||||
private static final String JAR_NAME = "luckperms-forge.jarinjar";
|
||||
private static final String BOOTSTRAP_CLASS = "me.lucko.luckperms.forge.LPForgeBootstrap";
|
||||
|
||||
private final ModContainer container;
|
||||
private final FMLModContainer container;
|
||||
|
||||
private JarInJarClassLoader loader;
|
||||
private LoaderBootstrap plugin;
|
||||
|
||||
public ForgeLoaderPlugin() {
|
||||
this.container = ModList.get().getModContainerByObject(this).orElse(null);
|
||||
|
||||
markAsNotRequiredClientSide();
|
||||
public ForgeLoaderPlugin(FMLJavaModLoadingContext ctx) {
|
||||
this.container = ctx.getContainer();
|
||||
ctx.registerDisplayTest(IExtensionPoint.DisplayTest.IGNORE_SERVER_VERSION);
|
||||
|
||||
if (FMLEnvironment.dist.isClient()) {
|
||||
LOGGER.info("Skipping LuckPerms init (not supported on the client!)");
|
||||
@@ -64,7 +61,7 @@ public class ForgeLoaderPlugin implements Supplier<ModContainer> {
|
||||
}
|
||||
|
||||
this.loader = new JarInJarClassLoader(getClass().getClassLoader(), JAR_NAME);
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onCommonSetup);
|
||||
FMLCommonSetupEvent.getBus(ctx.getModBusGroup()).addListener(this::onCommonSetup);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -77,21 +74,4 @@ public class ForgeLoaderPlugin implements Supplier<ModContainer> {
|
||||
this.plugin.onLoad();
|
||||
}
|
||||
|
||||
private static void markAsNotRequiredClientSide() {
|
||||
try {
|
||||
// workaround as we don't compile against java 17
|
||||
ModLoadingContext.class.getDeclaredMethod("registerExtensionPoint", Class.class, Supplier.class)
|
||||
.invoke(
|
||||
ModLoadingContext.get(),
|
||||
IExtensionPoint.DisplayTest.class,
|
||||
(Supplier<?>) () -> new IExtensionPoint.DisplayTest(
|
||||
() -> IExtensionPoint.DisplayTest.IGNORESERVERONLY,
|
||||
(a, b) -> true
|
||||
)
|
||||
);
|
||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -37,7 +37,7 @@ import net.minecraft.commands.Commands;
|
||||
import net.minecraft.commands.arguments.EntityArgument;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraftforge.event.RegisterCommandsEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
@@ -26,6 +26,7 @@
|
||||
package me.lucko.luckperms.forge;
|
||||
|
||||
import com.mojang.brigadier.ParseResults;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
|
||||
import me.lucko.luckperms.common.locale.TranslationManager;
|
||||
import me.lucko.luckperms.common.query.QueryOptionsImpl;
|
||||
@@ -41,7 +42,7 @@ import net.luckperms.api.util.Tristate;
|
||||
import net.minecraft.commands.CommandSource;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.network.chat.Component.Serializer;
|
||||
import net.minecraft.network.chat.ComponentSerialization;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.rcon.RconConsoleSource;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
@@ -118,7 +119,10 @@ public class ForgeSenderFactory extends SenderFactory<LPForgePlugin, CommandSour
|
||||
}
|
||||
|
||||
public static net.minecraft.network.chat.Component toNativeText(Component component) {
|
||||
return Serializer.fromJson(GsonComponentSerializer.gson().serializeToTree(component), RegistryAccess.EMPTY);
|
||||
return ComponentSerialization.CODEC.decode(
|
||||
RegistryAccess.EMPTY.createSerializationContext(JsonOps.INSTANCE),
|
||||
GsonComponentSerializer.gson().serializeToTree(component)
|
||||
).getOrThrow(IllegalArgumentException::new).getFirst();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -34,15 +34,16 @@ import me.lucko.luckperms.common.plugin.classpath.JarInJarClassPathAppender;
|
||||
import me.lucko.luckperms.common.plugin.logging.Log4jPluginLogger;
|
||||
import me.lucko.luckperms.common.plugin.logging.PluginLogger;
|
||||
import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter;
|
||||
import me.lucko.luckperms.forge.util.ForgeEventBusFacade;
|
||||
import net.luckperms.api.platform.Platform;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.players.PlayerList;
|
||||
import net.minecraftforge.event.server.ServerAboutToStartEvent;
|
||||
import net.minecraftforge.event.server.ServerStoppingEvent;
|
||||
import net.minecraftforge.eventbus.api.EventPriority;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.eventbus.api.bus.BusGroup;
|
||||
import net.minecraftforge.eventbus.api.listener.EventListener;
|
||||
import net.minecraftforge.eventbus.api.listener.Priority;
|
||||
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.loading.FMLPaths;
|
||||
@@ -50,6 +51,7 @@ import net.minecraftforge.forgespi.language.IModInfo;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.maven.artifact.versioning.ArtifactVersion;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
@@ -88,9 +90,9 @@ public final class LPForgeBootstrap implements LuckPermsBootstrap, LoaderBootstr
|
||||
private final ClassPathAppender classPathAppender;
|
||||
|
||||
/**
|
||||
* A facade for the forge event bus, compatible with LP's jar-in-jar packaging
|
||||
* A list of all event listerners registered by the plugin.
|
||||
*/
|
||||
private final ForgeEventBusFacade forgeEventBus;
|
||||
private final List<EventListener> listeners = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The plugin instance
|
||||
@@ -116,7 +118,6 @@ public final class LPForgeBootstrap implements LuckPermsBootstrap, LoaderBootstr
|
||||
this.logger = new Log4jPluginLogger(LogManager.getLogger(LPForgeBootstrap.ID));
|
||||
this.schedulerAdapter = new ForgeSchedulerAdapter(this);
|
||||
this.classPathAppender = new JarInJarClassPathAppender(getClass().getClassLoader());
|
||||
this.forgeEventBus = new ForgeEventBusFacade();
|
||||
this.plugin = new LPForgePlugin(this);
|
||||
}
|
||||
|
||||
@@ -143,7 +144,16 @@ public final class LPForgeBootstrap implements LuckPermsBootstrap, LoaderBootstr
|
||||
}
|
||||
|
||||
public void registerListeners(Object target) {
|
||||
this.forgeEventBus.register(target);
|
||||
Collection<EventListener> listeners = BusGroup.DEFAULT.register(MethodHandles.lookup(), target);
|
||||
this.listeners.addAll(listeners);
|
||||
}
|
||||
|
||||
public void unregisterListeners() {
|
||||
if (this.listeners.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
BusGroup.DEFAULT.unregister(this.listeners);
|
||||
this.listeners.clear();
|
||||
}
|
||||
|
||||
// lifecycle
|
||||
@@ -157,11 +167,11 @@ public final class LPForgeBootstrap implements LuckPermsBootstrap, LoaderBootstr
|
||||
this.loadLatch.countDown();
|
||||
}
|
||||
|
||||
this.forgeEventBus.register(this);
|
||||
registerListeners(this);
|
||||
this.plugin.registerEarlyListeners();
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||
@SubscribeEvent(priority = Priority.HIGHEST)
|
||||
public void onServerAboutToStart(ServerAboutToStartEvent event) {
|
||||
this.server = event.getServer();
|
||||
try {
|
||||
@@ -171,10 +181,10 @@ public final class LPForgeBootstrap implements LuckPermsBootstrap, LoaderBootstr
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||
@SubscribeEvent(priority = Priority.LOWEST)
|
||||
public void onServerStopping(ServerStoppingEvent event) {
|
||||
this.plugin.disable();
|
||||
this.forgeEventBus.unregisterAll();
|
||||
unregisterListeners();
|
||||
this.server = null;
|
||||
}
|
||||
|
||||
|
@@ -36,7 +36,7 @@ import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.event.AttachCapabilitiesEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
@@ -42,7 +42,7 @@ import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.GameType;
|
||||
import net.minecraft.world.level.storage.ServerLevelData;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import java.util.Set;
|
||||
@@ -68,7 +68,7 @@ public class ForgePlayerCalculator implements ContextCalculator<ServerPlayer> {
|
||||
|
||||
@Override
|
||||
public void calculate(@NonNull ServerPlayer target, @NonNull ContextConsumer consumer) {
|
||||
ServerLevel level = target.serverLevel();
|
||||
ServerLevel level = target.level();
|
||||
if (this.dimensionType) {
|
||||
consumer.accept(DefaultContextKeys.DIMENSION_TYPE_KEY, getContextKey(level.dimension().location()));
|
||||
}
|
||||
|
@@ -45,8 +45,8 @@ import net.minecraft.server.network.ServerConfigurationPacketListenerImpl;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedInEvent;
|
||||
import net.minecraftforge.event.network.GatherLoginConfigurationTasksEvent;
|
||||
import net.minecraftforge.eventbus.api.EventPriority;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.eventbus.api.listener.Priority;
|
||||
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -117,7 +117,7 @@ public class ForgeConnectionListener extends AbstractConnectionListener {
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||
@SubscribeEvent(priority = Priority.HIGHEST)
|
||||
public void onPlayerLoggedIn(PlayerLoggedInEvent event) {
|
||||
ServerPlayer player = (ServerPlayer) event.getEntity();
|
||||
GameProfile profile = player.getGameProfile();
|
||||
@@ -152,7 +152,7 @@ public class ForgeConnectionListener extends AbstractConnectionListener {
|
||||
this.plugin.getContextManager().signalContextUpdate(player);
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||
@SubscribeEvent(priority = Priority.LOWEST)
|
||||
public void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) {
|
||||
ServerPlayer player = (ServerPlayer) event.getEntity();
|
||||
handleDisconnect(player.getGameProfile().getId());
|
||||
|
@@ -38,7 +38,7 @@ import net.minecraft.server.players.ServerOpList;
|
||||
import net.minecraftforge.event.AddReloadListenerEvent;
|
||||
import net.minecraftforge.event.CommandEvent;
|
||||
import net.minecraftforge.event.server.ServerStartedEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
@@ -51,7 +51,7 @@ public class ForgePlatformListener {
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onCommand(CommandEvent event) {
|
||||
public boolean onCommand(CommandEvent event) {
|
||||
CommandContextBuilder<CommandSourceStack> context = event.getParseResults().getContext();
|
||||
|
||||
if (!this.plugin.getConfiguration().get(ConfigKeys.OPS_ENABLED)) {
|
||||
@@ -63,11 +63,12 @@ public class ForgePlatformListener {
|
||||
String name = node.getNode().getName().toLowerCase(Locale.ROOT);
|
||||
if (name.equals("op") || name.equals("deop")) {
|
||||
Message.OP_DISABLED.send(this.plugin.getSenderFactory().wrap(context.getSource()));
|
||||
event.setCanceled(true);
|
||||
return;
|
||||
return true; // cancel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false; // don't cancel
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
@@ -29,7 +29,7 @@ import me.lucko.luckperms.common.command.access.CommandPermission;
|
||||
import me.lucko.luckperms.forge.LPForgePlugin;
|
||||
import net.minecraftforge.common.ForgeConfig;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
|
||||
import net.minecraftforge.server.permission.events.PermissionGatherEvent;
|
||||
import net.minecraftforge.server.permission.handler.DefaultPermissionHandler;
|
||||
import net.minecraftforge.server.permission.nodes.PermissionNode;
|
||||
|
@@ -1,264 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.forge.util;
|
||||
|
||||
import me.lucko.luckperms.common.loader.JarInJarClassLoader;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
import net.minecraftforge.eventbus.api.GenericEvent;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.eventbus.api.IGenericEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.event.IModBusEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.LambdaMetafactory;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* A utility for registering Forge listeners for methods in a jar-in-jar.
|
||||
*
|
||||
* <p>This differs from {@link IEventBus#register} as reflection is used for invoking the registered listeners
|
||||
* instead of ASM, which is incompatible with {@link JarInJarClassLoader}</p>
|
||||
*/
|
||||
public class ForgeEventBusFacade {
|
||||
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
|
||||
|
||||
private final List<ListenerRegistration> listeners = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Register listeners for all methods annotated with {@link SubscribeEvent} on the target object.
|
||||
*/
|
||||
public void register(Object target) {
|
||||
for (Method method : target.getClass().getMethods()) {
|
||||
// Ignore static methods, Support for these could be added, but they are not used in LuckPerms
|
||||
if (Modifier.isStatic(method.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Methods require a SubscribeEvent annotation in order to be registered
|
||||
SubscribeEvent subscribeEvent = method.getAnnotation(SubscribeEvent.class);
|
||||
if (subscribeEvent == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
EventType type = determineListenerType(method);
|
||||
Consumer<?> invoker = createInvokerFunction(method, target, type);
|
||||
|
||||
// Determine the 'IEventBus' that this eventType should be registered to.
|
||||
IEventBus eventBus;
|
||||
if (IModBusEvent.class.isAssignableFrom(type.eventType)) {
|
||||
eventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
} else {
|
||||
eventBus = MinecraftForge.EVENT_BUS;
|
||||
}
|
||||
|
||||
if (IGenericEvent.class.isAssignableFrom(type.eventType)) {
|
||||
addGenericListener(eventBus, type.genericType, subscribeEvent, type.eventType, invoker);
|
||||
} else {
|
||||
addListener(eventBus, subscribeEvent, type.eventType, invoker);
|
||||
}
|
||||
|
||||
this.listeners.add(new ListenerRegistration(invoker, eventBus, target));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister previously registered listeners on the target object.
|
||||
*
|
||||
* @param target the target listener
|
||||
*/
|
||||
public void unregister(Object target) {
|
||||
this.listeners.removeIf(listener -> {
|
||||
if (listener.target == target) {
|
||||
listener.close();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister all listeners created through this interface.
|
||||
*/
|
||||
public void unregisterAll() {
|
||||
for (ListenerRegistration listener : this.listeners) {
|
||||
listener.close();
|
||||
}
|
||||
this.listeners.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* A listener registration.
|
||||
*/
|
||||
private static final class ListenerRegistration implements AutoCloseable {
|
||||
/** The lambda invoker function */
|
||||
private final Consumer<?> invoker;
|
||||
/** The event bus that the invoker was registered to */
|
||||
private final IEventBus eventBus;
|
||||
/** The target listener class */
|
||||
private final Object target;
|
||||
|
||||
private ListenerRegistration(Consumer<?> invoker, IEventBus eventBus, Object target) {
|
||||
this.invoker = invoker;
|
||||
this.eventBus = eventBus;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
this.eventBus.unregister(this.invoker);
|
||||
}
|
||||
}
|
||||
|
||||
private static Consumer<?> createInvokerFunction(Method method, Object target, EventType type) {
|
||||
// Use the 'LambdaMetafactory' to generate a consumer which can be passed directly to an 'IEventBus'
|
||||
// when registering a listener, this reduces the overhead involved when reflectively invoking methods.
|
||||
try {
|
||||
MethodHandle methodHandle = LOOKUP.unreflect(method);
|
||||
CallSite callSite = LambdaMetafactory.metafactory(
|
||||
LOOKUP,
|
||||
"accept",
|
||||
MethodType.methodType(Consumer.class, target.getClass()),
|
||||
MethodType.methodType(void.class, Object.class),
|
||||
methodHandle,
|
||||
MethodType.methodType(void.class, type.eventType)
|
||||
);
|
||||
|
||||
return (Consumer<?>) callSite.getTarget().bindTo(target).invokeExact();
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException("Error whilst registering " + method, t);
|
||||
}
|
||||
}
|
||||
|
||||
public static EventType determineListenerType(Method method) {
|
||||
// Get the parameter types, this includes generic information which is required for GenericEvent
|
||||
Type[] parameterTypes = method.getGenericParameterTypes();
|
||||
if (parameterTypes.length != 1) {
|
||||
throw new IllegalArgumentException(""
|
||||
+ "Method " + method + " has @SubscribeEvent annotation. "
|
||||
+ "It has " + parameterTypes.length + " arguments, "
|
||||
+ "but event handler methods require a single argument only."
|
||||
);
|
||||
}
|
||||
|
||||
Type parameterType = parameterTypes[0];
|
||||
Class<?> eventType;
|
||||
Class<?> genericType;
|
||||
|
||||
if (parameterType instanceof Class) { // Non-generic event
|
||||
eventType = (Class<?>) parameterType;
|
||||
genericType = null;
|
||||
} else if (parameterType instanceof ParameterizedType) { // Generic event
|
||||
ParameterizedType parameterizedType = (ParameterizedType) parameterType;
|
||||
|
||||
// Get the event class
|
||||
Type rawType = parameterizedType.getRawType();
|
||||
if (rawType instanceof Class) {
|
||||
eventType = (Class<?>) rawType;
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Raw Type " + rawType.getClass() + " is not supported");
|
||||
}
|
||||
|
||||
// Find the type of 'T' in 'GenericEvent<T>'
|
||||
Type[] typeArguments = parameterizedType.getActualTypeArguments();
|
||||
if (typeArguments.length != 1) {
|
||||
throw new IllegalArgumentException(""
|
||||
+ "Method " + method + " has @SubscribeEvent annotation. "
|
||||
+ "It has a " + eventType + " argument, "
|
||||
+ "but generic events require a single type argument only."
|
||||
);
|
||||
}
|
||||
|
||||
// Get the generic class
|
||||
Type typeArgument = typeArguments[0];
|
||||
if (typeArgument instanceof Class<?>) {
|
||||
genericType = (Class<?>) typeArgument;
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Type Argument " + typeArgument.getClass() + " is not supported");
|
||||
}
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Parameter Type " + parameterType.getClass() + " is not supported");
|
||||
}
|
||||
|
||||
// Ensure 'genericType' is set if 'eventType' is a generic event
|
||||
if (GenericEvent.class.isAssignableFrom(eventType) && genericType == null) {
|
||||
throw new IllegalArgumentException(""
|
||||
+ "Method " + method + " has @SubscribeEvent annotation, "
|
||||
+ "but the generic argument type cannot be determined for "
|
||||
+ "for the GenericEvent subtype: " + eventType
|
||||
);
|
||||
}
|
||||
|
||||
// Ensure 'eventType' is a subclass of event
|
||||
if (!Event.class.isAssignableFrom(eventType)) {
|
||||
throw new IllegalArgumentException(""
|
||||
+ "Method " + method + " has @SubscribeEvent annotation, "
|
||||
+ "but takes an argument that is not an Event subtype: " + eventType
|
||||
);
|
||||
}
|
||||
|
||||
return new EventType(eventType, genericType);
|
||||
}
|
||||
|
||||
private static final class EventType {
|
||||
private final Class<?> eventType;
|
||||
private final Class<?> genericType;
|
||||
|
||||
private EventType(Class<?> eventType, Class<?> genericType) {
|
||||
this.eventType = eventType;
|
||||
this.genericType = genericType;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles casting generics for {@link IEventBus#addGenericListener}.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T extends GenericEvent<? extends F>, F> void addGenericListener(IEventBus eventBus, Class<?> genericClassFilter, SubscribeEvent annotation, Class<?> eventType, Consumer<?> consumer) {
|
||||
eventBus.addGenericListener((Class<F>) genericClassFilter, annotation.priority(), annotation.receiveCanceled(), (Class<T>) eventType, (Consumer<T>) consumer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles casting generics for {@link IEventBus#addListener}.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T extends Event> void addListener(IEventBus eventBus, SubscribeEvent annotation, Class<?> eventType, Consumer<?> consumer) {
|
||||
eventBus.addListener(annotation.priority(), annotation.receiveCanceled(), (Class<T>) eventType, (Consumer<T>) consumer);
|
||||
}
|
||||
|
||||
}
|
@@ -1,2 +1,2 @@
|
||||
minecraftVersion=1.21.5
|
||||
neoForgeVersion=21.5.63-beta
|
||||
minecraftVersion=1.21.6
|
||||
neoForgeVersion=21.6.5-beta
|
@@ -26,6 +26,7 @@
|
||||
package me.lucko.luckperms.neoforge;
|
||||
|
||||
import com.mojang.brigadier.ParseResults;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
|
||||
import me.lucko.luckperms.common.locale.TranslationManager;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
@@ -41,7 +42,7 @@ import net.luckperms.api.util.Tristate;
|
||||
import net.minecraft.commands.CommandSource;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.network.chat.Component.Serializer;
|
||||
import net.minecraft.network.chat.ComponentSerialization;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.rcon.RconConsoleSource;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
@@ -116,7 +117,10 @@ public class NeoForgeSenderFactory extends SenderFactory<LPNeoForgePlugin, Comma
|
||||
}
|
||||
|
||||
public static net.minecraft.network.chat.Component toNativeText(Component component) {
|
||||
return Serializer.fromJson(GsonComponentSerializer.gson().serializeToTree(component), RegistryAccess.EMPTY);
|
||||
return ComponentSerialization.CODEC.decode(
|
||||
RegistryAccess.EMPTY.createSerializationContext(JsonOps.INSTANCE),
|
||||
GsonComponentSerializer.gson().serializeToTree(component)
|
||||
).getOrThrow(IllegalArgumentException::new).getFirst();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -68,7 +68,7 @@ public class NeoForgePlayerCalculator implements ContextCalculator<ServerPlayer>
|
||||
|
||||
@Override
|
||||
public void calculate(@NonNull ServerPlayer target, @NonNull ContextConsumer consumer) {
|
||||
ServerLevel level = target.serverLevel();
|
||||
ServerLevel level = target.level();
|
||||
if (this.dimensionType) {
|
||||
consumer.accept(DefaultContextKeys.DIMENSION_TYPE_KEY, getContextKey(level.dimension().location()));
|
||||
}
|
||||
|
@@ -31,16 +31,13 @@ import me.lucko.luckperms.common.locale.TranslationManager;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.plugin.util.AbstractConnectionListener;
|
||||
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
|
||||
import org.spongepowered.api.event.Listener;
|
||||
import org.spongepowered.api.event.Order;
|
||||
import org.spongepowered.api.event.filter.IsCancelled;
|
||||
import org.spongepowered.api.event.network.ServerSideConnectionEvent;
|
||||
import org.spongepowered.api.profile.GameProfile;
|
||||
import org.spongepowered.api.util.Identifiable;
|
||||
import org.spongepowered.api.util.Tristate;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
|
@@ -31,12 +31,8 @@ import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||
import net.luckperms.api.messenger.IncomingMessageConsumer;
|
||||
import net.luckperms.api.messenger.Messenger;
|
||||
import org.spongepowered.api.ResourceKey;
|
||||
import org.spongepowered.api.Server;
|
||||
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
|
||||
import org.spongepowered.api.network.EngineConnectionSide;
|
||||
import org.spongepowered.api.network.EngineConnectionState;
|
||||
import org.spongepowered.api.network.ServerConnectionState;
|
||||
import org.spongepowered.api.network.ServerSideConnection;
|
||||
import org.spongepowered.api.network.channel.ChannelBuf;
|
||||
import org.spongepowered.api.network.channel.raw.RawDataChannel;
|
||||
import org.spongepowered.api.network.channel.raw.play.RawPlayDataHandler;
|
||||
|
Reference in New Issue
Block a user