Skip to content

Commit e65508f

Browse files
authored
Merge pull request #15 from astorks/dev
Dev -> Master v1.1.7
2 parents efabe04 + 468a2eb commit e65508f

File tree

8 files changed

+147
-86
lines changed

8 files changed

+147
-86
lines changed

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ plugins {
66
}
77

88
group = "com.pixlfox.scriptablemc"
9-
version = "1.1.6"
9+
version = "1.1.7"
1010

1111
java {
1212
sourceCompatibility = JavaVersion.VERSION_1_8

src/main/kotlin/com/pixlfox/scriptablemc/ScriptablePluginCommand.kt

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class ScriptablePluginCommand(private val basePlugin: ScriptablePluginMain) : Ba
1919

2020
@Subcommand("info|i")
2121
@CommandPermission("scriptablemc.info")
22-
fun onSmcInfo(player: Player) {
22+
fun onSmcInfo(player: CommandSender) {
2323
val scriptEngine = basePlugin.scriptEngine
2424
val isGraalRuntime = scriptEngine?.evalJs("if (typeof Graal != 'undefined') { Graal.isGraalRuntime() } else { false }")?.asBoolean() == true
2525
player.sendMessage("${ChatColor.GREEN}ScriptableMC Version: ${basePlugin.description.version}")
@@ -36,14 +36,6 @@ class ScriptablePluginCommand(private val basePlugin: ScriptablePluginMain) : Ba
3636
MainMenu.INVENTORY.open(player)
3737
}
3838

39-
}
40-
41-
42-
@Suppress("unused")
43-
@CommandAlias("scriptablemc|smc")
44-
@Subcommand("javascript|js")
45-
class ScriptablePluginJsCommand(private val basePlugin: ScriptablePluginMain) : BaseCommand() {
46-
4739
@Subcommand("reload|rl")
4840
@CommandAlias("jsrl")
4941
@CommandPermission("scriptablemc.js.reload")
@@ -77,6 +69,14 @@ class ScriptablePluginJsCommand(private val basePlugin: ScriptablePluginMain) :
7769
}
7870
}
7971

72+
}
73+
74+
75+
@Suppress("unused")
76+
@CommandAlias("scriptablemc|smc")
77+
@Subcommand("javascript|js")
78+
class ScriptablePluginJavaScriptCommand(private val basePlugin: ScriptablePluginMain) : BaseCommand() {
79+
8080
@Subcommand("execute|ex")
8181
@CommandAlias("jsex")
8282
@CommandPermission("scriptablemc.js.execute")
@@ -136,4 +136,43 @@ class ScriptablePluginJsCommand(private val basePlugin: ScriptablePluginMain) :
136136
}
137137
}
138138

139+
}
140+
141+
@Suppress("unused")
142+
@CommandAlias("scriptablemc|smc")
143+
@Subcommand("typescript|ts")
144+
class ScriptablePluginTypeScriptCommand(private val basePlugin: ScriptablePluginMain) : BaseCommand() {
145+
146+
@Subcommand("reload|rl")
147+
@CommandAlias("jsrl")
148+
@CommandPermission("scriptablemc.js.reload")
149+
fun onSmcJsReload(sender: CommandSender) {
150+
basePlugin.patchClassLoader {
151+
try {
152+
basePlugin.scriptEngine!!.close()
153+
basePlugin.logger.info("Scripting engine shutdown.")
154+
basePlugin.reloadConfig()
155+
156+
basePlugin.scriptEngine = ScriptablePluginEngine(
157+
basePlugin,
158+
basePlugin.config.getString("root_scripts_folder", "./scripts").orEmpty(),
159+
basePlugin.config.getBoolean("debug", false),
160+
basePlugin.config.getBoolean("extract_libs", true)
161+
)
162+
163+
basePlugin.scriptEngine!!.start()
164+
basePlugin.logger.info("Scripting engine started.")
165+
166+
sender.sendMessage("Javascript engine reloaded.")
167+
}
168+
catch (e: Exception) {
169+
e.printStackTrace()
170+
171+
sender.sendMessage("${ChatColor.DARK_RED}$e")
172+
for (stackTrace in e.stackTrace) {
173+
sender.sendMessage("${ChatColor.DARK_RED}$stackTrace")
174+
}
175+
}
176+
}
177+
}
139178
}

src/main/kotlin/com/pixlfox/scriptablemc/ScriptablePluginMain.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ class ScriptablePluginMain : JavaPlugin(), Listener {
1818
override fun onEnable() {
1919
commandManager = PaperCommandManager(this)
2020
commandManager?.registerCommand(ScriptablePluginCommand(this))
21-
commandManager?.registerCommand(ScriptablePluginJsCommand(this))
21+
commandManager?.registerCommand(ScriptablePluginJavaScriptCommand(this))
22+
commandManager?.registerCommand(ScriptablePluginTypeScriptCommand(this))
2223

2324
patchClassLoader {
2425
saveDefaultConfig()

src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginEngine.kt

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class ScriptablePluginEngine(val bootstrapPlugin: JavaPlugin, val rootScriptsFol
2525
private val jsBindings: Value = graalContext.getBindings("js")
2626
internal val scriptablePlugins: MutableList<ScriptablePluginContext> = mutableListOf()
2727
internal val inventoryManager: InventoryManager = InventoryManager(bootstrapPlugin)
28+
private var enabledAllPlugins: Boolean = false
2829

2930
internal fun start() {
3031
instance = this
@@ -39,19 +40,30 @@ class ScriptablePluginEngine(val bootstrapPlugin: JavaPlugin, val rootScriptsFol
3940
if(extractLibs) {
4041
val librariesResource = bootstrapPlugin.getResource("libraries.zip")
4142
if (librariesResource != null) {
42-
val unzipUtil = UnzipUtility()
43-
unzipUtil.unzip(librariesResource, "${rootScriptsFolder}/lib")
43+
UnzipUtility.unzip(librariesResource, "${rootScriptsFolder}/lib")
4444
}
4545
}
4646

4747
if(mainScriptFile.exists()) {
48-
eval(
48+
val pluginTypes = eval(
4949
Source.newBuilder("js", mainScriptFile)
5050
.name("main.js")
5151
.mimeType("application/javascript+module")
5252
.interactive(false)
5353
.build()
5454
)
55+
56+
// Load all plugin types returned as an array
57+
if(pluginTypes.hasArrayElements()) {
58+
for (i in 0..pluginTypes.arraySize) {
59+
this.loadPlugin(pluginTypes.getArrayElement(i))
60+
}
61+
}
62+
63+
// Enable all plugins if not already enabled
64+
if(!enabledAllPlugins) {
65+
enableAllPlugins()
66+
}
5567
}
5668
else {
5769
throw ScriptNotFoundException(mainScriptFile)
@@ -110,18 +122,23 @@ class ScriptablePluginEngine(val bootstrapPlugin: JavaPlugin, val rootScriptsFol
110122

111123
fun evalCommandSenderJs(source: String, sender: CommandSender): Value {
112124
val tempScriptFile = File("${rootScriptsFolder}/${UUID.randomUUID()}.js")
113-
tempScriptFile.writeText("import * as lib from './lib/global.js';\n" +
114-
"new (class EvalCommandSenderContext {\n" +
115-
" run(sender, server, servicesManager) {\n" +
116-
" $source\n" +
117-
" }\n" +
118-
"})()\n");
119-
val evalCommandSenderContext = evalFile(tempScriptFile)
120-
tempScriptFile.delete()
121-
evalCommandSenderContext.putMember("sender", sender)
122-
evalCommandSenderContext.putMember("server", Bukkit.getServer())
123-
evalCommandSenderContext.putMember("servicesManager", Bukkit.getServicesManager())
124-
return evalCommandSenderContext.invokeMember("run", sender, Bukkit.getServer(), Bukkit.getServicesManager());
125+
try {
126+
tempScriptFile.writeText("import * as lib from './lib/global.js';\n" +
127+
"new (class EvalCommandSenderContext {\n" +
128+
" run(sender, server, servicesManager) {\n" +
129+
" $source\n" +
130+
" }\n" +
131+
"})()\n");
132+
val evalCommandSenderContext = evalFile(tempScriptFile)
133+
134+
evalCommandSenderContext.putMember("sender", sender)
135+
evalCommandSenderContext.putMember("server", Bukkit.getServer())
136+
evalCommandSenderContext.putMember("servicesManager", Bukkit.getServicesManager())
137+
return evalCommandSenderContext.invokeMember("run", sender, Bukkit.getServer(), Bukkit.getServicesManager())
138+
}
139+
finally {
140+
tempScriptFile.delete()
141+
}
125142
}
126143

127144
fun eval(source: Source): Value {
@@ -142,6 +159,7 @@ class ScriptablePluginEngine(val bootstrapPlugin: JavaPlugin, val rootScriptsFol
142159
for (pluginContext in scriptablePlugins) {
143160
pluginContext.enable()
144161
}
162+
enabledAllPlugins = true
145163
}
146164

147165
fun enablePlugin(pluginContext: ScriptablePluginContext) {

src/main/kotlin/com/pixlfox/scriptablemc/utils/MysqlWrapper.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import java.sql.DriverManager
77
import java.sql.PreparedStatement
88
import java.sql.Statement
99

10-
@Suppress("unused")
10+
@Suppress("unused", "MemberVisibilityCanBePrivate")
1111
class MysqlWrapper(private val host: String, private val port: Int, private val database: String, private val username: String, private val password: String) {
1212
private var connection: Connection? = null
1313

src/main/kotlin/com/pixlfox/scriptablemc/utils/UnzipUtil.kt

Lines changed: 57 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -9,68 +9,69 @@ import java.util.zip.ZipInputStream
99
* a destination directory.
1010
* @author www.codejava.net
1111
*/
12+
@Suppress("unused")
1213
class UnzipUtility {
13-
/**
14-
* Extracts a zip file specified by the zipFilePath to a directory specified by
15-
* destDirectory (will be created if does not exists)
16-
* @param zipFilePath
17-
* @param destDirectory
18-
* @throws IOException
19-
*/
20-
@Throws(IOException::class)
21-
fun unzip(zipStream: InputStream, destDirectory: String) {
22-
val destDir = File(destDirectory)
23-
if (!destDir.exists()) {
24-
destDir.mkdirs()
25-
}
26-
val zipIn = ZipInputStream(zipStream)
27-
var entry = zipIn.nextEntry
28-
// iterates over entries in the zip file
29-
while (entry != null) {
30-
val filePath = destDirectory + File.separator + entry.name
31-
if (!entry.isDirectory) { // if the entry is a file, extracts it
32-
extractFile(zipIn, filePath)
33-
} else { // if the entry is a directory, make the directory
34-
val dir = File(filePath)
35-
dir.mkdir()
14+
companion object {
15+
/**
16+
* Size of the buffer to read/write data
17+
*/
18+
private const val BUFFER_SIZE = 4096
19+
20+
/**
21+
* Extracts a zip file from the zipStream to a directory specified by
22+
* destDirectory (will be created if does not exists)
23+
* @param zipStream
24+
* @param destDirectory
25+
* @throws IOException
26+
*/
27+
@Throws(IOException::class)
28+
fun unzip(zipStream: InputStream, destDirectory: String) {
29+
val destDir = File(destDirectory)
30+
if (!destDir.exists()) {
31+
destDir.mkdirs()
3632
}
37-
zipIn.closeEntry()
38-
entry = zipIn.nextEntry
33+
val zipIn = ZipInputStream(zipStream)
34+
var entry = zipIn.nextEntry
35+
// iterates over entries in the zip file
36+
while (entry != null) {
37+
val filePath = destDirectory + File.separator + entry.name
38+
if (!entry.isDirectory) { // if the entry is a file, extracts it
39+
extractFile(zipIn, filePath)
40+
} else { // if the entry is a directory, make the directory
41+
val dir = File(filePath)
42+
dir.mkdir()
43+
}
44+
zipIn.closeEntry()
45+
entry = zipIn.nextEntry
46+
}
47+
zipIn.close()
3948
}
40-
zipIn.close()
41-
}
4249

43-
/**
44-
* Extracts a zip file specified by the zipFilePath to a directory specified by
45-
* destDirectory (will be created if does not exists)
46-
* @param zipFilePath
47-
* @param destDirectory
48-
* @throws IOException
49-
*/
50-
@Throws(IOException::class)
51-
fun unzip(zipFilePath: String, destDirectory: String) = unzip(FileInputStream(zipFilePath), destDirectory)
52-
53-
/**
54-
* Extracts a zip entry (file entry)
55-
* @param zipIn
56-
* @param filePath
57-
* @throws IOException
58-
*/
59-
@Throws(IOException::class)
60-
private fun extractFile(zipIn: ZipInputStream, filePath: String) {
61-
val bos = BufferedOutputStream(FileOutputStream(filePath))
62-
val bytesIn = ByteArray(BUFFER_SIZE)
63-
var read: Int
64-
while (zipIn.read(bytesIn).also { read = it } != -1) {
65-
bos.write(bytesIn, 0, read)
66-
}
67-
bos.close()
68-
}
50+
/**
51+
* Extracts a zip file specified by the zipFilePath to a directory specified by
52+
* destDirectory (will be created if does not exists)
53+
* @param zipFilePath
54+
* @param destDirectory
55+
* @throws IOException
56+
*/
57+
@Throws(IOException::class)
58+
fun unzip(zipFilePath: String, destDirectory: String) = unzip(FileInputStream(zipFilePath), destDirectory)
6959

70-
companion object {
7160
/**
72-
* Size of the buffer to read/write data
61+
* Extracts a zip entry (file entry)
62+
* @param zipIn
63+
* @param filePath
64+
* @throws IOException
7365
*/
74-
private const val BUFFER_SIZE = 4096
66+
@Throws(IOException::class)
67+
private fun extractFile(zipIn: ZipInputStream, filePath: String) {
68+
val bos = BufferedOutputStream(FileOutputStream(filePath))
69+
val bytesIn = ByteArray(BUFFER_SIZE)
70+
var read: Int
71+
while (zipIn.read(bytesIn).also { read = it } != -1) {
72+
bos.write(bytesIn, 0, read)
73+
}
74+
bos.close()
75+
}
7576
}
7677
}

src/main/resources/config.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
# Root scripts folder default: ./scripts
1+
# Root scripts folder
22
# Example inside plugin folder: ./plugins/ScriptableMC/scripts
3+
# Default: ./scripts
34
root_scripts_folder: './scripts'
45

56
# Prints some additional debugging messages
7+
# Default: false
68
debug: false
79

810
# Automatically extract js libraries to scripts lib folder if lib folder is missing
911
# If you set this to false you'll need to download and extract the libs manually.
12+
# Default: true
1013
extract_libs: true

src/main/resources/plugin.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
name: ScriptableMC
22
description: 'Run JavaScript/TypeScript plugins for Bukkit/Spigot/Paper Minecraft 1.15'
3-
version: '1.1.6'
4-
api-version: '1.15'
3+
version: '1.1.7'
54
author: AStorks
65
main: com.pixlfox.scriptablemc.ScriptablePluginMain
76
depend: []

0 commit comments

Comments
 (0)