1.20.4 support
This commit is contained in:
@@ -7,7 +7,7 @@ import org.bukkit.block.Block;
|
||||
* This class serves as a bridge between the API and internal code that interacts with NMS.
|
||||
*/
|
||||
public interface InternalBridge {
|
||||
void sendBlockDestructionPacket(short entityId, int x, int y, int z, int progress);
|
||||
void sendBlockDestructionPacket(short entityId, Block block, int progress);
|
||||
|
||||
Sound breakBlockSound(Block block);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.nuggetmc.tplus.api.agent.legacyagent;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import net.nuggetmc.tplus.api.BotManager;
|
||||
import net.nuggetmc.tplus.api.Terminator;
|
||||
import net.nuggetmc.tplus.api.TerminatorPlusAPI;
|
||||
@@ -18,7 +19,8 @@ import org.bukkit.*;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.Waterlogged;
|
||||
import org.bukkit.block.data.type.*;
|
||||
import org.bukkit.block.data.type.Door;
|
||||
import org.bukkit.block.data.type.TrapDoor;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
@@ -26,8 +28,6 @@ import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -1114,7 +1114,7 @@ public class LegacyAgent extends Agent {
|
||||
if (player.isDead() || cur == null || (!block.equals(cur) || block.getType() != cur.getType())) {
|
||||
this.cancel();
|
||||
|
||||
TerminatorPlusAPI.getInternalBridge().sendBlockDestructionPacket(crackList.get(block), block.getX(), block.getY(), block.getZ(), -1);
|
||||
TerminatorPlusAPI.getInternalBridge().sendBlockDestructionPacket(crackList.get(block), block, -1);
|
||||
|
||||
crackList.remove(block);
|
||||
mining.remove(this);
|
||||
@@ -1126,7 +1126,7 @@ public class LegacyAgent extends Agent {
|
||||
if (i == 9) {
|
||||
this.cancel();
|
||||
|
||||
TerminatorPlusAPI.getInternalBridge().sendBlockDestructionPacket(crackList.get(block), block.getX(), block.getY(), block.getZ(), -1);
|
||||
TerminatorPlusAPI.getInternalBridge().sendBlockDestructionPacket(crackList.get(block), block, -1);
|
||||
|
||||
|
||||
if (sound != null) {
|
||||
@@ -1165,7 +1165,7 @@ public class LegacyAgent extends Agent {
|
||||
return;
|
||||
}
|
||||
|
||||
TerminatorPlusAPI.getInternalBridge().sendBlockDestructionPacket(crackList.get(block), block.getX(), block.getY(), block.getZ(), i);
|
||||
TerminatorPlusAPI.getInternalBridge().sendBlockDestructionPacket(crackList.get(block), block, i);
|
||||
|
||||
mining.put(this, (byte) (i + 1));
|
||||
}
|
||||
@@ -1571,7 +1571,7 @@ public class LegacyAgent extends Agent {
|
||||
Iterator<Entry<Block, Short>> itr = crackList.entrySet().iterator();
|
||||
while(itr.hasNext()) {
|
||||
Block block = itr.next().getKey();
|
||||
TerminatorPlusAPI.getInternalBridge().sendBlockDestructionPacket(crackList.get(block), block.getX(), block.getY(), block.getZ(), -1);
|
||||
TerminatorPlusAPI.getInternalBridge().sendBlockDestructionPacket(crackList.get(block), block, -1);
|
||||
itr.remove();
|
||||
}
|
||||
mining.clear();
|
||||
|
||||
@@ -13,7 +13,7 @@ java {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
paperDevBundle("1.20.1-R0.1-SNAPSHOT")
|
||||
paperDevBundle("1.20.4-R0.1-SNAPSHOT")
|
||||
|
||||
//add the TerminatorPlus-API module
|
||||
implementation(project(":TerminatorPlus-API"))
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.Arrays;
|
||||
|
||||
public class TerminatorPlus extends JavaPlugin {
|
||||
|
||||
public static final String REQUIRED_VERSION = "1.20.1";
|
||||
public static final String REQUIRED_VERSION = "1.20.4";
|
||||
|
||||
private static TerminatorPlus instance;
|
||||
private static String version;
|
||||
|
||||
@@ -2,14 +2,13 @@ package net.nuggetmc.tplus.bot;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.PacketSendListener;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.PacketFlow;
|
||||
import net.minecraft.network.protocol.game.*;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ClientInformation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.network.CommonListenerCookie;
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
@@ -31,16 +30,17 @@ import net.nuggetmc.tplus.api.event.BotDamageByPlayerEvent;
|
||||
import net.nuggetmc.tplus.api.event.BotFallDamageEvent;
|
||||
import net.nuggetmc.tplus.api.event.BotKilledByPlayerEvent;
|
||||
import net.nuggetmc.tplus.api.utils.*;
|
||||
import net.nuggetmc.tplus.nms.MockConnection;
|
||||
import net.nuggetmc.tplus.utils.NMSUtils;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.Waterlogged;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.CraftEquipmentSlot;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.v1_20_R3.CraftEquipmentSlot;
|
||||
import org.bukkit.craftbukkit.v1_20_R3.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_20_R3.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Damageable;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -48,7 +48,6 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -76,7 +75,7 @@ public class Bot extends ServerPlayer implements Terminator {
|
||||
private boolean inPlayerList;
|
||||
|
||||
private Bot(MinecraftServer minecraftServer, ServerLevel worldServer, GameProfile profile, boolean addToPlayerList) {
|
||||
super(minecraftServer, worldServer, profile);
|
||||
super(minecraftServer, worldServer, profile, ClientInformation.createDefault());
|
||||
|
||||
this.plugin = TerminatorPlus.getInstance();
|
||||
this.scheduler = Bukkit.getScheduler();
|
||||
@@ -111,13 +110,7 @@ public class Bot extends ServerPlayer implements Terminator {
|
||||
|
||||
Bot bot = new Bot(nmsServer, nmsWorld, profile, addPlayerList);
|
||||
|
||||
bot.connection = new ServerGamePacketListenerImpl(nmsServer, new Connection(PacketFlow.CLIENTBOUND) {
|
||||
|
||||
@Override
|
||||
public void send(Packet<?> packet, @Nullable PacketSendListener callbacks) {
|
||||
|
||||
}
|
||||
}, bot);
|
||||
bot.connection = new ServerGamePacketListenerImpl(nmsServer, new MockConnection(), bot, CommonListenerCookie.createInitial(bot.getGameProfile()));
|
||||
|
||||
bot.setPos(loc.getX(), loc.getY(), loc.getZ());
|
||||
bot.setRot(loc.getYaw(), loc.getPitch());
|
||||
@@ -203,7 +196,7 @@ public class Bot extends ServerPlayer implements Terminator {
|
||||
private Packet<?>[] getRenderPackets() {
|
||||
return new Packet[]{
|
||||
new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, this),
|
||||
new ClientboundAddPlayerPacket(this),
|
||||
new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, this),
|
||||
//new ClientboundSetEntityDataPacket(this.getId(), this.entityData, true),
|
||||
new ClientboundSetEntityDataPacket(this.getId(), NMSUtils.getEntityData(this.entityData)),
|
||||
new ClientboundRotateHeadPacket(this, (byte) ((this.yHeadRot * 256f) / 360f))
|
||||
@@ -212,8 +205,9 @@ public class Bot extends ServerPlayer implements Terminator {
|
||||
|
||||
private Packet<?>[] getRenderPacketsNoInfo() {
|
||||
return new Packet[]{
|
||||
new ClientboundAddPlayerPacket(this),
|
||||
new ClientboundAddEntityPacket(this),
|
||||
//new ClientboundSetEntityDataPacket(this.getId(), this.entityData, true),
|
||||
new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, this),
|
||||
new ClientboundSetEntityDataPacket(this.getId(), this.entityData.packDirty()),
|
||||
new ClientboundRotateHeadPacket(this, (byte) ((this.yHeadRot * 256f) / 360f))
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@ import net.nuggetmc.tplus.api.event.BotDeathEvent;
|
||||
import net.nuggetmc.tplus.api.utils.MojangAPI;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -6,30 +6,33 @@ import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.nuggetmc.tplus.api.InternalBridge;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.v1_20_R3.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class InternalBridgeImpl implements InternalBridge {
|
||||
@Override
|
||||
public void sendBlockDestructionPacket(short entityId, int x, int y, int z, int progress) {
|
||||
ClientboundBlockDestructionPacket crack = new ClientboundBlockDestructionPacket(entityId, new BlockPos(x, y, z), progress);
|
||||
for (Player all : Bukkit.getOnlinePlayers()) {
|
||||
public void sendBlockDestructionPacket(short entityId, Block block, int progress) {
|
||||
ClientboundBlockDestructionPacket crack = new ClientboundBlockDestructionPacket(entityId, new BlockPos(block.getX(), block.getY(), block.getZ()), progress);
|
||||
for (Player all : block.getLocation().getNearbyPlayers(64)) {
|
||||
((CraftPlayer) all).getHandle().connection.send(crack);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sound breakBlockSound(Block block) {
|
||||
Level nmsWorld = ((CraftWorld) block.getWorld()).getHandle();
|
||||
BlockState blockState = nmsWorld.getBlockState(new BlockPos(block.getX(), block.getY(), block.getZ()));
|
||||
net.minecraft.world.level.block.Block nmsBlock = blockState.getBlock();
|
||||
try {
|
||||
Level nmsWorld = ((CraftWorld) block.getWorld()).getHandle();
|
||||
BlockState blockState = nmsWorld.getBlockState(new BlockPos(block.getX(), block.getY(), block.getZ()));
|
||||
net.minecraft.world.level.block.Block nmsBlock = blockState.getBlock();
|
||||
|
||||
SoundType soundEffectType = nmsBlock.getSoundType(blockState);
|
||||
SoundType soundEffectType = nmsBlock.getSoundType(blockState);
|
||||
|
||||
return Sound.valueOf(soundEffectType.getBreakSound().getLocation().getPath().replace(".", "_").toUpperCase());
|
||||
return Sound.valueOf(soundEffectType.getBreakSound().getLocation().getPath().replace(".", "_").toUpperCase());
|
||||
} catch (Exception e) { // potentially unsafe, just fallback to stone break sound
|
||||
return Sound.BLOCK_STONE_BREAK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import net.nuggetmc.tplus.command.commands.MainCommand;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.SimpleCommandMap;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_20_R3.CraftServer;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package net.nuggetmc.tplus.nms;
|
||||
|
||||
import io.netty.channel.*;
|
||||
import io.netty.util.Attribute;
|
||||
import io.netty.util.AttributeKey;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
|
||||
public class MockChannel extends AbstractChannel {
|
||||
private final ChannelConfig config = new DefaultChannelConfig(this);
|
||||
|
||||
public MockChannel(Channel parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Attribute<T> attr(AttributeKey<T> key) {
|
||||
return super.attr(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelConfig config() {
|
||||
config.setAutoRead(true);
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doBeginRead() throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doBind(SocketAddress arg0) throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doClose() throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doDisconnect() throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doWrite(ChannelOutboundBuffer outboundBuffer) throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isCompatible(EventLoop arg0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SocketAddress localAddress0() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelMetadata metadata() {
|
||||
return new ChannelMetadata(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractUnsafe newUnsafe() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SocketAddress remoteAddress0() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package net.nuggetmc.tplus.nms;
|
||||
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.PacketListener;
|
||||
import net.minecraft.network.PacketSendListener;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.PacketFlow;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.SocketAddress;
|
||||
|
||||
@SuppressWarnings("JavaReflectionMemberAccess")
|
||||
public class MockConnection extends Connection {
|
||||
private static final Field PACKET_LISTENER_FIELD;
|
||||
private static final Field DISCONNECT_LISTENER_FIELD;
|
||||
|
||||
static {
|
||||
try {
|
||||
// https://mappings.cephx.dev/1.20.4/net/minecraft/network/Connection.html packetListener & disconnectListener
|
||||
PACKET_LISTENER_FIELD = Connection.class.getDeclaredField("q");
|
||||
DISCONNECT_LISTENER_FIELD = Connection.class.getDeclaredField("p");
|
||||
|
||||
PACKET_LISTENER_FIELD.setAccessible(true);
|
||||
DISCONNECT_LISTENER_FIELD.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public MockConnection() {
|
||||
super(PacketFlow.SERVERBOUND);
|
||||
this.channel = new MockChannel(null);
|
||||
this.address = new SocketAddress() {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushChannel() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnected() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(@NotNull Packet<?> packet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(@NotNull Packet<?> packet, PacketSendListener sendListener) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(@NotNull Packet<?> packet, PacketSendListener sendListener, boolean flag) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListener(@NotNull PacketListener packetListener) {
|
||||
try {
|
||||
PACKET_LISTENER_FIELD.set(this, packetListener);
|
||||
DISCONNECT_LISTENER_FIELD.set(this, null);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ public class NMSUtils {
|
||||
private static String itemsByIdFieldName;
|
||||
|
||||
static {
|
||||
// find a private final field in SynchedEntityData that is an Int2ObjectMap<SynchedEntityData.DataItem>
|
||||
// find a private final field in SynchedEntityData that is an Int2ObjectMap<SynchedEntityData.DataItem<?>>
|
||||
Class<SynchedEntityData> clazz = SynchedEntityData.class;
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
@@ -26,12 +26,13 @@ public class NMSUtils {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<SynchedEntityData.DataValue<?>> getEntityData(SynchedEntityData synchedEntityData) {
|
||||
Int2ObjectMap<SynchedEntityData.DataItem> map = null;
|
||||
Int2ObjectMap<SynchedEntityData.DataItem<?>> map = null;
|
||||
try {
|
||||
Field field = synchedEntityData.getClass().getDeclaredField(itemsByIdFieldName);
|
||||
field.setAccessible(true);
|
||||
map = (Int2ObjectMap<SynchedEntityData.DataItem>) field.get(synchedEntityData);
|
||||
map = (Int2ObjectMap<SynchedEntityData.DataItem<?>>) field.get(synchedEntityData);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user