Port to 1.20
parent
247159970c
commit
6320d31f01
|
@ -1,14 +1,14 @@
|
|||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "1.7.0-RC"
|
||||
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("io.papermc.paperweight.userdev") version "1.3.7"
|
||||
kotlin("jvm") version "1.8.22"
|
||||
id("com.github.johnrengelman.shadow") version "8.1.1"
|
||||
id("xyz.jpenilla.run-paper") version "2.1.0" // Adds runServer and runMojangMappedServer tasks for testing
|
||||
id("io.papermc.paperweight.userdev") version "1.5.5"
|
||||
}
|
||||
|
||||
group = "nl.kallestruik"
|
||||
version = "1.0"
|
||||
version = "1.1"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
@ -17,16 +17,16 @@ repositories {
|
|||
maven("https://papermc.io/repo/repository/maven-public/")
|
||||
maven("https://repo.aikar.co/content/groups/aikar/")
|
||||
maven("https://repo.dmulloy2.net/repository/public/")
|
||||
maven("https://git.kallestruik.nl/api/packages/mc/maven/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
paperDevBundle("1.19-R0.1-SNAPSHOT")
|
||||
paperweight.paperDevBundle("1.20-R0.1-SNAPSHOT")
|
||||
|
||||
implementation("co.aikar:acf-paper:0.5.0-SNAPSHOT")
|
||||
compileOnly("com.comphenix.protocol:ProtocolLib:4.6.0")
|
||||
compileOnly(kotlin("stdlib-jdk8"))
|
||||
implementation("co.aikar:acf-paper:0.5.1-SNAPSHOT")
|
||||
compileOnly("com.comphenix.protocol:ProtocolLib:5.0.0")
|
||||
|
||||
compileOnly("nl.kallestruik:DLib:1.4.4")
|
||||
compileOnly("nl.kallestruik:DLib:1.5.1")
|
||||
|
||||
testImplementation(kotlin("test-junit5"))
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
|
||||
|
@ -58,7 +58,7 @@ tasks {
|
|||
kotlinOptions.javaParameters = true
|
||||
}
|
||||
withType<KotlinCompile> {
|
||||
kotlinOptions.jvmTarget = "16"
|
||||
kotlinOptions.jvmTarget = "17"
|
||||
}
|
||||
|
||||
processResources {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
package nl.kallestruik.dtweaks
|
||||
|
||||
import org.bukkit.Material
|
||||
|
||||
enum class BundleColor(
|
||||
val modelData: Int,
|
||||
val dye: Material,
|
||||
) {
|
||||
BLACK(0, Material.BLACK_DYE),
|
||||
BLUE(1, Material.BLUE_DYE),
|
||||
BROWN(2, Material.BROWN_DYE),
|
||||
CYAN(3, Material.CYAN_DYE),
|
||||
GRAY(4, Material.GRAY_DYE),
|
||||
GREEN(5, Material.GREEN_DYE),
|
||||
LIGHT_BLUE(6, Material.LIGHT_BLUE_DYE),
|
||||
LIGHT_GRAY(7, Material.LIGHT_GRAY_DYE),
|
||||
LIME(8, Material.LIME_DYE),
|
||||
MAGENTA(9, Material.MAGENTA_DYE),
|
||||
ORANGE(10, Material.ORANGE_DYE),
|
||||
PINK(11, Material.PINK_DYE),
|
||||
PURPLE(12, Material.PURPLE_DYE),
|
||||
RED(13, Material.RED_DYE),
|
||||
WHITE(14, Material.WHITE_DYE),
|
||||
YELLOW(15, Material.YELLOW_DYE)
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package nl.kallestruik.dtweaks
|
||||
|
||||
import org.bukkit.Material
|
||||
|
||||
enum class BundleVariant(
|
||||
val modelDataStart: Int,
|
||||
val maxWeight: Int,
|
||||
val material: Material?,
|
||||
) {
|
||||
NORMAL(0, 1 * 64, null),
|
||||
IRON(100, 2 * 64, Material.IRON_INGOT),
|
||||
GOLD(200, 4 * 64, Material.GOLD_INGOT),
|
||||
DIAMOND(300, 6 * 64, Material.DIAMOND),
|
||||
NETHERITE(400, 8 * 64, Material.NETHERITE_INGOT)
|
||||
}
|
|
@ -5,7 +5,6 @@ import co.aikar.commands.PaperCommandManager
|
|||
import nl.kallestruik.dlib.DUtil
|
||||
import nl.kallestruik.dlib.MathHelper
|
||||
import nl.kallestruik.dlib.ReflectionUtil
|
||||
import nl.kallestruik.dtweaks.commands.CommandBundle
|
||||
import nl.kallestruik.dtweaks.commands.CommandPlayer
|
||||
import nl.kallestruik.dtweaks.commands.CommandSpawnzones
|
||||
import nl.kallestruik.dtweaks.commands.CommandToggletrample
|
||||
|
@ -25,6 +24,7 @@ import java.util.*
|
|||
|
||||
class DTweaks: JavaPlugin() {
|
||||
companion object {
|
||||
lateinit var plugin: DTweaks
|
||||
private lateinit var random: Random
|
||||
private lateinit var tweakManager: TweakManager
|
||||
private lateinit var util: DUtil
|
||||
|
@ -34,13 +34,13 @@ class DTweaks: JavaPlugin() {
|
|||
private lateinit var commandManager: PaperCommandManager
|
||||
private lateinit var fakePlayerManager: FakePlayerManager
|
||||
private lateinit var noSpawnZoneManager: NoSpawnZoneManager
|
||||
// private lateinit var pocketDimensionManager: PocketDimensionManager
|
||||
}
|
||||
|
||||
override fun onEnable() {
|
||||
/*
|
||||
* Initialize stuff
|
||||
*/
|
||||
plugin = this
|
||||
random = Random()
|
||||
tweakManager = TweakManager(this)
|
||||
util = DUtil(random)
|
||||
|
@ -50,23 +50,18 @@ class DTweaks: JavaPlugin() {
|
|||
commandManager = PaperCommandManager(this)
|
||||
fakePlayerManager = FakePlayerManager(this)
|
||||
noSpawnZoneManager = NoSpawnZoneManager()
|
||||
// pocketDimensionManager = PocketDimensionManager(mathHelper)
|
||||
|
||||
// Enable brigadier support on ACF
|
||||
commandManager.enableUnstableAPI("brigadier")
|
||||
|
||||
registerCommandConditions()
|
||||
|
||||
val betterBundles = BetterBundles(this)
|
||||
|
||||
/*
|
||||
* Commands
|
||||
*/
|
||||
// commandManager.registerCommand(CommandMobcaps(reflectionUtil))
|
||||
commandManager.registerCommand(CommandPlayer(fakePlayerManager))
|
||||
// commandManager.registerCommand(CommandPocketdim(pocketDimensionManager))
|
||||
commandManager.registerCommand(CommandToggletrample(trampleManager))
|
||||
commandManager.registerCommand(CommandBundle(betterBundles))
|
||||
commandManager.registerCommand(CommandSpawnzones(noSpawnZoneManager))
|
||||
|
||||
/*
|
||||
|
@ -75,7 +70,6 @@ class DTweaks: JavaPlugin() {
|
|||
tweakManager.loadFromFile(File(dataFolder, Const.TWEAK_STATE_FILE_NAME))
|
||||
trampleManager.loadFromFile(File(dataFolder, Const.TRAMPLE_ENABLED_FILE_NAME))
|
||||
noSpawnZoneManager.loadFromFile(File(dataFolder, Const.NO_SPAWN_ZONE_FILE_NAME))
|
||||
// pocketDimensionManager.loadData()
|
||||
|
||||
/*
|
||||
* Crafting tweaks
|
||||
|
@ -113,12 +107,8 @@ class DTweaks: JavaPlugin() {
|
|||
*/
|
||||
tweakManager.registerTweak(ArmorStandArmorSwapping(this))
|
||||
// tweakManager.registerTweak(CarpetBlockPlacingProtocol(this, mathHelper))
|
||||
tweakManager.registerTweak(betterBundles)
|
||||
// tweakManager.registerTweak(DyeableNetherite(this))
|
||||
tweakManager.registerTweak(FakePlayers(fakePlayerManager, this))
|
||||
tweakManager.registerTweak(Hammers(this))
|
||||
tweakManager.registerTweak(NoMelting(this))
|
||||
// tweakManager.registerTweak(SpaceTimePockets(this, pocketDimensionManager))
|
||||
|
||||
/*
|
||||
* Mob Tweaks
|
||||
|
@ -126,7 +116,6 @@ class DTweaks: JavaPlugin() {
|
|||
tweakManager.registerTweak(NoCreeperGrief(this))
|
||||
tweakManager.registerTweak(NoDoorBreaking(this))
|
||||
tweakManager.registerTweak(NoEndermanGrief(this))
|
||||
tweakManager.registerTweak(VillagerInfo(this))
|
||||
tweakManager.registerTweak(NoSpawnZones(this, noSpawnZoneManager))
|
||||
}
|
||||
|
||||
|
@ -137,7 +126,6 @@ class DTweaks: JavaPlugin() {
|
|||
tweakManager.saveToFile(File(dataFolder, Const.TWEAK_STATE_FILE_NAME))
|
||||
trampleManager.saveToFile(File(dataFolder, Const.TRAMPLE_ENABLED_FILE_NAME))
|
||||
noSpawnZoneManager.saveToFile()
|
||||
// pocketDimensionManager.saveData()
|
||||
}
|
||||
|
||||
private fun registerCommandConditions() {
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
package nl.kallestruik.dtweaks.commands
|
||||
|
||||
import co.aikar.commands.BaseCommand
|
||||
import co.aikar.commands.annotation.*
|
||||
import nl.kallestruik.dtweaks.BundleColor
|
||||
import nl.kallestruik.dtweaks.BundleVariant
|
||||
import nl.kallestruik.dtweaks.tweaks.miscellaneoustweaks.BetterBundles
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
|
||||
@CommandAlias("bundle")
|
||||
@Conditions("tweakEnabled:tweak=BetterBundles")
|
||||
class CommandBundle(
|
||||
private val betterBundles: BetterBundles,
|
||||
): BaseCommand() {
|
||||
@Subcommand("variant")
|
||||
fun onVariant(sender: Player, variant: BundleVariant) {
|
||||
val bundle = sender.inventory.itemInMainHand
|
||||
if (bundle.type != Material.BUNDLE)
|
||||
return
|
||||
|
||||
val bundleMeta = bundle.itemMeta
|
||||
bundleMeta.persistentDataContainer.set(betterBundles.VARIANT_KEY, PersistentDataType.STRING, variant.toString())
|
||||
bundle.itemMeta = bundleMeta
|
||||
betterBundles.updateBundle(bundle)
|
||||
}
|
||||
|
||||
@Subcommand("color")
|
||||
fun onVariant(sender: Player, color: BundleColor) {
|
||||
val bundle = sender.inventory.itemInMainHand
|
||||
if (bundle.type != Material.BUNDLE)
|
||||
return
|
||||
|
||||
val bundleMeta = bundle.itemMeta
|
||||
bundleMeta.persistentDataContainer.set(betterBundles.COLOR_KEY, PersistentDataType.STRING, color.toString())
|
||||
bundle.itemMeta = bundleMeta
|
||||
betterBundles.updateBundle(bundle)
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
//package nl.kallestruik.dtweaks.commands
|
||||
//
|
||||
//import co.aikar.commands.BaseCommand
|
||||
//import co.aikar.commands.annotation.CommandAlias
|
||||
//import co.aikar.commands.annotation.Conditions
|
||||
//import co.aikar.commands.annotation.Subcommand
|
||||
//import nl.kallestruik.dtweaks.managers.PocketDimensionManager
|
||||
//import org.bukkit.entity.Player
|
||||
//
|
||||
//@CommandAlias("pocketdim")
|
||||
//@Conditions("tweakEnabled:tweak=SpaceTimePockets")
|
||||
//class CommandPocketdim(
|
||||
// private val pocketDimensionManager: PocketDimensionManager
|
||||
//): BaseCommand() {
|
||||
//
|
||||
// @Subcommand("create")
|
||||
// fun onCreate(sender: Player) {
|
||||
// pocketDimensionManager.createPocketForPlayer(sender)
|
||||
// }
|
||||
//
|
||||
// @Subcommand("tp")
|
||||
// fun onTp(sender: Player) {
|
||||
// pocketDimensionManager.teleportPlayerIntoPocket(sender, sender.uniqueId)
|
||||
// }
|
||||
//}
|
|
@ -1,5 +1,8 @@
|
|||
package nl.kallestruik.dtweaks.fakeplayer
|
||||
|
||||
import io.netty.channel.ChannelHandler
|
||||
import io.netty.channel.ChannelHandlerContext
|
||||
import io.netty.channel.ChannelPipeline
|
||||
import io.netty.channel.embedded.EmbeddedChannel
|
||||
import net.minecraft.network.Connection
|
||||
import net.minecraft.network.protocol.PacketFlow
|
||||
|
@ -10,10 +13,31 @@ class FakeConnection(
|
|||
): Connection(packetFlow) {
|
||||
|
||||
init {
|
||||
this.channel = EmbeddedChannel()
|
||||
this.channel = FakeChannel()
|
||||
}
|
||||
|
||||
override fun setReadOnly() {}
|
||||
|
||||
override fun handleDisconnection() {}
|
||||
|
||||
// We need protocol lib to not get very confused with our fake connection,
|
||||
// so we need to create a fake netty pipeline.
|
||||
class FakeChannel: EmbeddedChannel() {
|
||||
override fun pipeline(): ChannelPipeline {
|
||||
val pipeline = newChannelPipeline()
|
||||
return pipeline
|
||||
.addFirst("encoder", NoopChannelHandler())
|
||||
.addFirst("decoder", NoopChannelHandler())
|
||||
}
|
||||
}
|
||||
|
||||
class NoopChannelHandler : ChannelHandler {
|
||||
override fun handlerAdded(ctx: ChannelHandlerContext?) {}
|
||||
|
||||
override fun handlerRemoved(ctx: ChannelHandlerContext?) {}
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun exceptionCaught(ctx: ChannelHandlerContext?, cause: Throwable?) {}
|
||||
|
||||
}
|
||||
}
|
|
@ -12,16 +12,17 @@ import net.minecraft.server.level.ServerPlayer
|
|||
import net.minecraft.world.damagesource.DamageSource
|
||||
import net.minecraft.world.food.FoodData
|
||||
import net.minecraft.world.level.block.entity.SkullBlockEntity
|
||||
import nl.kallestruik.dtweaks.fakeplayer.FakePlayerList.placeFakePlayer
|
||||
import nl.kallestruik.dtweaks.DTweaks
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld
|
||||
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
class FakePlayer(
|
||||
server: MinecraftServer,
|
||||
private val serverLevel: ServerLevel,
|
||||
gameProfile: GameProfile
|
||||
): ServerPlayer(server, serverLevel, gameProfile, null) {
|
||||
): ServerPlayer(server, serverLevel, gameProfile) {
|
||||
val locale = "en_US"
|
||||
|
||||
companion object {
|
||||
|
@ -31,7 +32,7 @@ class FakePlayer(
|
|||
// Get the world
|
||||
val serverLevel = (location.world as CraftWorld).handle
|
||||
// Get the game profile from the cache (or retrieve it if it is not cached)
|
||||
var gameProfile = minecraftServer.profileCache.get(name).takeIf { it.isPresent }?.get() ?: return null
|
||||
var gameProfile = minecraftServer.profileCache?.get(name).takeIf { it?.isPresent == true }?.get() ?: return null
|
||||
if (gameProfile.properties.containsKey("textures")) {
|
||||
val result = AtomicReference<GameProfile>()
|
||||
SkullBlockEntity.updateGameprofile(gameProfile, result::set)
|
||||
|
@ -43,14 +44,15 @@ class FakePlayer(
|
|||
|
||||
// Create a fake connection for our fake player.
|
||||
val connection = FakeConnection(PacketFlow.SERVERBOUND)
|
||||
minecraftServer.playerList.placeFakePlayer(connection, instance)
|
||||
|
||||
instance.respawn()
|
||||
instance.teleportTo(serverLevel, location.x, location.y, location.z, location.yaw, location.pitch)
|
||||
instance.dead = false
|
||||
instance.heal(instance.maxHealth)
|
||||
instance.unsetRemoved()
|
||||
instance.maxUpStep = 0.6F
|
||||
val bukkitPlayer = instance.bukkitEntity
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(DTweaks.plugin, Runnable {
|
||||
bukkitPlayer.spigot().respawn()
|
||||
bukkitPlayer.teleport(location)
|
||||
}, 0)
|
||||
|
||||
minecraftServer.playerList.placeNewPlayer(connection, instance)
|
||||
|
||||
minecraftServer.playerList.broadcastAll(
|
||||
ClientboundRotateHeadPacket(
|
||||
|
@ -62,59 +64,6 @@ class FakePlayer(
|
|||
|
||||
instance.entityData.set(DATA_PLAYER_MODE_CUSTOMISATION, 0x7f)
|
||||
return instance
|
||||
|
||||
// (DTweaks.reflectionUtil.getValueFromField(
|
||||
// serverConnection!!,
|
||||
// "connectedChannels"
|
||||
// ) as MutableList<NetworkManager?>).add(connection)
|
||||
//
|
||||
// // Connect the fake player to the server using the fake connection.
|
||||
// FakePlayerList.a(minecraftServer.playerList, connection, instance)
|
||||
//
|
||||
// // Check if the fake player is not yet in the correct world.
|
||||
// if (instance.world.dimensionKey != worldServer.dimensionKey) {
|
||||
// // Store the old world of the fake player.
|
||||
// val old_world = instance.world as WorldServer
|
||||
// // 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.playerList.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, yaw.toFloat(), pitch.toFloat())
|
||||
// // Set the fake player's world to the new world.
|
||||
// instance.playerInteractManager.world = worldServer
|
||||
// instance.teleportTo(worldServer, BlockPosition(x, y, z))
|
||||
// }
|
||||
//
|
||||
// /// Set the fake players health to max.
|
||||
// instance.health = 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, yaw.toFloat(), pitch.toFloat())
|
||||
// // 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.gameMode = EnumGamemode.SURVIVAL
|
||||
// // Tell everyone in the world about the fake player and where he is.
|
||||
// minecraftServer.playerList.a(
|
||||
// PacketPlayOutEntityHeadRotation(instance, (instance.yaw * 256 / 360).toByte()),
|
||||
// instance.world.dimensionKey
|
||||
// )
|
||||
// minecraftServer.playerList.a(PacketPlayOutEntityTeleport(instance), instance.world.dimensionKey)
|
||||
// // Move the fake player for the worlds chunk provider.
|
||||
// instance.worldServer.getChunkProvider().movePlayer(instance)
|
||||
// // bp == PLAYER_MODEL_PARTS
|
||||
// instance.datawatcher.set<Byte>(bj, 0x7f.toByte()) // show all model layers (incl. capes)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package nl.kallestruik.dtweaks.fakeplayer
|
|||
|
||||
import io.netty.util.concurrent.Future
|
||||
import io.netty.util.concurrent.GenericFutureListener
|
||||
import net.minecraft.network.PacketSendListener
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.protocol.Packet
|
||||
import net.minecraft.server.MinecraftServer
|
||||
|
@ -13,15 +14,10 @@ class FakePlayerConnection(
|
|||
connection: FakeConnection,
|
||||
player: FakePlayer
|
||||
): ServerGamePacketListenerImpl(minecraftServer, connection, player) {
|
||||
override fun send(packetIn: Packet<*>?) {}
|
||||
override fun send(packet: Packet<*>, listener: GenericFutureListener<out Future<in Void>>?) {}
|
||||
override fun send(packetIn: Packet<*>) {}
|
||||
override fun send(packet: Packet<*>, callbacks: PacketSendListener?) {}
|
||||
|
||||
override fun disconnect(message: Component) {
|
||||
player.kill()
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
println("Tick for ${player.name}")
|
||||
super.tick()
|
||||
}
|
||||
}
|
|
@ -1,338 +1,12 @@
|
|||
package nl.kallestruik.dtweaks.fakeplayer
|
||||
|
||||
import com.destroystokyo.paper.event.player.PlayerInitialSpawnEvent
|
||||
import com.mojang.authlib.GameProfile
|
||||
import com.mojang.datafixers.util.Either
|
||||
import com.mojang.serialization.Dynamic
|
||||
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.NbtOps
|
||||
import net.minecraft.nbt.Tag
|
||||
import net.minecraft.network.Connection
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.network.protocol.game.*
|
||||
import net.minecraft.resources.ResourceKey
|
||||
import net.minecraft.server.MinecraftServer
|
||||
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.players.GameProfileCache
|
||||
import net.minecraft.server.players.PlayerList
|
||||
import net.minecraft.tags.TagNetworkSerialization
|
||||
import net.minecraft.world.level.ChunkPos
|
||||
import net.minecraft.world.level.GameRules
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.biome.BiomeManager
|
||||
import net.minecraft.world.level.chunk.ChunkAccess
|
||||
import net.minecraft.world.level.dimension.DimensionType
|
||||
import nl.kallestruik.dlib.ReflectionUtil
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.craftbukkit.v1_19_R1.CraftServer
|
||||
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld
|
||||
import org.bukkit.entity.Player
|
||||
import org.spigotmc.event.player.PlayerSpawnLocationEvent
|
||||
import java.util.*
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
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 placeNewPlayerOld(playerList: PlayerList, server: MinecraftServer, connection: FakeConnection, player: FakePlayer) {
|
||||
player.isRealPlayer = true // Paper - Chunk priority
|
||||
|
||||
player.networkManager = connection // Paper
|
||||
|
||||
player.loginTime = System.currentTimeMillis() // Paper
|
||||
|
||||
val gameProfile: GameProfile = player.getGameProfile()
|
||||
val userCache: GameProfileCache = server.getProfileCache()
|
||||
val optional = userCache[gameProfile.id]
|
||||
var s: String? = optional.map { obj: GameProfile -> obj.name }.orElse(gameProfile.name)
|
||||
|
||||
userCache.add(gameProfile)
|
||||
val nbtTagCompound: CompoundTag? = playerList.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: ResourceKey<Level> = 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"]
|
||||
)
|
||||
)
|
||||
dataResult.result().orElse(Level.OVERWORLD)
|
||||
} else {
|
||||
Level.OVERWORLD
|
||||
}
|
||||
|
||||
var worldServer: ServerLevel = server.getLevel(resourceKey) ?: server.overworld()
|
||||
|
||||
if (nbtTagCompound == null) player.fudgeSpawnLocation(worldServer) // Paper - only move to spawn on first login, otherwise, stay where you are....
|
||||
|
||||
player.setLevel(worldServer)
|
||||
|
||||
|
||||
// Spigot start - spawn location event
|
||||
val spawnPlayer: Player = player.bukkitEntity
|
||||
val ev: PlayerSpawnLocationEvent =
|
||||
PlayerInitialSpawnEvent(spawnPlayer, spawnPlayer.location) // Paper use our duplicate event
|
||||
|
||||
Bukkit.getServer().pluginManager.callEvent(ev)
|
||||
|
||||
val loc = ev.spawnLocation
|
||||
worldServer = (loc.world as CraftWorld).handle
|
||||
|
||||
player.spawnIn(worldServer)
|
||||
player.gameMode.setLevel(player.level as ServerLevel)
|
||||
// Paper start - set raw so we aren't fully joined to the world (not added to chunk or world)
|
||||
// Paper start - set raw so we aren't fully joined to the world (not added to chunk or world)
|
||||
player.setPosRaw(loc.x, loc.y, loc.z)
|
||||
player.setRot(loc.yaw, loc.pitch)
|
||||
// Paper end
|
||||
// Spigot end
|
||||
|
||||
// CraftBukkit - Moved message to after join
|
||||
// PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ({}, {}, {})", entityplayer.getName().getString(), s1, entityplayer.getId(), entityplayer.getX(), entityplayer.getY(), entityplayer.getZ());
|
||||
// Paper end
|
||||
// Spigot end
|
||||
|
||||
// CraftBukkit - Moved message to after join
|
||||
// PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ({}, {}, {})", entityplayer.getName().getString(), s1, entityplayer.getId(), entityplayer.getX(), entityplayer.getY(), entityplayer.getZ());
|
||||
val worlddata = worldServer.getLevelData()
|
||||
|
||||
player.loadGameTypes(nbtTagCompound)
|
||||
val playerconnection = FakePlayerConnection(server, connection, player)
|
||||
val gamerules = worldServer.gameRules
|
||||
|
||||
player.bukkitEntity.sendSupportedChannels() // CraftBukkit
|
||||
|
||||
player.stats.markAllDirty()
|
||||
player.recipeBook.sendInitialRecipeBook(player)
|
||||
playerList.updateEntireScoreboard(worldServer.scoreboard, player)
|
||||
server.invalidateStatus()
|
||||
// Paper start - async load spawn in chunk
|
||||
// Paper start - async load spawn in chunk
|
||||
val finalWorldserver = worldServer
|
||||
val chunkX = loc.blockX shr 4
|
||||
val chunkZ = loc.blockZ shr 4
|
||||
val pos = ChunkPos(chunkX, chunkZ)
|
||||
val playerChunkMap = worldServer.getChunkSource().chunkMap
|
||||
val distanceManager: DistanceManager = playerChunkMap.distanceManager
|
||||
// distanceManager.addTicket(TicketType.LOGIN, pos, 31, pos.toLong())
|
||||
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)
|
||||
postChunkLoadJoin.isAccessible = true
|
||||
postChunkLoadJoin.invoke(playerList, player, finalWorldserver, connection, playerconnection,
|
||||
nbtTagCompound, "127.0.0.1", lastKnownName)
|
||||
|
||||
|
||||
// worldServer.getChunkSource().getChunkAtAsynchronously(chunkX, chunkZ, true, false)
|
||||
// .thenApply { chunk: Either<ChunkAccess, ChunkLoadingFailure> -> // Paper - Chunk priority
|
||||
// val updatingChunk = playerChunkMap.getUpdatingChunkIfPresent(pos.toLong())
|
||||
// if (updatingChunk != null) {
|
||||
// return@thenApply updatingChunk.entityTickingChunkFuture
|
||||
// } else {
|
||||
// return@thenApply CompletableFuture.completedFuture(
|
||||
// chunk
|
||||
// )
|
||||
// }
|
||||
// }.thenAccept {
|
||||
//
|
||||
// }
|
||||
}
|
||||
}
|
|
@ -4,8 +4,8 @@ import nl.kallestruik.dtweaks.DTweaks
|
|||
import nl.kallestruik.dtweaks.fakeplayer.FakePlayer
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftEntity
|
||||
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer
|
||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity
|
||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,108 +0,0 @@
|
|||
//package nl.kallestruik.dtweaks.managers
|
||||
//
|
||||
//import nl.kallestruik.dlib.MathHelper
|
||||
//import nl.kallestruik.dtweaks.spacetimepockets.SpaceTimePocketChunkGenerator
|
||||
//import org.bukkit.*
|
||||
//import org.bukkit.entity.Player
|
||||
//import java.util.*
|
||||
//
|
||||
//class PocketDimensionManager(
|
||||
// private val mathHelper: MathHelper
|
||||
//) {
|
||||
// val pocketDimension: World = WorldCreator.name("space-time-pockets").generator(SpaceTimePocketChunkGenerator()).createWorld()!!
|
||||
// private val data = HashMap<UUID, PocketData>()
|
||||
// private var lastCreatedPocket = -1
|
||||
//
|
||||
// fun loadData() {
|
||||
// //TODO: Load data from data file on disk.
|
||||
// }
|
||||
//
|
||||
// fun saveData() {
|
||||
// //TODO: Save data to file on disk.
|
||||
// }
|
||||
//
|
||||
// fun teleportPlayerIntoPocket(player: Player, pocketOwner: UUID) {
|
||||
// var pocketData = data[pocketOwner]
|
||||
// if (pocketData == null) pocketData = if (player.uniqueId == pocketOwner) {
|
||||
// createPocketForPlayer(player)
|
||||
// } else return
|
||||
// player.teleport(
|
||||
// Location(
|
||||
// pocketDimension, (pocketData.startX + 9).toDouble(), 128.0,
|
||||
// (pocketData.startZ + 9).toDouble()
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// fun createPocketForPlayer(player: Player): PocketData {
|
||||
// // Find a spot
|
||||
// val point = findNextFree()
|
||||
//
|
||||
// // Load the chunks
|
||||
// for (x in 0..2) {
|
||||
// for (y in 0..2) {
|
||||
// pocketDimension.loadChunk(point.x / 16 + x, point.z / 16 + y)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Build the box
|
||||
// for (x in 0..17) {
|
||||
// for (z in 0..17) {
|
||||
// for (y in 0..255) {
|
||||
// if (x == 0 || y == 0 || z == 0 || x == 17 || y == 255 || z == 17) {
|
||||
// pocketDimension.getBlockAt(point.x + x, y, point.z + z).type = Material.BLACK_CONCRETE
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Create the spawning platform
|
||||
// pocketDimension.getBlockAt(point.x + 8, 127, point.z + 8).type = Material.STONE
|
||||
// pocketDimension.getBlockAt(point.x + 8, 127, point.z + 9).type = Material.STONE
|
||||
// pocketDimension.getBlockAt(point.x + 9, 127, point.z + 8).type = Material.STONE
|
||||
// pocketDimension.getBlockAt(point.x + 9, 127, point.z + 9).type = Material.STONE
|
||||
//
|
||||
// // Unload the chunks
|
||||
// for (x in 0..2) {
|
||||
// for (y in 0..2) {
|
||||
// pocketDimension.unloadChunk(point.x / 16 + x, point.z / 16 + y)
|
||||
// }
|
||||
// }
|
||||
// val pocketData = PocketData(player.uniqueId, point.x, point.z, ArrayList())
|
||||
// data[player.uniqueId] = pocketData
|
||||
// return pocketData
|
||||
// }
|
||||
//
|
||||
// private fun findNextFree(): Point {
|
||||
// while (true) {
|
||||
// lastCreatedPocket++
|
||||
// val toCheck = getXYForIndex(lastCreatedPocket)
|
||||
// val chunk = pocketDimension.getChunkAt(
|
||||
// Location(
|
||||
// pocketDimension,
|
||||
// toCheck.x.toDouble(), 0.0, toCheck.z.toDouble()
|
||||
// )
|
||||
// )
|
||||
// val corner = chunk.getBlock(mathHelper.chunkAbs(toCheck.x % 16), 0, mathHelper.chunkAbs(toCheck.z % 16))
|
||||
// if (corner.type == Material.AIR) {
|
||||
// return toCheck
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private fun getXYForIndex(index: Int): Point {
|
||||
// // Space the pockets 256 blocks (16 chunks) from each other with each pocket being 16 blocks (and two for walls)
|
||||
// // Also subtract 1 from each point so the interior is chunk aligned.
|
||||
// val x = (256 + 16) * (index % 1000) - 1
|
||||
// val z = (256 + 16) * (index / 1000) - 1
|
||||
// return Point(x, z)
|
||||
// }
|
||||
//
|
||||
// class PocketData(var owner: UUID, var startX: Int, var startZ: Int, var queuedGateways: ArrayList<GatewayData?>)
|
||||
//
|
||||
// class GatewayData
|
||||
//
|
||||
// class Point(var x: Int, var y: Int, var z: Int) {
|
||||
// constructor(x: Int, z: Int) : this(x, 0, z) {}
|
||||
// }
|
||||
//}
|
|
@ -1,27 +0,0 @@
|
|||
//package nl.kallestruik.dtweaks.spacetimepockets
|
||||
//
|
||||
//import org.bukkit.World
|
||||
//import org.bukkit.block.Biome
|
||||
//import org.bukkit.craftbukkit.v1_18_R1.generator.CraftChunkData
|
||||
//import org.bukkit.generator.ChunkGenerator
|
||||
//import java.util.*
|
||||
//
|
||||
//class SpaceTimePocketChunkGenerator: ChunkGenerator() {
|
||||
//
|
||||
// override fun generateChunkData(
|
||||
// world: World,
|
||||
// random: Random,
|
||||
// x: Int,
|
||||
// z: Int,
|
||||
// biome: BiomeGrid
|
||||
// ): ChunkData {
|
||||
// for (cx in 0..15) {
|
||||
// for (cz in 0..15) {
|
||||
// for (cy in 0..264) {
|
||||
// biome.setBiome(cx, cy, cz, Biome.THE_VOID)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return CraftChunkData(world)
|
||||
// }
|
||||
//}
|
|
@ -1,345 +0,0 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.miscellaneoustweaks
|
||||
|
||||
import com.google.common.base.Preconditions
|
||||
import net.kyori.adventure.text.Component
|
||||
import net.kyori.adventure.text.format.NamedTextColor
|
||||
import net.kyori.adventure.text.format.TextDecoration
|
||||
import nl.kallestruik.dtweaks.BundleColor
|
||||
import nl.kallestruik.dtweaks.BundleVariant
|
||||
import nl.kallestruik.dtweaks.DTweaks
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Keyed
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.HandlerList
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.inventory.InventoryClickEvent
|
||||
import org.bukkit.event.inventory.PrepareItemCraftEvent
|
||||
import org.bukkit.inventory.*
|
||||
import org.bukkit.inventory.meta.BundleMeta
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
|
||||
|
||||
class BetterBundles(
|
||||
private val plugin: DTweaks
|
||||
): ITweak, Listener {
|
||||
override fun getIdentifier(): String = "BetterBundles"
|
||||
override fun getCategories(): List<String> = listOf("miscellaneous", "survival")
|
||||
|
||||
private val recipeKeys = mutableListOf<NamespacedKey>()
|
||||
|
||||
override fun onEnable() {
|
||||
plugin.server.pluginManager.registerEvents(this, plugin)
|
||||
|
||||
for (color in BundleColor.values()) {
|
||||
val result = ItemStack(Material.BUNDLE)
|
||||
val resultMeta = result.itemMeta
|
||||
resultMeta.setCustomModelData(BundleVariant.NORMAL.modelDataStart + color.modelData)
|
||||
resultMeta.persistentDataContainer.set(COLOR_KEY, PersistentDataType.STRING, color.toString())
|
||||
result.itemMeta = resultMeta
|
||||
|
||||
val key = NamespacedKey(plugin, "${color.name.lowercase()}_color_bundle")
|
||||
recipeKeys.add(key)
|
||||
|
||||
addDyeRecipe(key, color.dye, result)
|
||||
}
|
||||
|
||||
for (variant in BundleVariant.values()) {
|
||||
if (variant.material == null)
|
||||
continue
|
||||
|
||||
val result = ItemStack(Material.BUNDLE)
|
||||
val resultMeta = result.itemMeta
|
||||
resultMeta.setCustomModelData(variant.modelDataStart + BundleColor.BROWN.modelData)
|
||||
resultMeta.persistentDataContainer.set(VARIANT_KEY, PersistentDataType.STRING, variant.toString())
|
||||
|
||||
result.itemMeta = resultMeta
|
||||
|
||||
val key = NamespacedKey(plugin, "${variant.name.lowercase()}_variant_bundle")
|
||||
recipeKeys.add(key)
|
||||
|
||||
addUpgradeRecipe(key, variant.material, result)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
HandlerList.unregisterAll(this)
|
||||
for (key in recipeKeys) {
|
||||
plugin.server.removeRecipe(key)
|
||||
}
|
||||
|
||||
recipeKeys.clear()
|
||||
}
|
||||
|
||||
val VARIANT_KEY = NamespacedKey(plugin, "variant")
|
||||
val COLOR_KEY = NamespacedKey(plugin, "color")
|
||||
|
||||
private fun addDyeRecipe(key: NamespacedKey, dye: Material, result: ItemStack) {
|
||||
val recipe = ShapelessRecipe(key, result)
|
||||
recipe.addIngredient(dye)
|
||||
recipe.addIngredient(Material.BUNDLE)
|
||||
|
||||
plugin.server.addRecipe(recipe)
|
||||
}
|
||||
|
||||
private fun addUpgradeRecipe(key: NamespacedKey, material: Material, result: ItemStack) {
|
||||
val recipe = ShapedRecipe(key, result)
|
||||
recipe.shape("MMM", "MBM", "MMM")
|
||||
recipe.setIngredient('M', material)
|
||||
recipe.setIngredient('B', Material.BUNDLE)
|
||||
|
||||
plugin.server.addRecipe(recipe)
|
||||
}
|
||||
|
||||
private fun isBundleRecipe(recipe: Recipe): Boolean {
|
||||
return isDyeRecipe(recipe) || isVariantRecipe(recipe)
|
||||
}
|
||||
|
||||
private fun isDyeRecipe(recipe: Recipe): Boolean {
|
||||
if (recipe !is Keyed)
|
||||
return false
|
||||
|
||||
val key = recipe.key
|
||||
if (key.namespace != plugin.getNamespace())
|
||||
return false
|
||||
|
||||
if (!key.key.endsWith("_color_bundle"))
|
||||
return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun isVariantRecipe(recipe: Recipe): Boolean {
|
||||
if (recipe !is Keyed)
|
||||
return false
|
||||
|
||||
val key = recipe.key
|
||||
if (key.namespace != plugin.getNamespace())
|
||||
return false
|
||||
|
||||
if (!key.key.endsWith("_variant_bundle"))
|
||||
return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onCraft(event: PrepareItemCraftEvent) {
|
||||
val recipe = event.recipe ?: return
|
||||
|
||||
if (!isBundleRecipe(recipe))
|
||||
return
|
||||
|
||||
|
||||
val inventory = event.inventory
|
||||
Bukkit.getScheduler().runTask(
|
||||
plugin,
|
||||
Runnable {
|
||||
inventory.result =
|
||||
if (isDyeRecipe(recipe)) getDyeResult(recipe, inventory)
|
||||
else if (isVariantRecipe(recipe)) getVariantResult(recipe, inventory)
|
||||
else null
|
||||
})
|
||||
}
|
||||
|
||||
private fun getDyeResult(recipe: Recipe, inventory: CraftingInventory): ItemStack? {
|
||||
val bundle = inventory.matrix?.filter { it?.type == Material.BUNDLE }?.get(0) ?: return null
|
||||
val recipeResult = recipe.result
|
||||
|
||||
val result = bundle.clone()
|
||||
val resultMeta = result.itemMeta
|
||||
resultMeta.persistentDataContainer.set(
|
||||
COLOR_KEY,
|
||||
PersistentDataType.STRING,
|
||||
recipeResult.itemMeta.persistentDataContainer.get(
|
||||
COLOR_KEY,
|
||||
PersistentDataType.STRING
|
||||
) ?: BundleColor.BROWN.name
|
||||
)
|
||||
|
||||
result.itemMeta = resultMeta
|
||||
updateBundle(result)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun getVariantResult(recipe: Recipe, inventory: CraftingInventory): ItemStack? {
|
||||
val bundle = inventory.matrix?.filter { it?.type == Material.BUNDLE }?.get(0) ?: return null
|
||||
val recipeResult = recipe.result
|
||||
|
||||
val result = bundle.clone()
|
||||
val resultMeta = result.itemMeta
|
||||
resultMeta.persistentDataContainer.set(
|
||||
VARIANT_KEY,
|
||||
PersistentDataType.STRING,
|
||||
recipeResult.itemMeta.persistentDataContainer.get(
|
||||
VARIANT_KEY,
|
||||
PersistentDataType.STRING
|
||||
) ?: BundleVariant.NORMAL.name
|
||||
)
|
||||
|
||||
result.itemMeta = resultMeta
|
||||
updateBundle(result)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
@EventHandler
|
||||
fun onInventoryClick(event: InventoryClickEvent) {
|
||||
if (!event.isRightClick)
|
||||
return
|
||||
|
||||
val cursor = event.cursor ?: return
|
||||
val clicked = event.currentItem ?: return
|
||||
|
||||
val bundle: ItemStack
|
||||
val item: ItemStack
|
||||
var itemIsCursor = true
|
||||
|
||||
if (cursor.type == Material.BUNDLE) {
|
||||
bundle = cursor
|
||||
item = clicked
|
||||
itemIsCursor = false
|
||||
} else if (clicked.type == Material.BUNDLE) {
|
||||
bundle = clicked
|
||||
item = cursor
|
||||
} else
|
||||
return
|
||||
|
||||
if (item.type.isAir || item.amount == 0) {
|
||||
val itemStack = removeItemFromBundle(bundle) ?: return
|
||||
|
||||
if (itemIsCursor)
|
||||
event.cursor = itemStack
|
||||
else
|
||||
event.currentItem = itemStack
|
||||
} else
|
||||
addItemToBundle(bundle, item)
|
||||
|
||||
event.isCancelled = true
|
||||
}
|
||||
|
||||
private fun removeItemFromBundle(bundle: ItemStack): ItemStack? {
|
||||
val meta = bundle.itemMeta as BundleMeta
|
||||
if (!meta.hasItems())
|
||||
return null
|
||||
|
||||
val itemsInBundle = mutableListOf<ItemStack>()
|
||||
itemsInBundle.addAll(meta.items)
|
||||
val toReturn = itemsInBundle.removeFirst()
|
||||
|
||||
meta.setItems(itemsInBundle)
|
||||
bundle.itemMeta = meta
|
||||
|
||||
updateBundle(bundle)
|
||||
|
||||
return toReturn
|
||||
}
|
||||
|
||||
private fun addItemToBundle(bundle: ItemStack, item: ItemStack) {
|
||||
var meta = bundle.itemMeta as BundleMeta
|
||||
val persistentContainer = bundle.itemMeta.persistentDataContainer
|
||||
val variant = BundleVariant.valueOf(persistentContainer.get(VARIANT_KEY, PersistentDataType.STRING) ?: "NORMAL")
|
||||
|
||||
val currentWeight = computeWeight(meta.items)
|
||||
val availableWeight = variant.maxWeight - currentWeight
|
||||
|
||||
val weightPerItem = getWeightPerItem(item)
|
||||
val totalStackWeight = weightPerItem * item.amount
|
||||
if (totalStackWeight > availableWeight) {
|
||||
val toStoreAmount = availableWeight / weightPerItem
|
||||
if (toStoreAmount <= 0)
|
||||
return
|
||||
|
||||
meta = addItemToBundleProper(meta, item.asQuantity(toStoreAmount))
|
||||
item.amount -= toStoreAmount
|
||||
} else {
|
||||
meta = addItemToBundleProper(meta, item.clone())
|
||||
item.amount = 0
|
||||
}
|
||||
|
||||
bundle.itemMeta = meta
|
||||
|
||||
updateBundle(bundle)
|
||||
}
|
||||
|
||||
fun updateBundle(bundle: ItemStack) {
|
||||
val meta = bundle.itemMeta as BundleMeta
|
||||
val persistentContainer = meta.persistentDataContainer
|
||||
|
||||
val variant = BundleVariant.valueOf(persistentContainer.get(VARIANT_KEY, PersistentDataType.STRING) ?: "NORMAL")
|
||||
val color = BundleColor.valueOf(persistentContainer.get(COLOR_KEY, PersistentDataType.STRING) ?: "BROWN")
|
||||
|
||||
val customModelData = variant.modelDataStart + color.modelData
|
||||
|
||||
meta.setCustomModelData(customModelData)
|
||||
meta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS)
|
||||
meta.lore(listOf(Component
|
||||
.text("${computeWeight(meta.items)}/${variant.maxWeight}")
|
||||
.color(NamedTextColor.GRAY)
|
||||
.decoration(TextDecoration.ITALIC, false)))
|
||||
|
||||
bundle.itemMeta = meta
|
||||
}
|
||||
|
||||
private fun computeWeight(items: List<ItemStack>): Int {
|
||||
return items.sumOf { getWeight(it) }
|
||||
}
|
||||
|
||||
private fun getWeight(item: ItemStack): Int {
|
||||
return item.amount * getWeightPerItem(item)
|
||||
}
|
||||
|
||||
private fun getWeightPerItem(item: ItemStack): Int {
|
||||
// Special case for bundle nesting.
|
||||
if (item.type == Material.BUNDLE) {
|
||||
val meta = item.itemMeta as BundleMeta
|
||||
return if (meta.hasItems())
|
||||
64
|
||||
else
|
||||
4
|
||||
}
|
||||
|
||||
// Calculate the right weight.
|
||||
return (64 / item.maxStackSize)
|
||||
}
|
||||
|
||||
private fun addItemToBundleProper(itemMeta: BundleMeta, itemStack: ItemStack): BundleMeta {
|
||||
Preconditions.checkArgument(!itemStack.type.isAir, "item is null or air")
|
||||
|
||||
var leftOver = true
|
||||
val items = mutableListOf<ItemStack>()
|
||||
items.addAll(itemMeta.items)
|
||||
|
||||
for (item in itemMeta.items) {
|
||||
if (item.isSimilar(itemStack)) {
|
||||
if (item.amount >= item.maxStackSize)
|
||||
continue
|
||||
|
||||
items.remove(item)
|
||||
val spaceLeft = item.maxStackSize - item.amount
|
||||
if (spaceLeft >= itemStack.amount) {
|
||||
item.amount += itemStack.amount
|
||||
itemStack.amount = 0
|
||||
items.add(0, item)
|
||||
leftOver = false
|
||||
break
|
||||
} else {
|
||||
item.amount = item.maxStackSize
|
||||
itemStack.amount -= spaceLeft
|
||||
items.add(0, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (leftOver)
|
||||
items.add(0, itemStack)
|
||||
|
||||
itemMeta.setItems(items)
|
||||
|
||||
return itemMeta
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ import nl.kallestruik.dtweaks.DTweaks
|
|||
import nl.kallestruik.dtweaks.fakeplayer.FakePlayer
|
||||
import nl.kallestruik.dtweaks.managers.FakePlayerManager
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer
|
||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.HandlerList
|
||||
|
|
|
@ -1,134 +0,0 @@
|
|||
package nl.kallestruik.dtweaks.tweaks.miscellaneoustweaks
|
||||
|
||||
import nl.kallestruik.dtweaks.DTweaks
|
||||
import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.block.Block
|
||||
import org.bukkit.block.BlockFace
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.HandlerList
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.block.BlockBreakEvent
|
||||
import org.bukkit.inventory.*
|
||||
import org.bukkit.inventory.meta.Damageable
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
|
||||
|
||||
class Hammers(
|
||||
private val plugin: DTweaks
|
||||
): ITweak, Listener {
|
||||
override fun getIdentifier(): String = "Hammers"
|
||||
override fun getCategories(): List<String> = listOf("miscellaneous", "survival")
|
||||
|
||||
val HAMMER_KEY = NamespacedKey(plugin, "hammer")
|
||||
val diamondHammerRecipeKey = NamespacedKey(plugin, "diamond_hammer")
|
||||
|
||||
override fun onEnable() {
|
||||
plugin.server.pluginManager.registerEvents(this, plugin)
|
||||
|
||||
val diamondHammer = ItemStack(Material.DIAMOND_PICKAXE)
|
||||
val diamondHammerMeta = diamondHammer.itemMeta
|
||||
diamondHammerMeta.persistentDataContainer.set(HAMMER_KEY, PersistentDataType.SHORT, 1)
|
||||
diamondHammer.itemMeta = diamondHammerMeta
|
||||
updateHammer(diamondHammer)
|
||||
|
||||
val recipe = ShapedRecipe(diamondHammerRecipeKey, diamondHammer)
|
||||
recipe.shape(
|
||||
" BD",
|
||||
" SB",
|
||||
"S ")
|
||||
recipe.setIngredient('B', Material.DIAMOND_BLOCK)
|
||||
recipe.setIngredient('D', Material.DIAMOND)
|
||||
recipe.setIngredient('S', Material.STICK)
|
||||
|
||||
plugin.server.addRecipe(recipe)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
HandlerList.unregisterAll(this)
|
||||
plugin.server.removeRecipe(diamondHammerRecipeKey)
|
||||
}
|
||||
|
||||
fun updateHammer(hammer: ItemStack) {
|
||||
if (!isHammer(hammer))
|
||||
return
|
||||
val meta = hammer.itemMeta
|
||||
|
||||
meta.setCustomModelData(1)
|
||||
|
||||
hammer.itemMeta = meta
|
||||
}
|
||||
|
||||
private fun isHammer(itemStack: ItemStack): Boolean {
|
||||
val meta = itemStack.itemMeta ?: return false
|
||||
|
||||
val persistentContainer = meta.persistentDataContainer
|
||||
|
||||
return persistentContainer.get(HAMMER_KEY, PersistentDataType.SHORT) == 1.toShort()
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onBlockBreak(event: BlockBreakEvent) {
|
||||
val hammer = event.player.inventory.itemInMainHand
|
||||
if (!isHammer(hammer))
|
||||
return
|
||||
|
||||
val player = event.player
|
||||
|
||||
val lastTwoTargetBlocks: List<Block> = player.getLastTwoTargetBlocks(null, 100)
|
||||
if (lastTwoTargetBlocks.size != 2 || !lastTwoTargetBlocks[1].type.isOccluding) return
|
||||
|
||||
val targetBlock: Block = lastTwoTargetBlocks[1]
|
||||
val adjacentBlock: Block = lastTwoTargetBlocks[0]
|
||||
|
||||
val targetFace = targetBlock.getFace(adjacentBlock)
|
||||
|
||||
val toBreak: MutableList<Block> = mutableListOf()
|
||||
|
||||
when (targetFace) {
|
||||
BlockFace.NORTH, BlockFace.SOUTH -> {
|
||||
toBreak.add(targetBlock.getRelative(1, 0, 0))
|
||||
toBreak.add(targetBlock.getRelative(-1, 0, 0))
|
||||
toBreak.add(targetBlock.getRelative(0, 1, 0))
|
||||
toBreak.add(targetBlock.getRelative(0, -1, 0))
|
||||
toBreak.add(targetBlock.getRelative(1, 1, 0))
|
||||
toBreak.add(targetBlock.getRelative(-1, 1, 0))
|
||||
toBreak.add(targetBlock.getRelative(1, -1, 0))
|
||||
toBreak.add(targetBlock.getRelative(-1, -1, 0))
|
||||
}
|
||||
|
||||
BlockFace.EAST, BlockFace.WEST -> {
|
||||
toBreak.add(targetBlock.getRelative(0, 1, 0))
|
||||
toBreak.add(targetBlock.getRelative(0, -1, 0))
|
||||
toBreak.add(targetBlock.getRelative(0, 0, 1))
|
||||
toBreak.add(targetBlock.getRelative(0, 0, -1))
|
||||
toBreak.add(targetBlock.getRelative(0, 1, 1))
|
||||
toBreak.add(targetBlock.getRelative(0, -1, 1))
|
||||
toBreak.add(targetBlock.getRelative(0, 1, -1))
|
||||
toBreak.add(targetBlock.getRelative(0, -1, -1))
|
||||
}
|
||||
|
||||
BlockFace.UP, BlockFace.DOWN -> {
|
||||
toBreak.add(targetBlock.getRelative(1, 0, 0))
|
||||
toBreak.add(targetBlock.getRelative(-1, 0, 0))
|
||||
toBreak.add(targetBlock.getRelative(0, 0, 1))
|
||||
toBreak.add(targetBlock.getRelative(0, 0, -1))
|
||||
toBreak.add(targetBlock.getRelative(1, 0, 1))
|
||||
toBreak.add(targetBlock.getRelative(-1, 0, 1))
|
||||
toBreak.add(targetBlock.getRelative(1, 0, -1))
|
||||
toBreak.add(targetBlock.getRelative(-1, 0, -1))
|
||||
}
|
||||
else -> return
|
||||
}
|
||||
|
||||
val maxHardness = targetBlock.type.hardness
|
||||
|
||||
for (block in toBreak) {
|
||||
if (block.type.hardness > maxHardness)
|
||||
continue
|
||||
|
||||
block.breakNaturally(hammer)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
//package nl.kallestruik.dtweaks.tweaks.miscellaneoustweaks
|
||||
//
|
||||
//import nl.kallestruik.dtweaks.managers.PocketDimensionManager
|
||||
//import nl.kallestruik.dtweaks.tweaks.ITweak
|
||||
//import org.bukkit.entity.Player
|
||||
//import org.bukkit.event.EventHandler
|
||||
//import org.bukkit.event.HandlerList
|
||||
//import org.bukkit.event.Listener
|
||||
//import org.bukkit.event.block.BlockBreakEvent
|
||||
//import org.bukkit.event.entity.CreatureSpawnEvent
|
||||
//import org.bukkit.event.entity.EntityDamageEvent
|
||||
//import org.bukkit.event.player.PlayerMoveEvent
|
||||
//import org.bukkit.plugin.java.JavaPlugin
|
||||
//
|
||||
//class SpaceTimePockets(
|
||||
// private val plugin: JavaPlugin,
|
||||
// private val pocketDimensionManager: PocketDimensionManager
|
||||
//): ITweak, Listener {
|
||||
// override fun getIdentifier(): String = "SpaceTimePockets"
|
||||
// override fun getCategories(): List<String> = listOf("miscellaneous", "survival")
|
||||
//
|
||||
// override fun onRegister() {
|
||||
// plugin.server.pluginManager.registerEvents(this, plugin)
|
||||
// }
|
||||
//
|
||||
// override fun onUnRegister() {
|
||||
// HandlerList.unregisterAll(this)
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @EventHandler
|
||||
// fun onBlockBreak(event: BlockBreakEvent) {
|
||||
// if (event.player.world != pocketDimensionManager.pocketDimension) {
|
||||
// return
|
||||
// }
|
||||
// if (event.block.location.chunk == event.player.location.chunk && event.block.y != 0 && event.block.y != 255) return
|
||||
// event.isCancelled = true
|
||||
// event.player.sendMessage("It seems like a bad idea to break the only thing keeping you from getting lost into the endlessness around you.")
|
||||
// }
|
||||
//
|
||||
// @EventHandler
|
||||
// fun onMobSpawn(event: CreatureSpawnEvent) {
|
||||
// if (pocketDimensionManager.pocketDimension != event.location.world) return
|
||||
// event.isCancelled = true
|
||||
// }
|
||||
//
|
||||
// @EventHandler
|
||||
// fun onPlayerDamage(event: EntityDamageEvent) {
|
||||
// if (event.entity !is Player) return
|
||||
// if (pocketDimensionManager.pocketDimension != event.entity.world) return
|
||||
// event.isCancelled = true
|
||||
// }
|
||||
//
|
||||
// @EventHandler
|
||||
// fun onPlayerFall(event: PlayerMoveEvent) {
|
||||
// if (pocketDimensionManager.pocketDimension != event.from.world
|
||||
// || pocketDimensionManager.pocketDimension != event.to.world
|
||||
// ) return
|
||||
// if (event.from.chunk != event.to.chunk) {
|
||||
// event.player.sendMessage("Something pulls you back from the darkness.")
|
||||
// event.isCancelled = true
|
||||
// }
|
||||
// if (event.to.blockY < 0 || event.to.blockY > 256) {
|
||||
// event.player.sendMessage("Something pulls you back from the darkness.")
|
||||
// val safeLocation = event.player.location
|
||||
// safeLocation.y = 128.0
|
||||
// event.player.teleport(safeLocation)
|
||||
// }
|
||||
// }
|
||||
//}
|
|
@ -1,111 +0,0 @@
|
|||
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.tweaks.ITweak
|
||||
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftVillager
|
||||
import org.bukkit.entity.Villager
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.HandlerList
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
class VillagerInfo(
|
||||
private val plugin: JavaPlugin
|
||||
): ITweak, Listener {
|
||||
override fun getIdentifier(): String = "VillagerInfo"
|
||||
override fun getCategories(): List<String> = listOf("mobs")
|
||||
|
||||
override fun onEnable() {
|
||||
plugin.server.pluginManager.registerEvents(this, plugin)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
HandlerList.unregisterAll(this)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onInteractEvent(event: PlayerInteractEntityEvent) {
|
||||
if (!event.player.isSneaking) return
|
||||
val clicked = event.rightClicked as? Villager ?: return
|
||||
val eVillager: net.minecraft.world.entity.npc.Villager = (clicked as CraftVillager).handle
|
||||
val homePos: AtomicReference<GlobalPos?> = AtomicReference(null)
|
||||
eVillager.brain.getMemory(MemoryModuleType.HOME)
|
||||
.ifPresent { newValue -> homePos.set(newValue) }
|
||||
val workPos: AtomicReference<GlobalPos?> = AtomicReference(null)
|
||||
eVillager.brain.getMemory(MemoryModuleType.JOB_SITE).ifPresent { newValue ->
|
||||
workPos.set(
|
||||
newValue
|
||||
)
|
||||
}
|
||||
val meetingPos: AtomicReference<GlobalPos?> = AtomicReference(null)
|
||||
eVillager.brain.getMemory(MemoryModuleType.MEETING_POINT).ifPresent { newValue ->
|
||||
meetingPos.set(
|
||||
newValue
|
||||
)
|
||||
}
|
||||
val lastWork: AtomicReference<Long?> = AtomicReference(null)
|
||||
eVillager.brain.getMemory(MemoryModuleType.LAST_WORKED_AT_POI).ifPresent { newValue ->
|
||||
lastWork.set(
|
||||
newValue
|
||||
)
|
||||
}
|
||||
val lastSleep: AtomicReference<Long?> = AtomicReference(null)
|
||||
eVillager.brain.getMemory(MemoryModuleType.LAST_SLEPT).ifPresent { newValue ->
|
||||
lastSleep.set(
|
||||
newValue
|
||||
)
|
||||
}
|
||||
val seenIGRecently: AtomicReference<Boolean?> = AtomicReference(null)
|
||||
eVillager.brain.getMemory(MemoryModuleType.GOLEM_DETECTED_RECENTLY).ifPresent { newValue ->
|
||||
seenIGRecently.set(
|
||||
newValue
|
||||
)
|
||||
}
|
||||
|
||||
val isPanicking: Boolean = eVillager.brain.isActive(Activity.PANIC)
|
||||
val player = event.player
|
||||
|
||||
player.sendMessage("=====Villager Info=====")
|
||||
player.sendMessage("Type: " + clicked.villagerType)
|
||||
player.sendMessage("Profession: " + clicked.profession)
|
||||
player.sendMessage("Level: " + clicked.villagerLevel + "(" + clicked.villagerExperience + " xp)")
|
||||
player.sendMessage("Panic: $isPanicking")
|
||||
|
||||
if (homePos.get() != null) player.sendMessage(
|
||||
java.lang.String.format(
|
||||
"Home: %s, %s, %s",
|
||||
homePos.get()?.pos()?.x,
|
||||
homePos.get()?.pos()?.y,
|
||||
homePos.get()?.pos()?.z
|
||||
)
|
||||
)
|
||||
|
||||
if (workPos.get() != null) player.sendMessage(
|
||||
java.lang.String.format(
|
||||
"Work: %s, %s, %s",
|
||||
workPos.get()?.pos()?.x,
|
||||
workPos.get()?.pos()?.y,
|
||||
workPos.get()?.pos()?.z
|
||||
)
|
||||
)
|
||||
|
||||
if (homePos.get() != null) player.sendMessage(
|
||||
java.lang.String.format(
|
||||
"Meeting point: %s, %s, %s",
|
||||
meetingPos.get()?.pos()?.x,
|
||||
meetingPos.get()?.pos()?.y,
|
||||
meetingPos.get()?.pos()?.z
|
||||
)
|
||||
)
|
||||
|
||||
if (lastSleep.get() != null)
|
||||
player.sendMessage("Last slept: ${lastSleep.get()}")
|
||||
|
||||
if (seenIGRecently.get() != null)
|
||||
player.sendMessage("Seen iron golem Recently: ${seenIGRecently.get()}")
|
||||
}
|
||||
}
|
|
@ -1,22 +1,25 @@
|
|||
name: DTweaks
|
||||
version: ${version}
|
||||
main: nl.kallestruik.dtweaks.DTweaks
|
||||
api-version: 1.16
|
||||
depend:
|
||||
- "ProtocolLib"
|
||||
- "DLib"
|
||||
api-version: "1.20"
|
||||
dependencies:
|
||||
- name: "ProtocolLib"
|
||||
required: true
|
||||
- name: "DLib"
|
||||
required: true
|
||||
bootstrap: true
|
||||
has-open-classloader: true
|
||||
load-after:
|
||||
- name: "DLib"
|
||||
bootstrap: true
|
||||
|
||||
commands:
|
||||
toggletrample:
|
||||
description: "Toggles whether you can trample crops."
|
||||
player:
|
||||
description: "Interact with fake players."
|
||||
permission: op
|
||||
bundle:
|
||||
description: "Admin command for managing custom bundles."
|
||||
permission: op
|
||||
mobcaps:
|
||||
description: "Display mobcap information from your current dimension."
|
||||
pocketdim:
|
||||
description: "Interact with pocket dimensions. Testing command."
|
||||
spawnzones:
|
||||
description: "Manage no spawn zones"
|
|
@ -20,7 +20,6 @@ NoDoorBreaking: true
|
|||
NoCreeperGrief: false
|
||||
NoEndermanGrief: true
|
||||
SugarcaneBonemealing: true
|
||||
SpaceTimePockets: true
|
||||
VillagerInfo: true
|
||||
BetterBundles: true
|
||||
RedyeTerracotta: true
|
||||
|
|
Loading…
Reference in New Issue