From 71395ed65923c4201e5f09fd833e29a2efbccf5c Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 29 Mar 2021 13:09:57 -0400 Subject: [PATCH] Commands now work --- .../org/geysermc/floodgate/FabricMod.java | 33 ++++++------ .../module/FabricPlatformModule.java | 22 ++------ .../pluginmessage/FabricSkinApplier.java | 13 +++-- .../floodgate/util/FabricCommandUtil.java | 51 +++++++++++++------ .../floodgate/util/FabricUserAudience.java | 46 ++++++++++++++--- 5 files changed, 103 insertions(+), 62 deletions(-) diff --git a/src/main/java/org/geysermc/floodgate/FabricMod.java b/src/main/java/org/geysermc/floodgate/FabricMod.java index 7d12baa2..5085f596 100644 --- a/src/main/java/org/geysermc/floodgate/FabricMod.java +++ b/src/main/java/org/geysermc/floodgate/FabricMod.java @@ -7,36 +7,37 @@ import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.loader.api.FabricLoader; import net.kyori.adventure.platform.fabric.FabricServerAudiences; -import net.minecraft.server.MinecraftServer; import org.geysermc.floodgate.api.logger.FloodgateLogger; -import org.geysermc.floodgate.module.FabricAddonModule; -import org.geysermc.floodgate.module.FabricCommandModule; -import org.geysermc.floodgate.module.FabricListenerModule; -import org.geysermc.floodgate.module.FabricPlatformModule; -import org.geysermc.floodgate.module.ServerCommonModule; +import org.geysermc.floodgate.module.*; +import org.geysermc.floodgate.pluginmessage.FabricSkinApplier; +import org.geysermc.floodgate.util.FabricCommandUtil; public class FabricMod implements ModInitializer { - private MinecraftServer server; - @Override public void onInitialize() { FabricInjector.setInstance(new FabricInjector()); + Injector injector = Guice.createInjector( + new ServerCommonModule(FabricLoader.getInstance().getConfigDir().resolve("floodgate")), + new FabricPlatformModule() + ); + + FabricPlatform platform = injector.getInstance(FabricPlatform.class); + + platform.enable(new FabricCommandModule()); + ServerLifecycleEvents.SERVER_STARTED.register((server) -> { long ctm = System.currentTimeMillis(); - this.server = server; FabricServerAudiences adventure = FabricServerAudiences.of(server); - Injector injector = Guice.createInjector( - new ServerCommonModule(FabricLoader.getInstance().getConfigDir().resolve("floodgate")), - new FabricPlatformModule(this.server, adventure) - ); + // Stupid hack, see the class for more information + // This can probably be Guice-i-fied but that is beyond me + FabricCommandUtil.setLaterVariables(server, adventure); + FabricSkinApplier.setServer(server); - injector.getInstance(FabricPlatform.class) - .enable( + platform.enable( new FabricAddonModule(), - new FabricCommandModule(), new FabricListenerModule() ); diff --git a/src/main/java/org/geysermc/floodgate/module/FabricPlatformModule.java b/src/main/java/org/geysermc/floodgate/module/FabricPlatformModule.java index 41982bc3..87a7eea3 100644 --- a/src/main/java/org/geysermc/floodgate/module/FabricPlatformModule.java +++ b/src/main/java/org/geysermc/floodgate/module/FabricPlatformModule.java @@ -12,8 +12,6 @@ import com.google.inject.Provides; import com.google.inject.Singleton; import com.google.inject.name.Named; import lombok.RequiredArgsConstructor; -import net.kyori.adventure.platform.fabric.FabricServerAudiences; -import net.minecraft.server.MinecraftServer; import org.apache.logging.log4j.LogManager; import org.geysermc.floodgate.api.FloodgateApi; import org.geysermc.floodgate.api.logger.FloodgateLogger; @@ -24,20 +22,6 @@ import org.geysermc.floodgate.util.LanguageManager; @RequiredArgsConstructor public final class FabricPlatformModule extends AbstractModule { - private final MinecraftServer server; - private final FabricServerAudiences adventure; - - @Provides - @Singleton - public MinecraftServer server() { - return server; - } - - @Provides - @Singleton - public FabricServerAudiences adventure() { - return adventure; - } @Provides @Singleton @@ -51,7 +35,7 @@ public final class FabricPlatformModule extends AbstractModule { FloodgateApi api, FloodgateLogger logger, LanguageManager languageManager) { - return new FabricCommandUtil(adventure, api, logger, languageManager, server); + return new FabricCommandUtil(api, logger, languageManager); } @Provides @@ -96,7 +80,7 @@ public final class FabricPlatformModule extends AbstractModule { @Provides @Singleton - public SkinApplier skinApplier(MinecraftServer server) { - return new FabricSkinApplier(server); + public SkinApplier skinApplier() { + return new FabricSkinApplier(); } } diff --git a/src/main/java/org/geysermc/floodgate/pluginmessage/FabricSkinApplier.java b/src/main/java/org/geysermc/floodgate/pluginmessage/FabricSkinApplier.java index 789b037b..18381624 100644 --- a/src/main/java/org/geysermc/floodgate/pluginmessage/FabricSkinApplier.java +++ b/src/main/java/org/geysermc/floodgate/pluginmessage/FabricSkinApplier.java @@ -14,12 +14,13 @@ import org.geysermc.floodgate.skin.SkinApplier; @RequiredArgsConstructor public final class FabricSkinApplier implements SkinApplier { - private final MinecraftServer server; + // See FabricCommandUtil + private static MinecraftServer SERVER; @Override public void applySkin(FloodgatePlayer floodgatePlayer, JsonObject skinResult) { - this.server.execute(() -> { - ServerPlayerEntity bedrockPlayer = this.server.getPlayerManager().getPlayer(floodgatePlayer.getCorrectUniqueId()); + SERVER.execute(() -> { + ServerPlayerEntity bedrockPlayer = SERVER.getPlayerManager().getPlayer(floodgatePlayer.getCorrectUniqueId()); if (bedrockPlayer == null) { // Disconnected probably? return; @@ -36,7 +37,7 @@ public final class FabricSkinApplier implements SkinApplier { properties.put("textures", property); // Skin is applied - now it's time to refresh the player for everyone. Oof. - for (ServerPlayerEntity otherPlayer : this.server.getPlayerManager().getPlayerList()) { + for (ServerPlayerEntity otherPlayer : SERVER.getPlayerManager().getPlayerList()) { if (otherPlayer == bedrockPlayer) { continue; } @@ -55,4 +56,8 @@ public final class FabricSkinApplier implements SkinApplier { } }); } + + public static void setServer(MinecraftServer server) { + SERVER = server; + } } diff --git a/src/main/java/org/geysermc/floodgate/util/FabricCommandUtil.java b/src/main/java/org/geysermc/floodgate/util/FabricCommandUtil.java index 21e585d4..0fafebc8 100644 --- a/src/main/java/org/geysermc/floodgate/util/FabricCommandUtil.java +++ b/src/main/java/org/geysermc/floodgate/util/FabricCommandUtil.java @@ -25,11 +25,15 @@ import java.util.*; @RequiredArgsConstructor public final class FabricCommandUtil implements CommandUtil { - @Getter private final FabricServerAudiences adventure; + // Static because commands *need* to be initialized before the server is available + // Otherwise it would be a class variable + private static MinecraftServer SERVER; + // This one also requires the server so it's bundled in + private static FabricServerAudiences ADVENTURE; + @Getter private final FloodgateApi api; @Getter private final FloodgateLogger logger; @Getter private final LanguageManager manager; - @Getter private final MinecraftServer server; @Override public @NonNull UserAudience getAudience(@NonNull Object source) { @@ -46,8 +50,8 @@ public final class FabricCommandUtil implements CommandUtil { } @Override - public @Nullable UserAudience getAudienceByUuid(@NonNull UUID uuid) { - ServerPlayerEntity player = this.server.getPlayerManager().getPlayer(uuid); + public UserAudience getAudienceByUuid(@NonNull UUID uuid) { + ServerPlayerEntity player = SERVER.getPlayerManager().getPlayer(uuid); if (player != null) { return getAudience0(player); } @@ -55,8 +59,8 @@ public final class FabricCommandUtil implements CommandUtil { } @Override - public @Nullable UserAudience getAudienceByUsername(@NonNull String username) { - ServerPlayerEntity player = this.server.getPlayerManager().getPlayer(username); + public UserAudience getAudienceByUsername(@NonNull String username) { + ServerPlayerEntity player = SERVER.getPlayerManager().getPlayer(username); if (player != null) { return getAudience0(player); } @@ -66,10 +70,11 @@ public final class FabricCommandUtil implements CommandUtil { private FabricUserAudience getAudience0(ServerPlayerEntity player) { // Marked as internal??? Should probably find a better way to get this. Locale locale = ((ConnectionAccess) player.networkHandler.getConnection()).getChannel().attr(FriendlyByteBufBridge.CHANNEL_LOCALE).get(); - return new FabricUserAudience( + return new FabricUserAudience.NamedFabricUserAudience( + player.getName().asString(), player.getUuid(), locale != null ? locale.getLanguage().toLowerCase(Locale.ROOT) + "_" + locale.getCountry().toUpperCase(Locale.ROOT) : - manager.getDefaultLocale(), player.getCommandSource(), this); + manager.getDefaultLocale(), player.getCommandSource(), this, true); } @Override @@ -80,16 +85,16 @@ public final class FabricCommandUtil implements CommandUtil { @Override public @NonNull UserAudience getOfflineAudienceByUsername(@NonNull String username) { UUID uuid = null; - GameProfile profile = this.server.getUserCache().findByName(username); + GameProfile profile = SERVER.getUserCache().findByName(username); if (profile != null) { uuid = profile.getId(); } - return new FabricUserAudience(uuid, username, null, this); + return new FabricUserAudience.NamedFabricUserAudience(username, uuid, username, null, this, false); } @Override public @NonNull Collection getOnlineUsernames(UserAudienceArgument.@NonNull PlayerType limitTo) { - List players = this.server.getPlayerManager().getPlayerList(); + List players = SERVER.getPlayerManager().getPlayerList(); Collection usernames = new ArrayList<>(); switch (limitTo) { @@ -120,7 +125,14 @@ public final class FabricCommandUtil implements CommandUtil { @Override public void sendMessage(Object player, String locale, CommandMessage message, Object... args) { - getPlayer(player).sendMessage(translateAndTransform(locale, message, args), false); + ServerCommandSource commandSource = (ServerCommandSource) player; + if (commandSource.getEntity() instanceof ServerPlayerEntity) { + SERVER.execute(() -> ((ServerPlayerEntity) commandSource.getEntity()) + .sendMessage(translateAndTransform(locale, message, args), false)); + } else { + // Console? + logger.info(message.translateMessage(manager, locale, args)); + } } @Override @@ -131,14 +143,14 @@ public final class FabricCommandUtil implements CommandUtil { @Override public boolean whitelistPlayer(String xuid, String username) { GameProfile profile = new GameProfile(Utils.getJavaUuid(xuid), username); - this.server.getPlayerManager().getWhitelist().add(new WhitelistEntry(profile)); + SERVER.getPlayerManager().getWhitelist().add(new WhitelistEntry(profile)); return true; } @Override public boolean removePlayerFromWhitelist(String xuid, String username) { GameProfile profile = new GameProfile(Utils.getJavaUuid(xuid), username); - this.server.getPlayerManager().getWhitelist().remove(profile); + SERVER.getPlayerManager().getWhitelist().remove(profile); return true; } @@ -147,7 +159,7 @@ public final class FabricCommandUtil implements CommandUtil { ServerCommandSource source = (ServerCommandSource) instance; return source.getPlayer(); } catch (ClassCastException | CommandSyntaxException exception) { - logger.error("Failed to cast {} to Player", instance.getClass().getName()); + logger.error("Failed to cast {} as a player", instance.getClass().getName()); throw new RuntimeException(); } } @@ -155,4 +167,13 @@ public final class FabricCommandUtil implements CommandUtil { public Text translateAndTransform(String locale, CommandMessage message, Object... args) { return Text.of(message.translateMessage(manager, locale, args)); } + + public FabricServerAudiences getAdventure() { + return ADVENTURE; + } + + public static void setLaterVariables(MinecraftServer server, FabricServerAudiences adventure) { + SERVER = server; + ADVENTURE = adventure; + } } diff --git a/src/main/java/org/geysermc/floodgate/util/FabricUserAudience.java b/src/main/java/org/geysermc/floodgate/util/FabricUserAudience.java index 548828b9..171c242b 100644 --- a/src/main/java/org/geysermc/floodgate/util/FabricUserAudience.java +++ b/src/main/java/org/geysermc/floodgate/util/FabricUserAudience.java @@ -1,6 +1,7 @@ package org.geysermc.floodgate.util; import lombok.RequiredArgsConstructor; +import me.lucko.fabric.api.permissions.v0.Permissions; import net.kyori.adventure.audience.Audience; import net.kyori.adventure.audience.ForwardingAudience; import net.kyori.adventure.audience.MessageType; @@ -15,7 +16,7 @@ import org.geysermc.floodgate.player.UserAudience; import java.util.UUID; @RequiredArgsConstructor -public final class FabricUserAudience implements UserAudience, ForwardingAudience.Single { +public class FabricUserAudience implements UserAudience, ForwardingAudience.Single { private final UUID uuid; private final String locale; private final ServerCommandSource source; @@ -33,6 +34,10 @@ public final class FabricUserAudience implements UserAudience, ForwardingAudienc @Override public @NonNull String username() { + if (source == null) { + return ""; + } + return source.getName(); } @@ -48,17 +53,12 @@ public final class FabricUserAudience implements UserAudience, ForwardingAudienc @Override public boolean hasPermission(@NonNull String permission) { - //TODO - return true; + return Permissions.check(source, permission); } @Override public void sendMessage(@NonNull Identity source, @NonNull Component message, @NonNull MessageType type) { - if (this.source.getEntity() instanceof ServerPlayerEntity) { - ((ServerPlayerEntity) this.source.getEntity()).sendMessage( - commandUtil.getAdventure().toNative(message), false - ); - } + commandUtil.getAdventure().audience(this.source).sendMessage(message); } @Override @@ -83,4 +83,34 @@ public final class FabricUserAudience implements UserAudience, ForwardingAudienc ); } } + + /** + * Used whenever a name has been explicitly defined for us. Most helpful in offline players. + */ + public static final class NamedFabricUserAudience extends FabricUserAudience implements PlayerAudience { + private final String name; + private final boolean online; + + public NamedFabricUserAudience( + String name, + UUID uuid, + String locale, + ServerCommandSource source, + FabricCommandUtil commandUtil, + boolean online) { + super(uuid, locale, source, commandUtil); + this.name = name; + this.online = online; + } + + @Override + public @NonNull String username() { + return name; + } + + @Override + public boolean online() { + return online; + } + } }