Update to 1.19
parent
10145032e2
commit
247159970c
|
@ -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")
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -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) {
|
||||||
|
|
|
@ -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}")
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue