diff --git a/docs-java/advance/Skript/AdvancedTutorials.md b/docs-java/advance/Skript/AdvancedTutorials.md index 43fcdd29f..dbb7ece57 100644 --- a/docs-java/advance/Skript/AdvancedTutorials.md +++ b/docs-java/advance/Skript/AdvancedTutorials.md @@ -167,34 +167,442 @@ command /example: System.out.println("test") ``` -在大多数情况下,由`import`块创建的表达式不会相互冲突,也不会与其他 **Skript** 表达式冲突。如果这个类的名称与另一个表达式(如 `Player` 和 `String` )冲突,则必须在别名下导入该类。 - ```sk import: java.lang.String as JavaString command /example: - -```sk -on TPARequestEvent: + trigger: + message JavaString.format("Hello %%s", sender) ``` -这行代码意为注册监听`TPARequestEvent`事件,与普通 sk 里注册事件的语法没啥区别。 +:::info + +别名必须是有效的 Java 标识符! + +::: + +###### 在低于 1.17 的 Minecraft 版本上导入 NMS 类 + +由于 **Minecraft** 1.17 以下版 + +::: + +###### 在低于 1.17 的 Minecraft 版本上导入 NMS 类 + +由于 **Minecraft** 1.17 以下版 + trigger: + message JavaString.format("Hello %%s", sender) -```sk - set {_ess_IUser} to event.getTarget() # 获取IUser对象 - set {_player} to {_ess_IUser}.getBase() # 获取Player对象 ``` -这行代码意为调用这个事件里的`getTarget()`方法,来获取 tpa 的目标,其返回一个`IUser`。 +:::info -这个`IUser`是 EssentialsX 的一个**接口**,`User`类**实现**了它,可以在[essentialsx 的 javadoc](https://jd-v2.essentialsx.net/net/ess3/api/iuser)里查看。 +别名必须是有效的 Java 标识符! + +::: + +###### 在低于 1.17 的 Minecraft 版本上导入 NMS 类 + +由于 **Minecraft** 1.17 以下版本的 **NMS** 包会随着每个 **Minecraft** 版本而变化,因此您应该动态生成包前缀。有关详细信息,请参阅[计算选项](https://tpgamesnl.gitbook.io/skript-reflect/advanced/computed-options#using-computed-options-for-nms-imports)。 + +##### _在运行时导入类_ + +有时,在执行脚本之前,无法确定所需的类引用。 + +###### 从完全限定的名称 + +语法: ```sk - if {_player} is player("lilingfeng"): - send "&cliliangfeng是我的不准tpa到她那里🥵" - cancel event +[the] [java] class %text% ``` -这几行和普通的 sk 语法没什么区别,作用是判断然后取消事件。 +示例: +```sk +on script load: + set {Player} to the class "org.bukkit.entity.Player" + message "%{Player}%" # org.bukkit.entity.Player +``` + +###### _从对象_ + +语法: + +```sk +[the] [java] class[es] of %objects% +%objects%'[s] [java] class[es] +``` + +示例: + +```sk +command /example: + executable by: players + trigger: + set {Player} to player's class + message "%{Player}%" # org.bukkit.entity.Player +``` + +###### 在effect命令中导入 + +由于导入块在 effect 命令中不可用,因此您可以使用 import effect(仅在 effect 命令中可用): + +```sk +import [as ] +``` + +此导入只能在以上效果命令中使用,直到您停止服务器。 + +##### _处理内部类_ + +有时,一个类可能嵌套在另一个类中。当引用类的完全限定名称时,内部类使用一个`$`而不是`.` + +例如,将`org.bukkit.entity.EnderDragon.Phase`变成`org.bukkit.entity.EnderDragon$Phase`。 + +内部类通常比其周围的类具有更通用的名称,因此应在别名下导入这些名称: + +```sk +import: + org.bukkit.entity.EnderDragon$Phase as EnderDragonPhase +``` + +导入这些类的另一种方法是只导入它们的封闭类: + +```sk +import: + org.bukkit.entity.EnderDragon + +on load: + set {phase} to EnderDragon.Phase.LEAVE_PORTAL +``` + +#### 运行 Java 代码 + +##### _调用方法_ + +语法: + +```sk +%object%.(%objects%) +``` + +示例: + +```sk +event-block.breakNaturally() +(last spawned creeper).setPowered(true) +player.giveExpLevels({_levels}) +``` + +方法可以用作 **Effects** 、 **Expressions** 和 **Conditions** 。如果用作**Conditions**,则只要方法的返回值不是 `false` 、`null`或`0` ,这个 **Conditions** 就会通过。 + +###### 调用非公共方法 + +如果尝试调用的方法不是公共的,则可能需要在方法名称前面加上括号中的声明类。由于一个对象在多个父类中可能具有同名的非公共方法,因此必须显式指定在何处查找该方法。 + +语法: + +```sk +{_arraylist}.[ArrayList]fastRemove(1) +``` + +###### 调用重载的方法 + +通常, **skript-reflect** 可以从运行时传递的参数中推断出要调用的正确的重载方法。如果需要使用某个方法的某种实现,可以在方法名称的末尾附加一个逗号分隔的列表,并用括号括起来。 + +语法: + +```sk +System.out.println[Object]({_something}) + +Math.max[int, int](0, {_value}) +``` + +##### _调用字段_ + +语法: + +```sk +%object%. +``` + +###### 调用非公共字段 + +如果您尝试访问的字段不是公共的,则可能需要在字段名称前面加上括号中的声明类。由于一个对象在多个父类中可能具有同名的非公共字段,因此必须显式指定查找该字段的位置。 + +示例: + +```sk +{_hashmap}.[HashMap]modCount +``` + +##### _调用构造函数_ + +语法: + +```sk +[a] new %javatype%(%objects%) +``` + +示例: + +```sk +new Location(player's world, 0, 0, 0) +``` + +#### 处理事件 + +##### 监听事件 + +您可以通过引用导入的类来收听任何基于 Bukkit 的事件(包括其他插件添加的事件)。例如,如果要收听 `org.bukkit.event.entity.EnderDragonChangePhaseEvent`: + +```sk +import: + org.bukkit.event.entity.EnderDragonChangePhaseEvent + +on EnderDragonChangePhaseEvent: + # your code +``` + +:::warning + +一些插件使用自己的事件处理系统,或者不通过 **Bukkit** 的事件执行器传递他们的事件( **Skript** 的一些内部事件就是这种情况)。 + +为了侦听事件,它必须扩展`org.bukkit.event.Event`并由 **Bukkit** 的事件执行器执行。 + +::: + +您还可以使用同一处理程序侦听多个事件。这些事件不必相关,但如果尝试访问在一个事件中可用但在另一个事件中不可用的方法,则应采取适当的预防措施。例如,如果要同时侦听`org.bukkit.event.entity.ProjectileLaunchEvent`和`org.bukkit.event.entity.ProjectileHitEvent`: + +```sk +import: + org.bukkit.event.entity.ProjectileLaunchEvent + org.bukkit.event.entity.ProjectileHitEvent + +on ProjectileLaunchEvent and ProjectileHitEvent: + # your code +``` + +##### 使用`event` **Expressions** + +**skript-reflect** 公开一个叫做`event`的 **Expressions**,允许您使用反射访问事件值。 + +语法: + +```sk +[the] event +``` + +示例: + +```sk +import: + org.bukkit.event.entity.EnderDragonChangePhaseEvent + org.bukkit.entity.EnderDragon$Phase as EnderDragonPhase + +on EnderDragonChangePhaseEvent: + if event.getNewPhase() is EnderDragonPhase.CIRCLING: + event.setNewPhase(EnderDragonPhase.CHARGE_PLAYER) +``` + +:::info + +该 event 表达式也可用于正常的 Skript 事件。 + +::: + +##### 设置优先级 + +可以将事件的优先级设置为控制特定事件处理程序相对于其他事件处理程序的运行时间。 + +示例: + +```sk +import: + org.bukkit.event.entity.EnderDragonChangePhaseEvent + +on EnderDragonChangePhaseEvent with priority highest: + # your code +``` + +可以使用`org.bukkit.event.EventPriority`中定义的任何事件优先级。优先级较低的事件处理程序在优先级较高的事件处理程序之前运行。 + +事件优先级: + +``` +lowest +low +normal +high +highest +monitor +``` + +##### 处理已取消的事件 + +默认情况下,如果事件被优先级较低的处理程序取消,则不会调用事件处理程序。可以通过指定处理程序应处理`all`事件来更改此行为。 + +示例: + +```sk +import: + org.bukkit.event.block.BlockBreakEvent + +on all BlockBreakEvent: + uncancel event +``` + +#### 一些 **skript-reflect** 内置的小工具 + +##### Collect + +```sk +[%objects%] +[%objects% as %javatype%] +``` + +创建包含指定对象的数组。指定类型可确定生成数组的组件类型。 + +:::info + +此语法中的括号是文字,不表示可选组。 + +::: + +##### Spread + +```sk +...%object% +``` + +将Java类型的数组转化为sk可读形式。 + +实例: + +```sk +set {_list::*} to ...{_array} +``` + +##### 创建数组 + +```sk +new %javatype%[%integer%] +``` + +创建给定类型和大小的数组。类型可能是原始类型,不需要导入。 + +:::info + +此语法中的括号是文字,不表示可选组。 + +::: + +##### 通过索引获取数组的值 + +```sk +%array%[%integer%] +``` + +表示数组的某个索引处的值。 + +可以读取和写入此值。 + +:::info + +此语法中的括号是文字,不表示可选组。 + +::: + +##### Null + +```sk +null +``` + +在 **Java** 中表示 `null` 。这与 **Skript** 的``不同 . + +##### Bits + +```sk +[the] (bit %number%|bit(s| range) [from] %number%( to |[ ]-[ ])%number%) of %numbers% +%numbers%'[s] (bit %number%|1¦bit(s| range) [from] %number%( to |[ ]-[ ])%number%) +``` + +表示数字中的位的子集。 + +可以读取和写入此值。 + +##### Raw Expression + +```sk +[the] raw %objects% +``` + +返回表达式的基础对象。 + +:::info + +与 [Expression](https://tpgamesnl.gitbook.io/skript-reflect/advanced/custom-syntax#expression) 一起使用时,可以将其设置为一个值,这将更改该参数的输入值。这可用于将数据存储在调用触发器的变量中。 + +```sk +import: + ch.njol.skript.lang.Variable + +effect put %objects% in %objects%: + parse: + expr-2 is an instance of Variable # to check if the second argument is a variable + continue + trigger: + set raw expr-2 to expr-1 +``` + +::: + +##### 成员 + +```sk +[the] (fields|methods|constructors) of %objects% +%objects%'[s] (fields|methods|constructors) +``` + +返回对象的字段、方法或构造函数的列表,包括其修饰符和参数。 + +如果需要不带修饰符或参数详细信息的字段或方法名称列表,请参阅[成员名称](https://tpgamesnl.gitbook.io/skript-reflect/basics/utilities#member-names)。 + +##### 成员的名字 + +```sk +[the] (field|method) names of %objects% +%objects%'[s] (field|method) names +``` + +返回对象的字段或方法的列表。 + +##### 判断对象是否是某个类的实例 + +```sk +%objects% (is|are) [a[n]] instance[s] of %javatypes% +%objects% (is not|isn't|are not|aren't) [a[n]] instance[s] of %javatypes% +``` + +检查对象是否是给定 **Java** 类型的实例。 + +##### 类引用 + +```sk +%javatype%.class +``` + +从给定的 **Java** 类型返回对类的引用。返回`java.lang.Class`类型的对象。此表达式还支持不需要导入的基元类型。 + +##### 插件实例 + +```sk +[(an|the)] instance of [the] plugin %javatype/string% +``` + +返回给定插件的实例(字符串形式的名称或插件类)。 + +更高级的用法及详细内容请自行查阅[skript-reflect文档](https://tpgamesnl.gitbook.io/skript-reflect)