This commit is contained in:
AverageGithub 2024-01-29 15:29:51 +01:00
parent c086eb36a3
commit aadf5ebeb4
6 changed files with 245 additions and 187 deletions

View File

@ -20,6 +20,7 @@ repositories {
dependencies {
implementation project(path: ":api")
implementation project(path: ":common")
implementation project(path: ":nms:v1_19_R3", configuration: "reobf")
implementation project(path: ":nms:v1_20_R1", configuration: "reobf")
implementation project(path: ":nms:v1_20_R2", configuration: "reobf")
implementation project(path: ":nms:v1_20_R3", configuration: "reobf")
@ -120,8 +121,9 @@ allprojects {
compileOnly 'com.intellectualsites.plotsquared:plotsquared-core:7.0.0-rc.4'
compileOnly 'com.intellectualsites.plotsquared:plotsquared-bukkit:7.0.0-rc.4'
implementation platform('com.intellectualsites.bom:bom-newest:1.35')
implementation("com.artillexstudios.axapi:axapi:1.4.10")
implementation("com.artillexstudios.axapi:axapi:1.4.22")
implementation("net.byteflux:libby-bukkit:1.3.0")
implementation("com.zaxxer:HikariCP:5.1.0")
compileOnly files('../libs/CMI-API9.5.0.8.jar')
compileOnly files('../libs/IridiumSkyblock-3.2.12.jar')
compileOnly files('../libs/KingdomsX-1.16.12.jar')
@ -131,6 +133,7 @@ allprojects {
relocate("com.artillexstudios.axapi", "com.artillexstudios.axminions.libs.axapi")
relocate("org.h2", "com.artillexstudios.axminions.libs.h2")
relocate("org.jetbrains.kotlin", "com.artillexstudios.axminions.libs.kotlin")
relocate("com.zaxxer", "com.artillexstudios.axminions.libs.hikaricp")
}
}

View File

@ -5,6 +5,8 @@ import com.artillexstudios.axminions.AxMinionsPlugin
import com.artillexstudios.axminions.api.data.DataHandler
import com.artillexstudios.axminions.api.minions.Direction
import com.artillexstudios.axminions.api.minions.miniontype.MinionType
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.bukkit.Bukkit
import org.bukkit.Location
import org.bukkit.Material
@ -17,100 +19,119 @@ import java.util.Properties
import java.util.UUID
class H2DataHandler : DataHandler {
private lateinit var connection: JdbcConnection
private lateinit var dataSource: HikariDataSource
override fun getType(): String {
return "H2"
}
override fun setup() {
Class.forName("org.h2.Driver")
connection =
JdbcConnection("jdbc:h2:./${AxMinionsPlugin.INSTANCE.dataFolder}/data", Properties(), null, null, false)
val config = HikariConfig()
config.setDataSourceClassName("org.h2.jdbcx.JdbcDataSource")
config.addDataSourceProperty("url", "jdbc:h2:async:./${AxMinionsPlugin.INSTANCE.dataFolder}/data")
config.setAutoCommit(true)
dataSource = HikariDataSource(config)
connection.prepareStatement("CREATE TABLE IF NOT EXISTS `axminions_types`(`id` INT AUTO_INCREMENT PRIMARY KEY, `name` VARCHAR(64));")
.use {
it.executeUpdate()
}
dataSource.connection.use { connection ->
connection.prepareStatement("CREATE TABLE IF NOT EXISTS `axminions_types`(`id` INT AUTO_INCREMENT PRIMARY KEY, `name` VARCHAR(64));")
.use {
it.executeUpdate()
}
}
connection.prepareStatement("CREATE TABLE IF NOT EXISTS `axminions_users`(`uuid` UUID PRIMARY KEY, `name` VARCHAR(16));")
.use {
it.executeUpdate()
}
dataSource.connection.use { connection ->
connection.prepareStatement("CREATE TABLE IF NOT EXISTS `axminions_users`(`uuid` UUID PRIMARY KEY, `name` VARCHAR(16));")
.use {
it.executeUpdate()
}
}
connection.prepareStatement("CREATE TABLE IF NOT EXISTS `axminions_worlds`(`id` INT AUTO_INCREMENT PRIMARY KEY, `name` VARCHAR(64));")
.use {
it.executeUpdate()
}
dataSource.connection.use { connection ->
connection.prepareStatement("CREATE TABLE IF NOT EXISTS `axminions_worlds`(`id` INT AUTO_INCREMENT PRIMARY KEY, `name` VARCHAR(64));")
.use {
it.executeUpdate()
}
}
connection.prepareStatement("CREATE TABLE IF NOT EXISTS `axminions_locations`(`id` INT AUTO_INCREMENT PRIMARY KEY, `x` INT, `y` INT, `z` INT, `world_id` INT, FOREIGN KEY(world_id) REFERENCES `axminions_worlds`(`id`));")
.use {
it.executeUpdate()
}
connection.prepareStatement("CREATE TABLE IF NOT EXISTS `axminions_minions`(`id` INT AUTO_INCREMENT PRIMARY KEY, `location_id` INT, `chest_location_id` INT, `owner_id` UUID, `type_id` TINYINT, `direction` TINYINT, `level` SMALLINT, `storage` DOUBLE, `actions` BIGINT, `tool` CLOB, FOREIGN KEY(`location_id`) REFERENCES `axminions_locations`(id), FOREIGN KEY(`chest_location_id`) REFERENCES `axminions_locations`(`id`), FOREIGN KEY(`owner_id`) REFERENCES `axminions_users`(`uuid`), FOREIGN KEY(`type_id`) REFERENCES `axminions_types`(`id`));")
.use {
it.executeUpdate()
}
dataSource.connection.use { connection ->
connection.prepareStatement("CREATE TABLE IF NOT EXISTS `axminions_locations`(`id` INT AUTO_INCREMENT PRIMARY KEY, `x` INT, `y` INT, `z` INT, `world_id` INT, FOREIGN KEY(world_id) REFERENCES `axminions_worlds`(`id`));")
.use {
it.executeUpdate()
}
}
dataSource.connection.use { connection ->
connection.prepareStatement("CREATE TABLE IF NOT EXISTS `axminions_minions`(`id` INT AUTO_INCREMENT PRIMARY KEY, `location_id` INT, `chest_location_id` INT, `owner_id` UUID, `type_id` TINYINT, `direction` TINYINT, `level` SMALLINT, `storage` DOUBLE, `actions` BIGINT, `tool` CLOB, FOREIGN KEY(`location_id`) REFERENCES `axminions_locations`(id), FOREIGN KEY(`chest_location_id`) REFERENCES `axminions_locations`(`id`), FOREIGN KEY(`owner_id`) REFERENCES `axminions_users`(`uuid`), FOREIGN KEY(`type_id`) REFERENCES `axminions_types`(`id`));")
.use {
it.executeUpdate()
}
}
}
override fun insertType(minionType: MinionType) {
connection.prepareStatement("MERGE INTO `axminions_types`(`name`) KEY(`name`) VALUES(?);").use {
it.setString(1, minionType.getName())
it.executeUpdate()
dataSource.connection.use { connection ->
connection.prepareStatement("MERGE INTO `axminions_types`(`name`) KEY(`name`) VALUES(?);").use {
it.setString(1, minionType.getName())
it.executeUpdate()
}
}
}
override fun loadMinionsForWorld(minionType: MinionType, world: World) {
var typeId = 0
connection.prepareStatement("SELECT `id` FROM `axminions_types` WHERE `name` = ?;").use { statement ->
statement.setString(1, minionType.getName())
statement.executeQuery().use { resultSet ->
if (resultSet.next()) {
typeId = resultSet.getInt("id")
dataSource.connection.use { connection ->
connection.prepareStatement("SELECT `id` FROM `axminions_types` WHERE `name` = ?;").use { statement ->
statement.setString(1, minionType.getName())
statement.executeQuery().use { resultSet ->
if (resultSet.next()) {
typeId = resultSet.getInt("id")
}
}
}
}
connection.prepareStatement("SELECT `minions`.* FROM `axminions_minions` AS `minions` JOIN `axminions_locations` AS `location` ON `minions`.`location_id` = `location`.`id` WHERE `location`.`world_id` = (SELECT `id` FROM `axminions_worlds` WHERE `name` = ?) AND `type_id` = ?;").use { statement ->
statement.setString(1, world.name)
statement.setInt(2, typeId)
statement.executeQuery().use { resultSet ->
while (resultSet.next()) {
val locationId = resultSet.getInt("location_id")
val chestLocationId = resultSet.getInt("chest_location_id")
val ownerId = resultSet.getObject("owner_id") as UUID
val direction = Direction.entries[resultSet.getByte("direction").toInt()]
val level = resultSet.getShort("level")
val storage = resultSet.getDouble("storage")
val actions = resultSet.getLong("actions")
val tool = resultSet.getString("tool")
dataSource.connection.use { connection ->
connection.prepareStatement("SELECT `minions`.* FROM `axminions_minions` AS `minions` JOIN `axminions_locations` AS `location` ON `minions`.`location_id` = `location`.`id` WHERE `location`.`world_id` = (SELECT `id` FROM `axminions_worlds` WHERE `name` = ?) AND `type_id` = ?;").use { statement ->
statement.setString(1, world.name)
statement.setInt(2, typeId)
statement.executeQuery().use { resultSet ->
while (resultSet.next()) {
val locationId = resultSet.getInt("location_id")
val chestLocationId = resultSet.getInt("chest_location_id")
val ownerId = resultSet.getObject("owner_id") as UUID
val direction = Direction.entries[resultSet.getByte("direction").toInt()]
val level = resultSet.getShort("level")
val storage = resultSet.getDouble("storage")
val actions = resultSet.getLong("actions")
val tool = resultSet.getString("tool")
val location = getLocation(locationId)
var chestLocation: Location? = null
if (chestLocationId != 0) {
chestLocation = getLocation(chestLocationId)
val location = getLocation(locationId)
var chestLocation: Location? = null
if (chestLocationId != 0) {
chestLocation = getLocation(chestLocationId)
}
var itemStack = ItemStack(Material.AIR)
if (tool != null) {
itemStack = Serializers.ITEM_STACK.deserialize(tool)
}
com.artillexstudios.axminions.minions.Minion(
location!!,
ownerId,
Bukkit.getOfflinePlayer(ownerId),
minionType,
level.toInt(),
itemStack,
chestLocation,
direction,
actions,
storage,
locationId,
chestLocationId
)
}
var itemStack = ItemStack(Material.AIR)
if (tool != null) {
itemStack = Serializers.ITEM_STACK.deserialize(tool)
}
com.artillexstudios.axminions.minions.Minion(
location!!,
ownerId,
Bukkit.getOfflinePlayer(ownerId),
minionType,
level.toInt(),
itemStack,
chestLocation,
direction,
actions,
storage,
locationId,
chestLocationId
)
}
}
}
@ -118,33 +139,37 @@ class H2DataHandler : DataHandler {
override fun getLocationID(location: Location): Int {
var worldId = 0
connection.prepareStatement(
"MERGE INTO `axminions_worlds`(`name`) KEY(`name`) VALUES(?);",
Statement.RETURN_GENERATED_KEYS
).use { statement ->
statement.setString(1, location.world?.name)
statement.executeUpdate()
dataSource.connection.use { connection ->
connection.prepareStatement(
"MERGE INTO `axminions_worlds`(`name`) KEY(`name`) VALUES(?);",
Statement.RETURN_GENERATED_KEYS
).use { statement ->
statement.setString(1, location.world?.name)
statement.executeUpdate()
statement.generatedKeys.use { resultSet ->
if (resultSet.next()) {
worldId = resultSet.getInt(1)
statement.generatedKeys.use { resultSet ->
if (resultSet.next()) {
worldId = resultSet.getInt(1)
}
}
}
}
connection.prepareStatement(
"MERGE INTO `axminions_locations`(`x`, `y`, `z`, `world_id`) KEY(`x`, `y`, `z`, `world_id`) VALUES (?, ?, ?, ?);",
Statement.RETURN_GENERATED_KEYS
).use { statement ->
statement.setInt(1, location.blockX)
statement.setInt(2, location.blockY)
statement.setInt(3, location.blockZ)
statement.setInt(4, worldId)
statement.executeUpdate()
dataSource.connection.use { connection ->
connection.prepareStatement(
"MERGE INTO `axminions_locations`(`x`, `y`, `z`, `world_id`) KEY(`x`, `y`, `z`, `world_id`) VALUES (?, ?, ?, ?);",
Statement.RETURN_GENERATED_KEYS
).use { statement ->
statement.setInt(1, location.blockX)
statement.setInt(2, location.blockY)
statement.setInt(3, location.blockZ)
statement.setInt(4, worldId)
statement.executeUpdate()
statement.generatedKeys.use { resultSet ->
if (resultSet.next()) {
return resultSet.getInt(1)
statement.generatedKeys.use { resultSet ->
if (resultSet.next()) {
return resultSet.getInt(1)
}
}
}
}
@ -153,32 +178,36 @@ class H2DataHandler : DataHandler {
}
override fun getLocation(locationId: Int): Location? {
connection.prepareStatement("SELECT * FROM `axminions_locations` WHERE `id` = ?;").use { statement ->
statement.setInt(1, locationId)
statement.executeQuery().use { resultSet ->
if (resultSet.next()) {
val worldId = resultSet.getInt("world_id")
val x = resultSet.getInt("x")
val y = resultSet.getInt("y")
val z = resultSet.getInt("z")
dataSource.connection.use { connection ->
connection.prepareStatement("SELECT * FROM `axminions_locations` WHERE `id` = ?;").use { statement ->
statement.setInt(1, locationId)
statement.executeQuery().use { resultSet ->
if (resultSet.next()) {
val worldId = resultSet.getInt("world_id")
val x = resultSet.getInt("x")
val y = resultSet.getInt("y")
val z = resultSet.getInt("z")
return Location(getWorld(worldId), x.toDouble(), y.toDouble(), z.toDouble())
return Location(getWorld(worldId), x.toDouble(), y.toDouble(), z.toDouble())
}
return null
}
return null
}
}
}
override fun getWorld(worldId: Int): World? {
connection.prepareStatement("SELECT `name` FROM `axminions_worlds` WHERE `id` = ?;").use { statement ->
statement.setInt(1, worldId)
statement.executeQuery().use { resultSet ->
if (resultSet.next()) {
return Bukkit.getWorld(resultSet.getString("name"))
}
dataSource.connection.use { connection ->
connection.prepareStatement("SELECT `name` FROM `axminions_worlds` WHERE `id` = ?;").use { statement ->
statement.setInt(1, worldId)
statement.executeQuery().use { resultSet ->
if (resultSet.next()) {
return Bukkit.getWorld(resultSet.getString("name"))
}
return null
return null
}
}
}
}
@ -189,11 +218,13 @@ class H2DataHandler : DataHandler {
var userId: UUID? = null
var minionTypeId = 0
connection.prepareStatement("SELECT * FROM `axminions_types` WHERE `name` = ?;").use {
it.setString(1, minion.getType().getName())
it.executeQuery().use { resultSet ->
if (resultSet.next()) {
minionTypeId = resultSet.getInt("id")
dataSource.connection.use { connection ->
connection.prepareStatement("SELECT * FROM `axminions_types` WHERE `name` = ?;").use {
it.setString(1, minion.getType().getName())
it.executeQuery().use { resultSet ->
if (resultSet.next()) {
minionTypeId = resultSet.getInt("id")
}
}
}
}
@ -202,17 +233,19 @@ class H2DataHandler : DataHandler {
linkedChestId = getLocationID(minion.getLinkedChest()!!)
}
connection.prepareStatement(
"MERGE INTO `axminions_users`(`uuid`, `name`) KEY(`uuid`) VALUES (?,?);",
Statement.RETURN_GENERATED_KEYS
).use { statement ->
statement.setObject(1, minion.getOwnerUUID())
statement.setString(2, minion.getOwner()?.name ?: "---")
statement.executeUpdate()
dataSource.connection.use { connection ->
connection.prepareStatement(
"MERGE INTO `axminions_users`(`uuid`, `name`) KEY(`uuid`) VALUES (?,?);",
Statement.RETURN_GENERATED_KEYS
).use { statement ->
statement.setObject(1, minion.getOwnerUUID())
statement.setString(2, minion.getOwner()?.name ?: "---")
statement.executeUpdate()
statement.generatedKeys.use { resultSet ->
if (resultSet.next()) {
userId = resultSet.getObject(1) as UUID
statement.generatedKeys.use { resultSet ->
if (resultSet.next()) {
userId = resultSet.getObject(1) as UUID
}
}
}
}
@ -221,96 +254,110 @@ class H2DataHandler : DataHandler {
return
}
connection.prepareStatement("MERGE INTO `axminions_minions`(`location_id`, `chest_location_id`, `owner_id`, `type_id`, `direction`, `level`, `storage`, `actions`, `tool`) KEY(`location_id`) VALUES(?,?,?,?,?,?,?,?,?)")
.use { statement ->
statement.setInt(1, locationId)
if (linkedChestId == null) {
statement.setNull(2, Types.INTEGER)
} else {
statement.setInt(2, linkedChestId)
dataSource.connection.use { connection ->
connection.prepareStatement("MERGE INTO `axminions_minions`(`location_id`, `chest_location_id`, `owner_id`, `type_id`, `direction`, `level`, `storage`, `actions`, `tool`) KEY(`location_id`) VALUES(?,?,?,?,?,?,?,?,?)")
.use { statement ->
statement.setInt(1, locationId)
if (linkedChestId == null) {
statement.setNull(2, Types.INTEGER)
} else {
statement.setInt(2, linkedChestId)
}
statement.setObject(3, userId!!)
statement.setInt(4, minionTypeId)
statement.setByte(5, minion.getDirection().ordinal.toByte())
statement.setInt(6, minion.getLevel())
statement.setDouble(7, minion.getStorage())
statement.setLong(8, minion.getActionAmount())
if (minion.getTool() == null || minion.getTool()?.type == Material.AIR) {
statement.setNull(9, Types.CLOB)
} else {
statement.setString(9, Serializers.ITEM_STACK.serialize(minion.getTool()))
}
statement.executeUpdate()
}
statement.setObject(3, userId!!)
statement.setInt(4, minionTypeId)
statement.setByte(5, minion.getDirection().ordinal.toByte())
statement.setInt(6, minion.getLevel())
statement.setDouble(7, minion.getStorage())
statement.setLong(8, minion.getActionAmount())
if (minion.getTool() == null || minion.getTool()?.type == Material.AIR) {
statement.setNull(9, Types.CLOB)
} else {
statement.setString(9, Serializers.ITEM_STACK.serialize(minion.getTool()))
}
statement.executeUpdate()
}
}
}
override fun deleteMinion(minion: com.artillexstudios.axminions.api.minions.Minion) {
connection.prepareStatement("DELETE FROM `axminions_minions` WHERE `location_id` = ?;")
.use { preparedStatement ->
preparedStatement.setInt(1, minion.getLocationId())
preparedStatement.executeUpdate()
}
dataSource.connection.use { connection ->
connection.prepareStatement("DELETE FROM `axminions_minions` WHERE `location_id` = ?;")
.use { preparedStatement ->
preparedStatement.setInt(1, minion.getLocationId())
preparedStatement.executeUpdate()
}
}
connection.prepareStatement("SELECT * FROM `axminions_minions` WHERE `location_id` = ?;").use { statement ->
statement.setInt(1, minion.getLocationId())
statement.executeQuery().use { resultSet ->
if (!resultSet.next()) {
connection.prepareStatement("DELETE FROM `axminions_locations` WHERE `id` = ?").use {
it.setInt(1, minion.getLocationId())
it.executeUpdate()
dataSource.connection.use { connection ->
connection.prepareStatement("SELECT * FROM `axminions_minions` WHERE `location_id` = ?;").use { statement ->
statement.setInt(1, minion.getLocationId())
statement.executeQuery().use { resultSet ->
if (!resultSet.next()) {
connection.prepareStatement("DELETE FROM `axminions_locations` WHERE `id` = ?").use {
it.setInt(1, minion.getLocationId())
it.executeUpdate()
}
}
}
}
}
if (minion.getChestLocationId() != 0) {
connection.prepareStatement("SELECT * FROM `axminions_minions` WHERE `chest_location_id` = ?;")
.use { statement ->
statement.setInt(1, minion.getChestLocationId())
statement.executeQuery().use { resultSet ->
if (!resultSet.next()) {
connection.prepareStatement("DELETE FROM `axminions_locations` WHERE `id` = ?").use {
it.setInt(1, minion.getLocationId())
it.executeUpdate()
dataSource.connection.use { connection ->
connection.prepareStatement("SELECT * FROM `axminions_minions` WHERE `chest_location_id` = ?;")
.use { statement ->
statement.setInt(1, minion.getChestLocationId())
statement.executeQuery().use { resultSet ->
if (!resultSet.next()) {
connection.prepareStatement("DELETE FROM `axminions_locations` WHERE `id` = ?").use {
it.setInt(1, minion.getLocationId())
it.executeUpdate()
}
}
}
}
}
}
}
}
override fun getMinionAmount(uuid: UUID): Int {
connection.prepareStatement("SELECT COUNT(`owner_id`) FROM `axminions_minions` WHERE `owner_id` = ?;")
.use { statement ->
statement.setObject(1, uuid)
statement.executeQuery().use { resultSet ->
if (resultSet.next()) {
return resultSet.getInt(1)
dataSource.connection.use { connection ->
connection.prepareStatement("SELECT COUNT(`owner_id`) FROM `axminions_minions` WHERE `owner_id` = ?;")
.use { statement ->
statement.setObject(1, uuid)
statement.executeQuery().use { resultSet ->
if (resultSet.next()) {
return resultSet.getInt(1)
}
}
}
}
}
return 0
}
override fun isMinion(location: Location): Boolean {
connection.prepareStatement("SELECT * FROM `axminions_minions` WHERE `location_id` = (SELECT `id` FROM `axminions_locations` WHERE x = ? AND y = ? AND z = ? AND `world_id` = (SELECT `id` FROM `axminions_worlds` WHERE `name` = ?));")
.use { statement ->
statement.setInt(1, location.blockX)
statement.setInt(2, location.blockY)
statement.setInt(3, location.blockZ)
statement.setString(4, location.world?.name ?: "---")
statement.executeQuery().use { resultSet ->
if (resultSet.next()) {
return true
dataSource.connection.use { connection ->
connection.prepareStatement("SELECT * FROM `axminions_minions` WHERE `location_id` = (SELECT `id` FROM `axminions_locations` WHERE x = ? AND y = ? AND z = ? AND `world_id` = (SELECT `id` FROM `axminions_worlds` WHERE `name` = ?));")
.use { statement ->
statement.setInt(1, location.blockX)
statement.setInt(2, location.blockY)
statement.setInt(3, location.blockZ)
statement.setString(4, location.world?.name ?: "---")
statement.executeQuery().use { resultSet ->
if (resultSet.next()) {
return true
}
}
}
}
}
return false
}
override fun disable() {
connection.prepareStatement("SHUTDOWN DEFRAG;").executeUpdate()
dataSource.connection.use { connection ->
connection.prepareStatement("SHUTDOWN DEFRAG;").executeUpdate()
}
}
}

View File

@ -12,7 +12,7 @@ class SuperiorSkyBlock2Integration : ProtectionIntegration {
val island = SuperiorSkyblockAPI.getIslandAt(location) ?: return true
return island.isMember(localPlayer)
return island.isMember(localPlayer) || localPlayer.hasBypassModeEnabled()
}
override fun register() {

View File

@ -34,7 +34,7 @@ class MinionPlaceListener : Listener {
event.isCancelled = true
val item = event.item ?: return
val meta = item.itemMeta ?: return
var meta = item.itemMeta ?: return
if (!AxMinionsPlugin.integrations.getProtectionIntegration().canBuildAt(event.player, event.clickedBlock!!.location)) return
val level = meta.persistentDataContainer.get(Keys.LEVEL, PersistentDataType.INTEGER) ?: 0
val stats = meta.persistentDataContainer.get(Keys.STATISTICS, PersistentDataType.LONG) ?: 0
@ -81,7 +81,8 @@ class MinionPlaceListener : Listener {
0
)
minion.setTicking(true)
Scheduler.get().run {
Scheduler.get().run { task ->
meta = item.itemMeta!!
meta.persistentDataContainer.remove(Keys.PLACED)
item.itemMeta = meta
item.amount = item.amount.minus(1)

View File

@ -498,7 +498,7 @@ class Minion(
}
override fun addToContainerOrDrop(itemStack: ItemStack) {
if (linkedInventory == null) {
if (linkedInventory == null) {
AxMinionsPlugin.integrations.getStackerIntegration().dropItemAt(itemStack, itemStack.amount, location)
return
}
@ -566,6 +566,12 @@ class Minion(
override fun setTicking(ticking: Boolean) {
this.ticking = ticking
if (ticking && linkedChest != null) {
Scheduler.get().runAt(linkedChest) {
linkedInventory = (linkedChest?.block?.state as? Container)?.inventory
}
}
}
override fun setRange(range: Double) {

View File

@ -13,6 +13,7 @@ rootProject.name = 'AxMinions'
include 'api'
include 'common'
include 'nms'
include 'nms:v1_19_R3'
include 'nms:v1_20_R1'
include 'nms:v1_20_R2'
include 'nms:v1_20_R3'