Update to spigot 1.16.3. Add fake players. Reorganize tweaks.

master
kalle 2020-09-23 11:07:11 +02:00
parent 1b5cc25435
commit 31ce91a823
26 changed files with 681 additions and 12 deletions

View File

@ -21,7 +21,7 @@ repositories {
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile 'org.spigotmc:spigot:1.16.1-R0.1-SNAPSHOT'
compile 'org.spigotmc:spigot:1.16.3-R0.1-SNAPSHOT'
}
import org.apache.tools.ant.filters.ReplaceTokens

View File

@ -5,13 +5,9 @@ import nl.kallestruik.vanillatweaks.commands.CommandToggletrample;
import nl.kallestruik.vanillatweaks.core.TweakManager;
import nl.kallestruik.vanillatweaks.core.TweakStates;
import nl.kallestruik.vanillatweaks.tweaks.craftingtweaks.*;
import nl.kallestruik.vanillatweaks.tweaks.croptweaks.MobsCantTrampleCrops;
import nl.kallestruik.vanillatweaks.tweaks.croptweaks.PlayersCantTrampleCrops;
import nl.kallestruik.vanillatweaks.tweaks.croptweaks.*;
import nl.kallestruik.vanillatweaks.tweaks.dispensertweaks.DispensersCanPlantSaplings;
import nl.kallestruik.vanillatweaks.tweaks.miscellaneoustweaks.ArmorStandArmorSwapping;
import nl.kallestruik.vanillatweaks.tweaks.miscellaneoustweaks.HoesHarvestArea;
import nl.kallestruik.vanillatweaks.tweaks.miscellaneoustweaks.LilypadBonemealing;
import nl.kallestruik.vanillatweaks.tweaks.miscellaneoustweaks.SeedDropPlanting;
import nl.kallestruik.vanillatweaks.tweaks.miscellaneoustweaks.*;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
@ -30,6 +26,7 @@ public final class VanillaTweaks extends JavaPlugin {
* Commands
*/
getCommand("toggletrample").setExecutor(new CommandToggletrample());
getCommand("player").setExecutor(new CommandPlayer());
/*
* Crafting Tweaks
@ -59,6 +56,7 @@ public final class VanillaTweaks extends JavaPlugin {
* Miscellaneous Tweaks
*/
TweakManager.registerTweak(new ArmorStandArmorSwapping(), this);
TweakManager.registerTweak(new FakePlayers(), this);
TweakManager.registerTweak(new HoesHarvestArea(), this);
TweakManager.registerTweak(new LilypadBonemealing(), this);
TweakManager.registerTweak(new SeedDropPlanting(), this);

View File

@ -0,0 +1,33 @@
package nl.kallestruik.vanillatweaks.commands;
import nl.kallestruik.vanillatweaks.fakeplayer.FakePlayerManager;
import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class CommandPlayer implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player))
return false;
if (args.length < 2)
return false;
Player player = ((Player) sender);
Location loc = player.getLocation();
switch (args[1]) {
case "spawn":
FakePlayerManager.spawnFakePlayer(loc, args[0]);
break;
case "kill":
FakePlayerManager.killFakePlayer(args[0]);
break;
}
return true;
}
}

View File

@ -19,10 +19,10 @@ public class CommandToggletrample implements CommandExecutor {
Player player = (Player) sender;
if (PlayersCantTrampleCrops.trampleEnabled.remove(player.getUniqueId())) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&2Crop Trampling: &2&lEnabled"));
player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&2Crop Trampling: &4&lDisabled"));
} else {
PlayersCantTrampleCrops.trampleEnabled.add(player.getUniqueId());
player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&2Crop Trampling: &4&lDisabled"));
player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&2Crop Trampling: &2&lEnabled"));
}
return true;
}

View File

@ -0,0 +1,39 @@
package nl.kallestruik.vanillatweaks.fakeplayer;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import net.minecraft.server.v1_16_R2.EnumProtocolDirection;
import net.minecraft.server.v1_16_R2.NetworkManager;
import net.minecraft.server.v1_16_R2.Packet;
import javax.annotation.Nullable;
public class FakeConnection extends NetworkManager {
public boolean open = true;
public FakeConnection(EnumProtocolDirection enumprotocoldirection) {
super(enumprotocoldirection);
}
// isOpen()
@Override
public boolean isConnected() {
return this.open;
}
// hasChannel()
@Override
public boolean i() {
return false;
}
@Override
public void sendPacket(Packet<?> packet, @Nullable GenericFutureListener<? extends Future<? super Void>> genericfuturelistener) {}
// disableAutoRead()
@Override
public void stopReading() {}
@Override
public void handleDisconnection() {}
}

View File

@ -0,0 +1,157 @@
package nl.kallestruik.vanillatweaks.fakeplayer;
import com.mojang.authlib.GameProfile;
import net.minecraft.server.v1_16_R2.*;
import nl.kallestruik.vanillatweaks.util.ReflectionUtil;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_16_R2.CraftWorld;
import javax.annotation.Nullable;
import java.util.List;
public class FakePlayer extends EntityPlayer {
private boolean hasStartingPos;
private double startingX, startingY, startingZ;
private float startingYaw, startingPitch;
public FakePlayer(MinecraftServer minecraftserver, WorldServer worldserver, GameProfile gameprofile, PlayerInteractManager playerinteractmanager) {
super(minecraftserver, worldserver, gameprofile, playerinteractmanager);
this.hasStartingPos = false;
}
private FakePlayer(MinecraftServer server, WorldServer worldIn, GameProfile profile, PlayerInteractManager interactionManagerIn, double x, double y, double z, float yaw, float pitch) {
super(server, worldIn, profile, interactionManagerIn);
this.hasStartingPos = true;
this.startingX = x;
this.startingY = y;
this.startingZ = z;
this.startingYaw = yaw;
this.startingPitch = pitch;
}
@Nullable
public static FakePlayer atLocation(Location location, String name) {
// Split the location into its parts for use later.
double x = location.getX();
double y = location.getY();
double z = location.getZ();
double yaw = location.getYaw();
double pitch = location.getPitch();
try {
// Get the minecraft server instance.
MinecraftServer minecraftServer = MinecraftServer.getServer();
// Create an empty variable for the world server.
WorldServer worldServer = ((CraftWorld) location.getWorld()).getHandle();
// Get the game profile from the cache (or retrieve it if it is not cached)
GameProfile gameProfile = minecraftServer.getUserCache().getProfile(name);
if (gameProfile == null) {
return null;
}
if (gameProfile.getProperties().containsKey("textures")) {
gameProfile = TileEntitySkull.b(gameProfile, null, true).get();
}
// Create a player interact manager using the world server.
PlayerInteractManager playerInteractManager = new PlayerInteractManager(worldServer);
// Create an instance of our fake player.
FakePlayer instance = new FakePlayer(minecraftServer, worldServer, gameProfile, playerInteractManager, x, y, z, (float) yaw, (float) pitch);
// Create a fake connection for our fake player.
FakeConnection connection = new FakeConnection(EnumProtocolDirection.SERVERBOUND);
// Set access to connected channels so we can add our own connection.
ServerConnection serverConnection = minecraftServer.getServerConnection();
((List<NetworkManager>) ReflectionUtil.getValueFromField(serverConnection, "connectedChannels")).add(connection);
// Connect the fake player to the server using the fake connection.
FakePlayerList.a(minecraftServer.getPlayerList(), connection, instance);
// Check if the fake player is not yet in the correct world.
if (!instance.world.getDimensionKey().equals(worldServer.getDimensionKey())) {
// Store the old world of the fake player.
WorldServer old_world = (WorldServer) instance.world;
// Remove the fake player from the old world.
old_world.removePlayer(instance);
// Make the fake player not be dead.
instance.dead = false;
// Create the fake player in the new world.
worldServer.addEntity(instance);
// Spawn the fake player in the new world.
instance.spawnIn(worldServer);
// Move the fake player to the new world for the server.
minecraftServer.getPlayerList().moveToWorld(instance, old_world, true, null, false);
// requestTeleport(x, y, z, yaw, pitch)
// Request the teleport from the fake player.
instance.playerConnection.a(x, y, z, (float) yaw, (float) pitch);
// Set the fake player's world to the new world.
instance.playerInteractManager.world = worldServer;
}
/// Set the fake players health to max.
instance.setHealth(20.0F);
// Make the fake player not be dead.
instance.dead = false;
// a == requestTeleport
// Request the teleport from the fake player.
instance.playerConnection.a(x, y, z, (float) yaw, (float) pitch);
// G == stepHeight
// Set the fake players step height to 0.6 (The normal value).
instance.G = 0.6F;
// Set the fake players gamemode to survival.
playerInteractManager.setGameMode(EnumGamemode.SURVIVAL);
// Tell everyone in the world about the fake player and where he is.
minecraftServer.getPlayerList().a(new PacketPlayOutEntityHeadRotation(instance, (byte) (instance.yaw * 256 / 360)), instance.world.getDimensionKey());
minecraftServer.getPlayerList().a(new PacketPlayOutEntityTeleport(instance), instance.world.getDimensionKey());
// Move the fake player for the worlds chunk provider.
instance.getWorldServer().getChunkProvider().movePlayer(instance);
// bp == PLAYER_MODEL_PARTS
instance.datawatcher.set(bj, (byte) 0x7f); // show all model layers (incl. capes)
return instance;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void applyStartingPosition() {
if (hasStartingPos) {
this.setPositionRotation(startingX, startingY, startingZ, startingYaw, startingPitch);
this.setMot(new Vec3D(0, 0, 0));
}
}
@Override
public void killEntity() {
this.server.a(new TickTask(this.server.ah(), () -> {
this.playerConnection.a(new ChatComponentText("Killed"));
}));
}
@Override
public void tick() {
super.tick();
if (this.H()) {
this.I();
}
this.movementTick();
if (this.server.ah() % 10 == 0) {
this.playerConnection.syncPosition();
this.getWorldServer().getChunkProvider().movePlayer(this);
}
}
@Override
public void die(DamageSource cause) {
super.die(cause);
setHealth(20);
this.foodData = new FoodMetaData(this);
killEntity();
}
}

View File

@ -0,0 +1,50 @@
package nl.kallestruik.vanillatweaks.fakeplayer;
import net.minecraft.server.v1_16_R2.*;
import nl.kallestruik.vanillatweaks.util.ReflectionUtil;
import java.lang.reflect.Field;
public class FakePlayerConnection extends PlayerConnection {
public FakePlayerConnection(MinecraftServer minecraftserver, NetworkManager networkmanager, EntityPlayer entityplayer) {
super(minecraftserver, networkmanager, entityplayer);
}
@Override
public void tick() {
super.tick();
}
@Override
public void sendPacket(final Packet<?> packet) {
if (packet instanceof PacketPlayOutKeepAlive) {
PacketPlayOutKeepAlive ping = (PacketPlayOutKeepAlive) packet;
PacketPlayInKeepAlive pong = new PacketPlayInKeepAlive();
try {
Field pingId = ReflectionUtil.getField(PacketPlayOutKeepAlive.class, "a");
Field pongId = ReflectionUtil.getField(PacketPlayInKeepAlive.class, "a");
pingId.setAccessible(true);
pongId.setAccessible(true);
pongId.set(pong, pingId.get(ping));
} catch (Exception e) {
e.printStackTrace();
}
this.a(pong);
}
}
@Override
public void disconnect(String message) {
player.killEntity();
}
@Override
public void a(IChatBaseComponent text_1) {
super.a(text_1);
((FakeConnection) this.a()).open = false;
}
}

View File

@ -0,0 +1,240 @@
package nl.kallestruik.vanillatweaks.fakeplayer;
import com.mojang.authlib.GameProfile;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.Dynamic;
import io.netty.buffer.Unpooled;
import net.minecraft.server.v1_16_R2.*;
import nl.kallestruik.vanillatweaks.util.ReflectionUtil;
import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_16_R2.CraftServer;
import org.bukkit.craftbukkit.v1_16_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_16_R2.util.CraftChatMessage;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerJoinEvent;
import org.spigotmc.event.player.PlayerSpawnLocationEvent;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
public class FakePlayerList {
public static void a(PlayerList playerList, NetworkManager networkmanager, EntityPlayer entityplayer) {
MinecraftServer server = ((MinecraftServer) ReflectionUtil.getValueFromField(playerList, "server"));
Logger LOGGER = ((Logger) ReflectionUtil.getValueFromField(playerList, "LOGGER"));
GameProfile gameprofile = entityplayer.getProfile();
UserCache usercache = server.getUserCache();
GameProfile gameprofile1 = usercache.getProfile(gameprofile.getId());
String s = gameprofile1 == null ? gameprofile.getName() : gameprofile1.getName();
usercache.a(gameprofile);
NBTTagCompound nbttagcompound = playerList.a(entityplayer);
if (nbttagcompound != null && nbttagcompound.hasKey("bukkit")) {
NBTTagCompound bukkit = nbttagcompound.getCompound("bukkit");
s = bukkit.hasKeyOfType("lastKnownName", 8) ? bukkit.getString("lastKnownName") : s;
}
ResourceKey resourcekey;
if (nbttagcompound != null) {
DataResult dataresult = DimensionManager.a(new Dynamic(DynamicOpsNBT.a, nbttagcompound.get("Dimension")));
Logger logger = LOGGER;
logger.getClass();
logger.getClass();
resourcekey = (ResourceKey)dataresult.resultOrPartial(logger::error).orElse(World.OVERWORLD);
} else {
resourcekey = World.OVERWORLD;
}
WorldServer worldserver = server.getWorldServer(resourcekey);
WorldServer[] worldserver1 = new WorldServer[1];
if (worldserver == null) {
LOGGER.warn("Unknown respawn dimension {}, defaulting to overworld", resourcekey);
worldserver1[0] = server.E();
} else {
worldserver1[0] = worldserver;
}
entityplayer.spawnIn(worldserver1[0]);
entityplayer.playerInteractManager.a((WorldServer)entityplayer.world);
String s1 = "local";
if (networkmanager.getSocketAddress() != null) {
s1 = networkmanager.getSocketAddress().toString();
}
Player bukkitPlayer = entityplayer.getBukkitEntity();
PlayerSpawnLocationEvent ev = new PlayerSpawnLocationEvent(bukkitPlayer, bukkitPlayer.getLocation());
Bukkit.getPluginManager().callEvent(ev);
Location loc = ev.getSpawnLocation();
worldserver1[0] = ((CraftWorld)loc.getWorld()).getHandle();
entityplayer.spawnIn(worldserver1[0]);
entityplayer.playerInteractManager.a((WorldServer)entityplayer.world);
entityplayer.setPosition(loc.getX(), loc.getY(), loc.getZ());
//entityplayer.setYawPitch(loc.getYaw(), loc.getPitch());
try {
Method setYawPitch = Entity.class.getDeclaredMethod("setYawPitch", float.class, float.class);
setYawPitch.setAccessible(true);
setYawPitch.invoke(entityplayer, loc.getYaw(), loc.getPitch());
} catch (Exception e) {
e.printStackTrace();
}
WorldData worlddata = worldserver1[0].getWorldData();
//playerList.a(entityplayer, (EntityPlayer)null, worldserver1);
try {
Method a = PlayerList.class.getDeclaredMethod("a", EntityPlayer.class, EntityPlayer.class, WorldServer.class);
a.setAccessible(true);
a.invoke(playerList, entityplayer, null, worldserver1[0]);
} catch (Exception e) {
e.printStackTrace();
}
//PlayerConnection playerconnection = new PlayerConnection(server, networkmanager, entityplayer);
PlayerConnection playerconnection;
if (entityplayer instanceof FakePlayer) {
playerconnection = new FakePlayerConnection(server, networkmanager, entityplayer);
} else {
playerconnection = new PlayerConnection(server, networkmanager, entityplayer);
}
GameRules gamerules = worldserver1[0].getGameRules();
boolean flag = gamerules.getBoolean(GameRules.DO_IMMEDIATE_RESPAWN);
boolean flag1 = gamerules.getBoolean(GameRules.REDUCED_DEBUG_INFO);
try {
playerconnection.sendPacket(new PacketPlayOutLogin(entityplayer.getId(), entityplayer.playerInteractManager.getGameMode(), entityplayer.playerInteractManager.c(), BiomeManager.a(worldserver1[0].getSeed()), worlddata.isHardcore(), server.F(), ((IRegistryCustom.Dimension) ReflectionUtil.getValueFromField(playerList, "s")), worldserver1[0].getDimensionManager(), worldserver1[0].getDimensionKey(), playerList.getMaxPlayers(), worldserver1[0].spigotConfig.viewDistance, flag1, !flag, worldserver1[0].isDebugWorld(), worldserver1[0].isFlatWorld()));
} catch (Exception e) {
e.printStackTrace();
}
entityplayer.getBukkitEntity().sendSupportedChannels();
playerconnection.sendPacket(new PacketPlayOutCustomPayload(PacketPlayOutCustomPayload.a, (new PacketDataSerializer(Unpooled.buffer())).a(playerList.getServer().getServerModName())));
playerconnection.sendPacket(new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
playerconnection.sendPacket(new PacketPlayOutAbilities(entityplayer.abilities));
playerconnection.sendPacket(new PacketPlayOutHeldItemSlot(entityplayer.inventory.itemInHandIndex));
playerconnection.sendPacket(new PacketPlayOutRecipeUpdate(server.getCraftingManager().b()));
playerconnection.sendPacket(new PacketPlayOutTags(server.getTagRegistry()));
playerList.d(entityplayer);
entityplayer.getStatisticManager().c();
entityplayer.getRecipeBook().a(entityplayer);
playerList.sendScoreboard(worldserver1[0].getScoreboard(), entityplayer);
server.invalidatePingSample();
ChatMessage chatmessage;
if (entityplayer.getProfile().getName().equalsIgnoreCase(s)) {
chatmessage = new ChatMessage("multiplayer.player.joined", new Object[]{entityplayer.getScoreboardDisplayName()});
} else {
chatmessage = new ChatMessage("multiplayer.player.joined.renamed", new Object[]{entityplayer.getScoreboardDisplayName(), s});
}
chatmessage.a(EnumChatFormat.YELLOW);
String joinMessage = CraftChatMessage.fromComponent(chatmessage);
playerconnection.a(entityplayer.locX(), entityplayer.locY(), entityplayer.locZ(), entityplayer.yaw, entityplayer.pitch);
playerList.players.add(entityplayer);
//playerList.playersByName.put(entityplayer.getName().toLowerCase(Locale.ROOT), entityplayer);
((Map<String, EntityPlayer>) ReflectionUtil.getValueFromField(playerList, "playersByName")).put(entityplayer.getName().toLowerCase(Locale.ROOT), entityplayer);
//playerList.j.put(entityplayer.getUniqueID(), entityplayer);
((Map<UUID, EntityPlayer>) ReflectionUtil.getValueFromField(playerList, "j")).put(entityplayer.getUniqueID(), entityplayer);
PlayerJoinEvent playerJoinEvent = new PlayerJoinEvent(((CraftServer) Bukkit.getServer()).getPlayer(entityplayer), joinMessage);
Bukkit.getServer().getPluginManager().callEvent(playerJoinEvent);
if (entityplayer.playerConnection.networkManager.isConnected()) {
joinMessage = playerJoinEvent.getJoinMessage();
int i;
if (joinMessage != null && joinMessage.length() > 0) {
IChatBaseComponent[] var27;
int var26 = (var27 = CraftChatMessage.fromString(joinMessage)).length;
for(i = 0; i < var26; ++i) {
IChatBaseComponent line = var27[i];
server.getPlayerList().sendAll(new PacketPlayOutChat(line, ChatMessageType.SYSTEM, SystemUtils.b));
}
}
PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, new EntityPlayer[]{entityplayer});
for(i = 0; i < playerList.players.size(); ++i) {
EntityPlayer entityplayer1 = (EntityPlayer)playerList.players.get(i);
if (entityplayer1.getBukkitEntity().canSee(entityplayer.getBukkitEntity())) {
entityplayer1.playerConnection.sendPacket(packet);
}
if (entityplayer.getBukkitEntity().canSee(entityplayer1.getBukkitEntity())) {
entityplayer.playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, new EntityPlayer[]{entityplayer1}));
}
}
entityplayer.sentListPacket = true;
entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityMetadata(entityplayer.getId(), ((DataWatcher) ReflectionUtil.getValueFromField(entityplayer, "datawatcher")), true));
if (entityplayer.world == worldserver1[0] && !worldserver1[0].getPlayers().contains(entityplayer)) {
worldserver1[0].addPlayerJoin(entityplayer);
server.getBossBattleCustomData().a(entityplayer);
}
worldserver1[0] = entityplayer.getWorldServer();
playerList.a(entityplayer, worldserver1[0]);
if (!server.getResourcePack().isEmpty()) {
entityplayer.setResourcePack(server.getResourcePack(), server.getResourcePackHash());
}
Iterator iterator = entityplayer.getEffects().iterator();
while(iterator.hasNext()) {
MobEffect mobeffect = (MobEffect)iterator.next();
playerconnection.sendPacket(new PacketPlayOutEntityEffect(entityplayer.getId(), mobeffect));
}
if (nbttagcompound != null && nbttagcompound.hasKeyOfType("RootVehicle", 10)) {
NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("RootVehicle");
Entity entity = EntityTypes.a(nbttagcompound1.getCompound("Entity"), worldserver1[0], (entity1x) -> {
return !worldserver1[0].addEntitySerialized(entity1x) ? null : entity1x;
});
if (entity != null) {
UUID uuid;
if (nbttagcompound1.b("Attach")) {
uuid = nbttagcompound1.a("Attach");
} else {
uuid = null;
}
Iterator iterator1;
Entity entity1;
if (entity.getUniqueID().equals(uuid)) {
entityplayer.a(entity, true);
} else {
iterator1 = entity.getAllPassengers().iterator();
while(iterator1.hasNext()) {
entity1 = (Entity)iterator1.next();
if (entity1.getUniqueID().equals(uuid)) {
entityplayer.a(entity1, true);
break;
}
}
}
if (!entityplayer.isPassenger()) {
LOGGER.warn("Couldn't reattach entity to player");
worldserver1[0].removeEntity(entity);
iterator1 = entity.getAllPassengers().iterator();
while(iterator1.hasNext()) {
entity1 = (Entity)iterator1.next();
worldserver1[0].removeEntity(entity1);
}
}
}
}
entityplayer.syncInventory();
LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", entityplayer.getDisplayName().getString(), s1, entityplayer.getId(), worldserver1[0].worldDataServer.getName(), entityplayer.locX(), entityplayer.locY(), entityplayer.locZ());
}
}
}

View File

@ -0,0 +1,44 @@
package nl.kallestruik.vanillatweaks.fakeplayer;
import net.minecraft.server.v1_16_R2.EntityPlayer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class FakePlayerManager {
public static void spawnFakePlayer(Location loc, String name) {
Player player = Bukkit.getPlayer(name);
if (player != null && player.isOnline())
return;
FakePlayer.atLocation(loc, name);
}
public static void killFakePlayer(String name) {
Player player = Bukkit.getPlayer(name);
if (player == null || !player.isOnline())
return;
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
if (!(entityPlayer instanceof FakePlayer))
return;
entityPlayer.killEntity();
}
public static void killAllFakePlayers() {
for (Player player : Bukkit.getOnlinePlayers()) {
if (!player.isOnline())
continue;
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
if (!(entityPlayer instanceof FakePlayer))
continue;
entityPlayer.killEntity();
}
}
}

View File

@ -1,6 +1,7 @@
package nl.kallestruik.vanillatweaks.tweaks.craftingtweaks;
import nl.kallestruik.vanillatweaks.core.Tweak;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
@ -33,6 +34,8 @@ public class AlternativeDispenserRecipe implements Tweak {
dispenserRecipe.setIngredient('T', Material.STICK);
dispenserRecipe.setIngredient('D', Material.DROPPER);
dispenserRecipe.setIngredient('S', Material.STRING);
Bukkit.getServer().addRecipe(dispenserRecipe);
}
@Override

View File

@ -1,6 +1,7 @@
package nl.kallestruik.vanillatweaks.tweaks.craftingtweaks;
import nl.kallestruik.vanillatweaks.core.Tweak;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
@ -32,6 +33,8 @@ public class CraftableDragonsBreath implements Tweak {
dragonBreathRecipe.shape("GCG", " G ");
dragonBreathRecipe.setIngredient('G', Material.GLASS);
dragonBreathRecipe.setIngredient('C', Material.POPPED_CHORUS_FRUIT);
Bukkit.getServer().addRecipe(dragonBreathRecipe);
}
@Override

View File

@ -1,6 +1,7 @@
package nl.kallestruik.vanillatweaks.tweaks.craftingtweaks;
import nl.kallestruik.vanillatweaks.core.Tweak;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
@ -32,6 +33,8 @@ public class CraftableNametag implements Tweak {
nametagRecipe.shape(" I", " P ", "P ");
nametagRecipe.setIngredient('I', Material.IRON_INGOT);
nametagRecipe.setIngredient('P', Material.PAPER);
Bukkit.getServer().addRecipe(nametagRecipe);
}
@Override

View File

@ -1,6 +1,7 @@
package nl.kallestruik.vanillatweaks.tweaks.craftingtweaks;
import nl.kallestruik.vanillatweaks.core.Tweak;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
@ -33,6 +34,8 @@ public class CraftableSaddle implements Tweak {
saddleRecipe.setIngredient('L', Material.LEATHER);
saddleRecipe.setIngredient('S', Material.STRING);
saddleRecipe.setIngredient('I', Material.IRON_INGOT);
Bukkit.getServer().addRecipe(saddleRecipe);
}
@Override

View File

@ -1,6 +1,7 @@
package nl.kallestruik.vanillatweaks.tweaks.craftingtweaks;
import nl.kallestruik.vanillatweaks.core.Tweak;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
@ -32,6 +33,8 @@ public class CraftableShulkerShell implements Tweak {
shulkerShellRecipe.shape("BBB","F F");
shulkerShellRecipe.setIngredient('B', Material.PURPUR_SLAB);
shulkerShellRecipe.setIngredient('F', Material.POPPED_CHORUS_FRUIT);
Bukkit.getServer().addRecipe(shulkerShellRecipe);
}
@Override

View File

@ -1,6 +1,7 @@
package nl.kallestruik.vanillatweaks.tweaks.craftingtweaks;
import nl.kallestruik.vanillatweaks.core.Tweak;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
@ -32,6 +33,8 @@ public class CraftableSponge implements Tweak {
spongeRecipe.shape("KKK","KDK","KKK");
spongeRecipe.setIngredient('K', Material.KELP);
spongeRecipe.setIngredient('D', Material.YELLOW_DYE);
Bukkit.getServer().addRecipe(spongeRecipe);
}
@Override

View File

@ -1,6 +1,7 @@
package nl.kallestruik.vanillatweaks.tweaks.craftingtweaks;
import nl.kallestruik.vanillatweaks.core.Tweak;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
@ -32,10 +33,14 @@ public class IceDecompression implements Tweak {
ShapelessRecipe packedIceRecipe = new ShapelessRecipe(packedIceKey, new ItemStack(Material.PACKED_ICE, 9));
packedIceRecipe.addIngredient(Material.BLUE_ICE);
Bukkit.getServer().addRecipe(packedIceRecipe);
// Packed Ice -> Ice
NamespacedKey iceKey = new NamespacedKey(plugin, "ice");
ShapelessRecipe iceRecipe = new ShapelessRecipe(iceKey, new ItemStack(Material.ICE, 9));
iceRecipe.addIngredient(Material.PACKED_ICE);
Bukkit.getServer().addRecipe(iceRecipe);
}
@Override

View File

@ -1,6 +1,7 @@
package nl.kallestruik.vanillatweaks.tweaks.craftingtweaks;
import nl.kallestruik.vanillatweaks.core.Tweak;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
@ -32,6 +33,8 @@ public class LogsToChests implements Tweak {
ShapedRecipe chestRecipe = new ShapedRecipe(chestKey, new ItemStack(Material.CHEST, 4));
chestRecipe.shape("WWW", "W W", "WWW");
chestRecipe.setIngredient('W', MaterialGroups.ALL_LOG);
Bukkit.getServer().addRecipe(chestRecipe);
}
@Override

View File

@ -8,23 +8,33 @@ public class MaterialGroups {
Material.OAK_LOG,
Material.STRIPPED_OAK_LOG,
Material.OAK_WOOD,
Material.STRIPPED_OAK_WOOD,
Material.BIRCH_LOG,
Material.STRIPPED_BIRCH_LOG,
Material.BIRCH_WOOD,
Material.STRIPPED_BIRCH_WOOD,
Material.SPRUCE_LOG,
Material.STRIPPED_SPRUCE_LOG,
Material.SPRUCE_WOOD,
Material.STRIPPED_SPRUCE_WOOD,
Material.JUNGLE_LOG,
Material.STRIPPED_JUNGLE_LOG,
Material.JUNGLE_WOOD,
Material.STRIPPED_JUNGLE_WOOD,
Material.ACACIA_LOG,
Material.STRIPPED_ACACIA_LOG,
Material.ACACIA_WOOD,
Material.STRIPPED_ACACIA_WOOD,
Material.DARK_OAK_LOG,
Material.STRIPPED_DARK_OAK_LOG,
Material.DARK_OAK_WOOD,
Material.STRIPPED_DARK_OAK_WOOD,
Material.CRIMSON_STEM,
Material.STRIPPED_CRIMSON_STEM,
Material.CRIMSON_HYPHAE,
Material.STRIPPED_CRIMSON_HYPHAE,
Material.WARPED_STEM,
Material.STRIPPED_WARPED_STEM,
Material.WARPED_HYPHAE,
Material.STRIPPED_WARPED_HYPHAE);
public static final RecipeChoice ALL_WOOL = new RecipeChoice.MaterialChoice(

View File

@ -1,6 +1,7 @@
package nl.kallestruik.vanillatweaks.tweaks.craftingtweaks;
import nl.kallestruik.vanillatweaks.core.Tweak;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
@ -30,6 +31,8 @@ public class WoolToString implements Tweak {
NamespacedKey stringKey = new NamespacedKey(plugin, "string");
ShapelessRecipe stringRecipe = new ShapelessRecipe(stringKey, new ItemStack(Material.STRING, 4));
stringRecipe.addIngredient(MaterialGroups.ALL_WOOL);
Bukkit.getServer().addRecipe(stringRecipe);
}
@Override

View File

@ -1,4 +1,4 @@
package nl.kallestruik.vanillatweaks.tweaks.miscellaneoustweaks;
package nl.kallestruik.vanillatweaks.tweaks.croptweaks;
import nl.kallestruik.vanillatweaks.core.Tweak;
import org.bukkit.*;

View File

@ -1,4 +1,4 @@
package nl.kallestruik.vanillatweaks.tweaks.miscellaneoustweaks;
package nl.kallestruik.vanillatweaks.tweaks.croptweaks;
import nl.kallestruik.vanillatweaks.util.Util;
import nl.kallestruik.vanillatweaks.core.Tweak;

View File

@ -67,6 +67,9 @@ public class PlayersCantTrampleCrops implements Tweak, Listener {
if (!(event.getEntity() instanceof Player))
return;
if (trampleEnabled.contains(event.getEntity().getUniqueId()))
return;
event.setCancelled(true);
}

View File

@ -1,4 +1,4 @@
package nl.kallestruik.vanillatweaks.tweaks.miscellaneoustweaks;
package nl.kallestruik.vanillatweaks.tweaks.croptweaks;
import nl.kallestruik.vanillatweaks.core.Tweak;
import org.bukkit.*;

View File

@ -0,0 +1,33 @@
package nl.kallestruik.vanillatweaks.tweaks.miscellaneoustweaks;
import nl.kallestruik.vanillatweaks.core.Tweak;
import nl.kallestruik.vanillatweaks.fakeplayer.FakePlayerManager;
import org.bukkit.plugin.java.JavaPlugin;
public class FakePlayers implements Tweak {
@Override
public String getIdentifier() {
return "FakePlayers";
}
@Override
public void onRegister(JavaPlugin pluginInstance) {
}
@Override
public void onUnRegister() {
}
@Override
public void onEnable() {
}
@Override
public void onDisable() {
FakePlayerManager.killAllFakePlayers();
}
}

View File

@ -0,0 +1,32 @@
package nl.kallestruik.vanillatweaks.util;
import java.lang.reflect.Field;
public class ReflectionUtil {
public static Field getField(Class clazz, String fieldName)
throws NoSuchFieldException {
try {
return clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
Class superClass = clazz.getSuperclass();
if (superClass == null) {
throw e;
} else {
return getField(superClass, fieldName);
}
}
}
public static Object getValueFromField(Object instance, String fieldName) {
try {
Field connectedChannelsField = getField(instance.getClass(), fieldName);
connectedChannelsField.setAccessible(true); //required if field is not normally accessible
return connectedChannelsField.get(instance);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -14,3 +14,4 @@ MobsCantTrampleCrops: true
CraftableDragonsBreath: true
ArmorSwapping: true
HoesHarvestArea: true
FakePlayers: false