diff --git a/spigot/src/main/java/com/github/camotoy/geyserskinmanager/spigot/listener/BungeecordPluginMessageListener.java b/spigot/src/main/java/com/github/camotoy/geyserskinmanager/spigot/listener/BungeecordPluginMessageListener.java index 4824b1c..63a50a0 100644 --- a/spigot/src/main/java/com/github/camotoy/geyserskinmanager/spigot/listener/BungeecordPluginMessageListener.java +++ b/spigot/src/main/java/com/github/camotoy/geyserskinmanager/spigot/listener/BungeecordPluginMessageListener.java @@ -7,9 +7,15 @@ import com.github.camotoy.geyserskinmanager.spigot.profile.GameProfileWrapper; import com.github.camotoy.geyserskinmanager.spigot.profile.MinecraftProfileWrapper; import com.github.camotoy.geyserskinmanager.spigot.profile.PaperProfileWrapper; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import io.papermc.lib.PaperLib; import org.bukkit.Bukkit; import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.plugin.messaging.PluginMessageListener; import javax.annotation.Nonnull; @@ -17,18 +23,36 @@ import java.io.DataInputStream; import java.io.IOException; import java.util.UUID; +import java.util.concurrent.TimeUnit; import java.util.function.Function; -public class BungeecordPluginMessageListener implements PluginMessageListener { +public class BungeecordPluginMessageListener implements Listener, PluginMessageListener { private final GeyserSkinManager plugin; private final Function getProfileFunction; private final SpigotSkinApplier skinApplier; + /** + * Information is stored here in the event that a plugin message is received before the player has joined. + */ + private final Cache skinEntryCache = CacheBuilder.newBuilder() + .expireAfterWrite(10, TimeUnit.SECONDS) + .build(); + public BungeecordPluginMessageListener(GeyserSkinManager plugin) { this.plugin = plugin; this.skinApplier = new SpigotSkinApplier(plugin); this.getProfileFunction = (PaperLib.isPaper() && PaperLib.isVersion(12, 2)) ? PaperProfileWrapper::from : GameProfileWrapper::from; + + Bukkit.getPluginManager().registerEvents(this, this.plugin); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerJoin(PlayerJoinEvent event) { + SkinEntry skinEntry = skinEntryCache.getIfPresent(event.getPlayer().getUniqueId()); + if (skinEntry != null) { + skinApplier.setSkin(getProfileFunction.apply(event.getPlayer()), event.getPlayer(), skinEntry); + } } @Override @@ -44,14 +68,16 @@ public void onPluginMessageReceived(@Nonnull String channel, @Nonnull Player pla return; } UUID uuid = new UUID(in.readLong(), in.readLong()); + String value = in.readUTF(); + String signature = in.readUTF(); + SkinEntry skinEntry = new SkinEntry(value, signature); + Player bedrockPlayer = Bukkit.getPlayer(uuid); if (bedrockPlayer == null) { - this.plugin.getLogger().warning("Player with UUID " + uuid + " could not be found!"); + // Wait until they have officially joined + skinEntryCache.put(uuid, skinEntry); return; } - String value = in.readUTF(); - String signature = in.readUTF(); - SkinEntry skinEntry = new SkinEntry(value, signature); skinApplier.setSkin(getProfileFunction.apply(bedrockPlayer), bedrockPlayer, skinEntry); } catch (IOException e) { e.printStackTrace();