mirror of
https://github.com/Artillex-Studios/AxMinions.git
synced 2024-12-01 13:03:43 +01:00
Minor memory leak fix, try fixing weird ticking bug, new feature
This commit is contained in:
parent
ebd053e9ee
commit
19eb8f561e
@ -9,6 +9,7 @@ import com.artillexstudios.axapi.libs.boostedyaml.boostedyaml.settings.updater.U
|
||||
import com.artillexstudios.axminions.api.AxMinionsAPI
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.util.Locale
|
||||
|
||||
class Config(file: File, stream: InputStream) {
|
||||
companion object {
|
||||
@ -42,6 +43,8 @@ class Config(file: File, stream: InputStream) {
|
||||
@JvmStatic
|
||||
fun PULL_FROM_CHEST() = AxMinionsAPI.INSTANCE.getConfig().get("pull-tools-from-chest", false)
|
||||
@JvmStatic
|
||||
fun UPGRADE_FAIL() = AxMinionsAPI.INSTANCE.getConfig().get("upgrade-fail", "chat").lowercase(Locale.ENGLISH)
|
||||
@JvmStatic
|
||||
fun PLACE_PERMISSION() = AxMinionsAPI.INSTANCE.getConfig().get("place-permissions", false)
|
||||
@JvmStatic
|
||||
fun DEBUG(): Boolean {
|
||||
|
@ -7,7 +7,6 @@ import com.artillexstudios.axapi.utils.ItemBuilder
|
||||
import com.artillexstudios.axminions.api.AxMinionsAPI
|
||||
import com.artillexstudios.axminions.api.minions.Minion
|
||||
import com.artillexstudios.axminions.api.utils.Keys
|
||||
import com.artillexstudios.axminions.api.utils.fastFor
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
import java.io.File
|
||||
@ -33,12 +32,7 @@ abstract class MinionType(private val name: String, private val defaults: InputS
|
||||
return true
|
||||
}
|
||||
|
||||
fun isTicking(minion: Minion): Boolean {
|
||||
return minion.isTicking()
|
||||
}
|
||||
|
||||
fun tick(minion: Minion) {
|
||||
if (!minion.isTicking()) return
|
||||
if (!shouldRun(minion)) return
|
||||
|
||||
minion.resetAnimation()
|
||||
|
@ -1,10 +1,9 @@
|
||||
package com.artillexstudios.axminions.api.minions.utils
|
||||
|
||||
import com.artillexstudios.axminions.api.minions.Minion
|
||||
import com.artillexstudios.axminions.api.utils.fastFor
|
||||
import org.bukkit.World
|
||||
|
||||
data class ChunkPos(val world: World, val x: Int, val z: Int) {
|
||||
data class ChunkPos(val world: World, val x: Int, val z: Int, @Volatile var ticking: Boolean) {
|
||||
val minions = arrayListOf<Minion>()
|
||||
val worldUUID = world.uid
|
||||
|
||||
@ -19,8 +18,10 @@ data class ChunkPos(val world: World, val x: Int, val z: Int) {
|
||||
}
|
||||
|
||||
fun setTicking(ticking: Boolean) {
|
||||
minions.fastFor {
|
||||
it.setTicking(ticking)
|
||||
this.ticking = ticking
|
||||
|
||||
minions.forEach {
|
||||
it.setTicking(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
package com.artillexstudios.axminions.api.utils
|
||||
|
||||
import java.util.WeakHashMap
|
||||
|
||||
class CoolDown<T> {
|
||||
private val map = HashMap<T, Long>()
|
||||
private val map = WeakHashMap<T, Long>()
|
||||
|
||||
fun add(value: T, time: Long) {
|
||||
expire()
|
||||
|
@ -123,7 +123,7 @@ 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.22")
|
||||
implementation("com.artillexstudios.axapi:axapi:1.4.23")
|
||||
implementation("net.byteflux:libby-bukkit:1.3.0")
|
||||
implementation("com.zaxxer:HikariCP:5.1.0")
|
||||
implementation("org.bstats:bstats-bukkit:3.0.2")
|
||||
|
@ -82,7 +82,7 @@ class AxMinionsCommand {
|
||||
val total = minions.size
|
||||
|
||||
minions.fastFor {
|
||||
if (it.getType().isTicking(it)) {
|
||||
if (it.isTicking()) {
|
||||
loaded++
|
||||
}
|
||||
}
|
||||
|
@ -5,26 +5,27 @@ import com.artillexstudios.axminions.AxMinionsPlugin
|
||||
import com.artillexstudios.axminions.api.config.Config
|
||||
import com.artillexstudios.axminions.api.config.Messages
|
||||
import com.artillexstudios.axminions.api.minions.Minion
|
||||
import java.util.UUID
|
||||
import java.util.WeakHashMap
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.player.PlayerInteractEvent
|
||||
|
||||
class LinkingListener : Listener {
|
||||
companion object {
|
||||
val linking = hashMapOf<UUID, Minion>()
|
||||
val linking = WeakHashMap<Player, Minion>()
|
||||
private val CONTAINERS = listOf(Material.BARREL, Material.CHEST, Material.TRAPPED_CHEST)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onPlayerInteractEvent(event: PlayerInteractEvent) {
|
||||
if (event.player.uniqueId !in linking) return
|
||||
if (event.clickedBlock == null) return
|
||||
if (event.player !in linking) return
|
||||
if (event.clickedBlock!!.type !in CONTAINERS) return
|
||||
if (!AxMinionsPlugin.integrations.getProtectionIntegration().canBuildAt(event.player, event.clickedBlock!!.location)) return
|
||||
|
||||
val minion = linking.remove(event.player.uniqueId) ?: return
|
||||
val minion = linking.remove(event.player) ?: return
|
||||
event.isCancelled = true
|
||||
if (minion.getLocation()
|
||||
.distanceSquared(event.clickedBlock!!.location) > Config.MAX_LINKING_DISTANCE() * Config.MAX_LINKING_DISTANCE()
|
||||
|
@ -3,6 +3,7 @@ package com.artillexstudios.axminions.listeners
|
||||
import com.artillexstudios.axapi.utils.StringUtils
|
||||
import com.artillexstudios.axminions.AxMinionsPlugin
|
||||
import com.artillexstudios.axminions.api.AxMinionsAPI
|
||||
import com.artillexstudios.axminions.api.config.Config
|
||||
import com.artillexstudios.axminions.api.config.Messages
|
||||
import com.artillexstudios.axminions.api.minions.Direction
|
||||
import com.artillexstudios.axminions.api.minions.Minion
|
||||
@ -10,7 +11,8 @@ import com.artillexstudios.axminions.api.minions.miniontype.MinionTypes
|
||||
import com.artillexstudios.axminions.api.utils.CoolDown
|
||||
import com.artillexstudios.axminions.api.utils.Keys
|
||||
import com.artillexstudios.axminions.api.utils.fastFor
|
||||
import java.util.UUID
|
||||
import net.md_5.bungee.api.ChatMessageType
|
||||
import net.md_5.bungee.api.chat.TextComponent
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.EventHandler
|
||||
@ -22,7 +24,7 @@ import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
|
||||
class MinionInventoryListener : Listener {
|
||||
private val coolDown = CoolDown<UUID>()
|
||||
private val coolDown = CoolDown<Player>()
|
||||
|
||||
@EventHandler
|
||||
fun onInventoryDragEvent(event: InventoryDragEvent) {
|
||||
@ -38,11 +40,11 @@ class MinionInventoryListener : Listener {
|
||||
event.isCancelled = true
|
||||
val player = event.whoClicked as Player
|
||||
|
||||
if (coolDown.contains(player.uniqueId)) {
|
||||
if (coolDown.contains(player)) {
|
||||
return
|
||||
}
|
||||
|
||||
coolDown.add(player.uniqueId, 250)
|
||||
coolDown.add(player, 250)
|
||||
|
||||
val allowedTools = arrayListOf<Material>()
|
||||
minion.getType().getConfig().getStringList("tool.material").fastFor {
|
||||
@ -116,7 +118,7 @@ class MinionInventoryListener : Listener {
|
||||
}
|
||||
|
||||
player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.LINK_START()))
|
||||
LinkingListener.linking[player.uniqueId] = minion
|
||||
LinkingListener.linking[player] = minion
|
||||
player.closeInventory()
|
||||
}
|
||||
|
||||
@ -129,13 +131,13 @@ class MinionInventoryListener : Listener {
|
||||
}
|
||||
|
||||
if (minion.getActionAmount() < actions) {
|
||||
player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.UPGRADE_FAIL()))
|
||||
sendFail(player)
|
||||
return
|
||||
}
|
||||
|
||||
AxMinionsPlugin.integrations.getEconomyIntegration()?.let {
|
||||
if (it.getBalance(player) < money) {
|
||||
player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.UPGRADE_FAIL()))
|
||||
sendFail(player)
|
||||
return
|
||||
}
|
||||
|
||||
@ -154,8 +156,8 @@ class MinionInventoryListener : Listener {
|
||||
|
||||
if (minion.getType() == MinionTypes.getMinionTypes()["seller"]) {
|
||||
AxMinionsPlugin.integrations.getEconomyIntegration()?.let {
|
||||
minion.getOwner()?.let {
|
||||
player -> it.giveBalance(player, stored)
|
||||
minion.getOwner()?.let { player ->
|
||||
it.giveBalance(player, stored)
|
||||
minion.setStorage(0.0)
|
||||
}
|
||||
}
|
||||
@ -175,4 +177,30 @@ class MinionInventoryListener : Listener {
|
||||
|
||||
holder.removeOpenInventory(event.inventory)
|
||||
}
|
||||
|
||||
private fun sendFail(player: Player) {
|
||||
when (Config.UPGRADE_FAIL()) {
|
||||
"title" -> {
|
||||
player.closeInventory()
|
||||
player.sendTitle(StringUtils.formatToString(Messages.UPGRADE_FAIL()), "", 10, 70, 20)
|
||||
}
|
||||
|
||||
"subtitle" -> {
|
||||
player.closeInventory()
|
||||
player.sendTitle("", StringUtils.formatToString(Messages.UPGRADE_FAIL()), 10, 70, 20)
|
||||
}
|
||||
|
||||
"actionbar" -> {
|
||||
player.closeInventory()
|
||||
player.spigot().sendMessage(
|
||||
ChatMessageType.ACTION_BAR,
|
||||
*TextComponent.fromLegacyText(StringUtils.formatToString(Messages.UPGRADE_FAIL()))
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.UPGRADE_FAIL()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -51,6 +51,7 @@ class MinionPlaceListener : Listener {
|
||||
|
||||
val maxMinions = AxMinionsAPI.INSTANCE.getMinionLimit(event.player)
|
||||
|
||||
val chunk = location.chunk
|
||||
AxMinionsPlugin.dataQueue.submit {
|
||||
val placed = AxMinionsPlugin.dataHandler.getMinionAmount(event.player.uniqueId)
|
||||
|
||||
@ -85,7 +86,8 @@ class MinionPlaceListener : Listener {
|
||||
locationId,
|
||||
0
|
||||
)
|
||||
minion.setTicking(true)
|
||||
Minions.addTicking(chunk)
|
||||
|
||||
Scheduler.get().run { task ->
|
||||
meta = item.itemMeta!!
|
||||
meta.persistentDataContainer.remove(Keys.PLACED)
|
||||
@ -97,7 +99,7 @@ class MinionPlaceListener : Listener {
|
||||
event.player.sendMessage(
|
||||
"Placed minion $minion. Ticking? ${minion.isTicking()} Is chunk ticking? ${
|
||||
Minions.isTicking(
|
||||
location.chunk
|
||||
chunk
|
||||
)
|
||||
}"
|
||||
)
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.artillexstudios.axminions.listeners
|
||||
|
||||
import com.artillexstudios.axminions.AxMinionsPlugin
|
||||
import com.artillexstudios.axminions.api.minions.miniontype.MinionTypes
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.Listener
|
||||
@ -10,8 +9,6 @@ class WorldListener : Listener {
|
||||
|
||||
@EventHandler
|
||||
fun onWorldLoadEvent(event: WorldLoadEvent) {
|
||||
AxMinionsPlugin.dataQueue.submit {
|
||||
MinionTypes.loadForWorld(event.world)
|
||||
}
|
||||
}
|
||||
}
|
@ -67,6 +67,7 @@ class Minion(
|
||||
private val extraData = hashMapOf<String, String>()
|
||||
private var linkedInventory: Inventory? = null
|
||||
internal val openInventories = mutableListOf<Inventory>()
|
||||
@Volatile
|
||||
private var ticking = false
|
||||
private var debugHologram: Hologram? = null
|
||||
private var broken = false
|
||||
@ -74,12 +75,6 @@ class Minion(
|
||||
init {
|
||||
spawn()
|
||||
Minions.load(this)
|
||||
|
||||
if (linkedChest != null) {
|
||||
Scheduler.get().runAt(linkedChest) {
|
||||
linkedInventory = (linkedChest?.block?.state as? Container)?.inventory
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getType(): MinionType {
|
||||
@ -149,7 +144,7 @@ class Minion(
|
||||
}
|
||||
|
||||
private fun breakMinion(event: PacketEntityInteractEvent) {
|
||||
LinkingListener.linking.remove(event.player.uniqueId)
|
||||
LinkingListener.linking.remove(event.player)
|
||||
remove()
|
||||
setTicking(false)
|
||||
openInventories.fastFor { it.viewers.fastFor { viewer -> viewer.closeInventory() } }
|
||||
@ -307,7 +302,7 @@ class Minion(
|
||||
}
|
||||
|
||||
override fun openInventory(player: Player) {
|
||||
LinkingListener.linking.remove(player.uniqueId)
|
||||
LinkingListener.linking.remove(player)
|
||||
val inventory = Bukkit.createInventory(
|
||||
this,
|
||||
Config.GUI_SIZE(),
|
||||
@ -565,10 +560,14 @@ class Minion(
|
||||
override fun setTicking(ticking: Boolean) {
|
||||
this.ticking = ticking
|
||||
|
||||
if (ticking && linkedChest != null) {
|
||||
if (linkedChest == null) return
|
||||
|
||||
if (ticking) {
|
||||
Scheduler.get().runAt(linkedChest) {
|
||||
linkedInventory = (linkedChest?.block?.state as? Container)?.inventory
|
||||
}
|
||||
} else {
|
||||
linkedInventory = null
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ object MinionTicker {
|
||||
private inline fun tickAll() {
|
||||
Minions.get { minions ->
|
||||
minions.fastFor { pos ->
|
||||
if (!pos.ticking) return@fastFor
|
||||
pos.minions.fastFor {
|
||||
it.tick()
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ object Minions {
|
||||
lock.read {
|
||||
minions.forEach {
|
||||
if (world.uid == it.worldUUID && it.x == chunkX && it.z == chunkZ) {
|
||||
return true
|
||||
return it.ticking
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -63,8 +63,8 @@ object Minions {
|
||||
}
|
||||
|
||||
fun load(minion: Minion) {
|
||||
val chunkX = round(minion.getLocation().x) shr 4
|
||||
val chunkZ = round(minion.getLocation().z) shr 4
|
||||
val chunkX = (Math.round(minion.getLocation().x) shr 4).toInt()
|
||||
val chunkZ = (Math.round(minion.getLocation().z) shr 4).toInt()
|
||||
val world = minion.getLocation().world ?: return
|
||||
|
||||
lock.write {
|
||||
@ -79,7 +79,7 @@ object Minions {
|
||||
}
|
||||
|
||||
if (pos === null) {
|
||||
pos = ChunkPos(world, chunkX, chunkZ)
|
||||
pos = ChunkPos(world, chunkX, chunkZ, false)
|
||||
minions.add(pos!!)
|
||||
}
|
||||
|
||||
@ -89,8 +89,8 @@ object Minions {
|
||||
}
|
||||
|
||||
fun remove(minion: Minion) {
|
||||
val chunkX = round(minion.getLocation().x) shr 4
|
||||
val chunkZ = round(minion.getLocation().z) shr 4
|
||||
val chunkX = (Math.round(minion.getLocation().x) shr 4).toInt()
|
||||
val chunkZ = (Math.round(minion.getLocation().z) shr 4).toInt()
|
||||
val world = minion.getLocation().world ?: return
|
||||
|
||||
lock.write {
|
||||
@ -124,8 +124,4 @@ object Minions {
|
||||
minions(this.minions)
|
||||
}
|
||||
}
|
||||
|
||||
private infix fun round(double: Double): Int {
|
||||
return (double + 0.5).toInt()
|
||||
}
|
||||
}
|
@ -52,9 +52,9 @@ class FarmerMinionType : MinionType("farmer", AxMinionsPlugin.INSTANCE.getResour
|
||||
Warnings.remove(minion, Warnings.NO_TOOL)
|
||||
|
||||
var size = 0
|
||||
val drops = arrayListOf<ItemStack>()
|
||||
LocationUtils.getAllBlocksInRadius(minion.getLocation(), minion.getRange(), false).fastFor { location ->
|
||||
val block = location.block
|
||||
val drops = arrayListOf<ItemStack>()
|
||||
|
||||
when (block.type) {
|
||||
Material.CACTUS, Material.SUGAR_CANE, Material.BAMBOO -> {
|
||||
@ -95,10 +95,10 @@ class FarmerMinionType : MinionType("farmer", AxMinionsPlugin.INSTANCE.getResour
|
||||
|
||||
else -> return@fastFor
|
||||
}
|
||||
}
|
||||
|
||||
minion.addToContainerOrDrop(drops)
|
||||
minion.damageTool(size)
|
||||
minion.setActions(minion.getActionAmount() + size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,11 @@ use-durability: true
|
||||
# If the minion should pull new tools from the chest it's connected to
|
||||
pull-tools-from-chest: false
|
||||
|
||||
# What type of message we should send when the upgrade fails
|
||||
# due to insufficient funds
|
||||
# Possible options: chat, title, subtitle, actionbar
|
||||
upgrade-fail: "chat"
|
||||
|
||||
database:
|
||||
# Can be H2 (SqLite support is planned)
|
||||
type: "H2"
|
||||
@ -90,4 +95,4 @@ gui:
|
||||
debug: false
|
||||
|
||||
# Do not change!
|
||||
config-version: 2
|
||||
config-version: 3
|
Loading…
Reference in New Issue
Block a user