diff --git a/forge/gradle.properties b/forge/gradle.properties index 96afd9f7c..e70c58602 100644 --- a/forge/gradle.properties +++ b/forge/gradle.properties @@ -1,2 +1,2 @@ -minecraftVersion=1.20.1 -forgeVersion=47.0.1 \ No newline at end of file +minecraftVersion=1.20.2 +forgeVersion=48.0.49 \ No newline at end of file diff --git a/forge/loader/src/main/java/me/lucko/luckperms/forge/loader/ForgeLoaderPlugin.java b/forge/loader/src/main/java/me/lucko/luckperms/forge/loader/ForgeLoaderPlugin.java index efa83d172..9db514200 100644 --- a/forge/loader/src/main/java/me/lucko/luckperms/forge/loader/ForgeLoaderPlugin.java +++ b/forge/loader/src/main/java/me/lucko/luckperms/forge/loader/ForgeLoaderPlugin.java @@ -35,7 +35,6 @@ import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fml.loading.FMLEnvironment; -import net.minecraftforge.network.NetworkConstants; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -86,7 +85,7 @@ public class ForgeLoaderPlugin implements Supplier { ModLoadingContext.get(), IExtensionPoint.DisplayTest.class, (Supplier) () -> new IExtensionPoint.DisplayTest( - () -> NetworkConstants.IGNORESERVERONLY, + () -> IExtensionPoint.DisplayTest.IGNORESERVERONLY, (a, b) -> true ) ); diff --git a/forge/src/main/java/me/lucko/luckperms/forge/listeners/ForgeConnectionListener.java b/forge/src/main/java/me/lucko/luckperms/forge/listeners/ForgeConnectionListener.java index fad2eca18..40f3ed731 100644 --- a/forge/src/main/java/me/lucko/luckperms/forge/listeners/ForgeConnectionListener.java +++ b/forge/src/main/java/me/lucko/luckperms/forge/listeners/ForgeConnectionListener.java @@ -34,13 +34,16 @@ import me.lucko.luckperms.common.plugin.util.AbstractConnectionListener; import me.lucko.luckperms.forge.ForgeSenderFactory; import me.lucko.luckperms.forge.LPForgePlugin; import me.lucko.luckperms.forge.capabilities.UserCapabilityImpl; +import me.lucko.luckperms.forge.util.AsyncConfigurationTask; import net.kyori.adventure.text.Component; -import net.minecraft.core.UUIDUtil; import net.minecraft.network.Connection; +import net.minecraft.network.PacketListener; import net.minecraft.network.protocol.login.ClientboundLoginDisconnectPacket; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ConfigurationTask; +import net.minecraft.server.network.ServerConfigurationPacketListenerImpl; import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.event.entity.player.PlayerNegotiationEvent; +import net.minecraftforge.event.network.GatherLoginConfigurationTasksEvent; import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.SubscribeEvent; @@ -48,6 +51,8 @@ import java.util.UUID; import java.util.concurrent.CompletableFuture; public class ForgeConnectionListener extends AbstractConnectionListener { + private static final ConfigurationTask.Type USER_LOGIN_TASK_TYPE = new ConfigurationTask.Type("luckperms:user_login"); + private final LPForgePlugin plugin; public ForgeConnectionListener(LPForgePlugin plugin) { @@ -56,17 +61,27 @@ public class ForgeConnectionListener extends AbstractConnectionListener { } @SubscribeEvent - public void onPlayerNegotiation(PlayerNegotiationEvent event) { - String username = event.getProfile().getName(); - UUID uniqueId = event.getProfile().isComplete() ? event.getProfile().getId() : UUIDUtil.createOfflinePlayerUUID(username); + public void onGatherLoginConfigurationTasks(GatherLoginConfigurationTasksEvent event) { + PacketListener packetListener = event.getConnection().getPacketListener(); + if (!(packetListener instanceof ServerConfigurationPacketListenerImpl)) { + return; + } + + GameProfile gameProfile = ((ServerConfigurationPacketListenerImpl) packetListener).getOwner(); + if (gameProfile == null) { + return; + } + + String username = gameProfile.getName(); + UUID uniqueId = gameProfile.getId(); if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) { this.plugin.getLogger().info("Processing pre-login (sync phase) for " + uniqueId + " - " + username); } - event.enqueueWork(CompletableFuture.runAsync(() -> { - onPlayerNegotiationAsync(event.getConnection(), uniqueId, username); - }, this.plugin.getBootstrap().getScheduler().async())); + event.addTask(new AsyncConfigurationTask(this.plugin, USER_LOGIN_TASK_TYPE, ctx -> CompletableFuture.runAsync(() -> { + onPlayerNegotiationAsync(ctx.getConnection(), uniqueId, username); + }, this.plugin.getBootstrap().getScheduler().async()))); } private void onPlayerNegotiationAsync(Connection connection, UUID uniqueId, String username) { @@ -89,7 +104,7 @@ public class ForgeConnectionListener extends AbstractConnectionListener { this.plugin.getEventDispatcher().dispatchPlayerLoginProcess(uniqueId, username, user); } catch (Exception ex) { this.plugin.getLogger().severe("Exception occurred whilst loading data for " + uniqueId + " - " + username, ex); - + if (this.plugin.getConfiguration().get(ConfigKeys.CANCEL_FAILED_LOGINS)) { Component component = TranslationManager.render(Message.LOADING_DATABASE_ERROR.build()); connection.send(new ClientboundLoginDisconnectPacket(ForgeSenderFactory.toNativeText(component))); diff --git a/forge/src/main/java/me/lucko/luckperms/forge/messaging/PluginMessageMessenger.java b/forge/src/main/java/me/lucko/luckperms/forge/messaging/PluginMessageMessenger.java index ece83b802..a5f285aba 100644 --- a/forge/src/main/java/me/lucko/luckperms/forge/messaging/PluginMessageMessenger.java +++ b/forge/src/main/java/me/lucko/luckperms/forge/messaging/PluginMessageMessenger.java @@ -34,13 +34,14 @@ import net.luckperms.api.messenger.IncomingMessageConsumer; import net.luckperms.api.messenger.Messenger; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.protocol.Packet; -import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket; +import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.players.PlayerList; +import net.minecraftforge.network.ChannelBuilder; +import net.minecraftforge.network.EventNetworkChannel; import net.minecraftforge.network.NetworkRegistry; -import net.minecraftforge.network.event.EventNetworkChannel; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; @@ -57,13 +58,13 @@ public class PluginMessageMessenger extends AbstractPluginMessageMessenger imple } public void init() { - this.channel = NetworkRegistry.newEventChannel(CHANNEL, () -> "1", predicate -> true, predicate -> true); + this.channel = ChannelBuilder.named(CHANNEL).eventNetworkChannel(); this.channel.addListener(event -> { byte[] buf = new byte[event.getPayload().readableBytes()]; event.getPayload().readBytes(buf); handleIncomingMessage(buf); - event.getSource().get().setPacketHandled(true); + event.getSource().setPacketHandled(true); }); } @@ -83,7 +84,8 @@ public class PluginMessageMessenger extends AbstractPluginMessageMessenger imple FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer()); byteBuf.writeBytes(buf); - Packet packet = new ClientboundCustomPayloadPacket(CHANNEL, byteBuf); + byteBuf.writeResourceLocation(CHANNEL); + Packet packet = new ClientboundCustomPayloadPacket(byteBuf); player.connection.send(packet); diff --git a/forge/src/main/java/me/lucko/luckperms/forge/util/AsyncConfigurationTask.java b/forge/src/main/java/me/lucko/luckperms/forge/util/AsyncConfigurationTask.java new file mode 100644 index 000000000..e740c9af8 --- /dev/null +++ b/forge/src/main/java/me/lucko/luckperms/forge/util/AsyncConfigurationTask.java @@ -0,0 +1,73 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * 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.forge.LPForgePlugin; +import net.minecraft.network.protocol.Packet; +import net.minecraft.server.network.ConfigurationTask; +import net.minecraftforge.network.config.ConfigurationTaskContext; + +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; + +public class AsyncConfigurationTask implements ConfigurationTask { + private final LPForgePlugin plugin; + private final Type type; + private final Function> task; + + public AsyncConfigurationTask(LPForgePlugin plugin, Type type, Function> task) { + this.plugin = plugin; + this.type = type; + this.task = task; + } + + public AsyncConfigurationTask(LPForgePlugin plugin, Type type, Supplier> task) { + this(plugin, type, c -> task.get()); + } + + @Override + public void start(ConfigurationTaskContext ctx) { + CompletableFuture future = this.task.apply(ctx); + future.whenCompleteAsync((o, e) -> { + if (e != null) { + this.plugin.getLogger().warn("Configuration task threw an exception", e); + } + ctx.finish(type()); + }, this.plugin.getBootstrap().getScheduler().sync()); // do we need to call this sync? + } + + @Override + public void start(Consumer> send) { + throw new IllegalStateException("This should never be called"); + } + + @Override + public Type type() { + return this.type; + } +} \ No newline at end of file