feat: add FakePlayer on Disconnect
This commit is contained in:
		
							parent
							
								
									fa18a203b1
								
							
						
					
					
						commit
						780e7dc597
					
				
					 4 changed files with 173 additions and 19 deletions
				
			
		| 
						 | 
				
			
			@ -21,18 +21,23 @@ import de.cliffbreak.varo.listeners.PlayerClientOptionsChangeListener;
 | 
			
		|||
import de.cliffbreak.varo.listeners.PlayerDeathListener;
 | 
			
		||||
import de.cliffbreak.varo.listeners.PlayerJoinQuitListener;
 | 
			
		||||
import de.cliffbreak.varo.listeners.PlayerPreLoginListener;
 | 
			
		||||
import de.cliffbreak.varo.managers.NPCManager;
 | 
			
		||||
 | 
			
		||||
public class Varo extends JavaPlugin {
 | 
			
		||||
 | 
			
		||||
    public File configurationFile = new File("plugins/CliffbreakVaro", "config.yml");
 | 
			
		||||
    public FileConfiguration config = YamlConfiguration.loadConfiguration(this.configurationFile);
 | 
			
		||||
    public PlayerCache playerCache = new PlayerCache(this);
 | 
			
		||||
    public NPCManager npcManager;
 | 
			
		||||
    public PlayerCache playerCache;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onEnable() {
 | 
			
		||||
 | 
			
		||||
        getLogger().info("CliffbreakVaro is starting...");
 | 
			
		||||
 | 
			
		||||
        this.npcManager = new NPCManager(this);
 | 
			
		||||
        this.playerCache = new PlayerCache(this);
 | 
			
		||||
 | 
			
		||||
        // this.config.addDefault("Varo.Start", "TODO: StartDate");
 | 
			
		||||
        this.config.addDefault("Varo.Bans", new ArrayList<String>());
 | 
			
		||||
        this.config.options().copyDefaults(true);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,6 @@
 | 
			
		|||
package de.cliffbreak.varo.commands;
 | 
			
		||||
 | 
			
		||||
import java.io.BufferedReader;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStreamReader;
 | 
			
		||||
import java.net.HttpURLConnection;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
import com.destroystokyo.paper.Title;
 | 
			
		||||
| 
						 | 
				
			
			@ -23,6 +19,7 @@ import org.json.simple.parser.ParseException;
 | 
			
		|||
 | 
			
		||||
import de.cliffbreak.varo.Varo;
 | 
			
		||||
import de.cliffbreak.varo.uitls.MessageUtils;
 | 
			
		||||
import de.cliffbreak.varo.uitls.WebUtils;
 | 
			
		||||
 | 
			
		||||
public class VaroCommand implements CommandExecutor {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -41,23 +38,13 @@ public class VaroCommand implements CommandExecutor {
 | 
			
		|||
        if (args.length == 2 && args[0].equals("unban")) {
 | 
			
		||||
            @SuppressWarnings("unchecked")
 | 
			
		||||
            final ArrayList<String> bans = (ArrayList<String>) this.plugin.config.get("Varo.Bans");
 | 
			
		||||
            String url = "https://api.mojang.com/users/profiles/minecraft/" + args[1];
 | 
			
		||||
            try {
 | 
			
		||||
                HttpURLConnection connection = ((HttpURLConnection) (new URL(url)).openConnection());
 | 
			
		||||
                connection.setRequestMethod("GET");
 | 
			
		||||
                BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
 | 
			
		||||
                String inputLine;
 | 
			
		||||
                StringBuffer content = new StringBuffer();
 | 
			
		||||
                while ((inputLine = in.readLine()) != null) {
 | 
			
		||||
                    content.append(inputLine);
 | 
			
		||||
                }
 | 
			
		||||
                in.close();
 | 
			
		||||
                connection.disconnect();
 | 
			
		||||
                if (content.toString().isEmpty()) {
 | 
			
		||||
                String result = WebUtils.GET("https://api.mojang.com/users/profiles/minecraft/" + args[1]);
 | 
			
		||||
                if (result.isEmpty()) {
 | 
			
		||||
                    sender.sendMessage("§c§lFehler: §r§cDer Spieler wurde nicht gefunden.");
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                JSONObject uuidObject = (JSONObject) JSONValue.parseWithException(content.toString());
 | 
			
		||||
                JSONObject uuidObject = (JSONObject) JSONValue.parseWithException(result);
 | 
			
		||||
                if (!bans.contains(uuidObject.get("id").toString())) {
 | 
			
		||||
                    sender.sendMessage("§c§lFehler: §r§cDer Spieler ist nicht gebannt.");
 | 
			
		||||
                    return true;
 | 
			
		||||
| 
						 | 
				
			
			@ -66,7 +53,7 @@ public class VaroCommand implements CommandExecutor {
 | 
			
		|||
                this.plugin.config.set("Varo.Bans", bans);
 | 
			
		||||
                this.plugin.saveConfiguration();
 | 
			
		||||
                sender.sendMessage("§a§lErfolg: §r§aDer Spieler ist nun nicht mehr gebannt.");
 | 
			
		||||
            } catch (ParseException | IOException e) {
 | 
			
		||||
            } catch (IOException | ParseException e) {
 | 
			
		||||
                sender.sendMessage(
 | 
			
		||||
                        "§c§lFehler:§r§c beim Verbinden mit der Mojang-API ist ein Fehler aufgetreten. Eventuell sind die Mojang Server down.");
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
| 
						 | 
				
			
			@ -94,11 +81,30 @@ public class VaroCommand implements CommandExecutor {
 | 
			
		|||
            sender.sendMessage(MessageUtils.getRichTextComponent("§9" + "Team 08", ""));
 | 
			
		||||
            sender.sendMessage(MessageUtils.getRichTextComponent("§d" + "Team 09", ""));
 | 
			
		||||
            sender.sendMessage(MessageUtils.getRichTextComponent("§5" + "Team 10", ""));
 | 
			
		||||
        } else if (args.length == 1 && args[0].equals("test")) {
 | 
			
		||||
            if (sender instanceof Player) {
 | 
			
		||||
                try {
 | 
			
		||||
                    plugin.npcManager.createClone((Player) sender, false);
 | 
			
		||||
                } catch (IOException e) {
 | 
			
		||||
                    sender.sendMessage(
 | 
			
		||||
                            "§c§lFehler:§r§c beim Verbinden mit der Mojang-API ist ein Fehler aufgetreten. Eventuell sind die Mojang Server down.");
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                sender.sendMessage("§c§lFehler:§r§c Dieses Kommando kann nur durch einen Spieler ausgeführt werden.");
 | 
			
		||||
            }
 | 
			
		||||
        } else if (args.length == 1 && args[0].equals("testremove")) {
 | 
			
		||||
            if (sender instanceof Player) {
 | 
			
		||||
                plugin.npcManager.removeClone(((Player) sender));
 | 
			
		||||
            } else {
 | 
			
		||||
                sender.sendMessage("§c§lFehler:§r§c Dieses Kommando kann nur durch einen Spieler ausgeführt werden.");
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            sender.sendMessage("\n§6========== §b§lCliffbreak.de VARO §r§6============\n ");
 | 
			
		||||
            sender.sendMessage("§a/varo start: §rStarte das Varo Projekt!");
 | 
			
		||||
            sender.sendMessage("§a/varo unban [Spieler]: §rSpieler wieder auf den Server lassen");
 | 
			
		||||
            sender.sendMessage("§a/varo teamcolors: §rZeige verfügbare Team-Farben an");
 | 
			
		||||
            sender.sendMessage("§a/varo test: §rSpawne einen Klon");
 | 
			
		||||
            sender.sendMessage("§a/varo testremove: §rLösche den Klon");
 | 
			
		||||
            sender.sendMessage("\n§6==========================================");
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
package de.cliffbreak.varo.listeners;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Stack;
 | 
			
		||||
 | 
			
		||||
import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
 | 
			
		||||
| 
						 | 
				
			
			@ -26,6 +27,11 @@ public class PlayerJoinQuitListener implements Listener {
 | 
			
		|||
    @EventHandler()
 | 
			
		||||
    public void onPlayerQuit(final PlayerQuitEvent e) {
 | 
			
		||||
        e.setQuitMessage(null);
 | 
			
		||||
        try {
 | 
			
		||||
            plugin.npcManager.createClone(e.getPlayer(), true);
 | 
			
		||||
        } catch (IOException ex) {
 | 
			
		||||
            ex.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        Bukkit.broadcast(
 | 
			
		||||
                MessageUtils.getRichTextComponent(e.getPlayer().getName(), "§f hat den Server verlassen.", true));
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -33,6 +39,8 @@ public class PlayerJoinQuitListener implements Listener {
 | 
			
		|||
    @EventHandler()
 | 
			
		||||
    public void onPlayerJoin(final PlayerJoinEvent e) {
 | 
			
		||||
        e.setJoinMessage(null);
 | 
			
		||||
        plugin.npcManager.removeClone(e.getPlayer());
 | 
			
		||||
        plugin.npcManager.syncClones(e.getPlayer());
 | 
			
		||||
        Bukkit.broadcast(
 | 
			
		||||
                MessageUtils.getRichTextComponent(e.getPlayer().getName(), "§f hat den Server betreten.", true));
 | 
			
		||||
        e.getPlayer().sendMessage("\n§7§l#### §9Cliffbreak.de - §lVaro §r§9Changelog §7§l####\n \n"
 | 
			
		||||
| 
						 | 
				
			
			@ -40,6 +48,8 @@ public class PlayerJoinQuitListener implements Listener {
 | 
			
		|||
 | 
			
		||||
        final Stack<String> changes = new Stack<String>();
 | 
			
		||||
 | 
			
		||||
        changes.push(" §7• §r§lADD: §rAdd a FakePlayer if Player is logged out");
 | 
			
		||||
        changes.push(" §7• §r§lADD: §rAdd /varo test && /varo testremove");
 | 
			
		||||
        changes.push(" §7• §r§lFIX: §r/varo Command is only usable by Server Operators now");
 | 
			
		||||
        changes.push(" §7• §r§lADD: §rDisallow special Items (Enchanted Golden Apple, Fishing Rod, Totem of Undying)");
 | 
			
		||||
        changes.push(" §7• §r§lADD: §rUse Vanilla Hearts");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										133
									
								
								varo/src/main/java/de/cliffbreak/varo/managers/NPCManager.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								varo/src/main/java/de/cliffbreak/varo/managers/NPCManager.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,133 @@
 | 
			
		|||
package de.cliffbreak.varo.managers;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
import com.mojang.authlib.GameProfile;
 | 
			
		||||
import com.mojang.authlib.properties.Property;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.ChatColor;
 | 
			
		||||
import org.bukkit.Location;
 | 
			
		||||
import org.bukkit.craftbukkit.v1_15_R1.CraftServer;
 | 
			
		||||
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
 | 
			
		||||
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.scoreboard.Scoreboard;
 | 
			
		||||
import org.bukkit.scoreboard.Team;
 | 
			
		||||
import org.json.simple.JSONArray;
 | 
			
		||||
import org.json.simple.JSONObject;
 | 
			
		||||
 | 
			
		||||
import org.json.simple.JSONValue;
 | 
			
		||||
import org.json.simple.parser.ParseException;
 | 
			
		||||
 | 
			
		||||
import de.cliffbreak.varo.Varo;
 | 
			
		||||
import de.cliffbreak.varo.uitls.WebUtils;
 | 
			
		||||
import net.minecraft.server.v1_15_R1.DataWatcherObject;
 | 
			
		||||
import net.minecraft.server.v1_15_R1.DataWatcherRegistry;
 | 
			
		||||
import net.minecraft.server.v1_15_R1.EntityPlayer;
 | 
			
		||||
import net.minecraft.server.v1_15_R1.MinecraftServer;
 | 
			
		||||
import net.minecraft.server.v1_15_R1.PacketPlayOutEntityDestroy;
 | 
			
		||||
import net.minecraft.server.v1_15_R1.PacketPlayOutEntityHeadRotation;
 | 
			
		||||
import net.minecraft.server.v1_15_R1.PacketPlayOutEntityMetadata;
 | 
			
		||||
import net.minecraft.server.v1_15_R1.PacketPlayOutNamedEntitySpawn;
 | 
			
		||||
import net.minecraft.server.v1_15_R1.PacketPlayOutPlayerInfo;
 | 
			
		||||
import net.minecraft.server.v1_15_R1.PlayerConnection;
 | 
			
		||||
import net.minecraft.server.v1_15_R1.PlayerInteractManager;
 | 
			
		||||
import net.minecraft.server.v1_15_R1.WorldServer;
 | 
			
		||||
import net.minecraft.server.v1_15_R1.PacketPlayOutPlayerInfo.EnumPlayerInfoAction;
 | 
			
		||||
 | 
			
		||||
public class NPCManager {
 | 
			
		||||
 | 
			
		||||
    private final Varo plugin;
 | 
			
		||||
    private final ArrayList<EntityPlayer> players = new ArrayList<EntityPlayer>();
 | 
			
		||||
    private Scoreboard scoreboard;
 | 
			
		||||
    private Team afkTeam;
 | 
			
		||||
 | 
			
		||||
    public NPCManager(final Varo plugin) {
 | 
			
		||||
        this.plugin = plugin;
 | 
			
		||||
        this.scoreboard = Bukkit.getScoreboardManager().getMainScoreboard();
 | 
			
		||||
        if (scoreboard.getTeam("afk") == null) {
 | 
			
		||||
 | 
			
		||||
            this.afkTeam = scoreboard.registerNewTeam("afk");
 | 
			
		||||
        } else {
 | 
			
		||||
            this.afkTeam = scoreboard.getTeam("afk");
 | 
			
		||||
        }
 | 
			
		||||
        this.afkTeam.setPrefix("§8§l[AFK] ");
 | 
			
		||||
        this.afkTeam.setColor(ChatColor.GRAY);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void createClone(final Player player, final boolean shouldHaveAFKPrefix) throws IOException {
 | 
			
		||||
        final Location location = player.getLocation();
 | 
			
		||||
        final MinecraftServer nmsServer = ((CraftServer) Bukkit.getServer()).getServer();
 | 
			
		||||
        final WorldServer nmsWorld = ((CraftWorld) player.getWorld()).getHandle();
 | 
			
		||||
        final GameProfile gameProfile = new GameProfile(player.getUniqueId(), player.getName());
 | 
			
		||||
        try {
 | 
			
		||||
            final String result = WebUtils.GET("https://sessionserver.mojang.com/session/minecraft/profile/"
 | 
			
		||||
                    + player.getUniqueId().toString().replace("-", "") + "?unsigned=false");
 | 
			
		||||
            final JSONObject resultObject = (JSONObject) JSONValue.parseWithException(result);
 | 
			
		||||
            final JSONObject properties = (JSONObject) ((JSONArray) resultObject.get("properties")).get(0);
 | 
			
		||||
 | 
			
		||||
            gameProfile.getProperties().put("textures", new Property("textures", properties.get("value").toString(),
 | 
			
		||||
                    properties.get("signature").toString()));
 | 
			
		||||
        } catch (IOException | ParseException e) {
 | 
			
		||||
            plugin.getLogger().info(e.getMessage());
 | 
			
		||||
            throw new IOException();
 | 
			
		||||
        }
 | 
			
		||||
        final EntityPlayer npc = new EntityPlayer(nmsServer, nmsWorld, gameProfile,
 | 
			
		||||
                new PlayerInteractManager(nmsWorld));
 | 
			
		||||
 | 
			
		||||
        npc.setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
 | 
			
		||||
 | 
			
		||||
        if (shouldHaveAFKPrefix) {
 | 
			
		||||
            this.afkTeam.addEntry(npc.getName());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        players.add(npc);
 | 
			
		||||
 | 
			
		||||
        for (Player connectionPlayer : Bukkit.getOnlinePlayers()) {
 | 
			
		||||
            final PlayerConnection connection = ((CraftPlayer) connectionPlayer).getHandle().playerConnection;
 | 
			
		||||
            connection.sendPacket(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER, npc));
 | 
			
		||||
            connection.sendPacket(new PacketPlayOutNamedEntitySpawn(npc));
 | 
			
		||||
            connection.sendPacket(
 | 
			
		||||
                    new PacketPlayOutEntityHeadRotation(npc, (byte) ((location.getYaw() * 256.0F) / 360.0F)));
 | 
			
		||||
            npc.getDataWatcher().set(new DataWatcherObject<>(16, DataWatcherRegistry.a),
 | 
			
		||||
                    (byte) plugin.playerCache.getSkinParts(player.getUniqueId().toString().replace("-", "")));
 | 
			
		||||
            npc.getDataWatcher().set(new DataWatcherObject<>(17, DataWatcherRegistry.a),
 | 
			
		||||
                    plugin.playerCache.getMainHandAsByte(player.getUniqueId().toString().replace("-", "")));
 | 
			
		||||
            connection.sendPacket(new PacketPlayOutEntityMetadata(npc.getId(), npc.getDataWatcher(), true));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void syncClones(Player player) {
 | 
			
		||||
        for (EntityPlayer npc : this.players) {
 | 
			
		||||
            final PlayerConnection connection = ((CraftPlayer) player).getHandle().playerConnection;
 | 
			
		||||
            connection.sendPacket(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER, npc));
 | 
			
		||||
            connection.sendPacket(new PacketPlayOutNamedEntitySpawn(npc));
 | 
			
		||||
            connection.sendPacket(new PacketPlayOutEntityHeadRotation(npc, (byte) ((npc.yaw * 256.0F) / 360.0F)));
 | 
			
		||||
            npc.getDataWatcher().set(new DataWatcherObject<>(16, DataWatcherRegistry.a),
 | 
			
		||||
                    (byte) plugin.playerCache.getSkinParts(player.getUniqueId().toString().replace("-", "")));
 | 
			
		||||
            npc.getDataWatcher().set(new DataWatcherObject<>(17, DataWatcherRegistry.a),
 | 
			
		||||
                    plugin.playerCache.getMainHandAsByte(player.getUniqueId().toString().replace("-", "")));
 | 
			
		||||
            connection.sendPacket(new PacketPlayOutEntityMetadata(npc.getId(), npc.getDataWatcher(), true));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void removeClone(Player player) {
 | 
			
		||||
        this.afkTeam.removeEntry(player.getName());
 | 
			
		||||
        for (int i = 0; i < this.players.size(); i++) {
 | 
			
		||||
            EntityPlayer npc = this.players.get(i);
 | 
			
		||||
            if (npc.getUniqueID().equals(player.getUniqueId())) {
 | 
			
		||||
                final WorldServer nmsWorld = ((CraftWorld) player.getWorld()).getHandle();
 | 
			
		||||
                nmsWorld.removeEntity(npc);
 | 
			
		||||
 | 
			
		||||
                for (Player connectionPlayer : Bukkit.getOnlinePlayers()) {
 | 
			
		||||
                    final PlayerConnection connection = ((CraftPlayer) connectionPlayer).getHandle().playerConnection;
 | 
			
		||||
                    connection.sendPacket(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER, npc));
 | 
			
		||||
                    connection.sendPacket(new PacketPlayOutEntityDestroy(npc.getId()));
 | 
			
		||||
                }
 | 
			
		||||
                this.players.remove(npc);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		
		Reference in a new issue