Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
80a4731
I think it works
Nuutrai Mar 10, 2025
b67f31c
Failed attempts at debugging (will keep trying)
Nuutrai Mar 10, 2025
969ad03
Made it more dynamic with the previous way of retrieving values
Nuutrai Mar 11, 2025
2408029
Merge remote-tracking branch 'upstream/main' into events-rehaul
Nuutrai Mar 11, 2025
3524629
A couple of small fixes
Nuutrai Mar 11, 2025
fceb00b
No idea if this works, mainly just putting this onto GitHub
Nuutrai Mar 14, 2025
902996f
Dynamic registry (expand for details)
Nuutrai Mar 14, 2025
9271572
Move to a new system to *finally* give tracking to events and other f…
Nuutrai Mar 16, 2025
4894dde
Adjust LuaEvents to use new system
Nuutrai Mar 16, 2025
2c98a1c
Adjust EventListener to use new system
Nuutrai Mar 16, 2025
ddc17e6
Make the disable subcommand work
Nuutrai Mar 16, 2025
2448a5e
Fix config reloading (maybe)
Nuutrai Mar 16, 2025
e681fd0
Very rudimentary debug system (see details)
Nuutrai Mar 16, 2025
5880019
Remove todo because it's added (yay!)
Nuutrai Mar 16, 2025
405274e
Adjust TODO message
Nuutrai Mar 16, 2025
c9041f2
Merge branch 'main' into events-rehaul
Nuutrai Mar 16, 2025
f055863
Not sure what happened here
Nuutrai Mar 16, 2025
7962964
Merge branch 'main' into events-rehaul
Nuutrai Mar 18, 2025
2ae3316
Revert "Very rudimentary debug system (see details)"
Nuutrai Mar 18, 2025
bbce335
Remove unnecessary debugs
Nuutrai Mar 18, 2025
55a4537
Merge remote-tracking branch 'origin/events-rehaul' into events-rehaul
Nuutrai Mar 18, 2025
8d3a8d4
Merge branch 'main' into events-rehaul
Nuutrai Mar 18, 2025
dc9e582
Use the spread operator ya dingus
Nuutrai Mar 20, 2025
e3ab81a
Merge branch 'main' into events-rehaul
Nuutrai Mar 23, 2025
3ede5a0
Merge branch 'main' into events-rehaul
Nuutrai Mar 23, 2025
eceafc1
Merge branch 'main' into events-rehaul
Nuutrai Apr 8, 2025
ce85a90
Finish fixing conflicts
Nuutrai Apr 8, 2025
00525ce
Minor fixes to use Rocket API
Nuutrai Apr 8, 2025
3ef5d79
Qodana warnings
Nuutrai Apr 10, 2025
9311f8c
Merge branch 'main' into events-rehaul
Nuutrai Apr 10, 2025
fd51bb8
Switch scriptName variables
Nuutrai Apr 10, 2025
a5b8f83
Remove unused INSTANCE variable
Nuutrai Apr 10, 2025
55f40b5
Merge remote-tracking branch 'origin/events-rehaul' into events-rehaul
Nuutrai Apr 10, 2025
1c6bbbd
Merge remote-tracking branch 'upstream/main' into events-rehaul
Nuutrai May 12, 2025
b7e18eb
Twine
Nuutrai May 13, 2025
3774d6d
Removed invalid imports
Nuutrai May 13, 2025
0b03213
Begin switch to Twine
Nuutrai May 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions build.gradle.kts
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,6 +52,9 @@ dependencies {
testImplementation("org.junit.jupiter:junit-jupiter:5.12.2")
testImplementation("org.mockbukkit.mockbukkit:mockbukkit-v1.21:4.45.1")
testImplementation("org.mockito.kotlin:mockito-kotlin:5.4.0")

// TODO check if needed
implementation("com.google.guava:guava:32.0.1-jre")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think guava is a welcome addition but I see not usages of it here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@blockarchitech said not to use guava, he should also comment here

}

val targetJavaVersion = 21
Expand Down
4 changes: 3 additions & 1 deletion src/main/kotlin/dev/znci/rocket/Rocket.kt
Original file line numberDiff line numberDiff line change
Expand Up@@ -66,7 +66,8 @@ open class Rocket : RocketAddon() {
this.getCommand("rocket")?.setExecutor(RocketCommand(this))

// Register all events
EventListener.registerAllEvents()
logger.info("Rocket plugin enabled")
EventListener.cacheEvents()

// Enable the base Rocket methods and globals
this.onAddonEnable()
Expand All@@ -86,4 +87,5 @@ open class Rocket : RocketAddon() {
override fun onDisable() {
logger.info("Rocket plugin disabled")
}

}
43 changes: 30 additions & 13 deletions src/main/kotlin/dev/znci/rocket/commands/RocketCommand.kt
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,6 +17,7 @@ package dev.znci.rocket.commands

import dev.znci.rocket.i18n.LocaleManager
import dev.znci.rocket.scripting.ScriptManager
import dev.znci.rocket.scripting.ScriptManager.disableFile
import dev.znci.rocket.scripting.ScriptManager.scriptsFolder
import org.bukkit.command.Command
import org.bukkit.command.CommandSender
Expand All@@ -32,7 +33,8 @@ class RocketCommand(private val plugin: JavaPlugin) : TabExecutor {
}

val action = args[0].lowercase()
val scriptName = if (!args[1].endsWith(".lua")) "${args[1]}.lua" else args[1]
val scriptName = args[1]
val rawScriptName = if (!scriptName.endsWith(".lua")) "${scriptName}.lua" else scriptName

if (!scriptsFolder.exists() || !scriptsFolder.isDirectory) {
sender.sendMessage(LocaleManager.getMessageAsComponent("rocket_command.scripts_folder_not_found"))
Expand All@@ -41,7 +43,7 @@ class RocketCommand(private val plugin: JavaPlugin) : TabExecutor {

when (action) {
"reload" -> {
if (scriptName.lowercase() == "config.lua") {
if (scriptName.lowercase() == "config") {
plugin.reloadConfig()

val defaultLocale = plugin.config.getString("locale", "en_GB").toString()
Expand All@@ -51,36 +53,49 @@ class RocketCommand(private val plugin: JavaPlugin) : TabExecutor {

sender.sendMessage(LocaleManager.getMessageAsComponent("rocket_command.config_reloaded"))
return true
} else if (scriptName.lowercase() == "all") {
val results = ScriptManager.loadAll()
if (results.isNotEmpty()) {
results.forEach { error ->
sender.sendMessage(LocaleManager.getMessageAsComponent("generic_error", error ?: "Unknown error"))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zNotChill - we need better error handling 🙂

Want to open a ticket for that?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zNotChill - we need better error handling 🙂

Want to open a ticket for that?

On my new branch (not yet published), I have already mostly done this. Anywhere you use a RocketError will now work, whereas before it would not, and it would just produce a error calling _: nil error. Now it actually shows you what you did wrong.

}
}
return true
}

val scriptFile = File(scriptsFolder, scriptName)
val scriptFile = File(scriptsFolder, rawScriptName)

if (!scriptFile.exists()) {
sender.sendMessage(LocaleManager.getMessageAsComponent("rocket_command.script_not_found", scriptName))
sender.sendMessage(LocaleManager.getMessageAsComponent("rocket_command.script_not_found", rawScriptName))
return true
}

val content = scriptFile.readText()
val result = ScriptManager.runScript(content)
val result = ScriptManager.loadScript(scriptFile)

if (result !== "") {
sender.sendMessage(LocaleManager.getMessageAsComponent("generic_error", result ?: "Unknown error"))
} else {
sender.sendMessage(
LocaleManager.getMessageAsComponent(
"rocket_command.script_reloaded",
scriptName
rawScriptName
)
)
}
}
"disable" -> {
val scriptFile = File(scriptsFolder, scriptName)
val scriptFile = File(scriptsFolder, rawScriptName)
if (!scriptFile.exists()) {
sender.sendMessage(LocaleManager.getMessageAsComponent("rocket_command.script_not_found", scriptName))
sender.sendMessage(LocaleManager.getMessageAsComponent("rocket_command.script_not_found", rawScriptName))
return true
}

sender.sendMessage(LocaleManager.getMessageAsComponent("rocket_command.script_disabled", scriptName))
// TODO: Add disabling of file (with '-')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you open a ticket for this?

// For another PR though

disableFile(scriptFile)

sender.sendMessage(LocaleManager.getMessageAsComponent("rocket_command.script_disabled", rawScriptName))
}
else -> {
sender.sendMessage(LocaleManager.getMessageAsComponent("rocket_command.usage"))
Expand All@@ -99,9 +114,11 @@ class RocketCommand(private val plugin: JavaPlugin) : TabExecutor {
if (args.size == 1) {
return mutableListOf("reload", "disable")
} else if (args.size == 2) {
return if (args[0] == "reload") ScriptManager.getAllScripts().toMutableList()
else if (args[0] == "disable") ScriptManager.getAllScripts(false).toMutableList()
else null
val list: MutableList<String>? =

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There has to be a better way of doing commands. I really don't like this class. Could we use some sort of command library?

Being said, this is scope creep 🙂

if (args[0] == "reload") ScriptManager.getAllScripts().toMutableList().also { it.add("config") }
else if (args[0] == "disable") ScriptManager.getAllScripts(false).toMutableList().also { it.add("config") }
else null
return list
}
return null

Expand Down
75 changes: 65 additions & 10 deletions src/main/kotlin/dev/znci/rocket/scripting/ScriptManager.kt
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,6 +22,7 @@ import dev.znci.twine.TwineProperty
import dev.znci.twine.TwineTable
import dev.znci.twine.TwineValueBase
import org.bukkit.event.Event
import org.luaj.vm2.*
import java.io.File
import org.luaj.vm2.Globals
import org.luaj.vm2.LuaError
Expand All@@ -45,11 +46,22 @@ object ScriptManager {
*/
var scriptsFolder: File = File("")

/**
* A map of loaded scripts associated by file path
*/
val loadedScriptFiles = mutableMapOf<String, MutableList<Function1<TwineTable, Unit>>>()

/**
* A map associating Lua event sections with a class.
* This mainly helps with disabling scripts
*/
val eventScript = mutableMapOf<Function1<TwineTable, Unit>, Class<out Event>>()

/**
* A map of events and their associated Lua handlers.
* It stores the events triggered in the system and the corresponding Lua functions that handle them.
*/
val usedEvents = mutableMapOf<Class<out Event>, LuaValue>()
val usedEvents = mutableMapOf<Class<out Event>, MutableList<Function1<TwineTable, Unit>>>()

/**
* A map of enabled commands by their names.
Expand All@@ -69,7 +81,6 @@ object ScriptManager {
*
* @param folder The folder containing the Lua scripts.
*/
@Suppress("unused") // TODO: Will be used in the future when custom configuration folders are implemented
fun setFolder(folder: File) {
scriptsFolder = folder
}
Expand All@@ -78,12 +89,10 @@ object ScriptManager {
* Loads all scripts from the `scriptsFolder` directory.
* This method currently prints the content of the scripts, but is planned for future use when custom folder configurations are implemented.
*/
@Suppress("unused") // TODO: Is this still required?
fun loadScripts() {
scriptsFolder.walkTopDown().forEach { file ->
if (file.isFile && !file.startsWith("-")) {
val content = file.readText()
runScript(content)
runScript(file)
}
}
}
Expand All@@ -106,21 +115,67 @@ object ScriptManager {
return list
}

/**
* Recursively loads all scripts located in the scripts folder
* @return A list of error messages where execution failed. The list will be empty if there were no errors
*/
fun loadAll(): List<String?> {
val results = mutableListOf<String?>()
getAllScripts(false).forEach { script ->
val result = loadScript(File("plugins/rocket/scripts/", script))
if (result != "")
results.add(result)
}
return results
}

/**
* Loads a script based off of a [File] object
*
* @param scriptFile The script to load
* @return An error message if execution fails, or an empty string if the script ran successfully.
*/
fun loadScript(scriptFile: File): String? {
if (loadedScriptFiles[scriptFile.absolutePath] != null) {
disableFile(scriptFile)
}
val result = runScript(scriptFile)
return result
}

/**
* Disables a script based off of a [File] object
* @param scriptFile The script to disable
*/
fun disableFile(scriptFile: File) {
val functions = loadedScriptFiles[scriptFile.absolutePath]!!
for (function in functions) {
val eventClass = eventScript[function]!!
for (eventCallback in usedEvents[eventClass]?:continue) {
if (eventCallback == function) usedEvents.remove(eventClass)
}
eventScript.remove(function)
}
}

/**
* Runs a Lua script provided as a string.
* The script is executed within the global Lua environment, and any errors are caught and returned as a string message.
*
* @param text The Lua script content to execute.
* @param scriptFile The Lua script content to execute.
* @return An error message if execution fails, or an empty string if the script ran successfully.
*/
fun runScript(text: String): String? {
fun runScript(scriptFile: File): String? {

val content = scriptFile.readText()

try {
applyGlobals()
val scriptResult = globals.load(text, "script", globals)
val scriptResult = globals.load(content, "::${scriptFile.absolutePath}::", globals)

scriptResult.call()
} catch (e: LuaError) {
return e.message
} catch (error: LuaError) {
return error.message
}

return ""
Expand Down
Loading