Update to 1.19

main
kalle 2023-04-08 23:51:19 +02:00
parent 10145032e2
commit 247159970c
10 changed files with 288 additions and 315 deletions

View File

@ -1,10 +1,10 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins { plugins {
kotlin("jvm") version "1.5.31" kotlin("jvm") version "1.7.0-RC"
id("com.github.johnrengelman.shadow") version "7.1.2" id("com.github.johnrengelman.shadow") version "7.1.2"
id("xyz.jpenilla.run-paper") version "1.0.6" // Adds runServer and runMojangMappedServer tasks for testing id("xyz.jpenilla.run-paper") version "1.0.6" // Adds runServer and runMojangMappedServer tasks for testing
id("io.papermc.paperweight.userdev") version "1.3.4" id("io.papermc.paperweight.userdev") version "1.3.7"
} }
group = "nl.kallestruik" group = "nl.kallestruik"
@ -20,12 +20,13 @@ repositories {
} }
dependencies { dependencies {
paperDevBundle("1.19-R0.1-SNAPSHOT")
implementation("co.aikar:acf-paper:0.5.0-SNAPSHOT") implementation("co.aikar:acf-paper:0.5.0-SNAPSHOT")
paperDevBundle("1.18.1-R0.1-SNAPSHOT")
compileOnly("com.comphenix.protocol:ProtocolLib:4.6.0") compileOnly("com.comphenix.protocol:ProtocolLib:4.6.0")
compileOnly(kotlin("stdlib-jdk8")) compileOnly(kotlin("stdlib-jdk8"))
compileOnly("nl.kallestruik:DLib:1.3.6") compileOnly("nl.kallestruik:DLib:1.4.4")
testImplementation(kotlin("test-junit5")) testImplementation(kotlin("test-junit5"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0") testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")

View File

@ -22,16 +22,4 @@ class CommandPlayer(
fun onKill(sender: Player, @Single playerName: String) { fun onKill(sender: Player, @Single playerName: String) {
fakePlayerManager.killFakePlayer(playerName) fakePlayerManager.killFakePlayer(playerName)
} }
@Subcommand("attack")
@CommandCompletion("@players")
fun onAttack(sender: Player, @Single playerName: String) {
fakePlayerManager.attack(playerName)
}
@Subcommand("use")
@CommandCompletion("@players")
fun onUse(sender: Player, @Single playerName: String) {
fakePlayerManager.use(playerName)
}
} }

View File

@ -1,7 +1,7 @@
package nl.kallestruik.dtweaks.fakeplayer package nl.kallestruik.dtweaks.fakeplayer
import com.mojang.authlib.GameProfile import com.mojang.authlib.GameProfile
import net.minecraft.network.chat.TextComponent import net.minecraft.network.chat.Component
import net.minecraft.network.protocol.PacketFlow import net.minecraft.network.protocol.PacketFlow
import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket
@ -10,18 +10,18 @@ import net.minecraft.server.TickTask
import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerLevel
import net.minecraft.server.level.ServerPlayer import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.damagesource.DamageSource import net.minecraft.world.damagesource.DamageSource
import net.minecraft.world.entity.Entity
import net.minecraft.world.food.FoodData import net.minecraft.world.food.FoodData
import net.minecraft.world.level.block.entity.SkullBlockEntity import net.minecraft.world.level.block.entity.SkullBlockEntity
import nl.kallestruik.dtweaks.fakeplayer.FakePlayerList.placeFakePlayer
import org.bukkit.Location import org.bukkit.Location
import org.bukkit.craftbukkit.v1_18_R1.CraftWorld import org.bukkit.craftbukkit.v1_19_R1.CraftWorld
import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.atomic.AtomicReference
class FakePlayer( class FakePlayer(
server: MinecraftServer, server: MinecraftServer,
val serverLevel: ServerLevel, private val serverLevel: ServerLevel,
gameProfile: GameProfile gameProfile: GameProfile
): ServerPlayer(server, serverLevel, gameProfile) { ): ServerPlayer(server, serverLevel, gameProfile, null) {
val locale = "en_US" val locale = "en_US"
companion object { companion object {
@ -43,7 +43,7 @@ class FakePlayer(
// Create a fake connection for our fake player. // Create a fake connection for our fake player.
val connection = FakeConnection(PacketFlow.SERVERBOUND) val connection = FakeConnection(PacketFlow.SERVERBOUND)
FakePlayerList.placeNewPlayer(minecraftServer.playerList, minecraftServer, connection, instance) minecraftServer.playerList.placeFakePlayer(connection, instance)
instance.respawn() instance.respawn()
instance.teleportTo(serverLevel, location.x, location.y, location.z, location.yaw, location.pitch) instance.teleportTo(serverLevel, location.x, location.y, location.z, location.yaw, location.pitch)
@ -119,7 +119,9 @@ class FakePlayer(
} }
override fun kill() { override fun kill() {
server.tell(TickTask(server.tickCount) {connection.onDisconnect(TextComponent("Killed"))}) server.tell(TickTask(server.tickCount) {
connection.onDisconnect(Component.literal("Killed"))
})
} }
override fun die(source: DamageSource) { override fun die(source: DamageSource) {

View File

@ -3,7 +3,6 @@ package nl.kallestruik.dtweaks.fakeplayer
import io.netty.util.concurrent.Future import io.netty.util.concurrent.Future
import io.netty.util.concurrent.GenericFutureListener import io.netty.util.concurrent.GenericFutureListener
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.network.chat.TranslatableComponent
import net.minecraft.network.protocol.Packet import net.minecraft.network.protocol.Packet
import net.minecraft.server.MinecraftServer import net.minecraft.server.MinecraftServer
import net.minecraft.server.network.ServerGamePacketListenerImpl import net.minecraft.server.network.ServerGamePacketListenerImpl
@ -18,11 +17,8 @@ class FakePlayerConnection(
override fun send(packet: Packet<*>, listener: GenericFutureListener<out Future<in Void>>?) {} override fun send(packet: Packet<*>, listener: GenericFutureListener<out Future<in Void>>?) {}
override fun disconnect(message: Component) { override fun disconnect(message: Component) {
if (message is TranslatableComponent && (message.key.equals("multiplayer.disconnect.idling") || message.equals("multiplayer.disconnect.duplicate_login")))
{
player.kill() player.kill()
} }
}
override fun tick() { override fun tick() {
println("Tick for ${player.name}") println("Tick for ${player.name}")

View File

@ -1,23 +1,29 @@
package nl.kallestruik.dtweaks.fakeplayer package nl.kallestruik.dtweaks.fakeplayer
import com.destroystokyo.paper.PaperConfig
import com.destroystokyo.paper.event.player.PlayerInitialSpawnEvent import com.destroystokyo.paper.event.player.PlayerInitialSpawnEvent
import com.mojang.authlib.GameProfile import com.mojang.authlib.GameProfile
import com.mojang.datafixers.util.Either import com.mojang.datafixers.util.Either
import com.mojang.serialization.Dynamic import com.mojang.serialization.Dynamic
import io.netty.buffer.Unpooled import io.netty.buffer.Unpooled
import io.papermc.paper.configuration.GlobalConfiguration
import net.minecraft.core.RegistryAccess
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.NbtOps import net.minecraft.nbt.NbtOps
import net.minecraft.nbt.Tag
import net.minecraft.network.Connection import net.minecraft.network.Connection
import net.minecraft.network.FriendlyByteBuf import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.protocol.game.* import net.minecraft.network.protocol.game.*
import net.minecraft.resources.ResourceKey import net.minecraft.resources.ResourceKey
import net.minecraft.server.MinecraftServer import net.minecraft.server.MinecraftServer
import net.minecraft.server.level.*
import net.minecraft.server.level.ChunkHolder.ChunkLoadingFailure import net.minecraft.server.level.ChunkHolder.ChunkLoadingFailure
import net.minecraft.server.level.DistanceManager
import net.minecraft.server.level.ServerLevel
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.level.TicketType
import net.minecraft.server.network.ServerGamePacketListenerImpl import net.minecraft.server.network.ServerGamePacketListenerImpl
import net.minecraft.server.players.GameProfileCache import net.minecraft.server.players.GameProfileCache
import net.minecraft.server.players.PlayerList import net.minecraft.server.players.PlayerList
import net.minecraft.tags.TagNetworkSerialization
import net.minecraft.world.level.ChunkPos import net.minecraft.world.level.ChunkPos
import net.minecraft.world.level.GameRules import net.minecraft.world.level.GameRules
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
@ -25,18 +31,185 @@ import net.minecraft.world.level.biome.BiomeManager
import net.minecraft.world.level.chunk.ChunkAccess import net.minecraft.world.level.chunk.ChunkAccess
import net.minecraft.world.level.dimension.DimensionType import net.minecraft.world.level.dimension.DimensionType
import nl.kallestruik.dlib.ReflectionUtil import nl.kallestruik.dlib.ReflectionUtil
import nl.kallestruik.dtweaks.DTweaks
import org.apache.logging.log4j.Logger
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.craftbukkit.v1_18_R1.CraftWorld import org.bukkit.craftbukkit.v1_19_R1.CraftServer
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.spigotmc.event.player.PlayerSpawnLocationEvent import org.spigotmc.event.player.PlayerSpawnLocationEvent
import java.util.* import java.util.*
import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletableFuture
import java.util.function.Consumer
object FakePlayerList { object FakePlayerList {
fun PlayerList.placeFakePlayer(connection: Connection, player: ServerPlayer) {
player.isRealPlayer = true // Paper - Chunk priority
player.networkManager = connection // Paper
player.loginTime = System.currentTimeMillis() // Paper
val gameprofile = player.getGameProfile()
val usercache = server.profileCache
val optional = usercache[gameprofile.id]
var s: String? = optional.map { obj: GameProfile -> obj.name }.orElse(gameprofile.name)
usercache.add(gameprofile)
val nbttagcompound = load(player)
// CraftBukkit start - Better rename detection
// CraftBukkit start - Better rename detection
if (nbttagcompound != null && nbttagcompound.contains("bukkit")) {
val bukkit = nbttagcompound.getCompound("bukkit")
s = if (bukkit.contains("lastKnownName", 8)) bukkit.getString("lastKnownName") else s
}
val lastKnownName = s // Paper
// CraftBukkit end
// Paper start - move logic in Entity to here, to use bukkit supplied world UUID.
// CraftBukkit end
// Paper start - move logic in Entity to here, to use bukkit supplied world UUID.
val resourcekey =
if (nbttagcompound != null && nbttagcompound.contains("WorldUUIDMost") && nbttagcompound.contains("WorldUUIDLeast")) {
val uid = UUID(nbttagcompound.getLong("WorldUUIDMost"), nbttagcompound.getLong("WorldUUIDLeast"))
val bWorld = Bukkit.getServer().getWorld(uid)
if (bWorld != null) {
(bWorld as CraftWorld).handle.dimension()
} else {
Level.OVERWORLD
}
} else if (nbttagcompound != null) {
// Vanilla migration support
// Paper end
val dataresult = DimensionType.parseLegacy(
Dynamic(
NbtOps.INSTANCE,
nbttagcompound["Dimension"]
)
) // CraftBukkit - decompile error
dataresult.resultOrPartial { msg: String? ->
}.orElse(Level.OVERWORLD)
} else {
Level.OVERWORLD
}
val resourcekey1: ResourceKey<Level> = resourcekey
val worldserver = server.getLevel(resourcekey1)
var worldserver1: ServerLevel
worldserver1 = if (worldserver == null) {
server.overworld()
} else {
worldserver
}
if (nbttagcompound == null) player.fudgeSpawnLocation(worldserver1) // Paper - only move to spawn on first login, otherwise, stay where you are....
player.setLevel(worldserver1)
// Paper start - make s1 final
// Paper start - make s1 final
val s1: String
s1 = if (connection.remoteAddress != null) {
if (GlobalConfiguration.get().logging.logPlayerIpAddresses) connection.remoteAddress.toString() else "<ip address withheld>" // Paper
} else {
"local"
}
// Paper end
// Spigot start - spawn location event
// Paper end
// Spigot start - spawn location event
val spawnPlayer: Player = player.bukkitEntity
val ev: PlayerSpawnLocationEvent =
PlayerInitialSpawnEvent(spawnPlayer, spawnPlayer.location) // Paper use our duplicate event
val cserver = ReflectionUtil().getValueFromField(this, "cserver") as CraftServer
cserver.pluginManager.callEvent(ev)
val loc = ev.spawnLocation
worldserver1 = (loc.world as CraftWorld).handle
player.spawnIn(worldserver1)
player.gameMode.setLevel(player.level as ServerLevel)
player.setPosRaw(loc.x, loc.y, loc.z)
player.setRot(loc.yaw, loc.pitch)
val worlddata = worldserver1.getLevelData()
player.loadGameTypes(nbttagcompound)
val playerconnection = ServerGamePacketListenerImpl(server, connection, player)
val gamerules = worldserver1.gameRules
val flag = gamerules.getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN)
val flag1 = gamerules.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO)
val registryHolder = ReflectionUtil().getValueFromField(this, "t" /* registryHolder -> t */) as RegistryAccess.Frozen
playerconnection.send(
ClientboundLoginPacket(
player.id,
worlddata.isHardcore,
player.gameMode.gameModeForPlayer,
player.gameMode.previousGameModeForPlayer,
server.levelKeys(),
registryHolder,
worldserver1.dimensionTypeId(),
worldserver1.dimension(),
BiomeManager.obfuscateSeed(worldserver1.seed),
maxPlayers,
worldserver1.getChunkSource().chunkMap.playerChunkManager.targetSendDistance,
worldserver1.getChunkSource().chunkMap.playerChunkManager.targetTickViewDistance,
flag1,
!flag,
worldserver1.isDebug,
worldserver1.isFlat,
player.lastDeathLocation
)
)
player.bukkitEntity.sendSupportedChannels() // CraftBukkit
playerconnection.send(
ClientboundCustomPayloadPacket(
ClientboundCustomPayloadPacket.BRAND, FriendlyByteBuf(Unpooled.buffer()).writeUtf(
server.serverModName
)
)
)
playerconnection.send(ClientboundChangeDifficultyPacket(worlddata.difficulty, worlddata.isDifficultyLocked))
playerconnection.send(ClientboundPlayerAbilitiesPacket(player.abilities))
playerconnection.send(ClientboundSetCarriedItemPacket(player.inventory.selected))
playerconnection.send(ClientboundUpdateRecipesPacket(server.recipeManager.getRecipes()))
playerconnection.send(ClientboundUpdateTagsPacket(TagNetworkSerialization.serializeTagsToNetwork(registryHolder)))
this.sendPlayerPermissionLevel(player)
player.stats.markAllDirty()
player.recipeBook.sendInitialRecipeBook(player)
updateEntireScoreboard(worldserver1.scoreboard, player)
server.invalidateStatus()
// Paper start - async load spawn in chunk
// Paper start - async load spawn in chunk
val finalWorldserver = worldserver1
val chunkX = loc.blockX shr 4
val chunkZ = loc.blockZ shr 4
val pos = ChunkPos(chunkX, chunkZ)
val playerChunkMap = worldserver1.getChunkSource().chunkMap
val distanceManager: DistanceManager = playerChunkMap.distanceManager
distanceManager.addTicket(TicketType.LOGIN, pos, 31, pos.toLong())
worldserver1.getChunkSource().markAreaHighPriority(pos, 28, 3) // Paper - Chunk priority
val postChunkLoadJoin = this::class.java.superclass.getDeclaredMethod("postChunkLoadJoin", ServerPlayer::class.java, ServerLevel::class.java, Connection::class.java, ServerGamePacketListenerImpl::class.java, CompoundTag::class.java, String::class.java, String::class.java)
postChunkLoadJoin.isAccessible = true
postChunkLoadJoin.invoke(this, player, finalWorldserver, connection, playerconnection,
nbttagcompound, "127.0.0.1", lastKnownName)
}
fun placeNewPlayer(playerList: PlayerList, server: MinecraftServer, connection: FakeConnection, player: FakePlayer) { fun placeNewPlayer(playerList: PlayerList, server: MinecraftServer, connection: FakeConnection, player: FakePlayer) {
}
fun placeNewPlayerOld(playerList: PlayerList, server: MinecraftServer, connection: FakeConnection, player: FakePlayer) {
player.isRealPlayer = true // Paper - Chunk priority player.isRealPlayer = true // Paper - Chunk priority
player.networkManager = connection // Paper player.networkManager = connection // Paper
@ -139,7 +312,7 @@ object FakePlayerList {
val pos = ChunkPos(chunkX, chunkZ) val pos = ChunkPos(chunkX, chunkZ)
val playerChunkMap = worldServer.getChunkSource().chunkMap val playerChunkMap = worldServer.getChunkSource().chunkMap
val distanceManager: DistanceManager = playerChunkMap.distanceManager val distanceManager: DistanceManager = playerChunkMap.distanceManager
distanceManager.addTicketAtLevel(TicketType.LOGIN, pos, 31, pos.toLong()) // distanceManager.addTicket(TicketType.LOGIN, pos, 31, pos.toLong())
worldServer.getChunkSource().markAreaHighPriority(pos, 28, 3) // Paper - Chunk priority worldServer.getChunkSource().markAreaHighPriority(pos, 28, 3) // Paper - Chunk priority
val postChunkLoadJoin = playerList::class.java.superclass.getDeclaredMethod("postChunkLoadJoin", ServerPlayer::class.java, ServerLevel::class.java, Connection::class.java, ServerGamePacketListenerImpl::class.java, CompoundTag::class.java, String::class.java, String::class.java) val postChunkLoadJoin = playerList::class.java.superclass.getDeclaredMethod("postChunkLoadJoin", ServerPlayer::class.java, ServerLevel::class.java, Connection::class.java, ServerGamePacketListenerImpl::class.java, CompoundTag::class.java, String::class.java, String::class.java)

View File

@ -1,20 +1,11 @@
package nl.kallestruik.dtweaks.managers package nl.kallestruik.dtweaks.managers
import net.minecraft.core.Direction
import net.minecraft.world.InteractionHand
import net.minecraft.world.entity.Entity
import net.minecraft.world.level.ClipContext
import net.minecraft.world.phys.*
import nl.kallestruik.dlib.ReflectionUtil
import nl.kallestruik.dtweaks.DTweaks import nl.kallestruik.dtweaks.DTweaks
import nl.kallestruik.dtweaks.fakeplayer.FakePlayer import nl.kallestruik.dtweaks.fakeplayer.FakePlayer
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.Location import org.bukkit.Location
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftEntity import org.bukkit.craftbukkit.v1_19_R1.entity.CraftEntity
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftPlayer import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer
import org.bukkit.scheduler.BukkitRunnable
import org.bukkit.scheduler.BukkitTask
import java.util.function.Predicate
/* /*
@ -24,12 +15,6 @@ import java.util.function.Predicate
class FakePlayerManager( class FakePlayerManager(
val plugin: DTweaks, val plugin: DTweaks,
) { ) {
init {
// Tick all fake players.
FakePlayerTickTask().runTaskTimer(plugin, 10, 10)
}
fun getPlayerByName(name: String): FakePlayer? { fun getPlayerByName(name: String): FakePlayer? {
val player = Bukkit.getPlayer(name) val player = Bukkit.getPlayer(name)
if (player == null || !player.isOnline) return null if (player == null || !player.isOnline) return null
@ -57,166 +42,4 @@ class FakePlayerManager(
fakePlayer.kill() fakePlayer.kill()
} }
} }
private fun tickAll() {
for (player in Bukkit.getOnlinePlayers()) {
if (!player.isOnline) continue
val fakePlayer = (player as CraftPlayer).handle as? FakePlayer ?: continue
fakePlayer.doTick()
}
}
// fun attackInterval(name: String, interval: Int) {
//
//
// fakePlayer.swing()
// }
fun attack(name: String) {
val player = getPlayerByName(name) ?: return
val target = getTarget(player) ?: return
when (target.type) {
HitResult.Type.BLOCK -> {/*TODO: Not implemented*/}
HitResult.Type.ENTITY -> {
if (target !is EntityHitResult) return
player.attack(target.entity);
player.swing(InteractionHand.MAIN_HAND);
player.resetLastActionTime();
}
else -> return
}
}
fun use(name: String) {
val player = getPlayerByName(name) ?: return
val target = getTarget(player) ?: return
for (hand in InteractionHand.values()) {
when (target.type) {
HitResult.Type.BLOCK -> {
if (target !is BlockHitResult) return
player.resetLastActionTime()
val world = player.getLevel()
val pos = target.blockPos
val side = target.direction
if (pos.y < player.getLevel().maxBuildHeight - (if (side === Direction.UP) 1 else 0)
&& world.mayInteract(player, pos)) {
val result = player.gameMode.useItemOn(player, world, player.getItemInHand(hand), hand, target)
if (result.consumesAction()) {
if (result.shouldSwing()) player.swing(hand)
return
}
}
}
HitResult.Type.ENTITY -> {
if (target !is EntityHitResult) return
player.resetLastActionTime()
val entity = target.entity
val relativeHitPos: Vec3 = target.getLocation().subtract(entity.x, entity.y, entity.z)
entity.interactAt(player, relativeHitPos, hand).consumesAction()
// fix for SS itemframe always returns CONSUME even if no action is performed
player.interactOn(entity, hand).consumesAction()
}
}
player.gameMode.useItem(player, player.getLevel(), player.getItemInHand(hand), hand)
}
}
//
// Ray tracing code borrowed from carpet mod: https://github.com/gnembon/fabric-carpet/blob/master/src/main/java/carpet/helpers/Tracer.java
//
fun getTarget(player: FakePlayer): HitResult? {
val reach: Double = if (player.gameMode.isCreative) 5.0 else 4.5f.toDouble()
return rayTrace(player, 1F, reach, false)
}
fun rayTrace(source: FakePlayer, partialTicks: Float, reach: Double, fluids: Boolean): HitResult? {
val blockHit = rayTraceBlocks(source, partialTicks, reach, fluids)
var maxSqDist = reach * reach
if (blockHit != null) {
maxSqDist = blockHit.location.distanceToSqr(source.getEyePosition(partialTicks))
}
val entityHit = rayTraceEntities(source, partialTicks, reach, maxSqDist)
return entityHit ?: blockHit
}
fun rayTraceBlocks(source: FakePlayer, partialTicks: Float, reach: Double, fluids: Boolean): BlockHitResult? {
val pos: Vec3 = source.getEyePosition(partialTicks)
val rotation: Vec3 = source.getViewVector(partialTicks)
val reachEnd = pos.add(rotation.x * reach, rotation.y * reach, rotation.z * reach)
return source.level.clip(
ClipContext(
pos,
reachEnd,
ClipContext.Block.OUTLINE,
if (fluids) ClipContext.Fluid.ANY else ClipContext.Fluid.NONE,
source
)
)
}
fun rayTraceEntities(source: FakePlayer, partialTicks: Float, reach: Double, maxSqDist: Double): EntityHitResult? {
val pos = source.getEyePosition(partialTicks)
val reachVec = source.getViewVector(partialTicks).scale(reach)
val box = source.boundingBox.expandTowards(reachVec).inflate(1.0)
return rayTraceEntities(source, pos, pos.add(reachVec), box, maxSqDist) {
e -> !e.isSpectator && e.isPickable
}
}
fun rayTraceEntities(
source: FakePlayer,
start: Vec3,
end: Vec3,
box: AABB,
maxSqDistance: Double,
predicate: Predicate<Entity>,
): EntityHitResult? {
val world = source.level
var targetDistance = maxSqDistance
var target: Entity? = null
var targetHitPos: Vec3? = null
for (current in world.getEntities(source, box, predicate)) {
val currentBox = current.boundingBox.inflate(current.pickRadius.toDouble())
val currentHit = currentBox.clip(start, end)
if (currentBox.contains(start)) {
if (targetDistance >= 0) {
target = current
targetHitPos = currentHit.orElse(start)
targetDistance = 0.0
}
} else if (currentHit.isPresent) {
val currentHitPos: Vec3 = currentHit.get()
val currentDistance = start.distanceToSqr(currentHitPos)
if (currentDistance < targetDistance || targetDistance == 0.0) {
if (current.rootVehicle === source.rootVehicle) {
if (targetDistance == 0.0) {
target = current
targetHitPos = currentHitPos
}
} else {
target = current
targetHitPos = currentHitPos
targetDistance = currentDistance
}
}
}
}
return if (target == null) null else EntityHitResult(target, targetHitPos!!)
}
inner class FakePlayerTickTask: BukkitRunnable() {
override fun run() {
tickAll()
}
}
} }

View File

@ -4,9 +4,7 @@ import nl.kallestruik.dtweaks.DTweaks
import nl.kallestruik.dtweaks.fakeplayer.FakePlayer import nl.kallestruik.dtweaks.fakeplayer.FakePlayer
import nl.kallestruik.dtweaks.managers.FakePlayerManager import nl.kallestruik.dtweaks.managers.FakePlayerManager
import nl.kallestruik.dtweaks.tweaks.ITweak import nl.kallestruik.dtweaks.tweaks.ITweak
import org.bukkit.Material import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftPlayer
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
import org.bukkit.event.HandlerList import org.bukkit.event.HandlerList

View File

@ -1,20 +1,12 @@
package nl.kallestruik.dtweaks.tweaks.mobtweaks package nl.kallestruik.dtweaks.tweaks.mobtweaks
import net.minecraft.core.GlobalPos
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.schedule.Activity
import nl.kallestruik.dtweaks.managers.NoSpawnZoneManager import nl.kallestruik.dtweaks.managers.NoSpawnZoneManager
import nl.kallestruik.dtweaks.tweaks.ITweak import nl.kallestruik.dtweaks.tweaks.ITweak
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftVillager
import org.bukkit.entity.Villager
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
import org.bukkit.event.HandlerList import org.bukkit.event.HandlerList
import org.bukkit.event.Listener import org.bukkit.event.Listener
import org.bukkit.event.entity.CreatureSpawnEvent import org.bukkit.event.entity.CreatureSpawnEvent
import org.bukkit.event.entity.EntitySpawnEvent
import org.bukkit.event.player.PlayerInteractEntityEvent
import org.bukkit.plugin.java.JavaPlugin import org.bukkit.plugin.java.JavaPlugin
import java.util.concurrent.atomic.AtomicReference
class NoSpawnZones( class NoSpawnZones(
private val plugin: JavaPlugin, private val plugin: JavaPlugin,

View File

@ -4,7 +4,7 @@ import net.minecraft.core.GlobalPos
import net.minecraft.world.entity.ai.memory.MemoryModuleType import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.schedule.Activity import net.minecraft.world.entity.schedule.Activity
import nl.kallestruik.dtweaks.tweaks.ITweak import nl.kallestruik.dtweaks.tweaks.ITweak
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftVillager import org.bukkit.craftbukkit.v1_19_R1.entity.CraftVillager
import org.bukkit.entity.Villager import org.bukkit.entity.Villager
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
import org.bukkit.event.HandlerList import org.bukkit.event.HandlerList