package com.github.games647.fastlogin.bukkit.listener.protocollib;

import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.comphenix.protocol.wrappers.WrappedSignedProperty;
import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;

import java.util.Collection;

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.PlayerLoginEvent;

public class LoginSkinApplyListener implements Listener {

    private final FastLoginBukkit plugin;

    public LoginSkinApplyListener(FastLoginBukkit plugin) {
        this.plugin = plugin;
    }

    @EventHandler(priority = EventPriority.LOW)
    //run this on the loginEvent to let skins plugins see the skin like in normal minecraft behaviour
    public void onPlayerLogin(PlayerLoginEvent loginEvent) {
        Player player = loginEvent.getPlayer();

        if (plugin.getConfig().getBoolean("forwardSkin")) {
            //go through every session, because player.getAddress is null 
            //loginEvent.getAddress is just a InetAddress not InetSocketAddres, so not unique enough
            Collection<BukkitLoginSession> sessions = plugin.getSessions().values();
            for (BukkitLoginSession session : sessions) {
                if (session.getUsername().equals(player.getName())) {
                    applySkin(player, session);
                    break;
                }
            }
        }
    }

    private void applySkin(Player player, BukkitLoginSession session) {
        WrappedGameProfile gameProfile = WrappedGameProfile.fromPlayer(player);
        String skinData = session.getEncodedSkinData();
        String signature = session.getSkinSignature();
        if (skinData != null && signature != null) {
            WrappedSignedProperty skin = WrappedSignedProperty.fromValues("textures", skinData, signature);
            gameProfile.getProperties().put("textures", skin);
        }
    }
}

@@ -61,16 +61,198 @@
 ollib;%0A%0A
+import com.comphenix.protocol.reflect.accessors.Accessors;%0Aimport com.comphenix.protocol.reflect.accessors.MethodAccessor;%0Aimport com.comphenix.protocol.utility.MinecraftReflection;%0A
 import c
@@ -506,23 +506,140 @@
 ava.
-util.Collection
+lang.reflect.InvocationTargetException;%0Aimport java.lang.reflect.Method;%0Aimport java.util.Collection;%0Aimport java.util.logging.Level
 ;%0A%0Ai
@@ -890,16 +890,247 @@
 ener %7B%0A%0A
+    private static final Class%3C?%3E GAME_PROFILE = MinecraftReflection.getGameProfileClass();%0A%0A    private static final MethodAccessor GET_PROPERTIES = Accessors.getMethodAcccessorOrNull(%0A            GAME_PROFILE, %22getProperties%22);%0A%0A
     priv
@@ -2518,16 +2518,38 @@
 ature);%0A
+            try %7B%0A    
         
@@ -2599,24 +2599,583 @@
 es%22, skin);%0A
+            %7D catch (ClassCastException castException) %7B%0A                Object map = GET_PROPERTIES.invoke(gameProfile.getHandle());%0A                try %7B%0A                    Method putMethod = map.getClass().getMethod(%22put%22, Object.class, Object.class);%0A                    putMethod.invoke(map, %22textures%22, skin.getHandle());%0A                %7D catch (NoSuchMethodException %7C IllegalAccessException %7C InvocationTargetException ex) %7B%0A                    plugin.getLogger().log(Level.SEVERE, %22Error setting premium skin%22, ex);%0A                %7D%0A            %7D%0A
         %7D%0A  

Fix setting skin on Cauldron (Fixes #36)