├── docs ├── advanced │ ├── README.md │ ├── reflection │ │ ├── README.md │ │ ├── sections.md │ │ └── proxies.md │ ├── loading-external-libraries.md │ ├── error-handling.md │ ├── computed-options.md │ ├── experiments.md │ └── custom-syntax │ │ ├── effects.md │ │ ├── README.md │ │ ├── conditions.md │ │ └── events.md ├── basics │ ├── README.md │ ├── reading-javadocs.md │ ├── running-java-code.md │ └── handling-events.md ├── .gitbook │ └── assets │ │ ├── screen-shot-2018-08-20-at-7.57.53-pm.png │ │ ├── screen-shot-2018-08-20-at-7.58.41-pm.png │ │ └── screen-shot-2018-08-20-at-8.07.22-pm.png ├── getting-started.md ├── SUMMARY.md ├── frequently-asked-questions.md └── code-conventions.md ├── settings.gradle ├── .gitbook.yaml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── src ├── test │ └── scripts │ │ ├── reflect │ │ ├── ExprJavaCall.sk │ │ ├── StructImport.sk │ │ └── EffImport.sk │ │ └── custom │ │ ├── custom constants.sk │ │ ├── custom effects.sk │ │ ├── custom condition.sk │ │ ├── custom expressions.sk │ │ └── custom events.sk └── main │ ├── resources │ ├── lang │ │ └── english.lang │ └── plugin.yml │ └── java │ ├── com │ └── btk5h │ │ └── skriptmirror │ │ ├── skript │ │ ├── custom │ │ │ ├── Continuable.java │ │ │ ├── CustomSyntaxEvent.java │ │ │ ├── ExprEventClasses.java │ │ │ ├── CustomSyntaxExpression.java │ │ │ ├── ExprParseMark.java │ │ │ ├── ExprParseTags.java │ │ │ ├── ExprMatchedPattern.java │ │ │ ├── EffContinue.java │ │ │ ├── SyntaxParseEvent.java │ │ │ ├── ExprParseRegex.java │ │ │ └── ExprRawExpression.java │ │ ├── reflect │ │ │ ├── sections │ │ │ │ ├── SectionEvent.java │ │ │ │ ├── Section.java │ │ │ │ └── SecSection.java │ │ │ ├── ExprJavaError.java │ │ │ ├── ExprEvent.java │ │ │ ├── ExprJavaTypeOf.java │ │ │ ├── ExprJavaType.java │ │ │ ├── ExprClassReference.java │ │ │ ├── ExprMemberNames.java │ │ │ ├── ExprMembers.java │ │ │ └── ExprNewArray.java │ │ ├── LitNullObject.java │ │ ├── CondIsInstanceOf.java │ │ ├── ExprFunction.java │ │ ├── EffExpressionStatement.java │ │ ├── ExprPlugin.java │ │ ├── CondExpressionStatement.java │ │ ├── ExprCollect.java │ │ └── ExprBits.java │ │ ├── Null.java │ │ ├── JavaCallException.java │ │ ├── util │ │ ├── lookup │ │ │ └── LookupGetter.java │ │ ├── LRUCache.java │ │ ├── JavaTypeWrapper.java │ │ ├── SkriptMirrorUtil.java │ │ └── StringSimilarity.java │ │ ├── ImportNotFoundException.java │ │ ├── WrappedEvent.java │ │ ├── JavaType.java │ │ ├── FunctionWrapper.java │ │ ├── LibraryLoader.java │ │ ├── ObjectWrapper.java │ │ └── ParseOrderWorkarounds.java │ └── org │ └── skriptlang │ └── reflect │ └── syntax │ ├── expression │ ├── ConstantGetEvent.java │ ├── ExpressionChangeEvent.java │ ├── ExpressionGetEvent.java │ ├── ConstantSyntaxInfo.java │ ├── ChangerEntryData.java │ ├── elements │ │ ├── StructCustomConstant.java │ │ ├── EffReturn.java │ │ └── ExprChangeValue.java │ └── ExpressionSyntaxInfo.java │ ├── event │ ├── elements │ │ ├── CondEventCancelled.java │ │ ├── EffCallEvent.java │ │ ├── CustomEventUtils.java │ │ ├── ExprEventData.java │ │ ├── ExprReplacedEventValue.java │ │ ├── ExprCustomEvent.java │ │ ├── ExprCustomEventValue.java │ │ └── CustomEvent.java │ ├── EventTriggerEvent.java │ ├── EventSyntaxInfo.java │ ├── EventValuesEntryData.java │ └── BukkitCustomEvent.java │ ├── effect │ ├── EffectSyntaxInfo.java │ ├── elements │ │ ├── EffDelayEffect.java │ │ └── CustomEffect.java │ └── EffectTriggerEvent.java │ ├── PatternsEntryData.java │ └── condition │ ├── elements │ ├── EffNegateCondition.java │ └── CustomCondition.java │ ├── ConditionCheckEvent.java │ └── ConditionSyntaxInfo.java ├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── documentation-suggestion.md │ ├── Feature_request.md │ └── Bug_report.md └── workflows │ └── gradle.yml ├── README.md ├── .gitattributes ├── LICENSE └── gradlew.bat /docs/advanced/README.md: -------------------------------------------------------------------------------- 1 | # Advanced 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /docs/advanced/reflection/README.md: -------------------------------------------------------------------------------- 1 | # Reflection 2 | -------------------------------------------------------------------------------- /docs/basics/README.md: -------------------------------------------------------------------------------- 1 | # Basics 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'skript-reflect' 2 | 3 | -------------------------------------------------------------------------------- /.gitbook.yaml: -------------------------------------------------------------------------------- 1 | root: ./docs/ 2 | 3 | structure: 4 | readme: ../README.md 5 | summary: SUMMARY.md 6 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SkriptLang/skript-reflect/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## OSX 2 | *.DS_Store 3 | 4 | ## Gradle 5 | .gradle 6 | build/ 7 | 8 | ## IntelliJ 9 | .idea/ 10 | *.iml 11 | -------------------------------------------------------------------------------- /src/test/scripts/reflect/ExprJavaCall.sk: -------------------------------------------------------------------------------- 1 | test "ExprJavaCall": 2 | assert "123".length() is 3 with "incorrect String##length return" 3 | -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen-shot-2018-08-20-at-7.57.53-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SkriptLang/skript-reflect/HEAD/docs/.gitbook/assets/screen-shot-2018-08-20-at-7.57.53-pm.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen-shot-2018-08-20-at-7.58.41-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SkriptLang/skript-reflect/HEAD/docs/.gitbook/assets/screen-shot-2018-08-20-at-7.58.41-pm.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen-shot-2018-08-20-at-8.07.22-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SkriptLang/skript-reflect/HEAD/docs/.gitbook/assets/screen-shot-2018-08-20-at-8.07.22-pm.png -------------------------------------------------------------------------------- /src/main/resources/lang/english.lang: -------------------------------------------------------------------------------- 1 | version: 2.2 2 | types: 3 | event: event¦s @an 4 | javatype: java class¦es @a 5 | null: null¦s @a 6 | javaobject: java object¦s @a 7 | section: section¦s @a 8 | -------------------------------------------------------------------------------- /src/test/scripts/custom/custom constants.sk: -------------------------------------------------------------------------------- 1 | option test constant value: 2 | get: 3 | return "test constant value" 4 | 5 | 6 | test "custom constants": 7 | assert "{@test constant value}" is "test constant value" with "Failed to get constant" 8 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /src/main/java/com/btk5h/skriptmirror/skript/custom/Continuable.java: -------------------------------------------------------------------------------- 1 | package com.btk5h.skriptmirror.skript.custom; 2 | 3 | public interface Continuable { 4 | 5 | default void markContinue() { 6 | setContinue(true); 7 | } 8 | 9 | void setContinue(boolean b); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/btk5h/skriptmirror/Null.java: -------------------------------------------------------------------------------- 1 | package com.btk5h.skriptmirror; 2 | 3 | public class Null { 4 | private static final Null instance = new Null(); 5 | 6 | private Null() { 7 | } 8 | 9 | public static Null getInstance() { 10 | return instance; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/test/scripts/reflect/StructImport.sk: -------------------------------------------------------------------------------- 1 | import: 2 | java.lang.Math 3 | java.lang.Math as AliasForMath 4 | 5 | test "import from structure": 6 | assert Math.PI is set with "Failed to use import from structure" 7 | assert AliasForMath.PI is set with "Failed to use import alias from structure" 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = tab 6 | indent_size = 4 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.java] 13 | continuation_indent_size = 4 14 | ij_continuation_indent_size = 4 15 | -------------------------------------------------------------------------------- /src/main/java/com/btk5h/skriptmirror/JavaCallException.java: -------------------------------------------------------------------------------- 1 | package com.btk5h.skriptmirror; 2 | 3 | public class JavaCallException extends RuntimeException { 4 | public JavaCallException(String message) { 5 | super(message); 6 | } 7 | 8 | @Override 9 | public synchronized Throwable fillInStackTrace() { 10 | return this; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scripts/custom/custom effects.sk: -------------------------------------------------------------------------------- 1 | effect skript-reflect test set var %string%: 2 | trigger: 3 | set {%expr-1%} to true 4 | 5 | test "custom effects": 6 | delete {skript-reflect.tests.custom effects} 7 | skript-reflect test set var "skript-reflect.tests.custom effects" 8 | assert {skript-reflect.tests.custom effects} is set with "Failed custom effect" 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation-suggestion.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Documentation suggestion 3 | about: Suggest improvements for our documentation 4 | 5 | --- 6 | 7 | **Describe the changes you would like to see** 8 | A clear and concise description of what you want to see changed or added. 9 | 10 | **Additional context** 11 | Add any other context or screenshots about the suggestion here. 12 | -------------------------------------------------------------------------------- /src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: skript-reflect 2 | version: @version@ 3 | description: Reflection utilities for Skript. 4 | authors: [Bryan Terce , TPGamesNL, 'SkriptLang Team'] 5 | website: https://github.com/SkriptLang/skript-reflect 6 | api-version: 1.13 7 | 8 | main: com.btk5h.skriptmirror.SkriptMirror 9 | softdepend: [Skript] 10 | loadbefore: [skript-mirror] 11 | -------------------------------------------------------------------------------- /src/main/java/com/btk5h/skriptmirror/util/lookup/LookupGetter.java: -------------------------------------------------------------------------------- 1 | package com.btk5h.skriptmirror.util.lookup; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | 5 | /** 6 | * A class and package specifically for the lookup creator, 7 | * so it cannot access anything it isn't supposed to. 8 | */ 9 | public class LookupGetter { 10 | 11 | public static MethodHandles.Lookup getLookup() { 12 | return MethodHandles.lookup(); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/btk5h/skriptmirror/util/LRUCache.java: -------------------------------------------------------------------------------- 1 | package com.btk5h.skriptmirror.util; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.Map; 5 | 6 | public class LRUCache extends LinkedHashMap { 7 | 8 | private final int cacheSize; 9 | 10 | public LRUCache(int cacheSize) { 11 | super(16, 0.75F, true); 12 | this.cacheSize = cacheSize; 13 | } 14 | 15 | @Override 16 | protected boolean removeEldestEntry(Map.Entry eldest) { 17 | return size() >= cacheSize; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /docs/advanced/loading-external-libraries.md: -------------------------------------------------------------------------------- 1 | # Loading external libraries 2 | 3 | Normally, you may only access classes loaded in the server's classpath, such as Java standard library classes, Bukkit classes, and plugin classes. If you want to use third-party libraries that are not included on the server classpath, you must load them through skript-reflect first. 4 | 5 | To load a jar file, place it in `plugins/skript-reflect/` \(create the folder if it doesn't exist\). 6 | 7 | Once an external library is loaded, its classes may be imported just like any other class. 8 | 9 | -------------------------------------------------------------------------------- /src/test/scripts/reflect/EffImport.sk: -------------------------------------------------------------------------------- 1 | import: 2 | ch.njol.skript.SkriptConfig 3 | 4 | function runEffectCommand(effect: string): 5 | set {_effect command token} to SkriptConfig.effectCommandToken.value() 6 | execute console command "%{_effect command token}%%{_effect}%" 7 | 8 | test "import from effect": 9 | delete {tests::EffImport::byte size} 10 | runEffectCommand("import java.lang.Byte") 11 | runEffectCommand("set {tests::EffImport::byte size} to Byte.SIZE") 12 | assert {tests::EffImport::byte size} is set with "Failed to use import from effect" 13 | delete {tests::EffImport::byte size} 14 | -------------------------------------------------------------------------------- /src/main/java/com/btk5h/skriptmirror/ImportNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.btk5h.skriptmirror; 2 | 3 | /** 4 | * Exception thrown when the user tries to use a certain class, but that class is not imported. 5 | * Currently only used in the {@link Descriptor} class. 6 | */ 7 | public class ImportNotFoundException extends Exception { 8 | 9 | private final String userType; 10 | 11 | public ImportNotFoundException(String userType) { 12 | super("Import not found: " + userType); 13 | this.userType = userType; 14 | } 15 | 16 | public String getUserType() { 17 | return userType; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /docs/getting-started.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | ## Installation 4 | 5 | 1. Download the latest `skript-reflect.jar` from GitHub 6 | 2. Move `skript-reflect.jar` to your `plugins/` folder 7 | 3. If you have third-party libraries you would like to use \(that are not Bukkit plugins\), [follow the steps outlined here.](advanced/loading-external-libraries.md) 8 | 9 | {% hint style="info" %} 10 | Tip: Enable effect commands in Skript's config! Effect commands make it extremely easy to prototype and test Skript code, which can be especially useful when working with skript-reflect. 11 | {% endhint %} 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /src/main/java/com/btk5h/skriptmirror/WrappedEvent.java: -------------------------------------------------------------------------------- 1 | package com.btk5h.skriptmirror; 2 | 3 | import org.bukkit.event.Event; 4 | 5 | public abstract class WrappedEvent extends Event { 6 | private final Event event; 7 | 8 | protected WrappedEvent(Event event) { 9 | this.event = event; 10 | } 11 | 12 | protected WrappedEvent(Event event, boolean isAsynchronous) { 13 | super(isAsynchronous); 14 | this.event = event; 15 | } 16 | 17 | public Event getEvent() { 18 | if (event instanceof WrappedEvent) { 19 | return ((WrappedEvent) event).getEvent(); 20 | } 21 | return event; 22 | } 23 | 24 | public Event getDirectEvent() { 25 | return event; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | **To reproduce** 11 | Steps to reproduce the behavior. If applicable, add a script or code snippet here. 12 | 13 | **Expected behavior** 14 | A clear and concise description of what you expected to happen. 15 | 16 | **Screenshots** 17 | If applicable, add screenshots to help explain your problem. 18 | 19 | **Server information** 20 | - skript-reflect: 21 | - Skript: 22 | - Bukkit: 23 | - Minecraft: 24 | - Java: 25 | - OS: 26 | 27 | **Additional context** 28 | Add any other context about the problem here. 29 | -------------------------------------------------------------------------------- /src/main/java/com/btk5h/skriptmirror/JavaType.java: -------------------------------------------------------------------------------- 1 | package com.btk5h.skriptmirror; 2 | 3 | import java.util.Objects; 4 | 5 | public final class JavaType { 6 | 7 | private final Class javaClass; 8 | 9 | public JavaType(Class javaClass) { 10 | this.javaClass = javaClass; 11 | } 12 | 13 | public Class getJavaClass() { 14 | return javaClass; 15 | } 16 | 17 | @Override 18 | public boolean equals(Object o) { 19 | if (this == o) return true; 20 | if (o == null || getClass() != o.getClass()) return false; 21 | JavaType javaType1 = (JavaType) o; 22 | return Objects.equals(javaClass, javaType1.javaClass); 23 | } 24 | 25 | @Override 26 | public int hashCode() { 27 | return Objects.hash(javaClass); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/org/skriptlang/reflect/syntax/expression/ConstantGetEvent.java: -------------------------------------------------------------------------------- 1 | package org.skriptlang.reflect.syntax.expression; 2 | 3 | import ch.njol.skript.lang.Expression; 4 | import ch.njol.skript.lang.SkriptParser; 5 | import org.bukkit.event.HandlerList; 6 | 7 | public class ConstantGetEvent extends ExpressionGetEvent { 8 | private final static HandlerList handlers = new HandlerList(); 9 | 10 | public ConstantGetEvent(int matchedPattern, SkriptParser.ParseResult parseResult) { 11 | super(null, new Expression[0], matchedPattern, parseResult); 12 | } 13 | 14 | public static HandlerList getHandlerList() { 15 | return handlers; 16 | } 17 | 18 | @Override 19 | public HandlerList getHandlers() { 20 | return handlers; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/btk5h/skriptmirror/skript/reflect/sections/SectionEvent.java: -------------------------------------------------------------------------------- 1 | package com.btk5h.skriptmirror.skript.reflect.sections; 2 | 3 | import org.bukkit.event.Event; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public class SectionEvent extends Event { 7 | 8 | private final Section section; 9 | private Object[] output; 10 | 11 | public SectionEvent(Section section) { 12 | this.section = section; 13 | } 14 | 15 | public Section getSection() { 16 | return section; 17 | } 18 | 19 | public Object[] getOutput() { 20 | return output; 21 | } 22 | 23 | public void setOutput(Object[] output) { 24 | this.output = output; 25 | } 26 | 27 | @Override 28 | public HandlerList getHandlers() { 29 | throw new IllegalStateException(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # skript-reflect 2 | 3 | This fork of [skript-mirror](https://github.com/btk5h/skript-mirror) aims to fix 4 | multiple issues that I believe have been present for too long, and implement some long-wanted features. 5 | 6 | Documentation: https://tpgamesnl.gitbook.io/skript-reflect 7 | 8 | Source code: https://github.com/TPGamesNL/skript-reflect 9 | 10 | Downloads: [releases](https://github.com/TPGamesNL/skript-reflect/releases) or 11 | [actions](https://github.com/TPGamesNL/skript-reflect/actions?query=event%3Apush+is%3Asuccess+actor%3ATPGamesNL) \(not stable\) 12 | 13 | Discord: https://discord.gg/jDW8UbD 14 | 15 | ## What's been changed in this fork: 16 | * Added custom events 17 | * Support for more Java versions \(Java 13+, OpenJ9\) 18 | * Support for listening to asynchronous events 19 | * Class proxy fixes + documentation 20 | * Fixed multiple issues with local variables 21 | * \+ much more 22 | -------------------------------------------------------------------------------- /src/test/scripts/custom/custom condition.sk: -------------------------------------------------------------------------------- 1 | condition test true condition: 2 | check: 3 | continue 4 | 5 | condition test false condition: 6 | check: 7 | stop 8 | 9 | condition test input based condition %boolean%: 10 | check: 11 | continue if expr-1 is true 12 | 13 | boolean property condition test property condition: 14 | check: 15 | continue if expr-1 is true 16 | 17 | test "custom conditions": 18 | assert test true condition with "Failed true condition" 19 | 20 | assert test false condition to fail with "Failed false condition" 21 | 22 | assert test input based condition (true) with "Failed input based true condition" 23 | assert test input based condition (false) to fail with "Failed input based false condition" 24 | 25 | assert true is test property condition with "Failed input based true property condition" 26 | assert false isn't test property condition with "Failed input based false property condition" 27 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # File source: https://github.com/alexkaratarakis/gitattributes/blob/master/Java.gitattributes 2 | 3 | # Java sources 4 | *.java text diff=java 5 | *.gradle text diff=java 6 | *.gradle.kts text diff=java 7 | 8 | # These files are text and should be normalized (Convert crlf => lf) 9 | *.css text diff=css 10 | *.df text 11 | *.htm text diff=html 12 | *.html text diff=html 13 | *.js text 14 | *.jsp text 15 | *.jspf text 16 | *.jspx text 17 | *.properties text 18 | *.tld text 19 | *.tag text 20 | *.tagx text 21 | *.xml text 22 | 23 | # These files are binary and should be left untouched 24 | # (binary is a macro for -text -diff) 25 | *.class binary 26 | *.dll binary 27 | *.ear binary 28 | *.jar binary 29 | *.so binary 30 | *.war binary 31 | *.jks binary 32 | -------------------------------------------------------------------------------- /src/main/java/com/btk5h/skriptmirror/skript/LitNullObject.java: -------------------------------------------------------------------------------- 1 | package com.btk5h.skriptmirror.skript; 2 | 3 | import ch.njol.skript.Skript; 4 | import ch.njol.skript.lang.Expression; 5 | import ch.njol.skript.lang.ExpressionType; 6 | import ch.njol.skript.lang.SkriptParser; 7 | import ch.njol.skript.lang.util.SimpleLiteral; 8 | import ch.njol.util.Kleenean; 9 | import com.btk5h.skriptmirror.Null; 10 | import org.bukkit.event.Event; 11 | 12 | public class LitNullObject extends SimpleLiteral { 13 | static { 14 | Skript.registerExpression(LitNullObject.class, Null.class, ExpressionType.SIMPLE, "null"); 15 | } 16 | 17 | public LitNullObject() { 18 | super(Null.getInstance(), false); 19 | } 20 | 21 | @Override 22 | public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, 23 | SkriptParser.ParseResult parseResult) { 24 | return true; 25 | } 26 | 27 | @Override 28 | public String toString(Event e, boolean debug) { 29 | return "null"; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/org/skriptlang/reflect/syntax/expression/ExpressionChangeEvent.java: -------------------------------------------------------------------------------- 1 | package org.skriptlang.reflect.syntax.expression; 2 | 3 | import ch.njol.skript.lang.Expression; 4 | import ch.njol.skript.lang.SkriptParser; 5 | import com.btk5h.skriptmirror.skript.custom.CustomSyntaxEvent; 6 | import org.bukkit.event.Event; 7 | import org.bukkit.event.HandlerList; 8 | 9 | public class ExpressionChangeEvent extends CustomSyntaxEvent { 10 | private final static HandlerList handlers = new HandlerList(); 11 | private final Object[] delta; 12 | 13 | public ExpressionChangeEvent(Event event, Expression[] expressions, int matchedPattern, 14 | SkriptParser.ParseResult parseResult, Object[] delta) { 15 | super(event, expressions, matchedPattern, parseResult); 16 | this.delta = delta; 17 | } 18 | 19 | public static HandlerList getHandlerList() { 20 | return handlers; 21 | } 22 | 23 | public Object[] getDelta() { 24 | return delta; 25 | } 26 | 27 | @Override 28 | public HandlerList getHandlers() { 29 | return handlers; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/btk5h/skriptmirror/FunctionWrapper.java: -------------------------------------------------------------------------------- 1 | package com.btk5h.skriptmirror; 2 | 3 | import ch.njol.skript.lang.function.Function; 4 | import ch.njol.skript.lang.function.Functions; 5 | import ch.njol.skript.lang.parser.ParserInstance; 6 | import org.jetbrains.annotations.Nullable; 7 | 8 | public class FunctionWrapper { 9 | 10 | private final String name; 11 | private final Object[] arguments; 12 | 13 | public FunctionWrapper(String name, Object[] arguments) { 14 | this.name = name; 15 | this.arguments = arguments; 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public Object[] getArguments() { 23 | return arguments; 24 | } 25 | 26 | @Nullable 27 | public Function getFunction() { 28 | // Get current script file name 29 | String script = null; 30 | ParserInstance parserInstance = ParserInstance.get(); 31 | if (parserInstance.isActive()) { 32 | script = parserInstance.getCurrentScript().getConfig().getFileName(); 33 | } 34 | 35 | return Functions.getFunction(name, script); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/skriptlang/reflect/syntax/event/elements/CondEventCancelled.java: -------------------------------------------------------------------------------- 1 | package org.skriptlang.reflect.syntax.event.elements; 2 | 3 | import ch.njol.skript.conditions.base.PropertyCondition; 4 | import org.bukkit.event.Cancellable; 5 | 6 | // So I should've used PropertyCondition, but if you want to implement the check method, you'd be overriding 7 | // the 'normal' Condition#check(Event) method, which is rightfully declared final in PropertyCondition. 8 | // They probably should've used some other name then check, but hey, I can't help it without breaking 9 | // backwards compatibility. And for some reason this works, so I'll keep it. 10 | public class CondEventCancelled extends PropertyCondition { 11 | 12 | static { 13 | register(CondEventCancelled.class, "cancelled", "events"); 14 | } 15 | 16 | @Override 17 | public boolean check(T event) { 18 | return event instanceof Cancellable && ((Cancellable) event).isCancelled(); 19 | } 20 | 21 | @Override 22 | protected String getPropertyName() { 23 | return "cancelled"; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/org/skriptlang/reflect/syntax/expression/ExpressionGetEvent.java: -------------------------------------------------------------------------------- 1 | package org.skriptlang.reflect.syntax.expression; 2 | 3 | import ch.njol.skript.lang.Expression; 4 | import ch.njol.skript.lang.SkriptParser; 5 | import com.btk5h.skriptmirror.skript.custom.CustomSyntaxEvent; 6 | import org.bukkit.event.Event; 7 | import org.bukkit.event.HandlerList; 8 | 9 | public class ExpressionGetEvent extends CustomSyntaxEvent { 10 | private final static HandlerList handlers = new HandlerList(); 11 | private Object[] output; 12 | 13 | public ExpressionGetEvent(Event event, Expression[] expressions, int matchedPattern, 14 | SkriptParser.ParseResult parseResult) { 15 | super(event, expressions, matchedPattern, parseResult); 16 | } 17 | 18 | public static HandlerList getHandlerList() { 19 | return handlers; 20 | } 21 | 22 | public Object[] getOutput() { 23 | return output; 24 | } 25 | 26 | public void setOutput(Object[] output) { 27 | this.output = output; 28 | } 29 | 30 | @Override 31 | public HandlerList getHandlers() { 32 | return handlers; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016-2023, Bryan Terce, TPGamesNL 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/main/java/org/skriptlang/reflect/syntax/effect/EffectSyntaxInfo.java: -------------------------------------------------------------------------------- 1 | package org.skriptlang.reflect.syntax.effect; 2 | 3 | import org.skriptlang.reflect.syntax.CustomSyntaxStructure; 4 | import com.btk5h.skriptmirror.util.SkriptMirrorUtil; 5 | import org.skriptlang.skript.lang.script.Script; 6 | 7 | import java.util.Objects; 8 | 9 | public class EffectSyntaxInfo extends CustomSyntaxStructure.SyntaxData { 10 | 11 | private EffectSyntaxInfo(Script script, String pattern, int matchedPattern) { 12 | super(script, pattern, matchedPattern); 13 | } 14 | 15 | public static EffectSyntaxInfo create(Script script, String pattern, int matchedPattern) { 16 | return new EffectSyntaxInfo(script, SkriptMirrorUtil.preprocessPattern(pattern), matchedPattern); 17 | } 18 | 19 | @Override 20 | public boolean equals(Object o) { 21 | if (this == o) return true; 22 | if (o == null || getClass() != o.getClass()) return false; 23 | EffectSyntaxInfo that = (EffectSyntaxInfo) o; 24 | return Objects.equals(getScript(), that.getScript()) && 25 | Objects.equals(getPattern(), that.getPattern()); 26 | } 27 | 28 | @Override 29 | public int hashCode() { 30 | return Objects.hash(getScript(), getPattern()); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /.github/workflows/gradle.yml: -------------------------------------------------------------------------------- 1 | name: Build and test 2 | 3 | on: 4 | push: 5 | branches: 6 | - 2.x 7 | pull_request: 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout repo 14 | uses: actions/checkout@v2 15 | - name: Set up JDK 11 16 | uses: actions/setup-java@v1 17 | with: 18 | java-version: 17 19 | - name: Grant execute permission for gradlew 20 | run: chmod +x gradlew 21 | - name: Build with Gradle 22 | run: ./gradlew build 23 | - name: Upload artifacts 24 | uses: actions/upload-artifact@master 25 | with: 26 | path: build/libs/*.jar 27 | test: 28 | runs-on: ubuntu-latest 29 | needs: [build] 30 | steps: 31 | - name: Checkout repo 32 | uses: actions/checkout@v2 33 | - name: Download artifacts 34 | uses: actions/download-artifact@v4 35 | with: 36 | path: extra-plugins/ 37 | merge-multiple: true 38 | - name: Run tests 39 | uses: SkriptLang/skript-test-action@v1.2 40 | with: 41 | test_script_directory: src/test/scripts 42 | extra_plugins_directory: extra-plugins/ 43 | -------------------------------------------------------------------------------- /src/main/java/com/btk5h/skriptmirror/skript/custom/CustomSyntaxEvent.java: -------------------------------------------------------------------------------- 1 | package com.btk5h.skriptmirror.skript.custom; 2 | 3 | import ch.njol.skript.lang.Expression; 4 | import ch.njol.skript.lang.SkriptParser; 5 | import com.btk5h.skriptmirror.WrappedEvent; 6 | import org.bukkit.event.Event; 7 | 8 | import java.util.Arrays; 9 | 10 | public abstract class CustomSyntaxEvent extends WrappedEvent { 11 | private final Expression[] expressions; 12 | private final int matchedPattern; 13 | private final SkriptParser.ParseResult parseResult; 14 | 15 | protected CustomSyntaxEvent(Event event, Expression[] expressions, int matchedPattern, 16 | SkriptParser.ParseResult parseResult) { 17 | super(event); 18 | this.expressions = Arrays.stream(expressions) 19 | .map(expr -> CustomSyntaxExpression.wrap(expr, event)) 20 | .toArray(Expression[]::new); 21 | this.matchedPattern = matchedPattern; 22 | this.parseResult = parseResult; 23 | } 24 | 25 | public Expression[] getExpressions() { 26 | return expressions; 27 | } 28 | 29 | public int getMatchedPattern() { 30 | return matchedPattern; 31 | } 32 | 33 | public SkriptParser.ParseResult getParseResult() { 34 | return parseResult; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /docs/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | * [skript-reflect](../README.md) 4 | * [Getting Started](getting-started.md) 5 | * [Basics](basics/README.md) 6 | * [Reading Javadocs](basics/reading-javadocs.md) 7 | * [Importing classes](basics/importing-classes.md) 8 | * [Running Java code](basics/running-java-code.md) 9 | * [Handling events](basics/handling-events.md) 10 | * [Utilities](basics/utilities.md) 11 | * [Advanced](advanced/README.md) 12 | * [Error handling](advanced/error-handling.md) 13 | * [Loading external libraries](advanced/loading-external-libraries.md) 14 | * [Custom syntax](advanced/custom-syntax/README.md) 15 | * [Effects](advanced/custom-syntax/effects.md) 16 | * [Conditions](advanced/custom-syntax/conditions.md) 17 | * [Expressions](advanced/custom-syntax/expressions.md) 18 | * [Events](advanced/custom-syntax/events.md) 19 | * [Computed Options](advanced/computed-options.md) 20 | * [Reflection](advanced/reflection/README.md) 21 | * [Proxies](advanced/reflection/proxies.md) 22 | * [Sections](advanced/reflection/sections.md) 23 | * [Experiments](advanced/experiments.md) 24 | * [Code Conventions](code-conventions.md) 25 | * [Frequently Asked Questions](frequently-asked-questions.md) 26 | 27 | -------------------------------------------------------------------------------- /src/main/java/org/skriptlang/reflect/syntax/PatternsEntryData.java: -------------------------------------------------------------------------------- 1 | package org.skriptlang.reflect.syntax; 2 | 3 | import ch.njol.skript.ScriptLoader; 4 | import ch.njol.skript.config.Node; 5 | import ch.njol.skript.config.SectionNode; 6 | import org.jetbrains.annotations.Nullable; 7 | import org.skriptlang.skript.lang.entry.EntryData; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | class PatternsEntryData extends EntryData> { 13 | 14 | public PatternsEntryData(String key, @Nullable List defaultValue, boolean optional) { 15 | super(key, defaultValue, optional); 16 | } 17 | 18 | @Override 19 | public List getValue(Node node) { 20 | List patterns = new ArrayList<>(); 21 | for (Node subNode : (SectionNode) node) { 22 | String key = subNode.getKey(); 23 | if (key == null) 24 | continue; 25 | patterns.add(key); 26 | } 27 | return patterns; 28 | } 29 | 30 | @Override 31 | public boolean canCreateWith(Node node) { 32 | if (!(node instanceof SectionNode)) 33 | return false; 34 | String key = node.getKey(); 35 | if (key == null) 36 | return false; 37 | key = ScriptLoader.replaceOptions(key); 38 | return getKey().equalsIgnoreCase(key); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/skriptlang/reflect/syntax/expression/ConstantSyntaxInfo.java: -------------------------------------------------------------------------------- 1 | package org.skriptlang.reflect.syntax.expression; 2 | 3 | import org.skriptlang.reflect.syntax.CustomSyntaxStructure; 4 | import com.btk5h.skriptmirror.util.SkriptMirrorUtil; 5 | import org.skriptlang.skript.lang.script.Script; 6 | 7 | import java.util.Objects; 8 | 9 | public class ConstantSyntaxInfo extends CustomSyntaxStructure.SyntaxData { 10 | 11 | private ConstantSyntaxInfo(Script script, String pattern, int matchedPattern) { 12 | super(script, pattern, matchedPattern); 13 | } 14 | 15 | public static ConstantSyntaxInfo create(Script script, String pattern, int matchedPattern) { 16 | return new ConstantSyntaxInfo(script, SkriptMirrorUtil.preprocessPattern(pattern), matchedPattern); 17 | } 18 | 19 | @Override 20 | public boolean equals(Object o) { 21 | if (this == o) return true; 22 | if (o == null || getClass() != o.getClass()) return false; 23 | ConstantSyntaxInfo that = (ConstantSyntaxInfo) o; 24 | return 25 | Objects.equals(getScript(), that.getScript()) && 26 | Objects.equals(getPattern(), that.getPattern()); 27 | } 28 | 29 | @Override 30 | public int hashCode() { 31 | return Objects.hash(getScript(), getPattern()); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/org/skriptlang/reflect/syntax/effect/elements/EffDelayEffect.java: -------------------------------------------------------------------------------- 1 | package org.skriptlang.reflect.syntax.effect.elements; 2 | 3 | import ch.njol.skript.Skript; 4 | import ch.njol.skript.lang.Effect; 5 | import ch.njol.skript.lang.Expression; 6 | import ch.njol.skript.lang.SkriptParser; 7 | import ch.njol.skript.log.ErrorQuality; 8 | import ch.njol.util.Kleenean; 9 | import org.bukkit.event.Event; 10 | import org.skriptlang.reflect.syntax.effect.EffectTriggerEvent; 11 | 12 | public class EffDelayEffect extends Effect { 13 | static { 14 | Skript.registerEffect(EffDelayEffect.class, "delay [the] [current] effect"); 15 | } 16 | 17 | @Override 18 | protected void execute(Event e) { 19 | ((EffectTriggerEvent) e).setSync(false); 20 | } 21 | 22 | @Override 23 | public String toString(Event e, boolean debug) { 24 | return "delay effect"; 25 | } 26 | 27 | @Override 28 | public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, 29 | SkriptParser.ParseResult parseResult) { 30 | if (!getParser().isCurrentEvent(EffectTriggerEvent.class)) { 31 | Skript.error("The effect 'delay effect' may only be used in a custom effect.", ErrorQuality.SEMANTIC_ERROR); 32 | return false; 33 | } 34 | return true; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /docs/advanced/error-handling.md: -------------------------------------------------------------------------------- 1 | # Error handling 2 | 3 | By default, warnings and errors related to your code are logged to the console. Skript-reflect also offers additional tools that give you more control over how errors are handled. 4 | 5 | ## Suppressing errors 6 | 7 | Adding `try` before a Java call prevents errors from being logged to the console. 8 | 9 | {% code-tabs %} 10 | {% code-tabs-item title="example.sk" %} 11 | ```text 12 | set {_second item in list} to try {_list}.get(1) 13 | try {_connection}.setUseCaches(true) 14 | ``` 15 | {% endcode-tabs-item %} 16 | {% endcode-tabs %} 17 | 18 | If an error occurs, the error object can still be accessed programmatically. 19 | 20 | ## Programmatic access 21 | 22 | In some cases, you may want to handle errors yourself, either to do your own error logging or to perform an alternate task in case of a failure. 23 | 24 | ### Error object 25 | 26 | {% code-tabs %} 27 | {% code-tabs-item title="Syntax" %} 28 | ```text 29 | [the] [last] [java] (throwable|exception|error) 30 | ``` 31 | {% endcode-tabs-item %} 32 | {% endcode-tabs %} 33 | 34 | Returns the last error object thrown by a java call. If there was an issue resolving the method or converting its output, it may be a `com.btk5h.skriptmirror.JavaCallException`. 35 | 36 | -------------------------------------------------------------------------------- /src/main/java/org/skriptlang/reflect/syntax/event/elements/EffCallEvent.java: -------------------------------------------------------------------------------- 1 | package org.skriptlang.reflect.syntax.event.elements; 2 | 3 | import ch.njol.skript.Skript; 4 | import ch.njol.skript.lang.Effect; 5 | import ch.njol.skript.lang.Expression; 6 | import ch.njol.skript.lang.SkriptParser; 7 | import ch.njol.util.Kleenean; 8 | import com.btk5h.skriptmirror.util.SkriptUtil; 9 | import org.bukkit.Bukkit; 10 | import org.bukkit.event.Event; 11 | import org.jetbrains.annotations.Nullable; 12 | 13 | public class EffCallEvent extends Effect { 14 | 15 | static { 16 | Skript.registerEffect(EffCallEvent.class, "call [event] %events%"); 17 | } 18 | 19 | private Expression eventExpr; 20 | 21 | @Override 22 | public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { 23 | eventExpr = SkriptUtil.defendExpression(exprs[0]); 24 | return SkriptUtil.canInitSafely(eventExpr); 25 | } 26 | 27 | @Override 28 | protected void execute(Event e) { 29 | for (Event event : eventExpr.getArray(e)) 30 | Bukkit.getPluginManager().callEvent(event); 31 | } 32 | 33 | @Override 34 | public String toString(@Nullable Event e, boolean debug) { 35 | return "call event " + eventExpr.toString(e, debug); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /docs/frequently-asked-questions.md: -------------------------------------------------------------------------------- 1 | # Frequently Asked Questions 2 | 3 | ## Why don't you keep documentation on another site? 4 | 5 | Though many Skript-specific documentation sites have popped up and grown in popularity, these sites typically have two issues that make them an unattractive option for skript-reflect. 6 | 7 | * Documentation is usually stored solely by the site. If the site ever breaks or shuts down, this means the documentation may be lost as well. 8 | * These sites lack the flexibility of other documentation solutions. Generally, these sites focus on documenting each feature individually. While this might be adequate for many simpler Skript addons, skript-reflect's complexity necessitates the use of manually organized documentation. 9 | 10 | That being said, third-party sites may display the contents of skript-reflect's documentation, but they would be responsible for keeping the documentation up-to-date. For the convenience of other scripters, these sites should prominently display [a link to the documentation](https://tpgamesnl.gitbook.io/) on each page. Please avoid documenting features individually or using an automated tool to extract syntax patterns from skript-reflect. Most of skript-reflect's core features are best explained using hand-written documentation. 11 | 12 | -------------------------------------------------------------------------------- /src/main/java/com/btk5h/skriptmirror/skript/reflect/ExprJavaError.java: -------------------------------------------------------------------------------- 1 | package com.btk5h.skriptmirror.skript.reflect; 2 | 3 | import ch.njol.skript.Skript; 4 | import ch.njol.skript.lang.Expression; 5 | import ch.njol.skript.lang.ExpressionType; 6 | import ch.njol.skript.lang.SkriptParser; 7 | import ch.njol.skript.lang.util.SimpleExpression; 8 | import ch.njol.util.Kleenean; 9 | import org.bukkit.event.Event; 10 | 11 | public class ExprJavaError extends SimpleExpression { 12 | static { 13 | Skript.registerExpression(ExprJavaError.class, Throwable.class, ExpressionType.SIMPLE, 14 | "[the] [last] [java] (throwable|exception|error)"); 15 | } 16 | 17 | @Override 18 | protected Throwable[] get(Event e) { 19 | return new Throwable[]{ExprJavaCall.lastError}; 20 | } 21 | 22 | @Override 23 | public boolean isSingle() { 24 | return true; 25 | } 26 | 27 | @Override 28 | public Class getReturnType() { 29 | return Throwable.class; 30 | } 31 | 32 | @Override 33 | public String toString(Event e, boolean debug) { 34 | return "last java error"; 35 | } 36 | 37 | @Override 38 | public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, 39 | SkriptParser.ParseResult parseResult) { 40 | return true; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/org/skriptlang/reflect/syntax/condition/elements/EffNegateCondition.java: -------------------------------------------------------------------------------- 1 | package org.skriptlang.reflect.syntax.condition.elements; 2 | 3 | import ch.njol.skript.Skript; 4 | import ch.njol.skript.lang.Effect; 5 | import ch.njol.skript.lang.Expression; 6 | import ch.njol.skript.lang.SkriptParser; 7 | import ch.njol.skript.log.ErrorQuality; 8 | import ch.njol.util.Kleenean; 9 | import org.bukkit.event.Event; 10 | import org.skriptlang.reflect.syntax.condition.ConditionCheckEvent; 11 | 12 | public class EffNegateCondition extends Effect { 13 | static { 14 | Skript.registerEffect(EffNegateCondition.class, "negate [the] [current] condition"); 15 | } 16 | 17 | @Override 18 | protected void execute(Event e) { 19 | ((ConditionCheckEvent) e).markNegated(); 20 | } 21 | 22 | @Override 23 | public String toString(Event e, boolean debug) { 24 | return "negate condition"; 25 | } 26 | 27 | @Override 28 | public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, 29 | SkriptParser.ParseResult parseResult) { 30 | if (!getParser().isCurrentEvent(ConditionCheckEvent.class)) { 31 | Skript.error("The effect 'negate condition' may only be used in a custom condition.", 32 | ErrorQuality.SEMANTIC_ERROR); 33 | return false; 34 | } 35 | return true; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/scripts/custom/custom expressions.sk: -------------------------------------------------------------------------------- 1 | expression test custom expression: 2 | get: 3 | return true 4 | 5 | plural expression test plural custom expression: 6 | get: 7 | return true and true 8 | 9 | world property test property expression: 10 | get: 11 | return 5 12 | 13 | test "custom expressions": 14 | assert test custom expression is true with "Failed to get custom expression" 15 | assert (raw expression (test custom expression)).isSingle() is true with "Custom expression is incorrectly non-single" 16 | 17 | assert test plural custom expression is (true and true) with "Failed to get custom expression" 18 | assert (raw expression (test plural custom expression)).isSingle() is false with "Custom expression is incorrectly single" 19 | 20 | set {_world} to random world out of all worlds 21 | assert test property expression of {_world} is 5 with "Failed to get custom property expression (single)" 22 | assert test property expression of ({_world} and {_world}) is 5 with "Failed to get custom property expression (multiple)" 23 | assert (raw expression (test property expression of {_world})).isSingle() is true with "Custom property expression is incorrectly non-single" 24 | assert (raw expression (test property expression of ({_world} and {_world}))).isSingle() is false with "Custom property expression is incorrectly single" 25 | -------------------------------------------------------------------------------- /src/main/java/org/skriptlang/reflect/syntax/event/EventTriggerEvent.java: -------------------------------------------------------------------------------- 1 | package org.skriptlang.reflect.syntax.event; 2 | 3 | import ch.njol.skript.lang.Expression; 4 | import ch.njol.skript.lang.SkriptParser; 5 | import com.btk5h.skriptmirror.skript.custom.Continuable; 6 | import com.btk5h.skriptmirror.skript.custom.CustomSyntaxEvent; 7 | import org.bukkit.event.Event; 8 | import org.bukkit.event.HandlerList; 9 | 10 | public class EventTriggerEvent extends CustomSyntaxEvent implements Continuable { 11 | 12 | private final static HandlerList handlers = new HandlerList(); 13 | private final String which; 14 | private boolean markedContinue = false; 15 | 16 | public EventTriggerEvent(Event event, Expression[] expressions, int matchedPattern, 17 | SkriptParser.ParseResult parseResult, String which) { 18 | super(event, expressions, matchedPattern, parseResult); 19 | this.which = which; 20 | } 21 | 22 | public String getWhich() { 23 | return which; 24 | } 25 | 26 | public boolean isMarkedContinue() { 27 | return markedContinue; 28 | } 29 | 30 | @Override 31 | public void setContinue(boolean b) { 32 | markedContinue = b; 33 | } 34 | 35 | public static HandlerList getHandlerList() { 36 | return handlers; 37 | } 38 | 39 | @Override 40 | public HandlerList getHandlers() { 41 | return handlers; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/btk5h/skriptmirror/skript/reflect/ExprEvent.java: -------------------------------------------------------------------------------- 1 | package com.btk5h.skriptmirror.skript.reflect; 2 | 3 | import ch.njol.skript.Skript; 4 | import ch.njol.skript.lang.Expression; 5 | import ch.njol.skript.lang.ExpressionType; 6 | import ch.njol.skript.lang.SkriptParser; 7 | import ch.njol.skript.lang.util.SimpleExpression; 8 | import ch.njol.util.Kleenean; 9 | import com.btk5h.skriptmirror.WrappedEvent; 10 | import org.bukkit.event.Event; 11 | 12 | public class ExprEvent extends SimpleExpression { 13 | static { 14 | Skript.registerExpression(ExprEvent.class, Event.class, ExpressionType.SIMPLE, "[the] event"); 15 | } 16 | 17 | @Override 18 | protected Event[] get(Event e) { 19 | if (e instanceof WrappedEvent) { 20 | return new Event[]{((WrappedEvent) e).getEvent()}; 21 | } 22 | return new Event[]{e}; 23 | } 24 | 25 | @Override 26 | public boolean isSingle() { 27 | return true; 28 | } 29 | 30 | @Override 31 | public Class getReturnType() { 32 | return Event.class; 33 | } 34 | 35 | @Override 36 | public String toString(Event e, boolean debug) { 37 | if (e == null) { 38 | return "the event"; 39 | } 40 | return e.getEventName(); 41 | } 42 | 43 | @Override 44 | public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, 45 | SkriptParser.ParseResult parseResult) { 46 | return true; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/org/skriptlang/reflect/syntax/condition/ConditionCheckEvent.java: -------------------------------------------------------------------------------- 1 | package org.skriptlang.reflect.syntax.condition; 2 | 3 | import ch.njol.skript.lang.Expression; 4 | import ch.njol.skript.lang.SkriptParser; 5 | import com.btk5h.skriptmirror.skript.custom.Continuable; 6 | import com.btk5h.skriptmirror.skript.custom.CustomSyntaxEvent; 7 | import org.bukkit.event.Event; 8 | import org.bukkit.event.HandlerList; 9 | 10 | public class ConditionCheckEvent extends CustomSyntaxEvent implements Continuable { 11 | 12 | private final static HandlerList handlers = new HandlerList(); 13 | private boolean markedContinue; 14 | private boolean markedNegated = false; 15 | 16 | public ConditionCheckEvent(Event event, Expression[] expressions, int matchedPattern, 17 | SkriptParser.ParseResult parseResult) { 18 | super(event, expressions, matchedPattern, parseResult); 19 | } 20 | 21 | public static HandlerList getHandlerList() { 22 | return handlers; 23 | } 24 | 25 | public boolean isMarkedContinue() { 26 | return markedContinue; 27 | } 28 | 29 | public boolean isMarkedNegated() { 30 | return markedNegated; 31 | } 32 | 33 | @Override 34 | public void setContinue(boolean b) { 35 | markedContinue = b; 36 | } 37 | 38 | public void markNegated() { 39 | markedNegated = true; 40 | } 41 | 42 | @Override 43 | public HandlerList getHandlers() { 44 | return handlers; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/btk5h/skriptmirror/skript/custom/ExprEventClasses.java: -------------------------------------------------------------------------------- 1 | package com.btk5h.skriptmirror.skript.custom; 2 | 3 | import ch.njol.skript.Skript; 4 | import ch.njol.skript.lang.Expression; 5 | import ch.njol.skript.lang.ExpressionType; 6 | import ch.njol.skript.lang.SkriptParser; 7 | import ch.njol.skript.lang.util.SimpleExpression; 8 | import ch.njol.util.Kleenean; 9 | import com.btk5h.skriptmirror.JavaType; 10 | import org.bukkit.event.Event; 11 | 12 | import java.util.Arrays; 13 | 14 | public class ExprEventClasses extends SimpleExpression { 15 | static { 16 | Skript.registerExpression(ExprEventClasses.class, JavaType.class, ExpressionType.SIMPLE, "event-classes"); 17 | } 18 | 19 | @Override 20 | protected JavaType[] get(Event e) { 21 | return Arrays.stream(((SyntaxParseEvent) e).getEventClasses()) 22 | .map(JavaType::new) 23 | .toArray(JavaType[]::new); 24 | } 25 | 26 | @Override 27 | public boolean isSingle() { 28 | return false; 29 | } 30 | 31 | @Override 32 | public Class getReturnType() { 33 | return JavaType.class; 34 | } 35 | 36 | @Override 37 | public String toString(Event e, boolean debug) { 38 | return "event-classes"; 39 | } 40 | 41 | @Override 42 | public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, 43 | SkriptParser.ParseResult parseResult) { 44 | return getParser().isCurrentEvent(SyntaxParseEvent.class); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/org/skriptlang/reflect/syntax/event/EventSyntaxInfo.java: -------------------------------------------------------------------------------- 1 | package org.skriptlang.reflect.syntax.event; 2 | 3 | import ch.njol.skript.Skript; 4 | import ch.njol.skript.util.Version; 5 | import com.btk5h.skriptmirror.util.SkriptMirrorUtil; 6 | import org.skriptlang.reflect.syntax.CustomSyntaxStructure; 7 | import org.skriptlang.skript.lang.script.Script; 8 | 9 | import java.util.Objects; 10 | 11 | public class EventSyntaxInfo extends CustomSyntaxStructure.SyntaxData { 12 | 13 | protected EventSyntaxInfo(Script script, String pattern, int matchedPattern) { 14 | super(script, pattern, matchedPattern); 15 | } 16 | 17 | public static EventSyntaxInfo create(Script script, String pattern, int matchedPattern) { 18 | if (Skript.getVersion().isSmallerThan(new Version(2, 8))) 19 | pattern = "[on] " + pattern + " [with priority (lowest|low|normal|high|highest|monitor)]"; 20 | return new EventSyntaxInfo(script, SkriptMirrorUtil.preprocessPattern(pattern), matchedPattern); 21 | } 22 | 23 | @Override 24 | public boolean equals(Object o) { 25 | if (this == o) 26 | return true; 27 | if (o == null || getClass() != o.getClass()) 28 | return false; 29 | EventSyntaxInfo that = (EventSyntaxInfo) o; 30 | return Objects.equals(getScript(), that.getScript()) && 31 | Objects.equals(getPattern(), that.getPattern()); 32 | } 33 | 34 | @Override 35 | public int hashCode() { 36 | return Objects.hash(getScript(), getPattern()); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/skriptlang/reflect/syntax/effect/EffectTriggerEvent.java: -------------------------------------------------------------------------------- 1 | package org.skriptlang.reflect.syntax.effect; 2 | 3 | import ch.njol.skript.lang.Expression; 4 | import ch.njol.skript.lang.SkriptParser; 5 | import ch.njol.skript.lang.TriggerItem; 6 | import com.btk5h.skriptmirror.skript.custom.CustomSyntaxEvent; 7 | import org.bukkit.event.Event; 8 | import org.bukkit.event.HandlerList; 9 | 10 | public class EffectTriggerEvent extends CustomSyntaxEvent { 11 | private final static HandlerList handlers = new HandlerList(); 12 | private final String which; 13 | private final TriggerItem next; 14 | private boolean sync = true; 15 | private boolean hasContinued = false; 16 | 17 | public EffectTriggerEvent(Event event, Expression[] expressions, int matchedPattern, 18 | SkriptParser.ParseResult parseResult, String which, TriggerItem next) { 19 | super(event, expressions, matchedPattern, parseResult); 20 | this.which = which; 21 | this.next = next; 22 | } 23 | 24 | public String getWhich() { 25 | return which; 26 | } 27 | 28 | public TriggerItem getNext() { 29 | return next; 30 | } 31 | 32 | public boolean isSync() { 33 | return sync; 34 | } 35 | 36 | public void setSync(boolean sync) { 37 | this.sync = sync; 38 | } 39 | 40 | public boolean hasContinued() { 41 | return hasContinued; 42 | } 43 | 44 | public void setContinued() { 45 | hasContinued = true; 46 | } 47 | 48 | public static HandlerList getHandlerList() { 49 | return handlers; 50 | } 51 | 52 | @Override 53 | public HandlerList getHandlers() { 54 | return handlers; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/btk5h/skriptmirror/skript/CondIsInstanceOf.java: -------------------------------------------------------------------------------- 1 | package com.btk5h.skriptmirror.skript; 2 | 3 | import ch.njol.skript.Skript; 4 | import ch.njol.skript.lang.Condition; 5 | import ch.njol.skript.lang.Expression; 6 | import ch.njol.skript.lang.SkriptParser; 7 | import ch.njol.util.Kleenean; 8 | import com.btk5h.skriptmirror.JavaType; 9 | import com.btk5h.skriptmirror.util.SkriptMirrorUtil; 10 | import com.btk5h.skriptmirror.util.SkriptUtil; 11 | import org.bukkit.event.Event; 12 | 13 | public class CondIsInstanceOf extends Condition { 14 | static { 15 | Skript.registerCondition(CondIsInstanceOf.class, 16 | "%objects% (is|are) [a[n]] instance[s] of %javatypes%", 17 | "%objects% (is not|isn't|are not|aren't) [a[n]] instance[s] of %javatypes%"); 18 | } 19 | 20 | private Expression objects; 21 | private Expression type; 22 | 23 | @Override 24 | public boolean check(Event e) { 25 | return objects.check(e, o -> 26 | type.check(e, t -> 27 | t.getJavaClass().isAssignableFrom(SkriptMirrorUtil.getClass(o)), 28 | isNegated() 29 | ) 30 | ); 31 | } 32 | 33 | @Override 34 | public String toString(Event e, boolean debug) { 35 | return String.format("%s instanceof %s", objects.toString(e, debug), type.toString(e, debug)); 36 | } 37 | 38 | @Override 39 | public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, 40 | SkriptParser.ParseResult parseResult) { 41 | objects = SkriptUtil.defendExpression(exprs[0]); 42 | type = SkriptUtil.defendExpression(exprs[1]); 43 | setNegated(matchedPattern == 1); 44 | return true; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/btk5h/skriptmirror/skript/reflect/ExprJavaTypeOf.java: -------------------------------------------------------------------------------- 1 | package com.btk5h.skriptmirror.skript.reflect; 2 | 3 | import ch.njol.skript.expressions.base.PropertyExpression; 4 | import ch.njol.skript.lang.Expression; 5 | import ch.njol.skript.lang.SkriptParser; 6 | import ch.njol.skript.lang.util.SimpleExpression; 7 | import ch.njol.util.Kleenean; 8 | import com.btk5h.skriptmirror.JavaType; 9 | import com.btk5h.skriptmirror.util.SkriptMirrorUtil; 10 | import com.btk5h.skriptmirror.util.SkriptUtil; 11 | import org.bukkit.event.Event; 12 | 13 | import java.util.Arrays; 14 | 15 | public class ExprJavaTypeOf extends SimpleExpression { 16 | static { 17 | PropertyExpression.register(ExprJavaTypeOf.class, JavaType.class, "[java] class[es]", "objects"); 18 | } 19 | 20 | private Expression target; 21 | 22 | @Override 23 | protected JavaType[] get(Event e) { 24 | return Arrays.stream(target.getArray(e)) 25 | .map(SkriptMirrorUtil::getClass) 26 | .map(JavaType::new) 27 | .toArray(JavaType[]::new); 28 | } 29 | 30 | @Override 31 | public boolean isSingle() { 32 | return target.isSingle(); 33 | } 34 | 35 | @Override 36 | public Class getReturnType() { 37 | return JavaType.class; 38 | } 39 | 40 | @Override 41 | public String toString(Event e, boolean debug) { 42 | return "class of " + target.toString(e, debug); 43 | } 44 | 45 | @SuppressWarnings("unchecked") 46 | @Override 47 | public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, 48 | SkriptParser.ParseResult parseResult) { 49 | target = SkriptUtil.defendExpression(exprs[0]); 50 | return SkriptUtil.canInitSafely(target); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/btk5h/skriptmirror/skript/reflect/ExprJavaType.java: -------------------------------------------------------------------------------- 1 | package com.btk5h.skriptmirror.skript.reflect; 2 | 3 | import ch.njol.skript.Skript; 4 | import ch.njol.skript.lang.Expression; 5 | import ch.njol.skript.lang.ExpressionType; 6 | import ch.njol.skript.lang.SkriptParser; 7 | import ch.njol.skript.lang.util.SimpleExpression; 8 | import ch.njol.util.Kleenean; 9 | import com.btk5h.skriptmirror.JavaType; 10 | import com.btk5h.skriptmirror.LibraryLoader; 11 | import org.bukkit.event.Event; 12 | 13 | public class ExprJavaType extends SimpleExpression { 14 | static { 15 | Skript.registerExpression(ExprJavaType.class, JavaType.class, ExpressionType.COMBINED, 16 | "[the] [java] class %string%"); 17 | } 18 | 19 | private Expression className; 20 | 21 | @Override 22 | protected JavaType[] get(Event e) { 23 | String cls = className.getSingle(e); 24 | 25 | if (cls == null) { 26 | return null; 27 | } 28 | 29 | try { 30 | return new JavaType[]{new JavaType(LibraryLoader.getClassLoader().loadClass(cls))}; 31 | } catch (ClassNotFoundException ex) { 32 | return null; 33 | } 34 | } 35 | 36 | @Override 37 | public boolean isSingle() { 38 | return true; 39 | } 40 | 41 | @Override 42 | public Class getReturnType() { 43 | return JavaType.class; 44 | } 45 | 46 | @Override 47 | public String toString(Event e, boolean debug) { 48 | return "class " + className.toString(e, debug); 49 | } 50 | 51 | @SuppressWarnings("unchecked") 52 | @Override 53 | public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, 54 | SkriptParser.ParseResult parseResult) { 55 | className = (Expression) exprs[0]; 56 | return true; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /docs/advanced/computed-options.md: -------------------------------------------------------------------------------- 1 | # Computed Options 2 | 3 | Skript's options section allows you to create snippets of text that are copied into other sections of your script. This is useful for static text, but does not work well for text that must be derived from dynamic sources, such as variables. 4 | 5 | {% code-tabs %} 6 | {% code-tabs-item title="Syntax" %} 7 | ```text 8 | option