From 99cecd7f734e6457f74985b5dec3d0475547a26b Mon Sep 17 00:00:00 2001 From: Ashton Storks Date: Sun, 9 Feb 2020 18:22:54 -0700 Subject: [PATCH 1/4] /smc menu should now work on minecraft version 1.8+. Cleaned up /smc menu and made the menu smaller. Fixed command breaking after script engine reload on MC v1.12 and lower. --- build.gradle.kts | 2 +- .../core/ScriptablePluginContext.kt | 8 ++++- .../smartinvs/ScriptablePluginMenu.kt | 32 +++++++------------ .../smartinvs/SmartInventoryInterface.kt | 4 +++ src/main/resources/plugin.yml | 2 +- 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 8f40fc31..e3532c1e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "com.pixlfox.scriptablemc" -version = "1.1.8" +version = "1.1.9" java { sourceCompatibility = JavaVersion.VERSION_1_8 diff --git a/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginContext.kt b/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginContext.kt index b86ba53e..80911f74 100644 --- a/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginContext.kt +++ b/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginContext.kt @@ -6,6 +6,7 @@ import com.pixlfox.scriptablemc.utils.FileWrapper import com.pixlfox.scriptablemc.utils.MysqlWrapper import me.clip.placeholderapi.PlaceholderAPI import org.bukkit.Bukkit +import org.bukkit.Material import org.bukkit.OfflinePlayer import org.bukkit.Server import org.bukkit.command.CommandMap @@ -128,7 +129,12 @@ class ScriptablePluginContext(private val engine: ScriptablePluginEngine, val pl commandMapField.isAccessible = true val commandMap = commandMapField.get(Bukkit.getServer()) as CommandMap - val knownCommandsField = commandMap.javaClass.superclass.declaredFields.firstOrNull { it.name.equals("knownCommands", false) } + var knownCommandsField = commandMap.javaClass.superclass.declaredFields.firstOrNull { it.name.equals("knownCommands", false) } + + if(knownCommandsField == null) { // Pre-MCv1.13 command unregister fix + knownCommandsField = commandMap.javaClass.declaredFields.firstOrNull { it.name.equals("knownCommands", false) } + } + knownCommandsField?.isAccessible = true val knownCommands = knownCommandsField?.get(commandMap) as HashMap<*, *>? diff --git a/src/main/kotlin/com/pixlfox/scriptablemc/smartinvs/ScriptablePluginMenu.kt b/src/main/kotlin/com/pixlfox/scriptablemc/smartinvs/ScriptablePluginMenu.kt index 4c85aca8..d57424d1 100644 --- a/src/main/kotlin/com/pixlfox/scriptablemc/smartinvs/ScriptablePluginMenu.kt +++ b/src/main/kotlin/com/pixlfox/scriptablemc/smartinvs/ScriptablePluginMenu.kt @@ -18,34 +18,26 @@ import fr.minuskube.inv.content.SlotIterator class MainMenu(private val pluginEngine: ScriptablePluginEngine) : InventoryProvider { override fun init(player: Player?, contents: InventoryContents?) { if(contents != null && player != null) { - contents.fillBorders(ClickableItem.empty(ItemStack(Material.BLACK_CONCRETE))) - - if(player.hasPermission("scriptablemc.js.reload")) { - val reloadItemStack = ItemStack(Material.GOLD_NUGGET) - val reloadItemMeta = reloadItemStack.itemMeta - reloadItemMeta?.setDisplayName("${ChatColor.DARK_AQUA}Reload Script Engine") - reloadItemStack.itemMeta = reloadItemMeta - contents.set(1, 1, ClickableItem.of(reloadItemStack) { - Bukkit.getServer().dispatchCommand(player, "jsreload") + if(player.hasPermission("scriptablemc.reload")) { + contents.set(0, 0, ClickableItem.of(SmartItemBuilder(Material.GOLD_NUGGET) + .setDisplayName("${ChatColor.DARK_AQUA}Reload Script Engine") + .build()) { + Bukkit.getServer().dispatchCommand(player, "scriptablemc reload") }) } if(player.hasPermission("scriptablemc.info")) { - val pluginsItemStack = ItemStack(Material.IRON_NUGGET) - val pluginsItemMeta = pluginsItemStack.itemMeta - pluginsItemMeta?.setDisplayName("${ChatColor.GREEN}Print ScriptableMC Info") - pluginsItemStack.itemMeta = pluginsItemMeta - contents.set(1, 2, ClickableItem.of(pluginsItemStack) { + contents.set(0, 1, ClickableItem.of(SmartItemBuilder(Material.IRON_NUGGET) + .setDisplayName("${ChatColor.GREEN}Print ScriptableMC Info") + .build()) { Bukkit.getServer().dispatchCommand(player, "scriptablemc info") player.closeInventory() }) } - val closeItemStack = ItemStack(Material.BARRIER) - val closeItemMeta = closeItemStack.itemMeta - closeItemMeta?.setDisplayName("${ChatColor.RED}Close Menu") - closeItemStack.itemMeta = closeItemMeta - contents.set(1, 7, ClickableItem.of(closeItemStack) { + contents.set(0, 8, ClickableItem.of(SmartItemBuilder(Material.BARRIER) + .setDisplayName("${ChatColor.RED}Close Menu") + .build()) { player.closeInventory() }) } @@ -59,7 +51,7 @@ class MainMenu(private val pluginEngine: ScriptablePluginEngine) : InventoryProv .id("spm.mainmenu") .manager(ScriptablePluginEngine.instance!!.inventoryManager) .provider(MainMenu(ScriptablePluginEngine.instance!!)) - .size(3, 9) + .size(1, 9) .title(ChatColor.LIGHT_PURPLE.toString() + "ScriptableMC | Main Menu") .closeable(true) .build() diff --git a/src/main/kotlin/com/pixlfox/scriptablemc/smartinvs/SmartInventoryInterface.kt b/src/main/kotlin/com/pixlfox/scriptablemc/smartinvs/SmartInventoryInterface.kt index 751e2f49..cae5743c 100644 --- a/src/main/kotlin/com/pixlfox/scriptablemc/smartinvs/SmartInventoryInterface.kt +++ b/src/main/kotlin/com/pixlfox/scriptablemc/smartinvs/SmartInventoryInterface.kt @@ -5,6 +5,7 @@ import fr.minuskube.inv.ClickableItem import fr.minuskube.inv.SmartInventory import fr.minuskube.inv.content.InventoryContents import fr.minuskube.inv.content.InventoryProvider +import org.bukkit.Material import org.bukkit.enchantments.Enchantment import org.bukkit.entity.Player import org.bukkit.event.inventory.InventoryClickEvent @@ -40,6 +41,9 @@ class SmartInventoryInterface { } class SmartItemBuilder(private val itemStack: ItemStack) { + + constructor(material: Material): this(ItemStack(material)) + fun setDisplayName(displayName: String): SmartItemBuilder { val itemMeta = itemStack.itemMeta itemMeta?.setDisplayName(displayName) diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 53e870dd..e548806e 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: ScriptableMC description: 'Run JavaScript/TypeScript plugins for Bukkit/Spigot/Paper Minecraft 1.15' -version: '1.1.8' +version: '1.1.9' api-version: '1.13' author: AStorks main: com.pixlfox.scriptablemc.ScriptablePluginMain From 4a44a821082d3099a7549d9228c41a5cd454431b Mon Sep 17 00:00:00 2001 From: Ashton Storks Date: Mon, 10 Feb 2020 17:59:26 -0700 Subject: [PATCH 2/4] Added static source files for the typescript library. Moved utilities to com.smc.utils namespace. Added MinecraftVersions library to the com.smc.version namespace. --- .idea/inspectionProfiles/Project_Default.xml | 6 + README.md | 6 + build.gradle.kts | 5 +- .../com/smc/version/MinecraftVersion.java | 331 ++++++++++++++++++ .../com/smc/version/MinecraftVersions.java | 127 +++++++ .../java/com/smc/version/SnapshotVersion.java | 161 +++++++++ .../scriptablemc/TypescriptLibraryExporter.kt | 24 +- .../core/ScriptablePluginContext.kt | 5 +- .../core/ScriptablePluginEngine.kt | 19 +- .../scriptablemc => smc}/utils/FileWrapper.kt | 5 +- .../utils/MysqlWrapper.kt | 2 +- src/main/ts/JsPlugin.ts | 77 ++++ 12 files changed, 754 insertions(+), 14 deletions(-) create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 src/main/java/com/smc/version/MinecraftVersion.java create mode 100644 src/main/java/com/smc/version/MinecraftVersions.java create mode 100644 src/main/java/com/smc/version/SnapshotVersion.java rename src/main/kotlin/com/{pixlfox/scriptablemc => smc}/utils/FileWrapper.kt (88%) rename src/main/kotlin/com/{pixlfox/scriptablemc => smc}/utils/MysqlWrapper.kt (98%) create mode 100644 src/main/ts/JsPlugin.ts diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..c4c8b6ed --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/README.md b/README.md index ab592107..d056c6e7 100644 --- a/README.md +++ b/README.md @@ -34,3 +34,9 @@ You can take the typescript example and compile it, then directly modify the jav > `/jsex sender.sendMessage(lib.org.bukkit.ChatColor.GREEN + "Hello World!")`
> ![Hello World!](https://i.imgur.com/1dzwpqy.png) + + +### Third Party Libraries +https://github.com/MinusKube/SmartInvs - Inventory menu library
+https://github.com/aikar/commands - Built-in commands and auto-completion
+https://github.com/graalvm/graaljs - JavaScript engine diff --git a/build.gradle.kts b/build.gradle.kts index e3532c1e..eeb7c868 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -36,10 +36,6 @@ repositories { name = "minecraft" url = uri("https://libraries.minecraft.net") } - maven { - name = "mccommandapi" - url = uri("https://raw.githubusercontent.com/JorelAli/1.13-Command-API/mvn-repo/1.13CommandAPI/") - } maven { name = "papermc" url = uri("https://papermc.io/repo/repository/maven-public/") @@ -69,6 +65,7 @@ dependencies { implementation("com.thoughtworks.paranamer:paranamer:2.8") implementation("com.beust:klaxon:5.2") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") + testImplementation("junit", "junit", "4.12") } diff --git a/src/main/java/com/smc/version/MinecraftVersion.java b/src/main/java/com/smc/version/MinecraftVersion.java new file mode 100644 index 00000000..28c5a3b0 --- /dev/null +++ b/src/main/java/com/smc/version/MinecraftVersion.java @@ -0,0 +1,331 @@ +/* + * This file is part of helper, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.smc.version; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.text.SimpleDateFormat; +import java.util.Comparator; +import java.util.Locale; +import java.util.Objects; + +/** + * Encapsulates a version of Minecraft. + * + * @author Kristian (ProtocolLib) + */ +@SuppressWarnings("unused") +public final class MinecraftVersion implements Comparable { + + public static final Comparator COMPARATOR = Comparator.nullsFirst(Comparator + .comparingInt(MinecraftVersion::getMajor) + .thenComparingInt(MinecraftVersion::getMinor) + .thenComparingInt(MinecraftVersion::getBuild) + .thenComparing(Comparator.nullsLast(Comparator.comparing(MinecraftVersion::getDevelopmentStage))) + .thenComparing(Comparator.nullsFirst(Comparator.comparing(MinecraftVersion::getSnapshot))) + ); + + /** + * The newest known version of Minecraft + */ + private static final String NEWEST_MINECRAFT_VERSION = "1.13.1"; + + /** + * The date (with ISO 8601 or YYYY-MM-DD) when the most recent version was released. + */ + private static final String MINECRAFT_LAST_RELEASE_DATE = "2018-08-22"; + + /** + * Gets the {@link MinecraftVersion} of the runtime server. + * + * @return the runtime minecraft version. + */ + public static MinecraftVersion getRuntimeVersion() { + return MinecraftVersions.RUNTIME_VERSION; + } + + /** + * Creates a new {@link MinecraftVersion} with the given properties. + * + * @param major the major component + * @param minor the minor component + * @param build the build component + * @return a version instance + */ + public static MinecraftVersion of(int major, int minor, int build) { + return new MinecraftVersion(major, minor, build, null, null); + } + + /** + * Parses a {@link MinecraftVersion} from a version string, in the format + * major.minor.build, or in the snapshot format. + * + * @param version the version in text form. + * @throws IllegalArgumentException if unable to parse + */ + public static MinecraftVersion parse(String version) throws IllegalArgumentException { + return parse(version, true); + } + + /** + * Parses a {@link MinecraftVersion} from a version string, in the format + * major.minor.build, or in the snapshot format. + * + * @param version the version in text form. + * @param parseSnapshot if the implementation should try to parse a snapshot version + * @throws IllegalArgumentException if unable to parse + */ + public static MinecraftVersion parse(String version, boolean parseSnapshot) throws IllegalArgumentException { + String[] parts = version.split("-"); + SnapshotVersion snapshot = null; + int[] versionComponents = new int[3]; + + try { + versionComponents = parseVersion(parts[0]); + } catch (NumberFormatException cause) { + // Skip snapshot parsing + if (!parseSnapshot) + throw cause; + + try { + // Determine if the snapshot is newer than the current release version + snapshot = SnapshotVersion.parse(parts[0]); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.US); + + MinecraftVersion latest = MinecraftVersion.parse(NEWEST_MINECRAFT_VERSION, false); + boolean newer = snapshot.getSnapshotDate().compareTo(format.parse(MINECRAFT_LAST_RELEASE_DATE)) > 0; + + versionComponents[0] = latest.getMajor(); + versionComponents[1] = latest.getMinor() + (newer ? 1 : -1); + } catch (Exception e) { + throw new IllegalArgumentException("Cannot parse " + parts[0], e); + } + } + + int major = versionComponents[0]; + int minor = versionComponents[1]; + int build = versionComponents[2]; + String development = parts.length > 1 ? parts[1] : (snapshot != null ? "snapshot" : null); + return new MinecraftVersion(major, minor, build, development, snapshot); + } + + private static int[] parseVersion(String version) { + String[] elements = version.split("\\."); + int[] numbers = new int[3]; + + // Make sure it's even a valid version + if (elements.length < 1) { + throw new IllegalStateException("Corrupt MC version: " + version); + } + + // The String 1 or 1.2 is interpreted as 1.0.0 and 1.2.0 respectively. + for (int i = 0; i < Math.min(numbers.length, elements.length); i++) { + numbers[i] = Integer.parseInt(elements[i].trim()); + } + return numbers; + } + + + private final int major; + private final int minor; + private final int build; + + // The development stage + @Nullable + private final String development; + + // Snapshot? + @Nullable + private final SnapshotVersion snapshot; + + /** + * Construct a version object. + * + * @param major - major version number. + * @param minor - minor version number. + * @param build - build version number. + * @param development - development stage. + */ + private MinecraftVersion(int major, int minor, int build, @Nullable String development, @Nullable SnapshotVersion snapshot) { + this.major = major; + this.minor = minor; + this.build = build; + this.development = development; + this.snapshot = snapshot; + } + + /** + * Gets the major component of the version. + * + * @return the major component of the version + */ + public int getMajor() { + return this.major; + } + + /** + * Gets the minor component of the version. + * + * @return the minor component of the version. + */ + public int getMinor() { + return this.minor; + } + + /** + * Gets the build component of the version. + * + * @return the build component of the version. + */ + public int getBuild() { + return this.build; + } + + /** + * Gets the development stage. + * + * @return the development stage, or null if this is a release. + */ + @Nullable + public String getDevelopmentStage() { + return this.development; + } + + /** + * Gets the snapshot version, or null if this is a release. + * + * @return The snapshot version. + */ + @Nullable + public SnapshotVersion getSnapshot() { + return this.snapshot; + } + + /** + * Gets if this version is a snapshot. + * + * @return if this version is a snapshot. + */ + public boolean isSnapshot() { + return this.snapshot != null; + } + + /** + * Gets the version String (major.minor.build) only. + * + * @return a normal version string. + */ + public String getVersion() { + if (getDevelopmentStage() == null) { + return String.format("%s.%s.%s", getMajor(), getMinor(), getBuild()); + } else { + return String.format("%s.%s.%s-%s%s", getMajor(), getMinor(), getBuild(), + getDevelopmentStage(), isSnapshot() ? this.snapshot : ""); + } + } + + @Override + public int compareTo(@NotNull MinecraftVersion that) { + return COMPARATOR.compare(this, that); + } + + /** + * Gets if this version was released after another version. + * + * @param other the other version + * @return if this version was released after another version + */ + public boolean isAfter(MinecraftVersion other) { + return compareTo(other) > 0; + } + + /** + * Gets if this version was released after another version, or is equal to it. + * + * @param other the other version + * @return if this version was released after another version, or is equal to it. + */ + public boolean isAfterOrEq(MinecraftVersion other) { + return compareTo(other) >= 0; + } + + /** + * Gets if this version was released before another version. + * + * @param other the other version + * @return if this version was released before another version + */ + public boolean isBefore(MinecraftVersion other) { + return compareTo(other) < 0; + } + + /** + * Gets if this version was released before another version, or is equal to it. + * + * @param other the other version + * @return if this version was released before another version, or is equal to it. + */ + public boolean isBeforeOrEq(MinecraftVersion other) { + return compareTo(other) <= 0; + } + + /** + * Gets if this version was released in the period between two other versions, or is equal + * to either of them. + * + * @param o1 the first other version + * @param o2 the second other version + * @return if this version was released between the others + */ + public boolean isBetween(MinecraftVersion o1, MinecraftVersion o2) { + return (isAfterOrEq(o1) && isBeforeOrEq(o2)) || (isBeforeOrEq(o1) && isAfterOrEq(o2)); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) return false; + if (obj == this) return true; + if (!(obj instanceof MinecraftVersion)) return false; + + MinecraftVersion other = (MinecraftVersion) obj; + return getMajor() == other.getMajor() && + getMinor() == other.getMinor() && + getBuild() == other.getBuild() && + Objects.equals(getDevelopmentStage(), other.getDevelopmentStage()); + } + + @Override + public int hashCode() { + return Objects.hash(getMajor(), getMinor(), getBuild()); + } + + @Override + public String toString() { + // Convert to a String that we can parse back again + return String.format("(MC: %s)", getVersion()); + } +} \ No newline at end of file diff --git a/src/main/java/com/smc/version/MinecraftVersions.java b/src/main/java/com/smc/version/MinecraftVersions.java new file mode 100644 index 00000000..b130a59d --- /dev/null +++ b/src/main/java/com/smc/version/MinecraftVersions.java @@ -0,0 +1,127 @@ +/* + * This file is part of helper, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.smc.version; + +import org.bukkit.Bukkit; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Utility class which holds some common versions of Minecraft. + * + * @author Kristian (ProtocolLib) + */ +@SuppressWarnings("unused") +public final class MinecraftVersions { + + /** + * Version 1.15 - buzzy bees update + */ + public static final MinecraftVersion v1_15 = MinecraftVersion.parse("1.15"); + + /** + * Version 1.14 - village and pillage update + */ + public static final MinecraftVersion v1_14 = MinecraftVersion.parse("1.14"); + + /** + * Version 1.13 - update aquatic. + */ + public static final MinecraftVersion v1_13 = MinecraftVersion.parse("1.13"); + + /** + * Version 1.12 - the world of color update. + */ + public static final MinecraftVersion v1_12 = MinecraftVersion.parse("1.12"); + + /** + * Version 1.11 - the exploration update. + */ + public static final MinecraftVersion v1_11 = MinecraftVersion.parse("1.11"); + + /** + * Version 1.10 - the frostburn update. + */ + public static final MinecraftVersion v1_10 = MinecraftVersion.parse("1.10"); + + /** + * Version 1.9 - the combat update. + */ + public static final MinecraftVersion v1_9 = MinecraftVersion.parse("1.9"); + + /** + * Version 1.8 - the "bountiful" update. + */ + public static final MinecraftVersion v1_8 = MinecraftVersion.parse("1.8"); + + /** + * Version 1.7.8 - the update that changed the skin format (and distribution - R.I.P. player disguise) + */ + public static final MinecraftVersion v1_7_8 = MinecraftVersion.parse("1.7.8"); + + /** + * Version 1.7.2 - the update that changed the world. + */ + public static final MinecraftVersion v1_7_2 = MinecraftVersion.parse("1.7.2"); + + /** + * Version 1.6.1 - the horse update. + */ + public static final MinecraftVersion v1_6_1 = MinecraftVersion.parse("1.6.1"); + + /** + * Version 1.5.0 - the redstone update. + */ + public static final MinecraftVersion v1_5_0 = MinecraftVersion.parse("1.5.0"); + + /** + * Version 1.4.2 - the scary update (Wither Boss). + */ + public static final MinecraftVersion v1_4_2 = MinecraftVersion.parse("1.4.2"); + + /** + * Regular expression used to parse version strings. + */ + private static final Pattern VERSION_PATTERN = Pattern.compile(".*\\(.*MC.\\s*([a-zA-z0-9\\-\\.]+)\\s*\\)"); + + /** + * The version of the runtime + */ + public static final MinecraftVersion RUNTIME_VERSION = parseServerVersion(Bukkit.getVersion()); + + private static MinecraftVersion parseServerVersion(String serverVersion) { + Matcher version = VERSION_PATTERN.matcher(serverVersion); + + if (version.matches() && version.group(1) != null) { + return MinecraftVersion.parse(version.group(1)); + } else { + throw new IllegalStateException("Cannot parse version String '" + serverVersion + "'"); + } + } + + private MinecraftVersions() {} +} \ No newline at end of file diff --git a/src/main/java/com/smc/version/SnapshotVersion.java b/src/main/java/com/smc/version/SnapshotVersion.java new file mode 100644 index 00000000..e52721f6 --- /dev/null +++ b/src/main/java/com/smc/version/SnapshotVersion.java @@ -0,0 +1,161 @@ +/* + * This file is part of helper, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.smc.version; + +import org.jetbrains.annotations.NotNull; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Comparator; +import java.util.Date; +import java.util.Locale; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +/** + * Encapsulates a snapshot version of Minecraft. + * + * @author Kristian (ProtocolLib) + */ +public class SnapshotVersion implements Comparable { + + public static final Comparator COMPARATOR = Comparator.nullsFirst(Comparator + .comparing(SnapshotVersion::getSnapshotDate) + .thenComparing(SnapshotVersion::getSnapshotWeekVersion) + ); + + private static final Pattern SNAPSHOT_PATTERN = Pattern.compile("(\\d{2}w\\d{2})([a-z])"); + + /** + * Parses a snapshot version + * + * @param version the version string + * @return the parsed version + * @throws IllegalArgumentException if the version is not a snapshot version + */ + public static SnapshotVersion parse(String version) throws IllegalArgumentException { + return new SnapshotVersion(version); + } + + private final Date snapshotDate; + private final int snapshotWeekVersion; + + private transient String rawString; + + private SnapshotVersion(String version) { + Matcher matcher = SNAPSHOT_PATTERN.matcher(version.trim()); + + if (matcher.matches()) { + try { + this.snapshotDate = getDateFormat().parse(matcher.group(1)); + this.snapshotWeekVersion = matcher.group(2).charAt(0) - 'a'; + this.rawString = version; + } catch (ParseException e) { + throw new IllegalArgumentException("Date implied by snapshot version is invalid.", e); + } + } else { + throw new IllegalArgumentException("Cannot parse " + version + " as a snapshot version."); + } + } + + /** + * Retrieve the snapshot date parser. + *

+ * We have to create a new instance of SimpleDateFormat every time as it is not thread safe. + * @return The date formatter. + */ + private static SimpleDateFormat getDateFormat() { + SimpleDateFormat format = new SimpleDateFormat("yy'w'ww", Locale.US); + format.setLenient(false); + return format; + } + + /** + * Retrieve the snapshot version within a week, starting at zero. + * + * @return The weekly version + */ + public int getSnapshotWeekVersion() { + return this.snapshotWeekVersion; + } + + /** + * Retrieve the week this snapshot was released. + * + * @return The week. + */ + public Date getSnapshotDate() { + return this.snapshotDate; + } + + /** + * Retrieve the raw snapshot string (yy'w'ww[a-z]). + * + * @return The snapshot string. + */ + public String getSnapshotString() { + if (this.rawString == null) { + // It's essential that we use the same locale + Calendar current = Calendar.getInstance(Locale.US); + current.setTime(this.snapshotDate); + this.rawString = String.format("%02dw%02d%s", + current.get(Calendar.YEAR) % 100, + current.get(Calendar.WEEK_OF_YEAR), + (char) ('a' + this.snapshotWeekVersion)); + } + return this.rawString; + } + + @Override + public int compareTo(@NotNull SnapshotVersion that) { + return COMPARATOR.compare(this, that); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) return false; + if (obj == this) return true; + if (!(obj instanceof SnapshotVersion)) return false; + + + SnapshotVersion other = (SnapshotVersion) obj; + return Objects.equals(this.snapshotDate, other.getSnapshotDate()) && + this.snapshotWeekVersion == other.getSnapshotWeekVersion(); + } + + @Override + public int hashCode() { + return Objects.hash(this.snapshotDate, this.snapshotWeekVersion); + } + + @Override + public String toString() { + return getSnapshotString(); + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/pixlfox/scriptablemc/TypescriptLibraryExporter.kt b/src/main/kotlin/com/pixlfox/scriptablemc/TypescriptLibraryExporter.kt index 6e8df034..637380f4 100644 --- a/src/main/kotlin/com/pixlfox/scriptablemc/TypescriptLibraryExporter.kt +++ b/src/main/kotlin/com/pixlfox/scriptablemc/TypescriptLibraryExporter.kt @@ -13,7 +13,7 @@ import java.lang.reflect.* class TypescriptLibraryExporter { private var basePath: String = "./lib" private val classList = mutableListOf>() - private var allowedPackagesRegex: Regex = Regex("(org\\.bukkit|com\\.pixlfox|fr\\.minuskube\\.inv|com\\.google|java\\.sql)(.*)?") + private var allowedPackagesRegex: Regex = Regex("(org\\.bukkit|com\\.pixlfox|com\\.smc|fr\\.minuskube\\.inv|com\\.google|java\\.sql)(.*)?") private val paranamer: Paranamer = BytecodeReadingParanamer() private fun safeName(name: String): String = when { @@ -87,7 +87,10 @@ class TypescriptLibraryExporter { com.pixlfox.scriptablemc.core.ScriptablePluginContext::class.java, com.pixlfox.scriptablemc.core.ScriptablePluginEngine::class.java, fr.minuskube.inv.SmartInventory::class.java, - com.pixlfox.scriptablemc.utils.FileWrapper::class.java, + com.smc.utils.FileWrapper::class.java, + com.smc.utils.MysqlWrapper::class.java, + com.smc.version.MinecraftVersion::class.java, + com.smc.version.MinecraftVersions::class.java, com.pixlfox.scriptablemc.smartinvs.SmartInventoryProvider::class.java, com.pixlfox.scriptablemc.smartinvs.SmartInventoryInterface::class.java, com.google.common.io.ByteStreams::class.java @@ -232,6 +235,14 @@ class TypescriptLibraryExporter { } } + val blacklistRegex = Regex("(spigot|wait|equals|toString|hashCode|getClass|notify|notifyAll|Companion)") + for (_field in _class.fields.filter { Modifier.isStatic(it.modifiers) &&Modifier.isPublic(it.modifiers) && !it.name.matches(blacklistRegex) }) { + val type = fixClass(_field.type) + if (!classList.contains(type) && type.name.matches(allowedPackagesRegex)) { + classList.add(type) + } + } + return classList.toTypedArray() } @@ -316,6 +327,12 @@ class TypescriptLibraryExporter { return this } + fun copyStaticSources(): TypescriptLibraryExporter { + File("./src/main/ts/").copyRecursively(File("$basePath/ts/"), true) + + return this + } + fun exportProjectFiles(): TypescriptLibraryExporter { File("$basePath/tsconfig.json").writeText("{\n" + " \"compilerOptions\": {\n" + @@ -394,7 +411,7 @@ class TypescriptLibraryExporter { for (_class in classList) { if(_class.name.matches(allowedPackagesRegex) && !_class.name.endsWith("\$Spigot")) { - tsGlobalExportsSource += generateTypescriptImportForClass(_class); + tsGlobalExportsSource += generateTypescriptImportForClass(_class) } } @@ -628,6 +645,7 @@ class TypescriptLibraryExporter { .clean() .exportLibraries() .exportGlobalLibrary() + .copyStaticSources() .exportProjectFiles() } } diff --git a/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginContext.kt b/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginContext.kt index 80911f74..584719b2 100644 --- a/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginContext.kt +++ b/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginContext.kt @@ -2,11 +2,10 @@ package com.pixlfox.scriptablemc.core import com.pixlfox.scriptablemc.smartinvs.SmartInventoryInterface import com.pixlfox.scriptablemc.smartinvs.SmartItemBuilder -import com.pixlfox.scriptablemc.utils.FileWrapper -import com.pixlfox.scriptablemc.utils.MysqlWrapper +import com.smc.utils.FileWrapper +import com.smc.utils.MysqlWrapper import me.clip.placeholderapi.PlaceholderAPI import org.bukkit.Bukkit -import org.bukkit.Material import org.bukkit.OfflinePlayer import org.bukkit.Server import org.bukkit.command.CommandMap diff --git a/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginEngine.kt b/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginEngine.kt index 4a1bcfde..125db749 100644 --- a/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginEngine.kt +++ b/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginEngine.kt @@ -10,6 +10,13 @@ import java.io.File import org.bukkit.plugin.java.JavaPlugin import java.util.* +private val helperClasses: Array = arrayOf( + "com.smc.version.MinecraftVersion", + "com.smc.version.MinecraftVersions", + "com.smc.version.SnapshotVersion", + "com.smc.utils.FileWrapper", + "com.smc.utils.MysqlWrapper" +) @Suppress("MemberVisibilityCanBePrivate", "unused") class ScriptablePluginEngine(val bootstrapPlugin: JavaPlugin, val rootScriptsFolder: String = "./scripts", val debugEnabled: Boolean = false, val extractLibs: Boolean = true): Listener { @@ -32,6 +39,16 @@ class ScriptablePluginEngine(val bootstrapPlugin: JavaPlugin, val rootScriptsFol inventoryManager.init() jsBindings.putMember("engine", this) + for(helperClass in helperClasses) { + try { + javaClass.classLoader.loadClass(helperClass) + } + catch (e: Exception) { + bootstrapPlugin.logger.warning("Failed to load helper class \"$helperClass\" via classloader.") + e.printStackTrace() + } + } + val mainScriptFile = File("${rootScriptsFolder}/main.js") if(!mainScriptFile.parentFile.exists()) { mainScriptFile.parentFile.mkdirs() @@ -55,7 +72,7 @@ class ScriptablePluginEngine(val bootstrapPlugin: JavaPlugin, val rootScriptsFol // Load all plugin types returned as an array if(pluginTypes.hasArrayElements()) { - for (i in 0..pluginTypes.arraySize) { + for (i in 0 until pluginTypes.arraySize) { this.loadPlugin(pluginTypes.getArrayElement(i)) } } diff --git a/src/main/kotlin/com/pixlfox/scriptablemc/utils/FileWrapper.kt b/src/main/kotlin/com/smc/utils/FileWrapper.kt similarity index 88% rename from src/main/kotlin/com/pixlfox/scriptablemc/utils/FileWrapper.kt rename to src/main/kotlin/com/smc/utils/FileWrapper.kt index 602bb342..d392f82d 100644 --- a/src/main/kotlin/com/pixlfox/scriptablemc/utils/FileWrapper.kt +++ b/src/main/kotlin/com/smc/utils/FileWrapper.kt @@ -1,4 +1,4 @@ -package com.pixlfox.scriptablemc.utils +package com.smc.utils @Suppress("unused") @@ -15,7 +15,8 @@ class FileWrapper(pathName: String) { fun mkdir(): Boolean = javaFile.mkdir() fun mkdirs(): Boolean = javaFile.mkdirs() fun isDirectory(): Boolean = javaFile.isDirectory - fun parentFile(): FileWrapper = new(javaFile.parentFile) + fun parentFile(): FileWrapper = + new(javaFile.parentFile) companion object { internal fun new(javaFile: java.io.File): FileWrapper { diff --git a/src/main/kotlin/com/pixlfox/scriptablemc/utils/MysqlWrapper.kt b/src/main/kotlin/com/smc/utils/MysqlWrapper.kt similarity index 98% rename from src/main/kotlin/com/pixlfox/scriptablemc/utils/MysqlWrapper.kt rename to src/main/kotlin/com/smc/utils/MysqlWrapper.kt index e002792f..8c91d77b 100644 --- a/src/main/kotlin/com/pixlfox/scriptablemc/utils/MysqlWrapper.kt +++ b/src/main/kotlin/com/smc/utils/MysqlWrapper.kt @@ -1,4 +1,4 @@ -package com.pixlfox.scriptablemc.utils +package com.smc.utils import com.pixlfox.scriptablemc.ScriptablePluginMain import org.bukkit.Bukkit diff --git a/src/main/ts/JsPlugin.ts b/src/main/ts/JsPlugin.ts new file mode 100644 index 00000000..f2691ab3 --- /dev/null +++ b/src/main/ts/JsPlugin.ts @@ -0,0 +1,77 @@ +import Event from "./org/bukkit/event/Event.js"; +import Server from "./org/bukkit/Server.js"; +import ScriptablePluginContext from "./com/pixlfox/scriptablemc/core/ScriptablePluginContext.js"; +import ScriptablePluginEngine from "./com/pixlfox/scriptablemc/core/ScriptablePluginEngine.js"; +import PluginCommand from "./org/bukkit/command/PluginCommand.js"; +import Player from "./org/bukkit/entity/Player.js"; +import PluginMessageListenerRegistration from "./org/bukkit/plugin/messaging/PluginMessageListenerRegistration.js"; +import OfflinePlayer from "./org/bukkit/OfflinePlayer.js"; +import FileWrapper from "./com/smc/utils/FileWrapper.js"; +import MysqlWrapper from "./com/smc/utils/MysqlWrapper.js"; + +declare const engine: ScriptablePluginEngine; +declare type Type = { new (...args: any[]): T; }; + +export default class JsPlugin { + public context: ScriptablePluginContext; + + get pluginName(): string { + return this.constructor.name; + } + + get server(): Server { + return this.context.getServer(); + } + + registerEvent(eventClass: Type, callback: (listener: any, event: T) => void) { + this.context.registerEvent(eventClass['$javaClass'], callback.bind(this)); + } + + newCommand(name: string): PluginCommand { + return this.context.newCommand(name); + } + + unregisterCommand(command: PluginCommand) { + this.context.unregisterCommand(command); + } + + registerCommand(command: PluginCommand) { + this.context.registerCommand(command); + } + + registerIncomingPluginChannel(channel: string, callback: (channel: string, player: Player, message: number[]) => void): PluginMessageListenerRegistration { + return this.context.registerIncomingPluginChannel(channel, callback.bind(this)); + } + + unregisterIncomingPluginChannel(channel: string) { + this.context.unregisterIncomingPluginChannel(channel); + } + + registerOutgoingPluginChannel(channel: string) { + this.context.registerOutgoingPluginChannel(channel); + } + + unregisterOutgoingPluginChannel(channel: string) { + this.context.unregisterOutgoingPluginChannel(channel); + } + + getFile(pathName: string): FileWrapper { + return this.context.getFile(pathName); + } + + newMysqlInstance(host: string, port: number, database: string, username: string, password: string): MysqlWrapper { + return this.context.newMysqlInstance(host, port, database, username, password); + } + + mysqlFromConfig(configObject: { host: string, port: number, database: string, username: string, password: string }): MysqlWrapper { + return this.newMysqlInstance(configObject.host, configObject.port, configObject.database, configObject.username, configObject.password); + } + + setPlaceholders(player: (Player | OfflinePlayer), placeholderText: string): string { + return this.context.setPlaceholders(player, placeholderText); + } + + onLoad(): void { console.log("[" + this.pluginName + "] onLoad()"); } + onEnable(): void { console.log("[" + this.pluginName + "] onEnable()"); } + onDisable(): void { console.log("[" + this.pluginName + "] onDisable()"); } +} \ No newline at end of file From 43089028027bceedb6dc91a7eff799f47fec0275 Mon Sep 17 00:00:00 2001 From: Ashton Storks Date: Mon, 10 Feb 2020 19:40:32 -0700 Subject: [PATCH 3/4] Fixed typescript package.json --- .../scriptablemc/TypescriptLibraryExporter.kt | 8 ++++---- .../scriptablemc/core/ScriptablePluginEngine.kt | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/kotlin/com/pixlfox/scriptablemc/TypescriptLibraryExporter.kt b/src/main/kotlin/com/pixlfox/scriptablemc/TypescriptLibraryExporter.kt index 637380f4..1d17f6ce 100644 --- a/src/main/kotlin/com/pixlfox/scriptablemc/TypescriptLibraryExporter.kt +++ b/src/main/kotlin/com/pixlfox/scriptablemc/TypescriptLibraryExporter.kt @@ -13,7 +13,7 @@ import java.lang.reflect.* class TypescriptLibraryExporter { private var basePath: String = "./lib" private val classList = mutableListOf>() - private var allowedPackagesRegex: Regex = Regex("(org\\.bukkit|com\\.pixlfox|com\\.smc|fr\\.minuskube\\.inv|com\\.google|java\\.sql)(.*)?") + private var allowedPackagesRegex: Regex = Regex("(org\\.bukkit|com\\.pixlfox|com\\.smc|fr\\.minuskube\\.inv|com\\.google|java\\.sql|java\\.io)(.*)?") private val paranamer: Paranamer = BytecodeReadingParanamer() private fun safeName(name: String): String = when { @@ -93,7 +93,8 @@ class TypescriptLibraryExporter { com.smc.version.MinecraftVersions::class.java, com.pixlfox.scriptablemc.smartinvs.SmartInventoryProvider::class.java, com.pixlfox.scriptablemc.smartinvs.SmartInventoryInterface::class.java, - com.google.common.io.ByteStreams::class.java + com.google.common.io.ByteStreams::class.java, + java.io.File::class.java ) return this } @@ -342,8 +343,7 @@ class TypescriptLibraryExporter { " \"allowJs\": true,\n" + " \"outDir\": \"js\",\n" + " \"rootDir\": \"ts\",\n" + - " \"declaration\": true,\n" + - " \"lib\": [\"ES5\", \"ES2015\", \"ES2016\", \"ES2017\", \"ES2018\", \"ES2019\"]\n" + + " \"declaration\": true\n" + " },\n" + " \"include\": [\n" + " \"ts/**/*\"\n" + diff --git a/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginEngine.kt b/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginEngine.kt index 125db749..3ac670f0 100644 --- a/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginEngine.kt +++ b/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginEngine.kt @@ -62,7 +62,7 @@ class ScriptablePluginEngine(val bootstrapPlugin: JavaPlugin, val rootScriptsFol } if(mainScriptFile.exists()) { - val pluginTypes = eval( + val mainReturn = eval( Source.newBuilder("js", mainScriptFile) .name("main.js") .mimeType("application/javascript+module") @@ -71,15 +71,15 @@ class ScriptablePluginEngine(val bootstrapPlugin: JavaPlugin, val rootScriptsFol ) // Load all plugin types returned as an array - if(pluginTypes.hasArrayElements()) { - for (i in 0 until pluginTypes.arraySize) { - this.loadPlugin(pluginTypes.getArrayElement(i)) + if(mainReturn.hasArrayElements()) { + for (i in 0 until mainReturn.arraySize) { + this.loadPlugin(mainReturn.getArrayElement(i)) } - } - // Enable all plugins if not already enabled - if(!enabledAllPlugins) { - enableAllPlugins() + // Enable all plugins if not already enabled + if(!enabledAllPlugins) { + enableAllPlugins() + } } } else { From 1b811c280f8d73d07de6e07b5bf16f0cb1bdb541 Mon Sep 17 00:00:00 2001 From: Ashton Storks Date: Mon, 10 Feb 2020 21:42:04 -0700 Subject: [PATCH 4/4] Moved smart inventory to com.smc.smartinvs namespace. Removed a few methods from ScriptablePluginContext and general cleanup of unused methods now that the class loader is fixed. --- .../scriptablemc/TypescriptLibraryExporter.kt | 15 ++- .../core/ScriptablePluginContext.kt | 21 --- .../core/ScriptablePluginEngine.kt | 19 ++- .../smartinvs/ScriptablePluginMenu.kt | 7 +- .../smartinvs/SmartInventoryInterface.kt | 122 ------------------ .../com/smc/smartinvs/SmartInventory.kt | 53 ++++++++ src/main/kotlin/com/smc/utils/FileWrapper.kt | 26 ---- src/main/kotlin/com/smc/utils/ItemBuilder.kt | 73 +++++++++++ src/main/ts/JsPlugin.ts | 10 +- 9 files changed, 158 insertions(+), 188 deletions(-) delete mode 100644 src/main/kotlin/com/pixlfox/scriptablemc/smartinvs/SmartInventoryInterface.kt create mode 100644 src/main/kotlin/com/smc/smartinvs/SmartInventory.kt delete mode 100644 src/main/kotlin/com/smc/utils/FileWrapper.kt create mode 100644 src/main/kotlin/com/smc/utils/ItemBuilder.kt diff --git a/src/main/kotlin/com/pixlfox/scriptablemc/TypescriptLibraryExporter.kt b/src/main/kotlin/com/pixlfox/scriptablemc/TypescriptLibraryExporter.kt index 1d17f6ce..5df465bd 100644 --- a/src/main/kotlin/com/pixlfox/scriptablemc/TypescriptLibraryExporter.kt +++ b/src/main/kotlin/com/pixlfox/scriptablemc/TypescriptLibraryExporter.kt @@ -86,14 +86,19 @@ class TypescriptLibraryExporter { addClasses( com.pixlfox.scriptablemc.core.ScriptablePluginContext::class.java, com.pixlfox.scriptablemc.core.ScriptablePluginEngine::class.java, - fr.minuskube.inv.SmartInventory::class.java, - com.smc.utils.FileWrapper::class.java, + + com.smc.utils.ItemBuilder::class.java, com.smc.utils.MysqlWrapper::class.java, + com.smc.version.MinecraftVersion::class.java, com.smc.version.MinecraftVersions::class.java, - com.pixlfox.scriptablemc.smartinvs.SmartInventoryProvider::class.java, - com.pixlfox.scriptablemc.smartinvs.SmartInventoryInterface::class.java, + + fr.minuskube.inv.SmartInventory::class.java, + com.smc.smartinvs.SmartInventoryProvider::class.java, + com.smc.smartinvs.SmartInventory::class.java, + com.google.common.io.ByteStreams::class.java, + java.io.File::class.java ) return this @@ -492,7 +497,7 @@ class TypescriptLibraryExporter { } } - for (_methodGroups in _class.methods.filter { e -> Modifier.isStatic(e.modifiers) && Modifier.isPublic(e.modifiers) }.groupBy { e -> e.name }) { + for (_methodGroups in _class.methods.filter { e -> Modifier.isStatic(e.modifiers) && !Modifier.isPrivate(e.modifiers) }.groupBy { e -> e.name }) { val jsMethodName: String = _methodGroups.key diff --git a/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginContext.kt b/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginContext.kt index 584719b2..12504fd9 100644 --- a/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginContext.kt +++ b/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginContext.kt @@ -1,9 +1,5 @@ package com.pixlfox.scriptablemc.core -import com.pixlfox.scriptablemc.smartinvs.SmartInventoryInterface -import com.pixlfox.scriptablemc.smartinvs.SmartItemBuilder -import com.smc.utils.FileWrapper -import com.smc.utils.MysqlWrapper import me.clip.placeholderapi.PlaceholderAPI import org.bukkit.Bukkit import org.bukkit.OfflinePlayer @@ -17,7 +13,6 @@ import java.util.HashMap import java.lang.reflect.InvocationTargetException import org.bukkit.command.PluginCommand import org.bukkit.entity.Player -import org.bukkit.inventory.ItemStack import org.bukkit.plugin.* import org.bukkit.plugin.java.JavaPlugin import org.bukkit.plugin.messaging.PluginMessageListener @@ -146,22 +141,6 @@ class ScriptablePluginContext(private val engine: ScriptablePluginEngine, val pl knownCommandsField?.isAccessible = false } - fun getFile(pathName: String): FileWrapper { - return FileWrapper(pathName) - } - - fun newMysqlInstance(host: String, port: Int, database: String, username: String, password: String): MysqlWrapper { - return MysqlWrapper(host, port, database, username, password) - } - - fun smartInventory(): SmartInventoryInterface { - return SmartInventoryInterface() - } - - fun itemBuilder(itemStack: ItemStack): SmartItemBuilder { - return SmartItemBuilder(itemStack) - } - fun setPlaceholders(player: Player, placeholderText: String): String { if(Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { return PlaceholderAPI.setPlaceholders(player, placeholderText) diff --git a/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginEngine.kt b/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginEngine.kt index 3ac670f0..468b74b4 100644 --- a/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginEngine.kt +++ b/src/main/kotlin/com/pixlfox/scriptablemc/core/ScriptablePluginEngine.kt @@ -14,8 +14,15 @@ private val helperClasses: Array = arrayOf( "com.smc.version.MinecraftVersion", "com.smc.version.MinecraftVersions", "com.smc.version.SnapshotVersion", - "com.smc.utils.FileWrapper", - "com.smc.utils.MysqlWrapper" + + "com.smc.utils.ItemBuilder", + "com.smc.utils.MysqlWrapper", + + "com.smc.smartinvs.SmartInventory", + "com.smc.smartinvs.SmartInventoryProvider", + + "*me.clip.placeholderapi.PlaceholderAPI" + ) @Suppress("MemberVisibilityCanBePrivate", "unused") @@ -41,11 +48,13 @@ class ScriptablePluginEngine(val bootstrapPlugin: JavaPlugin, val rootScriptsFol for(helperClass in helperClasses) { try { - javaClass.classLoader.loadClass(helperClass) + javaClass.classLoader.loadClass(helperClass.replace("*", "")) } catch (e: Exception) { - bootstrapPlugin.logger.warning("Failed to load helper class \"$helperClass\" via classloader.") - e.printStackTrace() + if(!helperClass.startsWith("*")) { + bootstrapPlugin.logger.warning("Failed to load helper class \"$helperClass\" via classloader.") + e.printStackTrace() + } } } diff --git a/src/main/kotlin/com/pixlfox/scriptablemc/smartinvs/ScriptablePluginMenu.kt b/src/main/kotlin/com/pixlfox/scriptablemc/smartinvs/ScriptablePluginMenu.kt index d57424d1..394aaf95 100644 --- a/src/main/kotlin/com/pixlfox/scriptablemc/smartinvs/ScriptablePluginMenu.kt +++ b/src/main/kotlin/com/pixlfox/scriptablemc/smartinvs/ScriptablePluginMenu.kt @@ -1,6 +1,7 @@ package com.pixlfox.scriptablemc.smartinvs import com.pixlfox.scriptablemc.core.ScriptablePluginEngine +import com.smc.utils.ItemBuilder import fr.minuskube.inv.content.InventoryContents import fr.minuskube.inv.content.InventoryProvider import org.bukkit.entity.Player @@ -19,7 +20,7 @@ class MainMenu(private val pluginEngine: ScriptablePluginEngine) : InventoryProv override fun init(player: Player?, contents: InventoryContents?) { if(contents != null && player != null) { if(player.hasPermission("scriptablemc.reload")) { - contents.set(0, 0, ClickableItem.of(SmartItemBuilder(Material.GOLD_NUGGET) + contents.set(0, 0, ClickableItem.of(ItemBuilder(Material.GOLD_NUGGET) .setDisplayName("${ChatColor.DARK_AQUA}Reload Script Engine") .build()) { Bukkit.getServer().dispatchCommand(player, "scriptablemc reload") @@ -27,7 +28,7 @@ class MainMenu(private val pluginEngine: ScriptablePluginEngine) : InventoryProv } if(player.hasPermission("scriptablemc.info")) { - contents.set(0, 1, ClickableItem.of(SmartItemBuilder(Material.IRON_NUGGET) + contents.set(0, 1, ClickableItem.of(ItemBuilder(Material.IRON_NUGGET) .setDisplayName("${ChatColor.GREEN}Print ScriptableMC Info") .build()) { Bukkit.getServer().dispatchCommand(player, "scriptablemc info") @@ -35,7 +36,7 @@ class MainMenu(private val pluginEngine: ScriptablePluginEngine) : InventoryProv }) } - contents.set(0, 8, ClickableItem.of(SmartItemBuilder(Material.BARRIER) + contents.set(0, 8, ClickableItem.of(ItemBuilder(Material.BARRIER) .setDisplayName("${ChatColor.RED}Close Menu") .build()) { player.closeInventory() diff --git a/src/main/kotlin/com/pixlfox/scriptablemc/smartinvs/SmartInventoryInterface.kt b/src/main/kotlin/com/pixlfox/scriptablemc/smartinvs/SmartInventoryInterface.kt deleted file mode 100644 index cae5743c..00000000 --- a/src/main/kotlin/com/pixlfox/scriptablemc/smartinvs/SmartInventoryInterface.kt +++ /dev/null @@ -1,122 +0,0 @@ -package com.pixlfox.scriptablemc.smartinvs - -import com.pixlfox.scriptablemc.core.ScriptablePluginEngine -import fr.minuskube.inv.ClickableItem -import fr.minuskube.inv.SmartInventory -import fr.minuskube.inv.content.InventoryContents -import fr.minuskube.inv.content.InventoryProvider -import org.bukkit.Material -import org.bukkit.enchantments.Enchantment -import org.bukkit.entity.Player -import org.bukkit.event.inventory.InventoryClickEvent -import org.bukkit.inventory.ItemStack -import org.graalvm.polyglot.Value -import java.util.function.Consumer - -@Suppress("unused", "MemberVisibilityCanBePrivate") -class SmartInventoryInterface { - fun builder(): SmartInventory.Builder { - return SmartInventory.builder().manager(ScriptablePluginEngine.instance!!.inventoryManager) - } - - fun provider(scriptableObject: Value): SmartInventoryProvider { - if(scriptableObject.canInstantiate()) { - return provider(scriptableObject.newInstance()) - } - - return SmartInventoryProvider(scriptableObject) - } - - fun clickableItem(item: ItemStack): ClickableItem { - return ClickableItem.empty(item) - } - - fun clickableItem(item: ItemStack, consumer: Consumer): ClickableItem { - return ClickableItem.of(item, consumer) - } - - fun itemBuilder(itemStack: ItemStack): SmartItemBuilder { - return SmartItemBuilder(itemStack) - } -} - -class SmartItemBuilder(private val itemStack: ItemStack) { - - constructor(material: Material): this(ItemStack(material)) - - fun setDisplayName(displayName: String): SmartItemBuilder { - val itemMeta = itemStack.itemMeta - itemMeta?.setDisplayName(displayName) - itemStack.itemMeta = itemMeta - - return this - } - - fun getDisplayName(): String { - val itemMeta = itemStack.itemMeta - if(itemMeta != null) { - return itemMeta.displayName - } - - return "" - } - - fun setLore(lore: Array): SmartItemBuilder { - val itemMeta = itemStack.itemMeta - itemMeta?.lore = lore.toList() - itemStack.itemMeta = itemMeta - - return this - } - - fun getLore(): Array { - val itemMeta = itemStack.itemMeta - if(itemMeta != null && itemMeta.lore != null) { - return itemMeta.lore!!.toTypedArray() - } - - return arrayOf() - } - - fun isUnbreakable(isUnbreakable: Boolean): SmartItemBuilder { - val itemMeta = itemStack.itemMeta - itemMeta?.isUnbreakable = isUnbreakable - itemStack.itemMeta = itemMeta - - return this - } - - fun addEnchant(enchantment: Enchantment, level: Int, ignoreLevelRestriction: Boolean): SmartItemBuilder { - val itemMeta = itemStack.itemMeta - itemMeta?.addEnchant(enchantment, level, ignoreLevelRestriction) - itemStack.itemMeta = itemMeta - - return this - } - - fun removeEnchantment(enchantment: Enchantment): SmartItemBuilder { - val itemMeta = itemStack.itemMeta - itemMeta?.removeEnchant(enchantment) - itemStack.itemMeta = itemMeta - - return this - } - - fun build(): ItemStack { - return itemStack - } -} - -class SmartInventoryProvider(private val scriptableObject: Value) : InventoryProvider { - override fun init(player: Player, contents: InventoryContents) { - if(scriptableObject.hasMember("init") && scriptableObject.canInvokeMember("init")) { - scriptableObject.invokeMember("init", player, contents) - } - } - - override fun update(player: Player, contents: InventoryContents) { - if(scriptableObject.hasMember("update") && scriptableObject.canInvokeMember("update")) { - scriptableObject.invokeMember("update", player, contents) - } - } -} diff --git a/src/main/kotlin/com/smc/smartinvs/SmartInventory.kt b/src/main/kotlin/com/smc/smartinvs/SmartInventory.kt new file mode 100644 index 00000000..3e3957be --- /dev/null +++ b/src/main/kotlin/com/smc/smartinvs/SmartInventory.kt @@ -0,0 +1,53 @@ +package com.smc.smartinvs + +import com.pixlfox.scriptablemc.core.ScriptablePluginEngine +import fr.minuskube.inv.ClickableItem +import fr.minuskube.inv.SmartInventory +import fr.minuskube.inv.content.InventoryContents +import fr.minuskube.inv.content.InventoryProvider +import org.bukkit.entity.Player +import org.bukkit.event.inventory.InventoryClickEvent +import org.bukkit.inventory.ItemStack +import org.graalvm.polyglot.Value +import java.util.function.Consumer + +@Suppress("unused", "MemberVisibilityCanBePrivate") +object SmartInventory { + @JvmStatic + fun builder(): SmartInventory.Builder { + return SmartInventory.builder().manager(ScriptablePluginEngine.instance!!.inventoryManager) + } + + @JvmStatic + fun provider(scriptableObject: Value): SmartInventoryProvider { + if (scriptableObject.canInstantiate()) { + return provider(scriptableObject.newInstance()) + } + + return SmartInventoryProvider(scriptableObject) + } + + @JvmStatic + fun clickableItem(item: ItemStack): ClickableItem { + return ClickableItem.empty(item) + } + + @JvmStatic + fun clickableItem(item: ItemStack, consumer: Consumer): ClickableItem { + return ClickableItem.of(item, consumer) + } +} + +class SmartInventoryProvider(private val scriptableObject: Value) : InventoryProvider { + override fun init(player: Player, contents: InventoryContents) { + if(scriptableObject.hasMember("init") && scriptableObject.canInvokeMember("init")) { + scriptableObject.invokeMember("init", player, contents) + } + } + + override fun update(player: Player, contents: InventoryContents) { + if(scriptableObject.hasMember("update") && scriptableObject.canInvokeMember("update")) { + scriptableObject.invokeMember("update", player, contents) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/smc/utils/FileWrapper.kt b/src/main/kotlin/com/smc/utils/FileWrapper.kt deleted file mode 100644 index d392f82d..00000000 --- a/src/main/kotlin/com/smc/utils/FileWrapper.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.smc.utils - - -@Suppress("unused") -class FileWrapper(pathName: String) { - - private val javaFile: java.io.File = java.io.File(pathName) - - fun readText(): String = javaFile.readText() - fun readLines(): Array = javaFile.readLines().toTypedArray() - fun writeText(text: String): Unit = javaFile.writeText(text) - fun exists(): Boolean = javaFile.exists() - fun createNewFile(): Boolean = javaFile.createNewFile() - fun isFile(): Boolean = javaFile.isFile - fun mkdir(): Boolean = javaFile.mkdir() - fun mkdirs(): Boolean = javaFile.mkdirs() - fun isDirectory(): Boolean = javaFile.isDirectory - fun parentFile(): FileWrapper = - new(javaFile.parentFile) - - companion object { - internal fun new(javaFile: java.io.File): FileWrapper { - return FileWrapper(javaFile.path) - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/smc/utils/ItemBuilder.kt b/src/main/kotlin/com/smc/utils/ItemBuilder.kt new file mode 100644 index 00000000..1bc8c62d --- /dev/null +++ b/src/main/kotlin/com/smc/utils/ItemBuilder.kt @@ -0,0 +1,73 @@ +package com.smc.utils + +import org.bukkit.Material +import org.bukkit.enchantments.Enchantment +import org.bukkit.inventory.ItemStack + +@Suppress("unused") +class ItemBuilder(private val itemStack: ItemStack) { + + constructor(material: Material): this(ItemStack(material)) + + fun setDisplayName(displayName: String): ItemBuilder { + val itemMeta = itemStack.itemMeta + itemMeta?.setDisplayName(displayName) + itemStack.itemMeta = itemMeta + + return this + } + + fun getDisplayName(): String { + val itemMeta = itemStack.itemMeta + if(itemMeta != null) { + return itemMeta.displayName + } + + return "" + } + + fun setLore(lore: Array): ItemBuilder { + val itemMeta = itemStack.itemMeta + itemMeta?.lore = lore.toList() + itemStack.itemMeta = itemMeta + + return this + } + + fun getLore(): Array { + val itemMeta = itemStack.itemMeta + if(itemMeta != null && itemMeta.lore != null) { + return itemMeta.lore!!.toTypedArray() + } + + return arrayOf() + } + + fun isUnbreakable(isUnbreakable: Boolean): ItemBuilder { + val itemMeta = itemStack.itemMeta + itemMeta?.isUnbreakable = isUnbreakable + itemStack.itemMeta = itemMeta + + return this + } + + fun addEnchant(enchantment: Enchantment, level: Int, ignoreLevelRestriction: Boolean): ItemBuilder { + val itemMeta = itemStack.itemMeta + itemMeta?.addEnchant(enchantment, level, ignoreLevelRestriction) + itemStack.itemMeta = itemMeta + + return this + } + + fun removeEnchantment(enchantment: Enchantment): ItemBuilder { + val itemMeta = itemStack.itemMeta + itemMeta?.removeEnchant(enchantment) + itemStack.itemMeta = itemMeta + + return this + } + + fun build(): ItemStack { + return itemStack + } +} \ No newline at end of file diff --git a/src/main/ts/JsPlugin.ts b/src/main/ts/JsPlugin.ts index f2691ab3..604108f5 100644 --- a/src/main/ts/JsPlugin.ts +++ b/src/main/ts/JsPlugin.ts @@ -1,15 +1,13 @@ import Event from "./org/bukkit/event/Event.js"; import Server from "./org/bukkit/Server.js"; import ScriptablePluginContext from "./com/pixlfox/scriptablemc/core/ScriptablePluginContext.js"; -import ScriptablePluginEngine from "./com/pixlfox/scriptablemc/core/ScriptablePluginEngine.js"; import PluginCommand from "./org/bukkit/command/PluginCommand.js"; import Player from "./org/bukkit/entity/Player.js"; import PluginMessageListenerRegistration from "./org/bukkit/plugin/messaging/PluginMessageListenerRegistration.js"; import OfflinePlayer from "./org/bukkit/OfflinePlayer.js"; -import FileWrapper from "./com/smc/utils/FileWrapper.js"; import MysqlWrapper from "./com/smc/utils/MysqlWrapper.js"; +import File from "./java/io/File.js"; -declare const engine: ScriptablePluginEngine; declare type Type = { new (...args: any[]): T; }; export default class JsPlugin { @@ -55,12 +53,12 @@ export default class JsPlugin { this.context.unregisterOutgoingPluginChannel(channel); } - getFile(pathName: string): FileWrapper { - return this.context.getFile(pathName); + getFile(pathName: string): File { + return new File(pathName); } newMysqlInstance(host: string, port: number, database: string, username: string, password: string): MysqlWrapper { - return this.context.newMysqlInstance(host, port, database, username, password); + return new MysqlWrapper(host, port, database, username, password); } mysqlFromConfig(configObject: { host: string, port: number, database: string, username: string, password: string }): MysqlWrapper {