Java 16 support, some dodgy code hmm. Has errors with "class loaded by another plugin" which needs to be resolved
This commit is contained in:
parent
269363753c
commit
f0448e6afc
@ -67,6 +67,8 @@ public class LibsDisguises extends JavaPlugin {
|
|||||||
|
|
||||||
instance = this;
|
instance = this;
|
||||||
|
|
||||||
|
WatcherSanitizer.init();
|
||||||
|
|
||||||
Plugin plugin = Bukkit.getPluginManager().getPlugin("ProtocolLib");
|
Plugin plugin = Bukkit.getPluginManager().getPlugin("ProtocolLib");
|
||||||
|
|
||||||
if (plugin == null || DisguiseUtilities.isOlderThan(DisguiseUtilities.getProtocolLibRequiredVersion(), plugin.getDescription().getVersion())) {
|
if (plugin == null || DisguiseUtilities.isOlderThan(DisguiseUtilities.getProtocolLibRequiredVersion(), plugin.getDescription().getVersion())) {
|
||||||
@ -105,8 +107,6 @@ public class LibsDisguises extends JavaPlugin {
|
|||||||
if (!reloaded) {
|
if (!reloaded) {
|
||||||
commandConfig.load();
|
commandConfig.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
WatcherSanitizer.init();
|
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
getUpdateChecker().doUpdate();
|
getUpdateChecker().doUpdate();
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import com.comphenix.protocol.PacketType;
|
|||||||
import com.comphenix.protocol.PacketType.Play.Server;
|
import com.comphenix.protocol.PacketType.Play.Server;
|
||||||
import com.comphenix.protocol.ProtocolLibrary;
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
import com.comphenix.protocol.reflect.StructureModifier;
|
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
|
import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
|
import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
|
||||||
import com.comphenix.protocol.wrappers.PlayerInfoData;
|
import com.comphenix.protocol.wrappers.PlayerInfoData;
|
||||||
@ -16,7 +15,10 @@ import me.libraryaddict.disguise.DisguiseAPI;
|
|||||||
import me.libraryaddict.disguise.DisguiseConfig;
|
import me.libraryaddict.disguise.DisguiseConfig;
|
||||||
import me.libraryaddict.disguise.LibsDisguises;
|
import me.libraryaddict.disguise.LibsDisguises;
|
||||||
import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType;
|
import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType;
|
||||||
import me.libraryaddict.disguise.disguisetypes.watchers.*;
|
import me.libraryaddict.disguise.disguisetypes.watchers.AbstractHorseWatcher;
|
||||||
|
import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher;
|
||||||
|
import me.libraryaddict.disguise.disguisetypes.watchers.BoatWatcher;
|
||||||
|
import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher;
|
||||||
import me.libraryaddict.disguise.events.DisguiseEvent;
|
import me.libraryaddict.disguise.events.DisguiseEvent;
|
||||||
import me.libraryaddict.disguise.events.UndisguiseEvent;
|
import me.libraryaddict.disguise.events.UndisguiseEvent;
|
||||||
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
||||||
@ -29,7 +31,6 @@ import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
|
|||||||
import me.libraryaddict.disguise.utilities.translations.LibsMsg;
|
import me.libraryaddict.disguise.utilities.translations.LibsMsg;
|
||||||
import net.md_5.bungee.api.ChatMessageType;
|
import net.md_5.bungee.api.ChatMessageType;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.boss.BarColor;
|
import org.bukkit.boss.BarColor;
|
||||||
import org.bukkit.boss.BarStyle;
|
import org.bukkit.boss.BarStyle;
|
||||||
@ -38,7 +39,6 @@ import org.bukkit.command.CommandSender;
|
|||||||
import org.bukkit.entity.*;
|
import org.bukkit.entity.*;
|
||||||
import org.bukkit.metadata.FixedMetadataValue;
|
import org.bukkit.metadata.FixedMetadataValue;
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -71,7 +71,7 @@ public abstract class Disguise {
|
|||||||
/**
|
/**
|
||||||
* If set, how long before disguise expires
|
* If set, how long before disguise expires
|
||||||
*/
|
*/
|
||||||
private long disguiseExpires;
|
protected long disguiseExpires;
|
||||||
/**
|
/**
|
||||||
* For when plugins may want to assign custom data to a disguise, such as who owns it
|
* For when plugins may want to assign custom data to a disguise, such as who owns it
|
||||||
*/
|
*/
|
||||||
@ -370,7 +370,7 @@ public abstract class Disguise {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doActionBar() {
|
protected void doActionBar() {
|
||||||
if (getNotifyBar() == DisguiseConfig.NotifyBar.ACTION_BAR && getEntity() instanceof Player && !getEntity().hasPermission("libsdisguises.noactionbar") &&
|
if (getNotifyBar() == DisguiseConfig.NotifyBar.ACTION_BAR && getEntity() instanceof Player && !getEntity().hasPermission("libsdisguises.noactionbar") &&
|
||||||
DisguiseAPI.getDisguise(getEntity()) == Disguise.this) {
|
DisguiseAPI.getDisguise(getEntity()) == Disguise.this) {
|
||||||
((Player) getEntity()).spigot().sendMessage(ChatMessageType.ACTION_BAR, LibsMsg.ACTION_BAR_MESSAGE.getChat(getDisguiseName()));
|
((Player) getEntity()).spigot().sendMessage(ChatMessageType.ACTION_BAR, LibsMsg.ACTION_BAR_MESSAGE.getChat(getDisguiseName()));
|
||||||
@ -394,227 +394,18 @@ public abstract class Disguise {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void createRunnable() {
|
private void createRunnable() {
|
||||||
if (runnable != null) {
|
if (runnable != null && !runnable.isCancelled()) {
|
||||||
runnable.cancel();
|
runnable.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean alwaysSendVelocity;
|
|
||||||
|
|
||||||
switch (getType()) {
|
|
||||||
case EXPERIENCE_ORB:
|
|
||||||
case WITHER_SKULL:
|
|
||||||
case FIREWORK:
|
|
||||||
alwaysSendVelocity = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
alwaysSendVelocity = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Double vectorY;
|
|
||||||
|
|
||||||
switch (getType()) {
|
|
||||||
case FIREWORK:
|
|
||||||
case WITHER_SKULL:
|
|
||||||
vectorY = 0.000001D;
|
|
||||||
break;
|
|
||||||
case EXPERIENCE_ORB:
|
|
||||||
vectorY = 0.0221;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
vectorY = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
final TargetedDisguise disguise = (TargetedDisguise) this;
|
final TargetedDisguise disguise = (TargetedDisguise) this;
|
||||||
|
|
||||||
// A scheduler to clean up any unused disguises.
|
// A scheduler to clean up any unused disguises.
|
||||||
runnable = new BukkitRunnable() {
|
runnable = new DisguiseRunnable(this);
|
||||||
private int blockX, blockY, blockZ, facing;
|
|
||||||
private int deadTicks = 0;
|
|
||||||
private int actionBarTicks = -1;
|
|
||||||
private long lastRefreshed = System.currentTimeMillis();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (!isDisguiseInUse() || getEntity() == null) {
|
|
||||||
cancel();
|
|
||||||
runnable = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (++actionBarTicks % 15 == 0) {
|
|
||||||
actionBarTicks = 0;
|
|
||||||
|
|
||||||
doActionBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If entity is no longer valid. Remove it.
|
|
||||||
if (getEntity() instanceof Player && !((Player) getEntity()).isOnline()) {
|
|
||||||
removeDisguise();
|
|
||||||
} else if (disguiseExpires > 0 &&
|
|
||||||
(DisguiseConfig.isDynamicExpiry() ? disguiseExpires-- == 1 : disguiseExpires < System.currentTimeMillis())) { // If disguise expired
|
|
||||||
removeDisguise();
|
|
||||||
|
|
||||||
if (getEntity() instanceof Player) {
|
|
||||||
LibsMsg.EXPIRED_DISGUISE.send(getEntity());
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
} else if (!getEntity().isValid()) {
|
|
||||||
// If it has been dead for 30+ ticks
|
|
||||||
// This is to ensure that this disguise isn't removed while clients think its the real entity
|
|
||||||
// The delay is because if it sends the destroy entity packets straight away, then it means no
|
|
||||||
// death animation
|
|
||||||
// This is probably still a problem for wither and enderdragon deaths.
|
|
||||||
if (deadTicks++ > (getType() == DisguiseType.ENDER_DRAGON ? 200 : 20)) {
|
|
||||||
if (isRemoveDisguiseOnDeath()) {
|
|
||||||
removeDisguise();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
deadTicks = 0;
|
|
||||||
|
|
||||||
// If the disguise type is tnt, we need to resend the entity packet else it will turn invisible
|
|
||||||
if (getType() == DisguiseType.FIREWORK || getType() == DisguiseType.EVOKER_FANGS) {
|
|
||||||
if (lastRefreshed + ((getType() == DisguiseType.FIREWORK ? 40 : 23) * 50) < System.currentTimeMillis()) {
|
|
||||||
lastRefreshed = System.currentTimeMillis();
|
|
||||||
|
|
||||||
DisguiseUtilities.refreshTrackers(disguise);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isModifyBoundingBox()) {
|
|
||||||
DisguiseUtilities.doBoundingBox(disguise);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getType() == DisguiseType.BAT && !((BatWatcher) getWatcher()).isHanging()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
doVelocity(vectorY, alwaysSendVelocity);
|
|
||||||
|
|
||||||
if (getType() == DisguiseType.EXPERIENCE_ORB) {
|
|
||||||
PacketContainer packet = new PacketContainer(Server.REL_ENTITY_MOVE);
|
|
||||||
|
|
||||||
packet.getIntegers().write(0, getEntity().getEntityId());
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (Player player : DisguiseUtilities.getPerverts(disguise)) {
|
|
||||||
if (getEntity() != player) {
|
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false);
|
|
||||||
continue;
|
|
||||||
} else if (!isSelfDisguiseVisible() || !(getEntity() instanceof Player)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
PacketContainer selfPacket = packet.shallowClone();
|
|
||||||
|
|
||||||
selfPacket.getModifier().write(0, DisguiseAPI.getSelfDisguiseId());
|
|
||||||
|
|
||||||
try {
|
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket((Player) getEntity(), selfPacket, false);
|
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
runnable.runTaskTimer(LibsDisguises.getInstance(), 1, 1);
|
runnable.runTaskTimer(LibsDisguises.getInstance(), 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doVelocity(Double vectorY, boolean alwaysSendVelocity) {
|
|
||||||
// If the vectorY isn't 0. Cos if it is. Then it doesn't want to send any vectors.
|
|
||||||
// If this disguise has velocity sending enabled and the entity is flying.
|
|
||||||
if (isVelocitySent() && vectorY != null && (alwaysSendVelocity || !getEntity().isOnGround())) {
|
|
||||||
Vector vector = getEntity().getVelocity();
|
|
||||||
|
|
||||||
// If the entity doesn't have velocity changes already - You know. I really can't wrap my
|
|
||||||
// head about the
|
|
||||||
// if statement.
|
|
||||||
// But it doesn't seem to do anything wrong..
|
|
||||||
if (vector.getY() != 0 && !(vector.getY() < 0 && alwaysSendVelocity && getEntity().isOnGround())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If disguise isn't a experience orb, or the entity isn't standing on the ground
|
|
||||||
if (getType() != DisguiseType.EXPERIENCE_ORB || !getEntity().isOnGround()) {
|
|
||||||
PacketContainer lookPacket = null;
|
|
||||||
|
|
||||||
if (getType() == DisguiseType.WITHER_SKULL && DisguiseConfig.isWitherSkullPacketsEnabled()) {
|
|
||||||
lookPacket = new PacketContainer(Server.ENTITY_LOOK);
|
|
||||||
|
|
||||||
StructureModifier<Object> mods = lookPacket.getModifier();
|
|
||||||
lookPacket.getIntegers().write(0, getEntity().getEntityId());
|
|
||||||
Location loc = getEntity().getLocation();
|
|
||||||
|
|
||||||
mods.write(4, DisguiseUtilities.getYaw(getType(), getEntity().getType(), (byte) Math.floor(loc.getYaw() * 256.0F / 360.0F)));
|
|
||||||
mods.write(5, DisguiseUtilities.getPitch(getType(), getEntity().getType(), (byte) Math.floor(loc.getPitch() * 256.0F / 360.0F)));
|
|
||||||
|
|
||||||
if (isSelfDisguiseVisible() && getEntity() instanceof Player) {
|
|
||||||
PacketContainer selfLookPacket = lookPacket.shallowClone();
|
|
||||||
|
|
||||||
selfLookPacket.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId());
|
|
||||||
|
|
||||||
try {
|
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket((Player) getEntity(), selfLookPacket, false);
|
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
PacketContainer velocityPacket = new PacketContainer(Server.ENTITY_VELOCITY);
|
|
||||||
|
|
||||||
StructureModifier<Integer> mods = velocityPacket.getIntegers();
|
|
||||||
|
|
||||||
// Write entity ID
|
|
||||||
mods.write(0, getEntity().getEntityId());
|
|
||||||
mods.write(1, (int) (vector.getX() * 8000));
|
|
||||||
mods.write(3, (int) (vector.getZ() * 8000));
|
|
||||||
|
|
||||||
for (Player player : DisguiseUtilities.getPerverts(this)) {
|
|
||||||
PacketContainer tempVelocityPacket = velocityPacket.shallowClone();
|
|
||||||
mods = tempVelocityPacket.getIntegers();
|
|
||||||
|
|
||||||
// If the viewing player is the disguised player
|
|
||||||
if (getEntity() == player) {
|
|
||||||
// If not using self disguise, continue
|
|
||||||
if (!isSelfDisguiseVisible()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write self disguise ID
|
|
||||||
mods.write(0, DisguiseAPI.getSelfDisguiseId());
|
|
||||||
}
|
|
||||||
|
|
||||||
mods.write(2, (int) (8000D * (vectorY * ReflectionManager.getPing(player)) * 0.069D));
|
|
||||||
|
|
||||||
if (lookPacket != null && player != getEntity()) {
|
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, lookPacket, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, tempVelocityPacket, false);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If we need to send a packet to update the exp position as it likes to gravitate client
|
|
||||||
// sided to
|
|
||||||
// players.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the disguised entity
|
* Get the disguised entity
|
||||||
*
|
*
|
||||||
@ -1189,8 +980,7 @@ public abstract class Disguise {
|
|||||||
DisguiseUtilities.refreshTrackers((TargetedDisguise) this);
|
DisguiseUtilities.refreshTrackers((TargetedDisguise) this);
|
||||||
|
|
||||||
// If he is a player, then self disguise himself
|
// If he is a player, then self disguise himself
|
||||||
Bukkit.getScheduler().
|
Bukkit.getScheduler().scheduleSyncDelayedTask(LibsDisguises.getInstance(), new Runnable() {
|
||||||
scheduleSyncDelayedTask(LibsDisguises.getInstance(), new Runnable() {
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
DisguiseUtilities.setupFakeDisguise(Disguise.this);
|
DisguiseUtilities.setupFakeDisguise(Disguise.this);
|
||||||
|
@ -0,0 +1,227 @@
|
|||||||
|
package me.libraryaddict.disguise.disguisetypes;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
import com.comphenix.protocol.reflect.StructureModifier;
|
||||||
|
import me.libraryaddict.disguise.DisguiseAPI;
|
||||||
|
import me.libraryaddict.disguise.DisguiseConfig;
|
||||||
|
import me.libraryaddict.disguise.disguisetypes.watchers.BatWatcher;
|
||||||
|
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
||||||
|
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
|
||||||
|
import me.libraryaddict.disguise.utilities.translations.LibsMsg;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by libraryaddict on 20/05/2021.
|
||||||
|
*/
|
||||||
|
class DisguiseRunnable extends BukkitRunnable {
|
||||||
|
private int blockX, blockY, blockZ, facing;
|
||||||
|
private int deadTicks = 0;
|
||||||
|
private int actionBarTicks = -1;
|
||||||
|
private long lastRefreshed = System.currentTimeMillis();
|
||||||
|
private Disguise disguise;
|
||||||
|
final Double vectorY;
|
||||||
|
final boolean alwaysSendVelocity;
|
||||||
|
|
||||||
|
public DisguiseRunnable(Disguise disguise) {
|
||||||
|
switch (disguise.getType()) {
|
||||||
|
case FIREWORK:
|
||||||
|
case WITHER_SKULL:
|
||||||
|
vectorY = 0.000001D;
|
||||||
|
alwaysSendVelocity = true;
|
||||||
|
break;
|
||||||
|
case EXPERIENCE_ORB:
|
||||||
|
vectorY = 0.0221;
|
||||||
|
alwaysSendVelocity = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
vectorY = null;
|
||||||
|
alwaysSendVelocity = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (!disguise.isDisguiseInUse() || disguise.getEntity() == null) {
|
||||||
|
cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (++actionBarTicks % 15 == 0) {
|
||||||
|
actionBarTicks = 0;
|
||||||
|
|
||||||
|
disguise.doActionBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If entity is no longer valid. Remove it.
|
||||||
|
if (disguise.getEntity() instanceof Player && !((Player) disguise.getEntity()).isOnline()) {
|
||||||
|
disguise.removeDisguise();
|
||||||
|
} else if (disguise.disguiseExpires > 0 && (DisguiseConfig.isDynamicExpiry() ? disguise.disguiseExpires-- == 1 :
|
||||||
|
disguise.disguiseExpires < System.currentTimeMillis())) { // If disguise expired
|
||||||
|
disguise.removeDisguise();
|
||||||
|
|
||||||
|
if (disguise.getEntity() instanceof Player) {
|
||||||
|
LibsMsg.EXPIRED_DISGUISE.send(disguise.getEntity());
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
} else if (!disguise.getEntity().isValid()) {
|
||||||
|
// If it has been dead for 30+ ticks
|
||||||
|
// This is to ensure that this disguise isn't removed while clients think its the real entity
|
||||||
|
// The delay is because if it sends the destroy entity packets straight away, then it means no
|
||||||
|
// death animation
|
||||||
|
// This is probably still a problem for wither and enderdragon deaths.
|
||||||
|
if (deadTicks++ > (disguise.getType() == DisguiseType.ENDER_DRAGON ? 200 : 20)) {
|
||||||
|
if (disguise.isRemoveDisguiseOnDeath()) {
|
||||||
|
disguise.removeDisguise();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
deadTicks = 0;
|
||||||
|
|
||||||
|
// If the disguise type is tnt, we need to resend the entity packet else it will turn invisible
|
||||||
|
if (disguise.getType() == DisguiseType.FIREWORK || disguise.getType() == DisguiseType.EVOKER_FANGS) {
|
||||||
|
if (lastRefreshed + ((disguise.getType() == DisguiseType.FIREWORK ? 40 : 23) * 50) < System.currentTimeMillis()) {
|
||||||
|
lastRefreshed = System.currentTimeMillis();
|
||||||
|
|
||||||
|
DisguiseUtilities.refreshTrackers((TargetedDisguise) disguise);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disguise.isModifyBoundingBox()) {
|
||||||
|
DisguiseUtilities.doBoundingBox((TargetedDisguise) disguise);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disguise.getType() == DisguiseType.BAT && !((BatWatcher) disguise.getWatcher()).isHanging()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
doVelocity(vectorY, alwaysSendVelocity);
|
||||||
|
|
||||||
|
if (disguise.getType() == DisguiseType.EXPERIENCE_ORB) {
|
||||||
|
PacketContainer packet = new PacketContainer(PacketType.Play.Server.REL_ENTITY_MOVE);
|
||||||
|
|
||||||
|
packet.getIntegers().write(0, disguise.getEntity().getEntityId());
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (Player player : DisguiseUtilities.getPerverts(disguise)) {
|
||||||
|
if (disguise.getEntity() != player) {
|
||||||
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false);
|
||||||
|
continue;
|
||||||
|
} else if (!disguise.isSelfDisguiseVisible() || !(disguise.getEntity() instanceof Player)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketContainer selfPacket = packet.shallowClone();
|
||||||
|
|
||||||
|
selfPacket.getModifier().write(0, DisguiseAPI.getSelfDisguiseId());
|
||||||
|
|
||||||
|
try {
|
||||||
|
ProtocolLibrary.getProtocolManager().sendServerPacket((Player) disguise.getEntity(), selfPacket, false);
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doVelocity(Double vectorY, boolean alwaysSendVelocity) {
|
||||||
|
// If the vectorY isn't 0. Cos if it is. Then it doesn't want to send any vectors.
|
||||||
|
// If this disguise has velocity sending enabled and the entity is flying.
|
||||||
|
if (disguise.isVelocitySent() && vectorY != null && (alwaysSendVelocity || !disguise.getEntity().isOnGround())) {
|
||||||
|
Vector vector = disguise.getEntity().getVelocity();
|
||||||
|
|
||||||
|
// If the entity doesn't have velocity changes already - You know. I really can't wrap my
|
||||||
|
// head about the
|
||||||
|
// if statement.
|
||||||
|
// But it doesn't seem to do anything wrong..
|
||||||
|
if (vector.getY() != 0 && !(vector.getY() < 0 && alwaysSendVelocity && disguise.getEntity().isOnGround())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If disguise isn't a experience orb, or the entity isn't standing on the ground
|
||||||
|
if (disguise.getType() != DisguiseType.EXPERIENCE_ORB || !disguise.getEntity().isOnGround()) {
|
||||||
|
PacketContainer lookPacket = null;
|
||||||
|
|
||||||
|
if (disguise.getType() == DisguiseType.WITHER_SKULL && DisguiseConfig.isWitherSkullPacketsEnabled()) {
|
||||||
|
lookPacket = new PacketContainer(PacketType.Play.Server.ENTITY_LOOK);
|
||||||
|
|
||||||
|
StructureModifier<Object> mods = lookPacket.getModifier();
|
||||||
|
lookPacket.getIntegers().write(0, disguise.getEntity().getEntityId());
|
||||||
|
Location loc = disguise.getEntity().getLocation();
|
||||||
|
|
||||||
|
mods.write(4,
|
||||||
|
DisguiseUtilities.getYaw(disguise.getType(), disguise.getEntity().getType(), (byte) Math.floor(loc.getYaw() * 256.0F / 360.0F)));
|
||||||
|
mods.write(5, DisguiseUtilities
|
||||||
|
.getPitch(disguise.getType(), disguise.getEntity().getType(), (byte) Math.floor(loc.getPitch() * 256.0F / 360.0F)));
|
||||||
|
|
||||||
|
if (disguise.isSelfDisguiseVisible() && disguise.getEntity() instanceof Player) {
|
||||||
|
PacketContainer selfLookPacket = lookPacket.shallowClone();
|
||||||
|
|
||||||
|
selfLookPacket.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId());
|
||||||
|
|
||||||
|
try {
|
||||||
|
ProtocolLibrary.getProtocolManager().sendServerPacket((Player) disguise.getEntity(), selfLookPacket, false);
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
PacketContainer velocityPacket = new PacketContainer(PacketType.Play.Server.ENTITY_VELOCITY);
|
||||||
|
|
||||||
|
StructureModifier<Integer> mods = velocityPacket.getIntegers();
|
||||||
|
|
||||||
|
// Write entity ID
|
||||||
|
mods.write(0, disguise.getEntity().getEntityId());
|
||||||
|
mods.write(1, (int) (vector.getX() * 8000));
|
||||||
|
mods.write(3, (int) (vector.getZ() * 8000));
|
||||||
|
|
||||||
|
for (Player player : DisguiseUtilities.getPerverts(disguise)) {
|
||||||
|
PacketContainer tempVelocityPacket = velocityPacket.shallowClone();
|
||||||
|
mods = tempVelocityPacket.getIntegers();
|
||||||
|
|
||||||
|
// If the viewing player is the disguised player
|
||||||
|
if (disguise.getEntity() == player) {
|
||||||
|
// If not using self disguise, continue
|
||||||
|
if (!disguise.isSelfDisguiseVisible()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write self disguise ID
|
||||||
|
mods.write(0, DisguiseAPI.getSelfDisguiseId());
|
||||||
|
}
|
||||||
|
|
||||||
|
mods.write(2, (int) (8000D * (vectorY * ReflectionManager.getPing(player)) * 0.069D));
|
||||||
|
|
||||||
|
if (lookPacket != null && player != disguise.getEntity()) {
|
||||||
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, lookPacket, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, tempVelocityPacket, false);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If we need to send a packet to update the exp position as it likes to gravitate client
|
||||||
|
// sided to
|
||||||
|
// players.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,6 @@ package me.libraryaddict.disguise.utilities.reflection.asm;
|
|||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -11,8 +10,7 @@ import java.util.Map;
|
|||||||
* Created by libraryaddict on 17/02/2020.
|
* Created by libraryaddict on 17/02/2020.
|
||||||
*/
|
*/
|
||||||
public class Asm13 {
|
public class Asm13 {
|
||||||
public byte[] createClassWithoutMethods(String className, ArrayList<Map.Entry<String, String>> illegalMethods)
|
public byte[] createClassWithoutMethods(String className, ArrayList<Map.Entry<String, String>> illegalMethods) throws IOException {
|
||||||
throws IOException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
|
|
||||||
className = className.replace(".", "/") + ".class";
|
className = className.replace(".", "/") + ".class";
|
||||||
|
|
||||||
ClassReader cr = new ClassReader(getClass().getClassLoader().getResourceAsStream(className));
|
ClassReader cr = new ClassReader(getClass().getClassLoader().getResourceAsStream(className));
|
||||||
@ -20,7 +18,6 @@ public class Asm13 {
|
|||||||
|
|
||||||
cr.accept(new ClassVisitor(Opcodes.ASM5, writer) {
|
cr.accept(new ClassVisitor(Opcodes.ASM5, writer) {
|
||||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||||
|
|
||||||
Map.Entry<String, String> entry =
|
Map.Entry<String, String> entry =
|
||||||
illegalMethods.stream().filter(e -> e.getKey().equals(name) && e.getValue().equals(desc)).findFirst().orElse(null);
|
illegalMethods.stream().filter(e -> e.getKey().equals(name) && e.getValue().equals(desc)).findFirst().orElse(null);
|
||||||
|
|
||||||
|
@ -7,8 +7,6 @@ import java.io.BufferedInputStream;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
@ -28,7 +26,6 @@ public class AsmLoader {
|
|||||||
private final File filePath = new File(LibsDisguises.getInstance().getDataFolder(), "libs/org-ow2-asm-9.1.jar");
|
private final File filePath = new File(LibsDisguises.getInstance().getDataFolder(), "libs/org-ow2-asm-9.1.jar");
|
||||||
private boolean asmExists;
|
private boolean asmExists;
|
||||||
private URLClassLoader classLoader;
|
private URLClassLoader classLoader;
|
||||||
private LibsJarFile libsJarFile;
|
|
||||||
|
|
||||||
public AsmLoader() {
|
public AsmLoader() {
|
||||||
try {
|
try {
|
||||||
@ -47,28 +44,6 @@ public class AsmLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void load() {
|
|
||||||
try {
|
|
||||||
ClassLoader pluginClassLoader = getClass().getClassLoader();
|
|
||||||
Class c = Class.forName("org.bukkit.plugin.java.PluginClassLoader");
|
|
||||||
Field file = c.getDeclaredField("file");
|
|
||||||
file.setAccessible(true);
|
|
||||||
|
|
||||||
libsJarFile = new LibsJarFile((File) file.get(pluginClassLoader));
|
|
||||||
|
|
||||||
Field field = c.getDeclaredField("jar");
|
|
||||||
field.setAccessible(true);
|
|
||||||
|
|
||||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
|
||||||
modifiersField.setAccessible(true);
|
|
||||||
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
|
|
||||||
|
|
||||||
field.set(pluginClassLoader, libsJarFile);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unload() {
|
public void unload() {
|
||||||
try {
|
try {
|
||||||
classLoader.close();
|
classLoader.close();
|
||||||
|
@ -0,0 +1,120 @@
|
|||||||
|
package me.libraryaddict.disguise.utilities.reflection.asm;
|
||||||
|
|
||||||
|
import me.libraryaddict.disguise.LibsDisguises;
|
||||||
|
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.jar.JarEntry;
|
||||||
|
import java.util.jar.JarFile;
|
||||||
|
import java.util.jar.JarOutputStream;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by libraryaddict on 20/05/2021.
|
||||||
|
*/
|
||||||
|
public class FakePluginCreator {
|
||||||
|
public String getPluginYAML() {
|
||||||
|
return "name: LibsDisguisesVersioning\nmain: " + getPluginClassPath().replace(".class", "").replace("/", ".") +
|
||||||
|
"\ndescription: Plugin created by Libs Disguises for " +
|
||||||
|
"compatibility with different versions\nversion: 1.0.0\nauthor: libraryaddict\napi-version: '1.13'\nsoftdepend: [ProtocolLib, LibsDisguises]";
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getDestination() {
|
||||||
|
return new File(LibsDisguises.getInstance().getDataFolder(), "libs/LibsDisguisesCompat.jar");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPluginClassPath() {
|
||||||
|
return "me/libraryaddict/disguise/utilities/reflection/asm/LibsDisguisesCompat.class";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() throws Exception {
|
||||||
|
File dest = getDestination();
|
||||||
|
|
||||||
|
if (!dest.exists()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
JarFile jarFile = new JarFile(dest);
|
||||||
|
|
||||||
|
try (InputStream stream = jarFile.getInputStream(jarFile.getEntry("version.txt"))) {
|
||||||
|
return new BufferedReader(new InputStreamReader(stream)).lines().collect(Collectors.joining("\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOurVersion() {
|
||||||
|
YamlConfiguration pluginYml = ReflectionManager.getPluginYAML(LibsDisguises.getInstance().getFile());
|
||||||
|
|
||||||
|
String buildNo = StringUtils.stripToNull(pluginYml.getString("build-number"));
|
||||||
|
|
||||||
|
return buildNo != null && buildNo.matches("[0-9]+") ? ReflectionManager.getBukkitVersion() + " " + Integer.parseInt(buildNo) :
|
||||||
|
ReflectionManager.getBukkitVersion() + " CUSTOM";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createJar(String ourVersion, Map<String, byte[]> classes) throws Exception {
|
||||||
|
File dest = getDestination();
|
||||||
|
|
||||||
|
if (!dest.getParentFile().exists()) {
|
||||||
|
dest.getParentFile().mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dest.exists()) {
|
||||||
|
dest.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
JarOutputStream out = new JarOutputStream(new FileOutputStream(dest));
|
||||||
|
|
||||||
|
out.putNextEntry(new ZipEntry("plugin.yml"));
|
||||||
|
out.write(getPluginYAML().getBytes(StandardCharsets.UTF_8));
|
||||||
|
out.closeEntry();
|
||||||
|
|
||||||
|
// Write our main plugin class
|
||||||
|
try (JarFile jar = new JarFile(LibsDisguises.getInstance().getFile())) {
|
||||||
|
Enumeration<JarEntry> entries = jar.entries();
|
||||||
|
String mainPath = getPluginClassPath().replace(".class", "");
|
||||||
|
|
||||||
|
while (entries.hasMoreElements()) {
|
||||||
|
JarEntry entry = entries.nextElement();
|
||||||
|
|
||||||
|
if (!entry.getName().equals(mainPath) && !entry.getName().startsWith("me/libraryaddict/disguise/disguisetypes/")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (classes.containsKey(entry.getName())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.putNextEntry(new ZipEntry(entry.getName().equals(mainPath) ? getPluginClassPath() : entry.getName()));
|
||||||
|
|
||||||
|
try (InputStream stream = jar.getInputStream(entry)) {
|
||||||
|
int nRead;
|
||||||
|
byte[] data = new byte[1024];
|
||||||
|
while ((nRead = stream.read(data, 0, data.length)) != -1) {
|
||||||
|
out.write(data, 0, nRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out.closeEntry();
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<String, byte[]> entry : classes.entrySet()) {
|
||||||
|
out.putNextEntry(new ZipEntry(entry.getKey()));
|
||||||
|
out.write(entry.getValue());
|
||||||
|
out.closeEntry();
|
||||||
|
}
|
||||||
|
|
||||||
|
out.putNextEntry(new ZipEntry("version.txt"));
|
||||||
|
out.write(ourVersion.getBytes(StandardCharsets.UTF_8));
|
||||||
|
out.closeEntry();
|
||||||
|
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package me.libraryaddict.disguise.utilities.reflection.asm;
|
||||||
|
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by libraryaddict on 20/05/2021.
|
||||||
|
*/
|
||||||
|
public class LibsDisguisesCompat extends JavaPlugin {
|
||||||
|
}
|
@ -1,39 +0,0 @@
|
|||||||
package me.libraryaddict.disguise.utilities.reflection.asm;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.jar.JarFile;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by libraryaddict on 15/05/2021.
|
|
||||||
*/
|
|
||||||
public class LibsJarFile extends JarFile {
|
|
||||||
private final HashMap<String, byte[]> customFiles = new HashMap<>();
|
|
||||||
|
|
||||||
public LibsJarFile(File file) throws IOException {
|
|
||||||
super(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized InputStream getInputStream(ZipEntry ze) throws IOException {
|
|
||||||
if (customFiles.containsKey(ze.getName())) {
|
|
||||||
return new ByteArrayInputStream(customFiles.get(ze.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.getInputStream(ze);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addClass(String name, byte[] bytes) {
|
|
||||||
customFiles.put(name, bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
customFiles.clear();
|
|
||||||
super.close();
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,9 +3,12 @@ package me.libraryaddict.disguise.utilities.reflection.asm;
|
|||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import me.libraryaddict.disguise.LibsDisguises;
|
import me.libraryaddict.disguise.LibsDisguises;
|
||||||
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
|
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.PluginDescriptionFile;
|
import org.bukkit.plugin.PluginDescriptionFile;
|
||||||
import org.bukkit.plugin.java.JavaPluginLoader;
|
import org.bukkit.plugin.java.JavaPluginLoader;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@ -69,11 +72,29 @@ public class WatcherSanitizer {
|
|||||||
} catch (NoSuchFieldException | IllegalAccessException ignored) {
|
} catch (NoSuchFieldException | IllegalAccessException ignored) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Bukkit.getPluginManager().getPlugin("LibsDisguisesVersioning") != null) {
|
||||||
|
throw new IllegalStateException("Why is LibsDisguisesVersioning already active? Did the server owner do something.. Weird?");
|
||||||
|
}
|
||||||
|
|
||||||
|
FakePluginCreator fakePluginCreator = new FakePluginCreator();
|
||||||
|
|
||||||
|
String ourVers = fakePluginCreator.getOurVersion();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (ourVers != null && ourVers.equals(fakePluginCreator.getVersion()) && !ourVers.contains(" CUSTOM")) {
|
||||||
|
loadPlugin(fakePluginCreator);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
LibsDisguises.getInstance().getLogger().info("Creating a new version compatibility jar");
|
||||||
|
|
||||||
ArrayList<String> mapped = new ArrayList<>();
|
ArrayList<String> mapped = new ArrayList<>();
|
||||||
|
|
||||||
try (InputStream stream = LibsDisguises.getInstance().getResource("ANTI_PIRACY_ENCRYPTION")) {
|
try (InputStream stream = LibsDisguises.getInstance().getResource("ANTI_PIRACY_ENCRYPTION")) {
|
||||||
AsmLoader loader = new AsmLoader();
|
AsmLoader loader = new AsmLoader();
|
||||||
loader.load();
|
|
||||||
|
|
||||||
Object obj;
|
Object obj;
|
||||||
Method getBytes;
|
Method getBytes;
|
||||||
@ -109,15 +130,18 @@ public class WatcherSanitizer {
|
|||||||
list.add(new HashMap.SimpleEntry(info.getMethod(), info.getDescriptor()));
|
list.add(new HashMap.SimpleEntry(info.getMethod(), info.getDescriptor()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, byte[]> classes = new HashMap<>();
|
||||||
|
|
||||||
for (Map.Entry<String, ArrayList<Map.Entry<String, String>>> entry : toRemove.entrySet()) {
|
for (Map.Entry<String, ArrayList<Map.Entry<String, String>>> entry : toRemove.entrySet()) {
|
||||||
byte[] bytes = (byte[]) getBytes.invoke(obj, entry.getKey(), entry.getValue());
|
byte[] bytes = (byte[]) getBytes.invoke(obj, entry.getKey(), entry.getValue());
|
||||||
mapped.add(entry.getKey());
|
mapped.add(entry.getKey());
|
||||||
|
|
||||||
String name = entry.getKey().replace(".", "/") + ".class";
|
classes.put(entry.getKey().replace(".", "/") + ".class", bytes);
|
||||||
|
|
||||||
loader.getLibsJarFile().addClass(name, bytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fakePluginCreator.createJar(ourVers, classes);
|
||||||
|
loadPlugin(fakePluginCreator);
|
||||||
|
|
||||||
if (!loader.isAsmExists()) {
|
if (!loader.isAsmExists()) {
|
||||||
loader.unload();
|
loader.unload();
|
||||||
}
|
}
|
||||||
@ -126,4 +150,32 @@ public class WatcherSanitizer {
|
|||||||
LibsDisguises.getInstance().getLogger().severe("Registered: " + new Gson().toJson(mapped));
|
LibsDisguises.getInstance().getLogger().severe("Registered: " + new Gson().toJson(mapped));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void loadPlugin(FakePluginCreator fakePluginCreator) throws Exception {
|
||||||
|
LibsDisguises.getInstance().getLogger().info("Starting version support plugin: LibsDisguisesVersioning");
|
||||||
|
Method method = Class.forName("org.bukkit.plugin.PluginManager", false, WatcherSanitizer.class.getClassLoader().getParent())
|
||||||
|
.getMethod("loadPlugin", File.class);
|
||||||
|
|
||||||
|
Plugin plugin = (Plugin) method.invoke(Bukkit.getPluginManager(), fakePluginCreator.getDestination());
|
||||||
|
|
||||||
|
Class pluginClassLoader = Class.forName("org.bukkit.plugin.java.PluginClassLoader");
|
||||||
|
|
||||||
|
Field loaderField = JavaPluginLoader.class.getDeclaredField("loaders");
|
||||||
|
loaderField.setAccessible(true);
|
||||||
|
List loaderList = (List) loaderField.get(LibsDisguises.getInstance().getPluginLoader());
|
||||||
|
|
||||||
|
Field pluginOwner = pluginClassLoader.getDeclaredField("plugin");
|
||||||
|
pluginOwner.setAccessible(true);
|
||||||
|
|
||||||
|
// Move Lib's Disguises to load its classes after the new plugin
|
||||||
|
for (Object o : loaderList) {
|
||||||
|
if (pluginOwner.get(o) != LibsDisguises.getInstance()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
loaderList.remove(o);
|
||||||
|
loaderList.add(o);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import me.libraryaddict.disguise.utilities.LibsPremium;
|
|||||||
import me.libraryaddict.disguise.utilities.reflection.ClassGetter;
|
import me.libraryaddict.disguise.utilities.reflection.ClassGetter;
|
||||||
import me.libraryaddict.disguise.utilities.reflection.NmsAddedIn;
|
import me.libraryaddict.disguise.utilities.reflection.NmsAddedIn;
|
||||||
import me.libraryaddict.disguise.utilities.reflection.NmsRemovedIn;
|
import me.libraryaddict.disguise.utilities.reflection.NmsRemovedIn;
|
||||||
|
import me.libraryaddict.disguise.utilities.reflection.asm.FakePluginCreator;
|
||||||
import me.libraryaddict.disguise.utilities.sounds.DisguiseSoundEnums;
|
import me.libraryaddict.disguise.utilities.sounds.DisguiseSoundEnums;
|
||||||
import me.libraryaddict.disguise.utilities.sounds.SoundGroup;
|
import me.libraryaddict.disguise.utilities.sounds.SoundGroup;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
@ -34,6 +35,14 @@ public class CompileMethods {
|
|||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
doMethods();
|
doMethods();
|
||||||
doSounds();
|
doSounds();
|
||||||
|
moveCompat();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void moveCompat() {
|
||||||
|
FakePluginCreator creator = new FakePluginCreator();
|
||||||
|
|
||||||
|
File compatFile = new File("target/classes/" + creator.getPluginClassPath());
|
||||||
|
compatFile.renameTo(new File(compatFile.getParentFile(), compatFile.getName().replace(".class", "")));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void doSounds() {
|
private static void doSounds() {
|
||||||
@ -91,8 +100,7 @@ public class CompileMethods {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void doMethods() {
|
private static void doMethods() {
|
||||||
ArrayList<Class<?>> classes =
|
ArrayList<Class<?>> classes = ClassGetter.getClassesForPackage(FlagWatcher.class, "me.libraryaddict.disguise.disguisetypes.watchers");
|
||||||
ClassGetter.getClassesForPackage(FlagWatcher.class, "me.libraryaddict.disguise.disguisetypes.watchers");
|
|
||||||
|
|
||||||
ArrayList<Class> sorted = new ArrayList<>();
|
ArrayList<Class> sorted = new ArrayList<>();
|
||||||
|
|
||||||
@ -106,12 +114,10 @@ public class CompileMethods {
|
|||||||
for (Method method : c.getMethods()) {
|
for (Method method : c.getMethods()) {
|
||||||
if (!FlagWatcher.class.isAssignableFrom(method.getDeclaringClass())) {
|
if (!FlagWatcher.class.isAssignableFrom(method.getDeclaringClass())) {
|
||||||
continue;
|
continue;
|
||||||
} else if (method.getParameterCount() > 1 && !method.isAnnotationPresent(NmsAddedIn.class) &&
|
} else if (method.getParameterCount() > 1 && !method.isAnnotationPresent(NmsAddedIn.class) && !method.isAnnotationPresent(NmsRemovedIn.class)) {
|
||||||
!method.isAnnotationPresent(NmsRemovedIn.class)) {
|
|
||||||
continue;
|
continue;
|
||||||
} else if (!(method.getName().startsWith("set") && method.getParameterCount() == 1) &&
|
} else if (!(method.getName().startsWith("set") && method.getParameterCount() == 1) && !method.getName().startsWith("get") &&
|
||||||
!method.getName().startsWith("get") && !method.getName().startsWith("has") &&
|
!method.getName().startsWith("has") && !method.getName().startsWith("is")) {
|
||||||
!method.getName().startsWith("is")) {
|
|
||||||
continue;
|
continue;
|
||||||
} else if (method.getName().equals("removePotionEffect")) {
|
} else if (method.getName().equals("removePotionEffect")) {
|
||||||
continue;
|
continue;
|
||||||
@ -141,8 +147,7 @@ public class CompileMethods {
|
|||||||
descriptor = ":" + getMethodDescriptor(method) + ":" + added + ":" + removed;
|
descriptor = ":" + getMethodDescriptor(method) + ":" + added + ":" + removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
String s =
|
String s = method.getDeclaringClass().getSimpleName() + ":" + method.getName() + ":" + param + descriptor;
|
||||||
method.getDeclaringClass().getSimpleName() + ":" + method.getName() + ":" + param + descriptor;
|
|
||||||
|
|
||||||
if (methods.contains(s)) {
|
if (methods.contains(s)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -6,7 +6,7 @@ build-date: ${timestamp}
|
|||||||
build-number: ${build.number}
|
build-number: ${build.number}
|
||||||
author: libraryaddict
|
author: libraryaddict
|
||||||
authors: [Byteflux, Navid K.]
|
authors: [Byteflux, Navid K.]
|
||||||
softdepend: [ProtocolLib]
|
softdepend: [ProtocolLib, LibsDisguisesVersioning]
|
||||||
api-version: '1.13'
|
api-version: '1.13'
|
||||||
commands:
|
commands:
|
||||||
libsdisguises:
|
libsdisguises:
|
||||||
|
Loading…
Reference in New Issue
Block a user