From 2eef24be0d5cc23ddc11b7a38541566709547506 Mon Sep 17 00:00:00 2001 From: Futrime Date: Thu, 1 Feb 2024 22:00:58 +0800 Subject: [PATCH] docs: migrate from LiteLoaderBDS --- .github/workflows/build_docs.yml | 36 + README.md | 2 + docs/apis/DataAPI/ConfigFile.md | 275 +++ docs/apis/DataAPI/ConfigFile.zh.md | 276 +++ docs/apis/DataAPI/DataBase.md | 105 ++ docs/apis/DataAPI/DataBase.zh.md | 463 +++++ docs/apis/DataAPI/Economy.md | 136 ++ docs/apis/DataAPI/Economy.zh.md | 136 ++ docs/apis/DataAPI/OtherData.md | 85 + docs/apis/DataAPI/OtherData.zh.md | 85 + docs/apis/DataAPI/PermAPI.md | 390 ++++ docs/apis/DataAPI/PermAPI.zh.md | 394 ++++ docs/apis/DataAPI/PlayerData.md | 125 ++ docs/apis/DataAPI/PlayerData.zh.md | 125 ++ docs/apis/EventAPI/BlockEvents.md | 281 +++ docs/apis/EventAPI/BlockEvents.zh.md | 283 +++ docs/apis/EventAPI/EconomicEvents.md | 108 ++ docs/apis/EventAPI/EconomicEvents.zh.md | 108 ++ docs/apis/EventAPI/EntityEvents.md | 226 +++ docs/apis/EventAPI/EntityEvents.zh.md | 274 +++ docs/apis/EventAPI/Listen.md | 40 + docs/apis/EventAPI/Listen.zh.md | 42 + docs/apis/EventAPI/OtherEvents.md | 60 + docs/apis/EventAPI/OtherEvents.zh.md | 60 + docs/apis/EventAPI/PlayerEvents.md | 587 ++++++ docs/apis/EventAPI/PlayerEvents.zh.md | 606 +++++++ docs/apis/GameAPI/Basic.md | 186 ++ docs/apis/GameAPI/Basic.zh.md | 172 ++ docs/apis/GameAPI/Block.md | 202 +++ docs/apis/GameAPI/Block.zh.md | 203 +++ docs/apis/GameAPI/BlockEntity.md | 73 + docs/apis/GameAPI/BlockEntity.zh.md | 73 + docs/apis/GameAPI/Command.md | 435 +++++ docs/apis/GameAPI/Command.zh.md | 444 +++++ docs/apis/GameAPI/Container.md | 154 ++ docs/apis/GameAPI/Container.zh.md | 154 ++ docs/apis/GameAPI/Device.md | 74 + docs/apis/GameAPI/Device.zh.md | 73 + docs/apis/GameAPI/Entity.md | 693 ++++++++ docs/apis/GameAPI/Entity.zh.md | 730 ++++++++ docs/apis/GameAPI/GameUtils.md | 58 + docs/apis/GameAPI/GameUtils.zh.md | 58 + docs/apis/GameAPI/Item.md | 231 +++ docs/apis/GameAPI/Item.zh.md | 232 +++ docs/apis/GameAPI/Packet.md | 139 ++ docs/apis/GameAPI/Packet.zh.md | 139 ++ docs/apis/GameAPI/Particle.md | 139 ++ docs/apis/GameAPI/Particle.zh.md | 140 ++ docs/apis/GameAPI/Player.md | 1360 ++++++++++++++ docs/apis/GameAPI/Player.zh.md | 2071 ++++++++++++++++++++++ docs/apis/GameAPI/ScoreBoard.md | 258 +++ docs/apis/GameAPI/ScoreBoard.zh.md | 263 +++ docs/apis/GameAPI/Server.md | 92 + docs/apis/GameAPI/Server.zh.md | 92 + docs/apis/GuiAPI/Form.md | 111 ++ docs/apis/GuiAPI/Form.zh.md | 111 ++ docs/apis/GuiAPI/FormBuilder.md | 262 +++ docs/apis/GuiAPI/FormBuilder.zh.md | 262 +++ docs/apis/LLSEJSPlugin.md | 60 + docs/apis/LLSEJSPlugin.zh.md | 62 + docs/apis/LanguageSupport.md | 104 ++ docs/apis/LanguageSupport.zh.md | 111 ++ docs/apis/NativeAPI/NativeFunction.zh.md | 116 ++ docs/apis/NativeAPI/NativePatch.zh.md | 51 + docs/apis/NativeAPI/NativePointer.zh.md | 121 ++ docs/apis/NativeAPI/Summary.zh.md | 7 + docs/apis/NbtAPI/NBT.md | 69 + docs/apis/NbtAPI/NBT.zh.md | 69 + docs/apis/NbtAPI/NBTCompound.md | 237 +++ docs/apis/NbtAPI/NBTCompound.zh.md | 237 +++ docs/apis/NbtAPI/NBTList.md | 161 ++ docs/apis/NbtAPI/NBTList.zh.md | 161 ++ docs/apis/NbtAPI/NBTValue.md | 67 + docs/apis/NbtAPI/NBTValue.zh.md | 68 + docs/apis/README.md | 109 ++ docs/apis/README.zh.md | 108 ++ docs/apis/ScriptAPI/Ll.md | 203 +++ docs/apis/ScriptAPI/Ll.zh.md | 221 +++ docs/apis/ScriptAPI/Logger.md | 154 ++ docs/apis/ScriptAPI/Logger.zh.md | 154 ++ docs/apis/ScriptAPI/ScriptHelp.md | 167 ++ docs/apis/ScriptAPI/ScriptHelp.zh.md | 168 ++ docs/apis/ScriptAPI/i18n.md | 154 ++ docs/apis/ScriptAPI/i18n.zh.md | 155 ++ docs/apis/SystemAPI/File.md | 385 ++++ docs/apis/SystemAPI/File.zh.md | 385 ++++ docs/apis/SystemAPI/FileSystem.md | 130 ++ docs/apis/SystemAPI/FileSystem.zh.md | 130 ++ docs/apis/SystemAPI/Network.md | 221 +++ docs/apis/SystemAPI/Network.zh.md | 570 ++++++ docs/apis/SystemAPI/SystemCall.md | 56 + docs/apis/SystemAPI/SystemCall.zh.md | 56 + docs/apis/SystemAPI/SystemInfo.md | 44 + docs/apis/SystemAPI/SystemInfo.zh.md | 44 + docs/faq.md | 0 docs/img/logo.png | Bin 0 -> 7093 bytes docs/index.md | 0 mkdocs.yml | 122 ++ requirements.txt | 29 + 99 files changed, 20458 insertions(+) create mode 100644 .github/workflows/build_docs.yml create mode 100644 docs/apis/DataAPI/ConfigFile.md create mode 100644 docs/apis/DataAPI/ConfigFile.zh.md create mode 100644 docs/apis/DataAPI/DataBase.md create mode 100644 docs/apis/DataAPI/DataBase.zh.md create mode 100644 docs/apis/DataAPI/Economy.md create mode 100644 docs/apis/DataAPI/Economy.zh.md create mode 100644 docs/apis/DataAPI/OtherData.md create mode 100644 docs/apis/DataAPI/OtherData.zh.md create mode 100644 docs/apis/DataAPI/PermAPI.md create mode 100644 docs/apis/DataAPI/PermAPI.zh.md create mode 100644 docs/apis/DataAPI/PlayerData.md create mode 100644 docs/apis/DataAPI/PlayerData.zh.md create mode 100644 docs/apis/EventAPI/BlockEvents.md create mode 100644 docs/apis/EventAPI/BlockEvents.zh.md create mode 100644 docs/apis/EventAPI/EconomicEvents.md create mode 100644 docs/apis/EventAPI/EconomicEvents.zh.md create mode 100644 docs/apis/EventAPI/EntityEvents.md create mode 100644 docs/apis/EventAPI/EntityEvents.zh.md create mode 100644 docs/apis/EventAPI/Listen.md create mode 100644 docs/apis/EventAPI/Listen.zh.md create mode 100644 docs/apis/EventAPI/OtherEvents.md create mode 100644 docs/apis/EventAPI/OtherEvents.zh.md create mode 100644 docs/apis/EventAPI/PlayerEvents.md create mode 100644 docs/apis/EventAPI/PlayerEvents.zh.md create mode 100644 docs/apis/GameAPI/Basic.md create mode 100644 docs/apis/GameAPI/Basic.zh.md create mode 100644 docs/apis/GameAPI/Block.md create mode 100644 docs/apis/GameAPI/Block.zh.md create mode 100644 docs/apis/GameAPI/BlockEntity.md create mode 100644 docs/apis/GameAPI/BlockEntity.zh.md create mode 100644 docs/apis/GameAPI/Command.md create mode 100644 docs/apis/GameAPI/Command.zh.md create mode 100644 docs/apis/GameAPI/Container.md create mode 100644 docs/apis/GameAPI/Container.zh.md create mode 100644 docs/apis/GameAPI/Device.md create mode 100644 docs/apis/GameAPI/Device.zh.md create mode 100644 docs/apis/GameAPI/Entity.md create mode 100644 docs/apis/GameAPI/Entity.zh.md create mode 100644 docs/apis/GameAPI/GameUtils.md create mode 100644 docs/apis/GameAPI/GameUtils.zh.md create mode 100644 docs/apis/GameAPI/Item.md create mode 100644 docs/apis/GameAPI/Item.zh.md create mode 100644 docs/apis/GameAPI/Packet.md create mode 100644 docs/apis/GameAPI/Packet.zh.md create mode 100644 docs/apis/GameAPI/Particle.md create mode 100644 docs/apis/GameAPI/Particle.zh.md create mode 100644 docs/apis/GameAPI/Player.md create mode 100644 docs/apis/GameAPI/Player.zh.md create mode 100644 docs/apis/GameAPI/ScoreBoard.md create mode 100644 docs/apis/GameAPI/ScoreBoard.zh.md create mode 100644 docs/apis/GameAPI/Server.md create mode 100644 docs/apis/GameAPI/Server.zh.md create mode 100644 docs/apis/GuiAPI/Form.md create mode 100644 docs/apis/GuiAPI/Form.zh.md create mode 100644 docs/apis/GuiAPI/FormBuilder.md create mode 100644 docs/apis/GuiAPI/FormBuilder.zh.md create mode 100644 docs/apis/LLSEJSPlugin.md create mode 100644 docs/apis/LLSEJSPlugin.zh.md create mode 100644 docs/apis/LanguageSupport.md create mode 100644 docs/apis/LanguageSupport.zh.md create mode 100644 docs/apis/NativeAPI/NativeFunction.zh.md create mode 100644 docs/apis/NativeAPI/NativePatch.zh.md create mode 100644 docs/apis/NativeAPI/NativePointer.zh.md create mode 100644 docs/apis/NativeAPI/Summary.zh.md create mode 100644 docs/apis/NbtAPI/NBT.md create mode 100644 docs/apis/NbtAPI/NBT.zh.md create mode 100644 docs/apis/NbtAPI/NBTCompound.md create mode 100644 docs/apis/NbtAPI/NBTCompound.zh.md create mode 100644 docs/apis/NbtAPI/NBTList.md create mode 100644 docs/apis/NbtAPI/NBTList.zh.md create mode 100644 docs/apis/NbtAPI/NBTValue.md create mode 100644 docs/apis/NbtAPI/NBTValue.zh.md create mode 100644 docs/apis/README.md create mode 100644 docs/apis/README.zh.md create mode 100644 docs/apis/ScriptAPI/Ll.md create mode 100644 docs/apis/ScriptAPI/Ll.zh.md create mode 100644 docs/apis/ScriptAPI/Logger.md create mode 100644 docs/apis/ScriptAPI/Logger.zh.md create mode 100644 docs/apis/ScriptAPI/ScriptHelp.md create mode 100644 docs/apis/ScriptAPI/ScriptHelp.zh.md create mode 100644 docs/apis/ScriptAPI/i18n.md create mode 100644 docs/apis/ScriptAPI/i18n.zh.md create mode 100644 docs/apis/SystemAPI/File.md create mode 100644 docs/apis/SystemAPI/File.zh.md create mode 100644 docs/apis/SystemAPI/FileSystem.md create mode 100644 docs/apis/SystemAPI/FileSystem.zh.md create mode 100644 docs/apis/SystemAPI/Network.md create mode 100644 docs/apis/SystemAPI/Network.zh.md create mode 100644 docs/apis/SystemAPI/SystemCall.md create mode 100644 docs/apis/SystemAPI/SystemCall.zh.md create mode 100644 docs/apis/SystemAPI/SystemInfo.md create mode 100644 docs/apis/SystemAPI/SystemInfo.zh.md create mode 100644 docs/faq.md create mode 100644 docs/img/logo.png create mode 100644 docs/index.md create mode 100644 mkdocs.yml create mode 100644 requirements.txt diff --git a/.github/workflows/build_docs.yml b/.github/workflows/build_docs.yml new file mode 100644 index 00000000..2a271cbd --- /dev/null +++ b/.github/workflows/build_docs.yml @@ -0,0 +1,36 @@ +on: + push: + paths: + - .github/workflows/build_docs.yml + - docs/** + - mkdocs.yml + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - run: | + pip install -r requirements.txt + + - run: | + mkdocs build + + - uses: actions/upload-pages-artifact@v3 + with: + path: | + site/ + + deploy: + # if: github.ref == 'refs/heads/main' && github.event_name == 'push' + needs: + - build + permissions: + id-token: write + pages: write + runs-on: ubuntu-latest + steps: + - uses: actions/deploy-pages@v4 + \ No newline at end of file diff --git a/README.md b/README.md index 8e49239b..9fd1ecec 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ lip install github.com/LiteLDev/LegacyScriptEngine Put LLSE plugins directly in `/path/to/bedrock_dedicated_server/plugins/` and run the server, then the plugins will be migrated to LeviLamina plugin manifest automatically. To load them, you need to restart the server. +For more information, please refer to [the documentation](https://lse.liteldev.com). + ## Contributing If you have any questions, please open an issue to discuss it. diff --git a/docs/apis/DataAPI/ConfigFile.md b/docs/apis/DataAPI/ConfigFile.md new file mode 100644 index 00000000..75bc0fcf --- /dev/null +++ b/docs/apis/DataAPI/ConfigFile.md @@ -0,0 +1,275 @@ +# LLSE - Configuration and Data Processing Interface Documentation + +> Here are a variety of options for working with **large amounts of data** + +In the process of plugin work, it is inevitable to encounter scenarios that need to deal with configuration and a large amount of game-related data. +LLSE provides a lot of `infrastructure`, including configuration files, databases, economic systems, and more. +It is convenient for developers to focus on business code implementation, rather than entangled in the technical details of these aspects. + +## 🔨 Profile API + +The configuration file is generally used to separate some settings of the plug-in that can be modified by the user into a file, so as to facilitate the modification of some settings. +Therefore, the content and format of the configuration file generally need to be readable. +LLSE provides the ConfigFile configuration file interface to accomplish this task. +Of course, you can also manually read and write files to assist in the operation of related configuration files. + +
+ +### Description: Selection of Configuration File Type + +The choice of configuration file format will affect the type of configuration data you can store. + +- `JSON` format can store **most** types of data, including arrays, objects, etc., and the representation logic is relatively rich. +- `ini` format is relatively `simple and intuitive`, and it is very easy for others to modify it, but the type of data stored is subject to certain restrictions. + +Please make your choice as needed. + +
+ +### 📰 JSON Format Configuration File + +#### Create/Open a JSON Configuration File + +[JavaScript] `new JsonConfigFile(path[,default])` +[Lua] `JsonConfigFile(path[,default])` + +- Parameters: + - path : `String` + The path where the configuration file is located, based on the BDS root directory. + LLSE will automatically create a directory in the configuration file path if it does not already exist. + - default : `String` + (Optional parameter) Default content of the configuration file. + If during initialization it **does not exist**, the engine will create a new configuration file and write the default content here. + If this parameter is not passed in, the new configuration file will be empty. +- Return value: Open/created profile object. +- Return value type: `JsonConfigFile` + - Throws exception if create/open fails. + +We recommend that you create a directory named `BDS_Root_Directory/plugins/plugin_name/` with a config file named `config.json` to keep the configuration of each plugin uniform. + +
+ +For a JSON profile object `conf`, you have these read and write interfaces available. + +#### Initialize Configuration Items (Convenience Function + +`conf.init(name,default)` + +- Parameters: + - name : `String` + Configuration item name + - default : `Any type` + The value written when the configuration item is initialized. +- Return value: The data of the specified configuration item. +- Return value type: `Any type`, subject to the specific type of data stored. + +Here is an easy way to initialize the configuration file, avoiding the trouble of handwriting the contents of the default configuration file: + +If the accessed configuration item does not exist, then the engine will automatically create the item `init` in the configuration file and write the given default value. +If the accessed configuration item `init` already exists, the engine will read and return the existing value in the configuration file. +
+ +#### Write Configuration Item + +`conf.set(name,data)` + +- Parameters: + - name : `String` + Configuration item name + - data : `Any type` + Configuration data to write. The allowed data types are: + `Integer` `Float` `String` `Boolean` `Array` `Object` + The above elements can only be nested inside `Array` and `Object`. + +- Return value: Whether the write is successful. + +- Return value type: `Boolean` + +
+ +#### Read Configuration Items + +`conf.get(name[,default])` + +- Parameters: + - name : `String` + Configuration item name + - default : `Any type` + (optional) The default value to return when the read fails. + The default is `Null` +- Return value: The data of the specified configuration item. +- Return value type: `Any type`, subject to the specific type of data stored. + +
+ +#### Delete Configuration Item + +`conf.delete(name)` + +- Parameter: + - name : `String` + Configuration item name +- Return value: Whether the deletion is successful. +- Return value type: `Boolean` + +If you don't need this configuration item, in order to avoid confusion when others modify the configuration file, you can choose to delete it. + +
+ +### 📄 Ini Format Configuration File + +#### Create/Open an Ini Profile + +[JavaScript] `new IniConfigFile(path[,default])` +[Lua] `IniConfigFile(path[,default])` + +- Parameters: + - path : `String` + The path where the configuration file is located, based on the BDS root directory. + LLSE will automatically create a directory in the configuration file path if it does not already exist. + - default : `String` + (Optional parameter) Default content of the configuration file. + If during initialization it **does not exist**, the engine will create a new configuration file and write the default content here. + If this parameter is not passed in, the new configuration file will be empty. +- Return value: Open/created profile object. +- Return value type: `IniConfigFile` + - Throws exception if create/open fails. + +We recommend that you create a directory named `BDS_Root_Directory/plugins/plugin_name/` with a config file named `config.json` to keep the configuration of each plugin uniform. + +
+ +For an ini profile object `conf`, you have these read and write interfaces available: + +#### Initialize Configuration Items (Convenience Function) + +`conf.init(section,name,default)` + +- Parameters: + - section : `String` + Configuration item key name + - name : `String` + Configuration item name + - default : `Any type` + The value written when the configuration item is initialized. The allowed data types are: + `Integer` `Float` `String` `Boolean` +- Return value: The data of the specified configuration item. +- Return value type: `Any type`, subject to the specific type of data stored. + +Here is an easy way to initialize the configuration file, avoiding the trouble of handwriting the contents of the default configuration file. + +If the accessed configuration item does not exist, then the engine will automatically create the item `init` in the configuration file and write the given default value. +If the accessed configuration item `init` already exists, the engine will read and return the existing value in the configuration file. + +
+ +#### Write Configuration Item + +`conf.set(section,name,data)` + +- Parameters: + - section : `String` + Configuration item key name + - name : `String` + Configuration item name + - data : `Any type` + Configuration data to write. The allowed data types are: + `Integer` `Float` `String` `Boolean` + +- Return value: Whether the write is successful. + +- Return value type: `Boolean` + +If the configuration item does not exist, the interface will be created automatically. + +
+ +#### Read Configuration Items + +Read string `conf.getStr(section,name[,default])` +Read integer `conf.getInt(section,name[,default])` +Read float `conf.getFloat(section,name[,default])` +Read boolean `conf.getBool(section,name[,default])` + +- Parameters: + - section : `String` + Configuration item key name + - name : `String` + Configuration item name + - default : `String`/ `Integer`/ `Float`/ `Boolean` + (optional) The default value to return when the read fails. + The default is `0` +- Return value: The data of the specified configuration item. +- Return value type: `String`/ `Integer`/ `Float`/ `Boolean` + +
+ +#### Delete Configuration Item + +`conf.delete(section,name)` + +- Parameters: + - section : `String` + Configuration item key name + - name : `String` + Configuration item name +- Return value: Whether the deletion is successful. +- Return value type: `Boolean` + +If you don't need this configuration item, in order to avoid confusion when others modify the configuration file, you can choose to delete it. + +
+ +### 💼 Other Common Interface Functions + +For a profile object `conf`, you can use these generic interfaces for auxiliary purposes: + +#### Reload the Configuration Items in the File + +`conf.reload()` + +- Return value: Whether the load was successful. + +For performance reasons, the configuration file interface caches read operations, each read operation is read from direct memory, and writes are written directly to disk files. Considering that the configuration file may be modified by the user, after you confirm that the user has modified the configuration file, you need to use this function to refresh the memory cache data of the configuration file. + +
+ +#### Close Config File + +`conf.close()` + +- Return value: Whether closing the file was successful. + +After the profile is closed, do not continue to use it! + +
+ +#### Get Configuration File Path + +`conf.getPath()` + +- Return value: The file path of the current configuration file. +- Return value type: `String` + +
+ +#### Read the Content of the Entire Configuration File + +`conf.read()` + +- Return value: All contents of the current configuration file. +- Return value type: `String` + +
+ +#### Write the Contents of the Entire Configuration File + +`conf.write(content)` + +- Parameter: + - content : `String` + The string that will be written to the configuration file. +- Return value: Whether the write is successful. +- Return value type: `Boolean` + +
\ No newline at end of file diff --git a/docs/apis/DataAPI/ConfigFile.zh.md b/docs/apis/DataAPI/ConfigFile.zh.md new file mode 100644 index 00000000..6bc6c537 --- /dev/null +++ b/docs/apis/DataAPI/ConfigFile.zh.md @@ -0,0 +1,276 @@ +# 脚本引擎 - 配置与数据处理接口文档 + +> 这里为你提供了处理 **大量数据** 时的多种可选方案 + +在插件工作过程中,难免会碰到需要处理配置和大量游戏相关数据的场景。 +脚本引擎为脚本插件提供了大量**基础设施**,包括配置文件、数据库、经济系统等。 +方便开发者专注于业务代码实现,而非纠结于这些方面的技术细节。 + +## 🔨 配置文件 API + +配置文件,一般用于将插件的某些可供用户修改的设置项独立成文件,以方便修改某些设置。 +因此,配置文件的内容和格式一般需要有一定的可读性。 +脚本引擎提供 ConfigFile 配置文件接口来完成这个任务。 +当然,你也可以手动读写文件来协助相关配置文件的操作。 + +
+ +### 说明:配置文件类型的选择 + +配置文件格式的选择,将影响你可以储存的配置数据类型。 + +- `JSON`(**JS** **O**bject **N**otation) 格式可以储存**大多数**类型的数据,包括数组、对象等,表示的逻辑相对丰富 +- `Ini`(**Ini**tialization File) 格式相对**简单直观**,他人修改起来非常轻松,不过储存的数据类型受到一定限制 + +请按需做出选择。 + +
+ +### 📰 JSON 格式配置文件 + +#### 创建 / 打开一个 JSON 配置文件 + +[JavaScript] `new JsonConfigFile(path[,default])` +[Lua] `JsonConfigFile(path[,default])` + +- 参数: + - path : `String` + 配置文件所在路径,以BDS根目录为基准 + 如果配置文件路径中有目录尚不存在,脚本引擎会自动创建 + - default : `String` + (可选参数)配置文件的默认内容。 + 如果初始化时目标文件**不存在**,引擎将新建一个配置文件并将此处的默认内容写入文件中。 + 如果不传入此参数,新建时的配置文件将为空 +- 返回值:打开 / 创建的配置文件对象 +- 返回值类型:`JsonConfigFile` + - 如果创建 / 打开失败,将抛出异常 + +我们建议你在 `BDS根目录/plugins/插件名字/` 目录下建立名为`config.json`的配置文件,以保持各插件的配置统一 + +
+ +对于一个 JSON 配置文件对象`conf`,你有这些读写接口可用 + +#### 初始化配置项(方便函数) + +`conf.init(name,default)` + +- 参数: + - name : `String` + 配置项名字 + - default : `任意类型` + 配置项初始化时写入的值 +- 返回值:指定配置项的数据 +- 返回值类型:`任意类型`,以具体储存的数据类型为准 + +这里提供了一种简便的方法来初始化配置文件,避免了需要手写默认配置文件内容的麻烦 + +如果`init`访问的配置项不存在,那么引擎将在配置文件中自动创建此项,并写入给出的默认值 +如果`init`访问的配置项已经存在,引擎将读取并返回配置文件中已有的值 + +
+ +#### 写入配置项 + +`conf.set(name,data)` + +- 参数: + - name : `String` + 配置项名字 + - data : `指定类型` + 要写入的配置数据。允许的数据类型有: + `Integer` `Float` `String` `Boolean` `Array` `Object` + 其中,`Array` 和 `Object` 内部仅能嵌套上面这些元素 + +- 返回值:是否写入成功 + +- 返回值类型:`Boolean` + +
+ +#### 读取配置项 + +`conf.get(name[,default])` + +- 参数: + - name : `String` + 配置项名字 + - default : `任意类型` + (可选参数)当读取失败时返回的默认值 + 默认为`Null` +- 返回值:指定配置项的数据 +- 返回值类型:`任意类型`,以具体储存的数据类型为准 + +
+ +#### 删除配置项 + +`conf.delete(name)` + +- 参数: + - name : `String` + 配置项名字 +- 返回值:是否删除成功 +- 返回值类型:`Boolean` + +如果这个配置项你不需要了,为了避免在他人修改配置文件时引起迷惑,你可以选择将它删除 + +
+ +### 📄 Ini 格式配置文件 + +#### 创建 / 打开一个 Ini 配置文件 + +[JavaScript] `new IniConfigFile(path[,default])` +[Lua] `IniConfigFile(path[,default])` + +- 参数: + - path : `String` + 配置文件所在路径,以BDS根目录为基准 + 如果配置文件路径中有目录尚不存在,脚本引擎会自动创建 + - default : `String` + (可选参数)配置文件的默认内容。 + 如果初始化时目标文件**不存在**,引擎将新建一个配置文件并将此处的默认内容写入文件中。 + 如果不传入此参数,新建时的配置文件将为空 +- 返回值:打开 / 创建的配置文件对象 +- 返回值类型:`IniConfigFile` + - 如果创建 / 打开失败,将抛出异常 + +我们建议你在 `BDS根目录/plugins/插件名字/` 目录下建立名为`config.ini`的配置文件,以保持各插件的配置统一 + +
+ +对于一个 Ini 配置文件对象`conf`,你有这些读写接口可用 + +#### 初始化配置项(方便函数) + +`conf.init(section,name,default)` + +- 参数: + - section : `String` + 配置项键名 + - name : `String` + 配置项名字 + - default : `指定类型` + 配置项初始化时写入的值。允许的数据类型有: + `Integer` `Float` `String` `Boolean` +- 返回值:指定配置项的数据 +- 返回值类型:`任意类型`,以具体储存的数据类型为准 + +这里提供了一种简便的方法来初始化配置文件,避免了需要手写默认配置文件内容的麻烦 + +如果`init`访问的配置项不存在,那么引擎将在配置文件中自动创建此项,并写入给出的默认值 +如果`init`访问的配置项已经存在,引擎将读取并返回配置文件中已有的值 + +
+ +#### 写入配置项 + +`conf.set(section,name,data)` + +- 参数: + - section : `String` + 配置项键名 + - name : `String` + 配置项名字 + - data : `指定类型` + 要写入的配置数据。允许的数据类型有: + `Integer` `Float` `String` `Boolean` + +- 返回值:是否写入成功 + +- 返回值类型:`Boolean` + +如果配置项不存在,接口会自动创建 + +
+ +#### 读取配置项 + +读取字符串 `conf.getStr(section,name[,default])` +读取整数项 `conf.getInt(section,name[,default])` +读取浮点数 `conf.getFloat(section,name[,default])` +读取布尔值 `conf.getBool(section,name[,default])` + +- 参数: + - section : `String` + 配置项键名 + - name : `String` + 配置项名字 + - default : `String`/ `Integer`/ `Float`/ `Boolean` + (可选参数)当读取失败时返回的默认值 + 默认为`0` +- 返回值:指定配置项的数据 +- 返回值类型:`String`/ `Integer`/ `Float`/ `Boolean` + +
+ +#### 删除配置项 + +`conf.delete(section,name)` + +- 参数: + - section : `String` + 配置项键名 + - name : `String` + 配置项名字 +- 返回值:是否删除成功 +- 返回值类型:`Boolean` + +如果这个配置项你不需要了,为了避免在他人修改配置文件时引起迷惑,你可以选择将它删除 + +
+ +### 💼 其他的通用接口函数 + +对于一个配置文件对象`conf`,你可以使用这些辅助用途的通用接口 + +#### 重新加载文件中的配置项 + +`conf.reload()` + +- 返回值:是否成功加载 + +为了性能考虑,配置文件接口对读操作进行缓存,每次读取操作都从直接内存中读取,而写入才会直接写入磁盘文件。考虑到配置文件可能被用户修改,当你确认用户已经修改配置文件之后,需要使用此函数刷新配置文件的内存缓存数据。 + +
+ +#### 关闭配置文件 + +`conf.close()` + +- 返回值:是否成功关闭 + +配置文件关闭之后,请勿继续使用! + +
+ +#### 获取配置文件路径 + +`conf.getPath()` + +- 返回值:当前配置文件的文件路径 +- 返回值类型:`String` + +
+ +#### 读取整个配置文件的内容 + +`conf.read()` + +- 返回值:当前配置文件的所有内容 +- 返回值类型:`String` + +
+ +#### 写入整个配置文件的内容 + +`conf.write(content)` + +- 参数: + - content : `String` + 写入的内容 +- 返回值:是否写入成功 +- 返回值类型:`Boolean` + +
\ No newline at end of file diff --git a/docs/apis/DataAPI/DataBase.md b/docs/apis/DataAPI/DataBase.md new file mode 100644 index 00000000..92817180 --- /dev/null +++ b/docs/apis/DataAPI/DataBase.md @@ -0,0 +1,105 @@ +## 📦 Database API + +Database, generally used for plugins to persistently store data generated and processed by certain plugins. +Unlike configuration files, databases generally have no readability requirements, but have considerable considerations for performance and stability. +LLSE provides a consolidated database interface to accomplish this task. +In terms of specific implementation, the engine provides two different database formats: NoSQL database in key-value pair format, and SQL database in tabular format. You can use either as needed. + +
+ +### 🔑 Key-Value NoSQL Database + +Key-value databases are suitable for storing data in key-value form, such as `name:apple`, `value:5` and many more. +This is accomplished with `leveldb`. + +#### Create/Open a Key-Value Database + +Before using the database, you need to give a database path, the interface will open/create the specified database and return a database object. +A leveldb database is composed of multiple files, so you need to pass in the path of a folder where the database files will be stored. +If this directory already contains a database, it will be opened, otherwise a new one will be created. + +[JavaScript] `new KVDatabase(dir)` +[Lua] `KVDatabase(dir)` + +- Parameters: + - dir : `String` + The storage directory path of the database, based on the BDS root directory. +- Return value: Open/created database objects +- Return value type: `KVDatabase` + - If the return value is `Null`, it means the creation/opening failed + +When the given directory does not exist, it will try to automatically create the corresponding directory path layer by layer. + +After successfully opening the database, you can use the following interfaces to perform related operations. +For a database object `db`, with the following functions: + +
+ +#### Write Data Item + +`db.set(name,data)` + +- Parameters: + - name : `String` + Data item name + - data : `Any type` + Data to write. The allowed data types are: + `Integer` `Float` `String` `Boolean` `Array` `Object ` + The above elements can only be nested inside an `Array` or an `Object`. +- Return value: Whether the write is successful. +- Return value type: `Boolean` + +
+ +#### Read Data Item + +`db.get(name)` + +- Parameters: + - name : `String` + Data item name +- Return value: The data of this item stored in the database. +- Return value type: `Any type`, depending on the specific type of data stored. + - If the return value is `Null` it means that the data does not exist. + +
+ +#### Delete Data Item + +`db.delete(name)` + +- Parameters: + - name : `String` + Data item name +- Return value: Whether the deletion was successfu. +- Return value type: `Boolean` + +
+ +#### Get All Data Item Names + +`db.listKey()` + +- Return value: An array of all data item names. +- Return value type: `Array` + +
+ +#### Close the Database + +`db.close()` + +- Return value: Whether the shutdown was successful +- Return value type: `Boolean` + +After the database is closed, do not continue to use it! + +
+ +------ + +### 📋 SQL Database + +SQL databases are suitable for processing large amounts of relational data using SQL statements. The bottom layer of the interface is implemented using a cross-database operation framework, which can connect to most of the commonly used SQL databases in the market. + +
\ No newline at end of file diff --git a/docs/apis/DataAPI/DataBase.zh.md b/docs/apis/DataAPI/DataBase.zh.md new file mode 100644 index 00000000..3a35e38d --- /dev/null +++ b/docs/apis/DataAPI/DataBase.zh.md @@ -0,0 +1,463 @@ +## 📦 数据库 API + +数据库,一般用于插件可持久化地储存某些插件所生成和处理的数据。 +不同于配置文件,数据库一般没有可读性方面的要求,而对性能和稳定性有相当的考虑。 +脚本引擎提供统一数据库接口来完成这个任务。 +具体实现上,引擎提供了两种不同的数据库格式:键 - 值对格式的NoSQL数据库,和表格形式的SQL数据库。你可以按需使用。 + +### 📄 目录 + +🔑 [KVDB 键值对数据库](#🔑-键---值对-nosql数据库) +📋 [SQL数据库](#📋-sql数据库) +- 🔍 [预准备语句](#sql预准备语句) + +附: 各SQL的官方文档 +[SQLite](https://www.sqlite.org/docs.html) [MySQL](https://dev.mysql.com/doc/) + +
+ +## 🔑 键 - 值对 NoSQL数据库 + +键 - 值对数据库适用于储存键 - 值形式的数据, 形如`name:apple`, `value:5`等等。 +底层使用 [`LevelDB`](https://github.com/google/leveldb) 实现 + +### 创建 / 打开一个键值对数据库 + +在使用数据库之前,你先需要给出一个数据库路径,接口将打开/创建指定的数据库并返回一个数据库对象。 +一个LevelDB数据库是由多个文件组成的,所以你需要传入一个文件夹的路径,数据库文件会被储存于这个文件夹当中。 +如果这个目录已含有一个数据库,将打开它,否则会新建一个。 + +[JavaScript] `new KVDatabase(dir)` +[Lua] `KVDatabase(dir)` + +- 参数: + - dir : `String` + 数据库的储存目录路径,以BDS根目录为基准 +- 返回值:打开 / 创建的数据库对象 +- 返回值类型:`KVDatabase` + - 如果返回值为`Null`,则代表创建 / 打开失败 + +当给出的目录不存在时,将尝试自动逐层创建对应的目录路径 + +成功打开数据库后,你可以使用下面的接口来进行相关的操作。 +对于一个数据库对象`db`,有以下这些函数: + +
+ +### 写入数据项 + +`db.set(name,data)` + +- 参数: + - name : `String` + 数据项名字 + - data : `指定类型` + 要写入的数据。允许使用的数据类型有: + `Integer` `Float` `String` `Boolean` `Array` `Object ` + 其中,`Array` 和 `Object` 内部仅能嵌套上面出现的这些元素 +- 返回值:是否写入成功 +- 返回值类型:`Boolean` + +
+ +### 读取数据项 + +`db.get(name)` + +- 参数: + - name : `String` + 数据项名字 +- 返回值:数据库中储存的这个项的数据 +- 返回值类型:`任意类型`,以具体储存的数据类型为准 + - 如返回值为 `Null` 则表示数据不存在 + +
+ +### 删除数据项 + +`db.delete(name)` + +- 参数: + - name : `String` + 数据项名字 +- 返回值:是否成功删除 +- 返回值类型:`Boolean` + +
+ +### 获取所有数据项名字 + +`db.listKey()` + +- 返回值:所有的数据项名字数组 +- 返回值类型:`Array` + +
+ +### 关闭数据库 + +`db.close()` + +- 返回值:是否成功关闭 + +数据库关闭之后,请勿继续使用! + +
+ +------ + +
+ +## 📋 SQL数据库 + +SQL数据库适用于使用SQL语句处理大量的关系型数据。接口底层使用跨数据库操作框架实现,可对接绝大多数市面常用SQL数据库。 + +注:以下API若未注明均可能会抛出异常,建议使用各语言的异常处理语句嵌套。JavaScript可使用`try ... catch`语句,Lua可使用`pcall`。一般情况下未抛出错误即代表调用成功。 + +> 如果您是JavaScript插件开发者,您还可以尝试使用[Yoyo](https://gitee.com/Y_oyo)封装的LLDB链式操作库(主要面向不了解SQL语法的新手开发者)。详情 [点击这里](https://gitee.com/Y_oyo/yoyo-mcbe-lite-xloader-item/blob/master/sql/yoyoSqlite.js%202.0.0.md) + +
+ +### 打开一个SQL数据库会话 + +由于需要做到多数据库兼容, 连接数据库需要传入一个包含连接参数的对象或字符串。 + +[JavaScript] `new DBSession(type, params)` +[Lua] `DBSession(type, params)` + +- 参数: + - type : `String` + 数据库的类型,目前仅支持`"sqlite3"` + - params: `Object` + [连接参数](#连接参数) +- 返回值:打开的数据库会话对象 +- 返回值类型:`DBSession` + - 如果返回值为`Null`,则代表打开失败 + +[JavaScript] `new DBSession(str)` +[Lua] `DBSession(str)` + +- 参数: + - str : `String` + 形如`file:///mydb.db?k=v`, `mysql://root:password@localhost:3306/db`的连接字符串 +- 返回值:打开的数据库会话对象 +- 返回值类型:`DBSession` + - 如果返回值为`Null`,则代表打开失败 + +
+ +#### 连接参数 + +键|用途|可用数据库|示例|默认值 +---|---|---|---|--- +path|指定数据库所在路径|`SQLite`|`plugins/test.db`|- +create|数据库不存在是否自动创建|`SQLite`|`true`/`false`|`true` +readonly|以只读模式打开|`SQLite`|`true`/`false`|`false` +readwrite|以读写模式打开|`SQLite`|`true`/`false`|`true` + +
+ +### 执行SQL并获取结果集 + +`session.query(sql)` + +- 参数: + - sql : `String` + 要查询的SQL语句 +- 返回值:查询的结果(结果集) +- 返回值类型:`Array` + 返回数组的第1行(`result[0]`)为结果集的表头(列名),剩余行为结果数据 + + +若查询结果为: +| a | b | + ---|--- + ll |233 + h |114 + +则用query方法返回值表示为 +```json +[ + ["a", "b"], + ["ll", 233], + ["h", 114] +] +``` + + +
+ +### 执行SQL但不获取结果 + +`session.exec(sql)` +`session.execute(sql)` + +- 参数: + - sql : `String` + 要执行的SQL语句 +- 返回值:处理完毕的会话对象(便于连锁进行其他操作) +- 返回值类型:`DBSession` + +
+ +### 获取当前会话是否为打开状态 + +`session.isOpen()` + +- 返回值:是否为打开状态 +- 返回值类型:`Boolean` + +
+ +### 关闭数据库会话 + +`session.close()` + +- 返回值:关闭成功与否 +- 返回值类型:`Boolean` + +
+ +### SQL预准备语句 + +
+ +> 预准备语句(Prepared Statement)是SQL的一个重要部分。它的实现原理是:先将含有未知参数的SQL语句(发往服务端)处理、编译,再绑定参数,最终执行并返回结果。各个SQL的预准备语句实现可能不同,其预准备语句的表示方法也可能存在差异,所以请务必仔细阅读文档(直接去阅读对应SQL的官方文档则更好)。 +预准备语句的主要作用是防止SQL注入攻击——一种很常见的、危险的攻击。如果在未经检验的情况下直接使用用户输入的数据(就像BDS一样 xD),就可能会造成免密码登录甚至数据丢失(注入执行`DROP TABLE`或`DROP DATABASE`)等严重后果。所以在处理用户输入的数据时,更推荐使用预准备语句。其次,它可以在(服务器)只编译一次语句的情况下,实现多次输入。 + +
+ +#### 准备一个预准备语句 + +`session.prepare(sql)` + +- 参数: + - sql : `String` + 要准备的SQL语句 +- 返回值:预准备语句,失败抛出错误 +- 返回值类型:`DBStmt` + +##### 各个SQL的预准备语句 + +SQLite: +```sql +-- 单个?表示参数 +SELECT * FROM table WHERE id = ?; +-- ?X和?Y,其中X、Y均为参数名,后面可以更方便地绑定 +INSERT INTO table VALUES (?X, ?Y); +-- $X、?Y、:Z、@V都是带参数名的参数,您也可以使用$/:/@ + name的形式定义参数 +-- @符号在其他SQL中可能存在特殊含义,建议避免使用@开头 +INSERT INTO table VALUES ($X, ?Y, :Z, @V); +/* 注: https://www.sqlite.org/c3ref/bind_blob.html */ +``` + +MySQL: +```sql +-- 单个?表示参数 +SELECT * FROM table WHERE id = ?; +-- 原生MySQL并不支持含参数名的参数,LLDB为了兼容其他SQL简单实现了参数名解析,建议避免使用 +-- ?X和?Y,其中X、Y均为参数名,后面可以更方便地绑定 +INSERT INTO table VALUES (?X, ?Y); +-- $X、?Y、:Z都是带参数名的参数,您也可以使用$/:/ + name的形式定义参数 +INSERT INTO table VALUES ($X, ?Y, :Z); +``` + +
+ +#### 预准备语句对象 - 属性 + +| 属性 | 含义 | 类型 | 另见 | +| ---- | ---------- | -------- | ------- | +| `stmt.affectedRows` | 获取该预准备语句执行后影响的行数(仅对`INSERT` `UPDATE` `DELETE` `REPLACE` 等语句生效) | `Integer` | [SQLite](https://www.sqlite.org/c3ref/changes.html) [MySQL](https://dev.mysql.com/doc/c-api/8.0/en/mysql-affected-rows.html) | +| `stmt.insertId` | 获取该`INSERT`/`UPDATE`/`REPLACE`语句执行后最后一个更改行的行号(关于行号的解释详见官方文档) | `Integer` | [SQLite](https://www.sqlite.org/c3ref/last_insert_rowid.html) [MySQL](https://dev.mysql.com/doc/c-api/8.0/en/mysql-stmt-insert-id.html) + +这些对象属性都是只读的,无法被修改,并且只能在语句执行之后获取到 + +#### 绑定参数到一个SQL语句 + +`stmt.bind(val)` + +- 参数: + - val : `Any` + 要绑定的值 +- 注:本重载将会将值绑定到第一个未绑定的参数上 + +`stmt.bind(obj)` + +- 参数: + - val : `Object` + 要绑定的对象,等同于遍历此对象并执行`bind(val, key)` + +`stmt.bind(arr)` + +- 参数: + - arr : `Array` + 要绑定的数组,等同于遍历此数组并执行`bind(val)` + +`stmt.bind(val, index)` + +- 参数: + - val : `Any` + 要绑定的值 + - index : `Integer` + 要绑定到的参数索引(从`0`开始) + +`stmt.bind(val, name)` + +- 参数: + - val : `Any` + 要绑定的值 + - *name : `String` + 要绑定到的参数的参数名 + +
+ +- 返回值:处理完毕的语句对象(便于连锁进行其他操作) +- 返回值类型:`DBStmt` + +在绑定完成后,应调用`stmt.execute()`执行语句,否则语句将不会被执行 + +
+ +##### 一个样例搞懂几个重载函数 + +```js +let stmt = session.prepare("INSERT INTO table VALUSE ($a, $b, $c, $d, $e, $f, $g, $h)"); +let values = { + c: "have you", + d: "finished", + e: "your", + f: "homework?" +}; +stmt.bind(values); // c,d,e,f将会被绑定 +stmt.bind("LLSE"); // 将会绑定到a +stmt.bind(["****", "mojang"]); // 将会绑定到b和g +stmt.bind(114514, 7); // 将会绑定到h +``` + +
+ +#### 执行当前语句 + +`stmt.execute()` + +- 返回值:- 返回值:处理完毕的语句对象(便于连锁进行其他操作) +- 返回值类型:`DBStmt` + +
+ +#### 步进到下一行结果 + +`stmt.step()` +`stmt.next()` + +- 返回值:执行成功与否 +- 返回值类型:`Boolean` +- **注意:所有参数绑定完成后会自动执行语句,执行完后此时的step就在第一行上,所以应使用do...while语句遍历,而不是while语句,否则将导致第一行被跳过** + +
+ +#### 获取当前结果行 + +`stmt.fetch()` + +- 返回值:当前结果行,形如`{col1: "value", col2: 2333}` +- 返回值类型:`Object` + +
+ +#### 获取所有结果行 + +`stmt.fetchAll()` + +- 返回值:查询的结果(结果集),详见[执行SQL并获取结果集](#执行sql并获取结果集) +- 返回值类型:`Array` + +
+ +`stmt.fetchAll(callback)` + +- 参数: + - callback : `Function` + 回调函数,用于遍历结果行;在回调函数中返回`false`可终止遍历 +- 返回值:处理完毕的语句对象(便于连锁进行其他操作) +- 返回值类型:`DBStmt` + +
+ +#### 重置当前语句状态至“待执行” + +`stmt.reset()` + +- 返回值:处理完毕的语句对象(便于连锁进行其他操作) +- 返回值类型:`DBStmt` +- **注意:本函数不会清除已绑定的参数** + +
+ +#### 重新执行预准备语句 + +`stmt.reexec()` + +- 返回值:处理完毕的语句对象(便于连锁进行其他操作) +- 返回值类型:`DBStmt` +- **注意:本函数是一个便捷函数,等同于执行`stmt.reset()`和`stmt.execute()`** + +
+ +#### 清除所有已绑定的参数 + +`stmt.clear()` + +- 返回值:处理完毕的语句对象(便于连锁进行其他操作) +- 返回值类型:`DBStmt` + +
+ +### 样例 + +```js +let dat = {}; +let modified = {}; +let session = null; +function initdb() { + if (!file.exists("plugins/MyPlugin")) file.mkdir("plugins/MyPlugin"); + session = new DBSession("sqlite", {path: "./plugins/MyPlugin/dat.db"}); + session.exec(` + CREATE TABLE IF NOT EXISTS "test" ( + player CHAR(100) NOT NULL, + coins INTEGER NOT NULL + );`); // 这里创建数据表后SQLite会自动添加一个隐藏的ROWID行,insertId就是这个隐藏的ROWID行的值 + // 另:如果数据库自带INTEGER类型主键,则ROWID即为该主键 +} +// 使用do...while语句 +function loadData() { + let stmt = session.prepare("SELECT * FROM test"); + do { // 准备并执行后,默认在第一行 + let row = stmt.fetch(); + dat[row.player] = row.coins; + } while (stmt.step()); // 第一次执行时步进到第二行,并成功获取到结果,返回true;最后一行时再步进则返回false +} +// 使用回调函数 +function loadData2() { + session.prepare("SELECT * FROM test") + .execute() + .fetchAll((player, coins) => { + dat[player] = coins; + }); +} +function writeData() { + let keys = Object.keys(modified); + let stmt = session.prepare("UPDATE FROM test WHERE player = ? SET coins = ?").execute(); + for (let i = 0; i < keys.length; i++) { + let v = modified[keys[i]]; + stmt.bind([keys[i], v]); // 绑定数组参数 + // 绑定完成后自动执行语句 + stmt.clear(); // 清除已经绑定的值 + } +} +mc.regPlayerCmd("getcoin", "Get a coin!", (pl, args) { + dat[pl.realName]++; + modified[pl.realName]++; +}); +``` diff --git a/docs/apis/DataAPI/Economy.md b/docs/apis/DataAPI/Economy.md new file mode 100644 index 00000000..a7069bbe --- /dev/null +++ b/docs/apis/DataAPI/Economy.md @@ -0,0 +1,136 @@ +## 💰 Economic System API + +In many servers, the economic system is a very critical part. +In order to solve various problems of traditional use of the scoreboard economic system, LLSE provides an interface to connect to the LLMoney economic system, which can communicate with other series of plugins. + +In addition to the capabilities of the traditional economic system, LLMoney also has additional capabilities such as querying the history of changes in the amount and operating the economy of offline players. +LiteLoader is installed with the LLMoney plugin, so you can use this interface directly without additional installation. + +### Set the Player’s Deposit Amount + +`Player.setMoney(value)` + +`money.set(xuid,value)` + +- Parameters: + - xuid : `String` + The XUID identifier of the player. + - value : `Integer` + Amount of money being set. +- Return value: Whether the setting is successful. +- Return value type: `Boolean` + +
+ +### Get the Player’s Deposit Amount + +`Player.getMoney()` + +`money.get(xuid)` + +- Parameter: + - xuid : `String` + The XUID identifier of the player to read. +- Return value: Player's bank value. +- Return value type: `Integer` + +
+ +### Increase Player’s Deposit + +`Player.addMoney(value)` + +`money.add(xuid,value)` + +- Parameters: + - xuid : `String` + The XUID identifier of the player. + - value : `Integer` + The amount of money to add to the player's bank. +- Return value: Whether the setting is successful. +- Return value type: `Boolean` + +
+ +### Decrease the Player’s Deposit + +`Player.reduceMoney(value)` + +`money.reduce(xuid,money)` + +- Parameters: + - xuid : `String` + The XUID identifier of the player. + - money : `Integer` + The amount of money to take from the player. +- Return value: Whether the setting is successful. +- Return value type: `Boolean` + +
+ +### Make a Transfer + +`Player.transMoney(target,money[,note])` + +`money.trans(xuid1,xuid2,money[,note])` + +- Parameters: + - xuid1 : `String` + The XUID identifier of the paying player. + + - xuid2 : `String` + The XUID identifier of the player who will receive the payment. + + If you are using `Player.transMoney`, target can be `Player`. + + - money : `Integer` + The amount of money being transferred. + + - note : `String` + (Optional) Add some text to this transfer. + +- Return value: Whether the transfer is successful. + +- Return value type: `Boolean` + +
+ +### Query Historical Payments + +`Player.getMoneyHistory(time)` + +`money.getHistory(xuid,time)` + +- Parameters: + - xuid : `String` + The XUID identifier of the player. + - time : `Integer` + Query all records within the last `time` seconds. +- Return value: An array of query result objects. +- Return value type: `Array` + +Where the result is an array of record objects. for each `record` object record, with the following keys and corresponding values: + +| Key | Meaning of Value | Data Type | +| -------------- | -------------------------- | --------- | +| `record.from` | XUID of money sender | `String` | +| `record.to` | XUID of money receiver | `String` | +| `record.money` | Amount of money | `Integer` | +| `record.time` | Time when this transaction occurred | `String` | +| `record.note` | Additional notes for this transaction. | `String` | + +The format of the time string is: YYYY-mm-dd hh:mm:ss + +
+ +### Delete Billing History + +`money.clearHistory(time)` + +- Parameter: + - time : `Integer` + Delete all records within the last `time` seconds. +- Return value: Whether the deletion is successful. +- Return value type: `Boolean` + +
\ No newline at end of file diff --git a/docs/apis/DataAPI/Economy.zh.md b/docs/apis/DataAPI/Economy.zh.md new file mode 100644 index 00000000..1499ea92 --- /dev/null +++ b/docs/apis/DataAPI/Economy.zh.md @@ -0,0 +1,136 @@ +## 💰 经济系统 API + +在很多服务器中,经济系统是非常关键的一环。 +为了解决传统使用计分板经济系统的种种问题,脚本引擎提供了对接LLMoney经济系统的接口,可以与其他各系列插件数据互通。 + +LLMoney除了拥有传统经济系统的能力之外,还有查询金额变动历史、操作离线玩家经济等额外能力。 +LiteLoaderBDS在安装时附带了LLMoney插件,因此无需额外安装,就可以直接使用此接口。 + +### 设置玩家的存款金额 + +`Player.setMoney(value)` + +`money.set(xuid,value)` + +- 参数: + - xuid : `String` + 要操作的玩家的XUID标识符 + - value : `Integer` + 要设置的金额 +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +
+ +### 获取玩家的存款金额 + +`Player.getMoney()` + +`money.get(xuid)` + +- 参数: + - xuid : `String` + 要读取的玩家的XUID标识符 +- 返回值:玩家的资金数值 +- 返回值类型:`Integer` + +
+ +### 增加玩家的存款 + +`Player.addMoney(value)` + +`money.add(xuid,value)` + +- 参数: + - xuid : `String` + 要操作的玩家的XUID标识符 + - value : `Integer` + 要增加的金额 +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +
+ +### 减少玩家的存款 + +`Player.reduceMoney(value)` + +`money.reduce(xuid,value)` + +- 参数: + - xuid : `String` + 要操作的玩家的XUID标识符 + - value : `Integer` + 要减小的金额 +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +
+ +### 进行一笔转账 + +`Player.transMoney(target,money[,note])` + +`money.trans(xuid1,xuid2,money[,note])` + +- 参数: + - xuid1 : `String` + 付款的玩家的XUID标识符 + + - xuid2 : `String` + 收款的玩家的XUID标识符 + + 如果你使用 `Player.transMoney`,target可以是玩家对象 + + - money : `Integer` + 要支付的金额 + + - note : `String` + (可选参数)给这笔转账附加一些文字说明 + +- 返回值:是否转账成功 + +- 返回值类型:`Boolean` + +
+ +### 查询历史账单 + +`Player.getHistory(time)` + +`money.getHistory(xuid,time)` + +- 参数: + - xuid : `String` + 要操作的玩家的XUID标识符 + - time : `Integer` + 查询从现在开始往前time秒的记录 +- 返回值:查询结果对象的数组 +- 返回值类型:`Array` + +其中,结果为一系列记录对象组成的数组。对于每个记录对象`record`,有如下的键和对应的值: + +| 键 | 值的意义 | 数据类型 | +| -------------- | -------------------------- | --------- | +| `record.from` | 此项交易的发起者玩家XUID | `String` | +| `record.to` | 此项交易的接收者玩家XUID | `String` | +| `record.money` | 此项交易的金额 | `Integer` | +| `record.time` | 此项交易发生时的时间字符串 | `String` | +| `record.note` | 此交易的附加说明信息 | `String` | + +时间字符串的格式为:YYYY-mm-dd hh:mm:ss + +
+ +### 删除账单历史记录 + +`money.clearHistory(time)` + +- 参数: + - time : `Integer` + 删除从现在开始往前time秒的记录 +- 返回值:是否删除成功 +- 返回值类型:`Boolean` + +
\ No newline at end of file diff --git a/docs/apis/DataAPI/OtherData.md b/docs/apis/DataAPI/OtherData.md new file mode 100644 index 00000000..f4e08990 --- /dev/null +++ b/docs/apis/DataAPI/OtherData.md @@ -0,0 +1,85 @@ +## 🧰 Other Data Processing APIs + +Provides some other common data processing interfaces. You can use and expand by yourself. + +### Convert Variable to JSON String + +`data.toJson(var[,space])` + +- Parameters: + - var : `Any type` + Variable to convert to JSON string. The allowed data types for conversion are: + `Integer` `Float` `String` `Boolean` `Array` `Object ` + The above elements can only be nested inside an `Array` or `Object`. + - space : `Integer` + (Optional parameter) If you want to format the output string, pass this parameter. + Represents the number of spaces in each indent, so that the output JSON string is more human-readable. + This parameter defaults to 0, that is, the output string is not formatted +- Return value: Converted JSON string. +- Return value type: `String` + - If the return value is `Null`, it means that the conversion failed. + +
+ +### JSON String Parsed as Variable + +`data.parseJson(json)` + +- Parameters: + - json : `String` + JSON string to convert to variable. +- Return value: The converted variable. +- Return value type: `Any type`, depending on the data type contained in JSON. + - If the return value is `Null`, it means that the conversion failed . + +
+ +### MD5 Calculation + +`data.toMD5(str)` + +- Parameters: + - str : `String` / `ByteBuffer` + String/byte array from which to calculate MD5. +- Return value: MD5 digest string of original data. +- Return value type: `String` + +
+ +### SHA1 Calculation + +`data.toSHA1(str)` + +- Parameters: + - str : `String` / `ByteBuffer` + String/byte array to calculate SHA1. +- Return value: SHA1 digest string of original data. +- Return value type: `String` + +
+ +### Data to Base64 + +`data.toBase64(str)` + +- Parameter: + - str : `String` / `ByteBuffer` + String/byte array to convert to Base64. +- Return value: Base64 result. +- Return value type: `String` + +
+ +### Base64 decode to data + +`data.fromBase64(base64, isBinary)` + +- Parameters: + - base64 : `String` + The base64 string to decode. + - isBinary : `Boolean` + Returns whether the data type is binary data, the default is false. +- Return value: Decoded data. +- Return value type: `String` or `ByteBuffer` + +
\ No newline at end of file diff --git a/docs/apis/DataAPI/OtherData.zh.md b/docs/apis/DataAPI/OtherData.zh.md new file mode 100644 index 00000000..4839327f --- /dev/null +++ b/docs/apis/DataAPI/OtherData.zh.md @@ -0,0 +1,85 @@ +## 🧰 其他数据处理 API + +提供一些其他的常用数据处理接口。你可以自行使用并拓展。 + +### 变量转换为JSON字符串 + +`data.toJson(var[,space])` + +- 参数: + - var : `指定类型` + 要转换为JSON字符串的变量。允许进行转换的数据类型有: + `Integer` `Float` `String` `Boolean` `Array` `Object ` + 其中,`Array` 和 `Object` 内部仅能嵌套上面出现的这些元素 + - space : `Integer` + (可选参数)如果要格式化输出的字符串,则传入此参数 + 代表每个缩进的空格数量,这样输出的JSON串更适合人阅读 + 此参数默认为0,即不对输出字符串进行格式化 +- 返回值:转换成的JSON字符串 +- 返回值类型:`String` + - 如果返回值为`Null`,则表示转换失败 + +
+ +### JSON字符串解析为变量 + +`data.parseJson(json)` + +- 参数: + - json : `String` + 要转换为变量的JSON字符串 +- 返回值:转换成的变量 +- 返回值类型:`任意类型`,以JSON具体包含的数据类型为准 + - 如返回值为 `Null` 则表示转换失败 + +
+ +### MD5计算 + +`data.toMD5(str)` + +- 参数: + - str : `String` / `ByteBuffer` + 要计算MD5的字符串 / 字节数组 +- 返回值:原数据的MD5摘要字符串 +- 返回值类型:`String` + +
+ +### SHA1计算 + +`data.toSHA1(str)` + +- 参数: + - str : `String` / `ByteBuffer` + 要计算SHA1的字符串 / 字节数组 +- 返回值:原数据的SHA1摘要字符串 +- 返回值类型:`String` + +
+ +### 数据转Base64 + +`data.toBase64(str)` + +- 参数: + - str : `String` / `ByteBuffer` + 要转化为Base64的字符串 / 字节数组 +- 返回值:Base64结果 +- 返回值类型:`String` + +
+ +### Base64解码为数据 + +`data.fromBase64(base64, isBinary)` + +- 参数: + - base64 : `String` + 要解码的base64字符串 + - isBinary : `Boolean` + 返回数据类型是否为二进制数据,默认为 false +- 返回值:解码后的数据 +- 返回值类型:`String` 或 `ByteBuffer` + +
\ No newline at end of file diff --git a/docs/apis/DataAPI/PermAPI.md b/docs/apis/DataAPI/PermAPI.md new file mode 100644 index 00000000..337de7c5 --- /dev/null +++ b/docs/apis/DataAPI/PermAPI.md @@ -0,0 +1,390 @@ +# 🔐 Permission Interface + +> The builtin permission system of BDS/MCBE sucks. In order to meet the needs of plugins for the permission system, we made Permission APIs. + +If you use Discord, you must know its Role system. +Our permission system is similar to Discord's Role system. +The whole system can be divided into three parts: `Role`, `Permission`(`PermInstance`) and `PermInfo`. +`Role` defines a group of players that have the specified permissions, and `PermInfo` stores the description of all the permissions. + +Like discord, we also have the default `admin` and `everyone` roles. +`admin` is a special role. All the permissions will be enabled by default. +`everyone` is a special role. All the players are its members. + +You can send command `/perm view role admin` to see information of the `admin` role. + +## Get Role instance + +### Create a role + +By constructor: +[JavaScript] `new Role(name[,displayName])` +[Lua] `Role(name[,displayName])` +By static method: +`Permission.createRole(name[,displayName])` + +- Parameters: + - name: `String` + The role name, which is unique and cannot contain space or @#[]{}<>()/|\$%^&*!~`"'+=?\n\t\r\f\v + - displayName: `String`(optional) + The role display name(default the same as `name`) +- Return Value: `Role` The role +- Throw when: + - Invalid arguments. + - Invalid name. + - The role already exists. + +
+ +### Get a role + +`Permission.getRole(name)` + +- Parameters: + - name: `String` + The role name +- Return Value: `Role` The role +- Throw when: + - Invalid arguments. + - The role not found. + +
+ +### Get or create a role + +`Permission.getOrCreateRole(name)` + +- Parameters: + - name: `String` + The role name, which is unique and cannot contain space or @#[]{}<>()/|\$%^&*!~`"'+=?\n\t\r\f\v +- Return Value: `Role` The role +- Throw when: + - Invalid arguments. + - The name is invalid. + + +
+ +## Class Role + +> To avoid lifetime issues, plugins(including native plugins) only have role's weak reference. It means if the role is deleted by users or other plugins, you won't be able to access the role anymore. + So, if you want to store a role instance for a long time, you should call `role.isValid()` before using to make sure it is still available. + +### Properties + + Name | Type | Description +-----------------|-----------------|----------------------- +`name` | `String` | The role name +`displayName` | `String` | The role display name +`priority` | `Number` | The role priority +`permissions` | `Array` | The role permissions +`members` | `Array` | The role members(XUID) + +The `permissions` property is an array of objects, each object contains the following properties: + + Name | Type | Description +-----------------|-----------------|----------------------- +`name` | `String` | The permission name +`enabled` | `Boolean` | Whether the permission is enabled +`extra` | `Object` | The extra data of the permission + +
+ +### Check whether the role is valid + +`role.isValid()` + +- Return Value: `Boolean` Whether the role is valid + +
+ +### Check whether the role has the member + +`role.hasMember(xuid)` + +- Parameters: + - xuid: `String` + The member(player) XUID +- Return Value: `Boolean` Whether the role has the member +- Throw when: + - Invalid arguments. + - The role reference is expired. + +
+ +### Add the member to the role + +`role.addMember(xuid)` + +- Parameters: + - xuid: `String` + The member(player) XUID +- Throw when: + - Invalid arguments. + - The role reference is expired. + - The member already in the role. + +
+ +### Remove the member from the role + +`role.removeMember(xuid)` + +- Parameters: + - xuid: `String` + The member(player) XUID +- Throw when: + - Invalid arguments. + - The role reference is expired. + - The member not found in the role. + +
+ +### Check whether the role has the permission + +`role.hasPermission(name)` + +- Parameters: + - name: `String` + The permission name +- Return Value: `Boolean` Whether the role has the permission +- Throw when: + - Invalid arguments. + - The role reference is expired. +- Note: The permission extra data will be ignored. It will return `true` if the `enabled` field is true. + +
+ +### Set the permission of the role + +`role.setPermission(name, enabled[,extraData])` + +- Parameters: + - name: `String` + The permission name, which is registered in the `PermInfoList`(see [Register a permission](#register-a-permission)) + - enabled: `Boolean` + Whether the permission is enabled + - extraData: `Object`(optional) + The extra data of the permission +- Throw when: + - Invalid arguments. + - Invalid extra data. + - Invalid permission name. + - The role reference is expired. +- Note: If the specified permission is not found in the role, it will be added and set to the specified value + +
+ +### Remove the permission of the role + +`role.removePermission(name)` + +- Parameters: + - name: `String` + The permission name +- Throw when: + - Invalid arguments. + - The role reference is expired. + - The permission not found. + +
+ +### Check whether the permission exists in the role + +`role.permissionExists(name)` + +- Parameters: + - name: `String` + The permission name +- Return Value: `Boolean` Whether the permission is defined +- Throw when: + - Invalid arguments. + - The role reference is expired. +- Note: Different from `hasPermission`, this method will return `true` if the permission is in the role, but may not be enabled. + +
+ +## Static methods + +### Check whether the role exists + +`Permission.roleExists(name)` + +- Parameters: + - name: `String` + The role name +- Return Value: `Boolean` Whether the role exists +- Throw when: + - Invalid arguments. + +
+ +### Delete a role + +`Permission.deleteRole(name)` + +- Parameters: + - name: `String` + The role name +- Throw when: + - Invalid arguments. + - The role not found. + +
+ +### Register a permission + +`Permission.registerPermission(name, desc)` + +- Parameters: + - name: `String` + The permission name, which is unique and cannot contain space or \t\n\r\f\v, and should be like `namespace:name`(at least one `:`) + - desc: `String` + The permission description +- Throw when: + - Invalid arguments. + - The permission name is invalid. + - The permission already registered. + +
+ +### Check whether the permission exists + +`Permission.permissionExists(name)` + +- Parameters: + - name: `String` + The permission name +- Return Value: `Boolean` Whether the permission exists +- Throw when: + - Invalid arguments. + +
+ +### Check whether the player has the permission + +`Permission.checkPermission(xuid, permName)` + +- Parameters: + - xuid: `String` + The player XUID + - permName: `String` + The permission name +- Return Value: `Boolean` Whether the player has the permission +- Throw when: + - Invalid arguments. + - The player not found. + - The permission not found. +- Note: The permission extra data will be ignored. It will return `true` if the `enabled` field is true. + +- 💡 You can use prototype mechanism of JavaScript or [ScriptX APIs in lua](https://github.com/Tencent/ScriptX/blob/main/docs/en/Lua.md) +```js +LLSE_Player.prototype.hasPermission = function(permName) { + return Permission.checkPermission(this.xuid, permName); +} +``` +```lua +local meta = ScriptX.getInstanceMeta(LLSE_Player); +function meta.instanceFunction:hasPermission(perm) + return Permission.checkPermission(self.xuid, perm); +end +``` + +
+ +### Delete a permission + +`Permission.deletePermission(permName)` + +- Parameters: + - permName: `String` + The permission name +- Throw when: + - Invalid arguments. + - The permission not found. + +
+ +### Check whether the player is in the role + +`Permission.isMemberOf(xuid, roleName)` + +- Parameters: + - xuid: `String` + The player xuid + - roleName: `String` + The role name +- Return Value: `Boolean` Whether the player is in the role +- Throw when: + - Invalid arguments. + - The player not found. +- Note: If the role not found, it will return `false`. + +
+ +### Get the player's roles + +`Permission.getPlayerRoles(xuid)` + +- Parameters: + - xuid: `String` + The player XUID +- Return Value: `Array` The player's roles + +
+ +### Get the player's permissions + +`Permission.getPlayerPermissions(xuid)` + +- Parameters: + - xuid: `String` + The player XUID +- Return Value: `Array` The player's permissions + +
+ +### Save the permission data + +`Permission.saveData()` + +- Note: The data will be auto-saved every 100 game ticks. + +
+ +## Example + +```js +LLSE_Player.prototype.hasPermission = function (permName) { + return Permission.checkPermission(this.xuid, permName); +} + +try { + if (!Permission.permissionExists("Global:chat")) { + Permission.registerPermission("Global:chat", "Allow player to chat"); + } + if (!Permission.permissionExists("Global:join")) { + Permission.registerPermission("Global:join", "Allow player to join"); + } + // To let @everyone be able to chat, send the following command: + // /perm update role everyone add perm "Global:chat" true + let role = Permission.getRole("everyone"); + if (role.permissionExists("Global:join")) { + role.setPermission("Global:join", true); + } + Permission.saveData(); // It is a good habit to save the data at once after modifying it. +} catch (e) { + logger.error("Error: " + e); +} + +mc.listen("onChat", function (pl, msg) { + if (!pl.hasPermission("Global:chat")) { + return false; + } +}); +mc.listen("onJoin", function (pl, msg) { + if (!pl.hasPermission("Global:join")) { + pl.kick("You are not allowed to join this server"); + } +}); +``` \ No newline at end of file diff --git a/docs/apis/DataAPI/PermAPI.zh.md b/docs/apis/DataAPI/PermAPI.zh.md new file mode 100644 index 00000000..0c90b3fe --- /dev/null +++ b/docs/apis/DataAPI/PermAPI.zh.md @@ -0,0 +1,394 @@ +# 🔐 权限系统接口 + +> BDS/MCBE自带的权限系统非常的拉跨,为了满足插件对权限系统的需要,我们完成了权限接口. + +如果你使用Discord,你大抵会了解它的身份组系统。 +我们的权限系统与Discord的身份组系统非常相似。 +整个系统可以被分成三部分:`Role`(身份组), `Permission`(`PermInstance`, 权限实例) 和 `PermInfo`(权限信息)。 +`Role`定义了一组拥有指定权限的玩家,`PermInfo`则储存了所有权限的描述。 + +与Discord类似,我们也有默认的`admin`(管理员)和`everyone`(所有人)身份组。 +`admin`是一个特殊的身份组,所有的权限都会默认开启。 +`everyone`也是一个特殊的身份组,所有的玩家都是它的成员。 + +你可以发送命令 `/perm view role admin` 来看`admin`身份组的信息。 + +## 获取身份组实例 + +### 创建身份组 + +通过构造函数: +[JavaScript] `new Role(name[,displayName])` +[Lua] `Role(name[,displayName])` +通过静态方法: +`Permission.createRole(name[,displayName])` + +- 参数: + - name: `String` + 身份组名称,必须是唯一的并且不能含有@#[]{}<>()/|\$%^&*!~`"'+=?\n\t\r\f\v + - displayName: `String`(可选) + 身份组显示名称(默认和`name`一样) +- 返回值: `Role` 身份组实例 +- 抛出: + - 无效的参数。 + - 无效的名称。 + - 该身份组已存在。 + +
+ +### 获取已有身份组 + +`Permission.getRole(name)` + +- 参数: + - name: `String` + 身份组名称 +- 返回值: `Role` 身份组实例 +- 抛出: + - 无效的参数。 + - 找不到该身份组。 + +
+ +### 创建或获取身份组实例 + +`Permission.getOrCreateRole(name)` + +- 参数: + - name: `String` + 身份组名称,必须是唯一的并且不能含有@#[]{}<>()/|\$%^&*!~`"'+=?\n\t\r\f\v +- 返回值: `Role` 身份组实例 +- 抛出: + - 无效的参数。 + - 无效的名称。 + + +
+ +## 身份组类 + +> 为了避免生命周期问题,插件(包括原生插件)只有身份组的弱引用。这意味着如果身份组被用户或其他插件删除,您将无法再访问此身份组。 + 所以,如果您想要长时间储存一个身份组实例,您应该在使用之前调用`role.isValid()`以保证权限组实例依然有效。 + +### 属性 + + 名称 | 类型 | 描述 +-----------------|-----------------|----------------------- +`name` | `String` | 身份组名称 +`displayName` | `String` | 身份组显示名称 +`priority` | `Number` | 身份组优先级,越大越优先 +`permissions` | `Array` | 身份组拥有的权限 +`members` | `Array` | 身份组成员的XUID + +`permissions` 属性是一个对象的数组,每个对象都含有以下属性: + + 名称 | 类型 | 描述 +-----------------|-----------------|----------------------- +`name` | `String` | 权限名称 +`enabled` | `Boolean` | 权限是否开启 +`extra` | `Object` | 权限的额外数据 + +
+ +### 检查身份组实例是否有效 + +`role.isValid()` + +- 返回值: `Boolean` 身份组实例是否有效 + +
+ +### 检查身份组是否有指定成员 + +`role.hasMember(xuid)` + +- 参数: + - xuid: `String` + 成员(玩家)的XUID +- 返回值: `Boolean` 是否有该成员 +- 抛出: + - 无效的参数。 + - 身份组实例已被销毁。 + +
+ +### 添加成员到身份组 + +`role.addMember(xuid)` + +- 参数: + - xuid: `String` + 成员(玩家)的XUID +- 抛出: + - 无效的参数。 + - 身份组实例已被销毁。 + - 成员已存在。 + +
+ +### 从身份组中移除成员 + +`role.removeMember(xuid)` + +- 参数: + - xuid: `String` + 成员(玩家)的XUID +- 抛出: + - 无效的参数。 + - 身份组实例已被销毁。 + - 成员不存在。 + +
+ +### 检查身份组是否有指定权限 + +`role.hasPermission(name)` + +- 参数: + - name: `String` + 权限名称 +- 返回值: `Boolean` 是否有该权限 +- 抛出: + - 无效的参数。 + - 身份组实例已被销毁。 +- 注意: 权限的额外数据将被忽略,如果`enabled`字段的值为`true`,它就会返回`true`。 + +
+ +### 设置身份组权限 + +`role.setPermission(name, enabled[,extraData])` + +- 参数: + - name: `String` + 权限名称,必须已经注册在`PermInfoList`中(参见 [注册权限](#注册权限)) + - enabled: `Boolean` + 权限是否开启 + - extraData: `Object` + 权限的额外数据 +- 抛出: + - 无效的参数。 + - 无效的额外数据。 + - 无效的权限名。 + - 身份组实例已被销毁。 +- 注意: 如果在身份组中未找到指定权限,将会添加该权限并设置为指定值。 + +
+ +### 移除身份组中的权限 + +`role.removePermission(name)` + +- 参数: + - name: `String` + 权限名称 +- 抛出: + - 无效的参数。 + - 身份组实例已被销毁。 + - 找不到指定权限。 + +
+ +### 检查权限是否存在于身份组中 + +`role.permissionExists(name)` + +- 参数: + - name: `String` + 权限名称 +- 返回值: `Boolean` 权限是否已经存在于身份组中 +- 抛出: + - 无效的参数。 + - 身份组实例已被销毁。 +- 注意: 不同于`hasPermission`,这个方法会返回`true`只要权限已经存在于身份组,但权限不一定开启。 + +
+ +## 静态方法 + +### 检查身份组是否存在 + +`Permission.roleExists(name)` + +- 参数: + - name: `String` + 身份组名称 +- 返回值: `Boolean` 身份组是否存在 +- 抛出: + - 无效的参数。 + +
+ +### 删除身份组 + +`Permission.deleteRole(name)` + +- 参数: + - name: `String` + 身份组名称 +- 抛出: + - 无效的参数。 + - 身份组不存在。 + +
+ +### 注册权限 + +`Permission.registerPermission(name, desc)` + +- 参数: + - name: `String` + 权限名,唯一且不包含空格或\t\n\r\f\v,形如`namespace:name`(至少有一个 `:`) + - desc: `String` + 权限描述 +- 抛出: + - 无效的参数。 + - 无效的权限名。 + - 权限已经存在。 + +
+ +### 检查权限是否存在 + +`Permission.permissionExists(name)` + +- 参数: + - name: `String` + 权限名称 +- 返回值: `Boolean` + 权限是否存在 +- 抛出: + - 无效的参数。 + +
+ +### 检查玩家是否有指定权限 + +`Permission.checkPermission(xuid, permName)` + +- 参数: + - xuid: `String` + 玩家XUID + - permName: `String` + 权限名称 +- 返回值: `Boolean` + 玩家是否有指定权限 +- 抛出: + - 无效的参数。 + - 找不到玩家。 + - 找不到权限。 +- 注意:权限的额外数据将被忽略,此方法会返回`true`如果`enabled`字段为`true`。 + +- 💡 您可以用JavaScript的原型机制或者[Lua的ScriptX接口](https://github.com/Tencent/ScriptX/blob/main/docs/zh/Lua.md) +```js +LLSE_Player.prototype.hasPermission = function(permName) { + return Permission.checkPermission(this.xuid, permName); +} +``` +```lua +local meta = ScriptX.getInstanceMeta(LLSE_Player); +function meta.instanceFunction:hasPermission(perm) + return Permission.checkPermission(self.xuid, perm); +end +``` + +
+ +### 删除权限 + +`Permission.deletePermission(permName)` + +- 参数: + - permName: `String` + 权限名称 +- 抛出: + - 无效的参数。 + - 找不到权限。 + +
+ +### 检查玩家是否是指定身份组的成员 + +`Permission.isMemberOf(xuid, roleName)` + +- 参数: + - xuid: `String` + 玩家XUID + - roleName: `String` + 身份组名称 +- 返回值: `Boolean` 玩家是否是指定身份组的成员 +- 抛出: + - 无效的参数。 + - 找不到玩家。 +- 注意:如果找不到指定权限组,此方法将返回`false`。 + +
+ +### 获取玩家的身份组列表 + +`Permission.getPlayerRoles(xuid)` + +- 参数: + - xuid: `String` + 玩家XUID +- 返回值: `Array` + 此玩家的身份组列表 + +
+ +### 获取玩家的权限列表 + +`Permission.getPlayerPermissions(xuid)` + +- 参数: + - xuid: `String` + 玩家XUID +- 返回值: `Array` + 此玩家的权限列表 + +
+ +### 保存数据 + +`Permission.saveData()` + +- 注意: 数据将每100游戏刻自动保存一次。 + +
+ +## 例子 + +```js +LLSE_Player.prototype.hasPermission = function (permName) { + return Permission.checkPermission(this.xuid, permName); +} + +try { + if (!Permission.permissionExists("Global:chat")) { + Permission.registerPermission("Global:chat", "Allow player to chat"); + } + if (!Permission.permissionExists("Global:join")) { + Permission.registerPermission("Global:join", "Allow player to join"); + } + // 为了让"所有人"能聊天,发送以下命令 + // /perm update role everyone add perm "Global:chat" true + let role = Permission.getRole("everyone"); + if (role.permissionExists("Global:join")) { + role.setPermission("Global:join", true); + } + Permission.saveData(); // 在修改完后立刻保存是个好习惯 +} catch (e) { + logger.error("Error: " + e); +} + +mc.listen("onChat", function (pl, msg) { + if (!pl.hasPermission("Global:chat")) { + return false; + } +}); +mc.listen("onJoin", function (pl, msg) { + if (!pl.hasPermission("Global:join")) { + pl.kick("You are not allowed to join this server"); + } +}); +``` \ No newline at end of file diff --git a/docs/apis/DataAPI/PlayerData.md b/docs/apis/DataAPI/PlayerData.md new file mode 100644 index 00000000..685695b2 --- /dev/null +++ b/docs/apis/DataAPI/PlayerData.md @@ -0,0 +1,125 @@ +## 🏃‍♂️ Player Binding Data + +In actual development, there is often a need to associate certain data with a player in the server, and to maintain these data continuously during the work cycle of the plugin. + +To this end, LLSE designed the player binding data interface. The bound data interface stores data in the form of key-value pairs. +After you bind data to a player, the player bound data will persist even if the player object goes out of scope and is destroyed, and even when the player exits the game. When you get the player's player object again, you can still read the previously stored binding data. +All data will be destroyed uniformly only when the server is shut down. + +As such, LLSE gives developers the ability to track data about a particular player throughout the plugin's lifecycle. + +
+ +For a specific player object `pl`, with the following interfaces: + +#### Store Player Binding Data + +`pl.setExtraData(name,data)` + +- Parameters: + - name : `String` + The name to store into the bound data. + - data : `Any type` + The binding data you want to store, which can be `Null` + +- Return value: Whether the save was successful or not. +- Return value type: `Boolean` + +
+ +#### Get Player Binding Data + +`pl.getExtraData(name)` + +- Parameters: + - name : `String` + The name of the bound data to read. +- Return value: Stored binding data +- Return value type: `Any type`, depending on the type of data stored. + - If the return value is `Null`, it means that the specified binding data is not obtained, or the data is empty. + +
+ +#### Delete Player Binding Data + +`pl.delExtraData(name)` + +- Parameters: + - name : `String` + The name of the bound data to delete. +- Return value: Whether the deletion is successful. +- Return value type: `Boolean` + +
+ +## 👨‍💻 XUID Database + +The XUID database allows you to query the correspondence between player names and XUIDs even when players are offline. +When a player enters the server for the first time, his name and XUID are automatically recorded in the built-in XUID database. Use the following functions to make related queries. + +#### Query XUID by Player Name + +`data.name2xuid(name)` + +- Parameters: + - name : `String` + The name of the player to query. +- Return value: Player's XUID. +- Return value type: `String` + - If the return value is `Null`, it means the query failed. + +
+ +#### Query Player Name Based on XUID + +`data.xuid2name(xuid)` + +- Parameters: + - xuid: `String` + Player's XUID to query. +- Return value: Player's name. +- Return value type: `String` + - If the return value is `Null`, it means the query failed. + +
+ +#### Query UUID by Player Name + +`data.name2uuid(name)` + +- Parameters: + - name : `String` + The name of the player to query. +- Return value: Player's UUID. +- Return value type: `String` + - If the return value is `Null`, it means the query failed. + +
+ +#### Query UUID Based on XUID + +`data.xuid2uuid(xuid)` + +- Parameters: + - xuid : `String` + The xuid of the player to query. +- Return value: Player's UUID. +- Return value type: `String` + - If the return value is `Null`, it means the query failed. + +
+ +#### Get all player information + +`data.getAllPlayerInfo()` + +- Return value: All player information. +- Return value type: `Array` + - Each object contains the following properties: + - `name`: Player's name. + - `xuid`: Player's XUID. + - `uuid`: Player's UUID. + +
+ +Tip: The player name stored in the XUID database is named corresponding to the player object. `realName` field. diff --git a/docs/apis/DataAPI/PlayerData.zh.md b/docs/apis/DataAPI/PlayerData.zh.md new file mode 100644 index 00000000..97e70617 --- /dev/null +++ b/docs/apis/DataAPI/PlayerData.zh.md @@ -0,0 +1,125 @@ +## 🏃‍♂️ 玩家绑定数据 + +在实际开发中,经常有需要将某些数据和服务器中的某个玩家相关联,并在插件的工作周期中不断维护这些数据的需求。 + +为此,脚本引擎设计了玩家绑定数据接口。绑定数据接口使用键 - 值对的形式储存数据。 +在你将数据绑定到某个玩家上以后,即使在玩家对象超出作用域被销毁,甚至当此玩家退出游戏时,玩家绑定数据将仍然存在。当你再次获得这个玩家的玩家对象的时候,仍然可以读取到之前储存的绑定数据。 +只有当服务端关闭的时候,所有的数据才会被统一销毁。 + +由此,脚本引擎给予开发者在插件的整个生命周期中跟踪某个特定玩家相关数据的能力。 + +
+ +对于某个特定的玩家对象`pl`,有如下这些接口: + +#### 储存玩家绑定数据 + +`pl.setExtraData(name,data)` + +- 参数: + - name : `String` + 要储存到绑定数据的名字 + - data : `任意类型` + 你要储存的绑定数据,可以是`Null` + +- 返回值:是否成功储存 +- 返回值类型:`Boolean` + +
+ +#### 获取玩家绑定数据 + +`pl.getExtraData(name)` + +- 参数: + - name : `String` + 要读取的绑定数据的名字 +- 返回值:储存的绑定数据 +- 返回值类型:`任意类型`,取决于储存的数据类型 + - 如返回值为 `Null` 则表示未获取到指定的绑定数据,或者数据为空 + +
+ +#### 删除玩家绑定数据 + +`pl.delExtraData(name)` + +- 参数: + - name : `String` + 要删除的绑定数据的名字 +- 返回值:是否删除成功 +- 返回值类型:`Boolean` + +
+ +## 👨‍💻 XUID 数据库 + +XUID数据库让你可以即使在玩家离线的时候,也可以查询玩家名字与XUID的对应关系。 +当一个玩家第一次进服的时候,他的名字和XUID就会被自动记录在内置 XUID 数据库中。使用下面的函数来进行相关查询 + +#### 根据玩家名查询XUID + +`data.name2xuid(name)` + +- 参数: + - name : `String` + 要查询的玩家名 +- 返回值:玩家的XUID +- 返回值类型:`String` + - 如果返回值为`Null`,则代表查询失败 + +
+ +#### 根据XUID查询玩家名 + +`data.xuid2name(xuid)` + +- 参数: + - xuid: `String` + 要查询的玩家XUID +- 返回值:玩家名 +- 返回值类型:`String` + - 如果返回值为`Null`,则代表查询失败 + +
+ +#### 根据玩家名查询UUID + +`data.name2uuid(name)` + +- 参数: + - name : `String` + 要查询的玩家名 +- 返回值:玩家的UUID +- 返回值类型:`String` + - 如果返回值为`Null`,则代表查询失败 + +
+ +#### 根据XUID查询玩家UUID + +`data.xuid2uuid(xuid)` + +- 参数: + - xuid: `String` + 要查询的玩家XUID +- 返回值:玩家的UUID +- 返回值类型:`String` + - 如果返回值为`Null`,则代表查询失败 + +
+ +#### 获取所有的玩家信息 + +`data.getAllPlayerInfo()` + +- 返回值: 所有的玩家信息 +- 返回值类型: `Array` + - 每个对象都含有以下属性: + - `name`: 玩家名 + - `xuid`: 玩家XUID + - `uuid`: 玩家UUID + +
+ +提示:XUID数据库中储存的玩家名为玩家对象对应的`realName`字段 diff --git a/docs/apis/EventAPI/BlockEvents.md b/docs/apis/EventAPI/BlockEvents.md new file mode 100644 index 00000000..d88b4a18 --- /dev/null +++ b/docs/apis/EventAPI/BlockEvents.md @@ -0,0 +1,281 @@ +## 📦 Block Related Events + +#### `"onBlockInteracted"` - Block Player Interaction Event + +- Listener function prototype + `function(player,block)` +- Parameters: + - player : `Player` + The player object that interacts with the block. + - block : `Block` + The block object being interacted with. + +- Intercept events: function returns `false` + +Only blocks that can be interacted with will trigger this event, such as barrels, beacons, cartography tables, grindstones, etc. +Intercept events have no effect on chests, shulker boxes, and workbenches. + +
+ +#### `"onBlockChanged"` - Block Change Event + +- Listener function prototype + `function(beforeBlock,afterBlock)` +- Parameters: + - beforeBlock : `Block` + The block object before the change. + - afterBlock : `Block` + The block object after the change. + +- Intercept events: function returns `false` +
+ Intercepting this event requires attention to the following issues + + 1. Block changes caused by some events cannot be intercepted, such as players digging and placing. + 2. For the changes caused by the relationship between blocks, some of them cannot be intercepted, such as explosions destroying surrounding blocks + (Actually, the client still looks like there is a block there, but it's already a fake one) + 3. But for a block such as a torch that needs to be attached to other blocks, if the block is destroyed because of the attached block, the torch will not be destroyed. + 4. Some specific features can be tested by themselves. +
+ +
+ +#### `"onBlockExplode"` - Block Explosion Event + +- Listener function prototype + `function(source,pos,radius,maxResistance,isDestroy,isFire)` +- Parameters: + - source : `Block` + The block object from which the explosion originated. + - pos : `FloatPos` + The coordinates of the explosion. + - radius : `Float` + Blast radius. + - maxResistance : `Float` + Maximum Blast Resistance of the Block. + - isDestroy : `Boolean` + If the explosion destroyed the block. + - isFire : `Boolean` + If the explosion caught the block on fire. + +- Intercept events: function returns `false` + +
+ +#### `"onRespawnAnchorExplode"` - Respawn Anchor Explosion Event + +- Listener function prototype + `function(pos,player)` +- Parameters: + - pos : `IntPos` + The coordinates of the respawn anchor where the explosion occured. + - player : `Player` + Player attempting to use a respawn anchor. +- Intercept events: function returns `false` + +
+ +#### `"onBlockExploded"` - Block Destroyed by Explosion Event + +- Listener function prototype + `function(block,source)` +- Parameters: + - block : `Block` + The block object destroyed by the explosion. + - source : `Entity` + The entity object from which the explosion originated. +- Intercept event: cannot be intercepted. + +
+ +#### `"onFireSpread"` - Fire Spread Event + +- Listener function prototype + `function(pos)` +- Parameters: + - pos : `IntPos` + The coordinates of the block the flame spread to. +- Intercept events: function returns `false` + +
+ +#### `"onCmdBlockExecute"` - Command Block Command Execution Event + +- Listener function prototype + `function(cmd,pos,isMinecart)` +- Parameters: + - cmd : `String` + The command executed. + - pos : `IntPos` + The coordinates of the command block where the command was executed. + - isMinecart : `bool` + Whether the command is executed by a command block minecart. + +- Intercept events: function returns `false` + +
+ +#### `"onContainerChange"` - Container Content Change Event + +- Listener function prototype + `function(player,container,slotNum,oldItem,newItem)` +- Parameters: + - player : `Player` + The player who manipulated the container. + - container : `Block` + he block object of the container being manipulated. + - slotNum : `Integer` + The grid position of the operation. (SlotNumber) + - oldItem : `Item` + The original item in the grid before the change. + - newItem : `Item` + The new item in the grid after the change. +- Intercept event: cannot be intercepted. + +The **container** here is a broad concept of container, including boxes, buckets and other containers that can store items can trigger this event. + +Explanation of callback parameters: +There are many different combinations of old item objects and new item objects, indicating different changes in the grid. + +- Put item: the old item object is empty, the new item object is not empty. +- Take out the item: the old item object is not empty, the new item object is not empty. +- Item Stack Increase: Old Item Object's `type`== new item object's `type`, and the old item object's `count`< new item object's `count`. +- Item Stack Reduction: Old Item Object's `type` == new item object's `type`, and the old item's `count` > new item object's `count` +- Replacement Item: Old Item Object's typenot equal to the new item object `type`, and neither `item` object is empty. + +
+ +#### `"onProjectileHitBlock"` - Block Hit by Projectile Event + +- Listener function prototype + `function(block,source)` +- Parameters: + - block : `Block` + The block that was hit. + - source : `Entity` + The projectile entities fired (arrows). +- Intercept event: cannot be intercepted. + +
+ +#### `"onRedStoneUpdate"` - Redstone Update Event + +- Listener function prototype + `function(block,level,isActive)` +- Parameters: + - block : `Block` + The block object where the redstone update occurred. + - level : `Integer` + Updated redstone power levels (0-15). + - isActive : `Boolean` + Indicates whether the redstone update is active or off. + - If `true`, the redstone became active. + - if `false`, the redstone became inactive. +- Intercept events: function returns `false` + +Currently, the types of blocks that can monitor redstone updates are: redstone wire, redstone torch, redstone repeater, redstone comparator. + +
+ +#### `"onHopperSearchItem"` - Hopper (or Funnel Minecart) Item Absorption Detection Event + +- Listener function prototype + `function(pos,isMinecart,item)` +- Parameters: + - pos : `FloatPos` + Where the hopper is located. + - isMinecart : `bool` + Is it a hopper minecart? + - item : `Item` + The searched item object. +- Intercept events: function returns `false` + +Note: After placing the funnel, this event will be repeatedly triggered on the server side. +After you intercept the event, the hopper will not be able to absorb the item. + +
+ +#### `"onHopperPushOut"` - Hopper Item Output Event + +- Listener function prototype + `function(pos,isMinecart,item)` +- Parameters: + - pos : `FloatPos` + Where the hopper is located. + - isMinecart : `bool` + Is it a hopper minecart? + - item : `Item` + The item object to be output. +- Intercept events: function returns `false` + +
+ +#### `"onPistonTryPush"` - Piston Push Attempt Event + +- Listener function prototype + `function(pistonPos,block)` +- Parameters: + - pistonPos : `IntPos` + Working piston coordinates. + - block : `Block` + The block object that the piston attempted to push. +- Intercept events: function returns `false` + +If the piston is blocked by a block and cannot be pushed, this event will loop continuously. + +
+ +#### `"onPistonPush"` - Piston Push Event + +- Listener function prototype + `function(pistonPos,block)` +- Parameters: + - pistonPos : `IntPos` + Working piston coordinates. + - block : `Block` + The pushed block object. +- Intercept event: Unable to intercept. + +Note: This event is different from the previous event, the last Try event is fired when the piston is trying to push, this event is fired after the push is complete. + +
+ +#### `"onFarmLandDecay"` - Farmland Degrade Event + +- Listener function prototype + `function(pos,entity)` +- Parameters: + - pos : `IntPos` + Coordinates of degraded arable land. + - entity : `Entity` + Entity that degraded the arable land. +- Intercept events: function returns `false` + +
+ +#### `"onUseFrameBlock"` - Manipulate Item Frame Event + +- Listener function prototype + `function(player,block)` +- Parameters: + - player : `Player` + The player object that manipulates the item frame. + - block : `Block` + The manipulated item frame block object. +- Intercept events: function returns `false` + +NOTE: Actions include placing items, removing items, and rotating items. + +
+ +#### `"onLiquidFlow"` - Liquid Flow Event + +- Listener function prototype + `function(from,to)` +- Parameters: + - from : `Block` + Water source block object. + - to : `IntPos` + The coordinates of the position where the liquid will flow. +- Intercept events: function returns `false` + diff --git a/docs/apis/EventAPI/BlockEvents.zh.md b/docs/apis/EventAPI/BlockEvents.zh.md new file mode 100644 index 00000000..aa7afb1e --- /dev/null +++ b/docs/apis/EventAPI/BlockEvents.zh.md @@ -0,0 +1,283 @@ +## 📦 方块相关事件 + +#### `"onBlockInteracted"` - 方块接受玩家互动 + +- 监听函数原型 + `function(player,block)` +- 参数: + - player : `Player` + 与方块互动的玩家对象 + + - block : `Block` + 被互动的方块对象 + +- 拦截事件:函数返回`false` + +只有可以被互动的方块才会触发此事件,如木桶、信标、制图台、磨石等 +拦截事件对箱子、潜影盒、工作台无效 + +
+ +#### `"onBlockChanged"` - 方块改变 + +- 监听函数原型 + `function(beforeBlock,afterBlock)` +- 参数: + - beforeBlock : `Block` + 改变前的方块对象 + + - afterBlock : `Block` + 改变后的方块对象 + +- 拦截事件:函数返回`false` +
+ 拦截此事件需要注意以下问题 + + 1.部分事件导致的方块变化无法拦截, 比如玩家挖掘,放置 + 2.对于方块与方块之间关系导致的变化,部分不可拦截,比如爆炸摧毁周围方块 + (实际上,客户端看起来那边还是存在方块的,但是已经是假方块了) + 3.但是对于火把这种需要附着在其他方块上的方块,如果因为附着方块被摧毁,那么火把不会随之被破坏 + 4.具体某些特性可以自行测试 +
+ +
+ +#### `"onBlockExplode"` - 发生由方块引起的爆炸 + +- 监听函数原型 + `function(source,pos,radius,maxResistance,isDestroy,isFire)` +- 参数: + - source : `Block` + 爆炸来源的方块对象 + - pos : `FloatPos` + 爆炸发生的坐标 + - radius : `Float` + 爆炸波及的半径 + - maxResistance : `Float` + 爆炸可破坏的方块爆炸抗性上限 + - isDestroy : `Boolean` + 爆炸是否破坏方块 + - isFire : `Boolean` + 爆炸是否产生火焰 + +- 拦截事件:函数返回`false` + +
+ +#### `"onRespawnAnchorExplode"` - 发生由重生锚引起的爆炸 + +- 监听函数原型 + `function(pos,player)` +- 参数: + - pos : `IntPos` + 爆炸发生的重生锚的坐标 + - player : `Player` + 试图使用重生锚的玩家 +- 拦截事件:函数返回`false` + +
+ +#### `"onBlockExploded"` - 方块被爆炸破坏 + +- 监听函数原型 + `function(block,source)` +- 参数: + - block : `Block` + 被爆炸破坏的方块对象 + - source : `Entity` + 爆炸来源的实体对象 +- 拦截事件:不可以拦截 + +
+ +#### `"onFireSpread"` - 火焰蔓延 + +- 监听函数原型 + `function(pos)` +- 参数: + - pos : `IntPos` + 火焰蔓延到的方块坐标 +- 拦截事件:函数返回`false` + +
+ +#### `"onCmdBlockExecute"` - 命令方块执行命令 + +- 监听函数原型 + `function(cmd,pos,isMinecart)` +- 参数: + - cmd : `String` + 执行的命令 + - pos : `IntPos` + 执行命令的命令方块坐标 + - isMinecart : `bool` + 命令是否由命令方块矿车执行 + +- 拦截事件:函数返回`false` + +
+ +#### `"onContainerChange"` - 容器内容改变 + +- 监听函数原型 + `function(player,container,slotNum,oldItem,newItem)` +- 参数: + - player : `Player` + 操作容器的玩家对象 + - container : `Block` + 被操作的容器的方块对象 + - slotNum : `Integer` + 操作容器的格子位置(第slotNum个格子) + - oldItem : `Item` + 格子中的原来旧物品对象 + - newItem : `Item` + 格子中新的物品对象 +- 拦截事件:不可以拦截 + +此处的 **容器** 为宽泛容器的概念,包括箱子、桶等多种可以储存物品的容器都可以触发此事件 + +对回调参数的解释: +旧物品对象与新物品对象有多种不同的组合情况,表示格子内不同的变化情况 + +- 放入物品:旧物品对象为空,新物品对象不为空 +- 取出物品:旧物品对象不为空,新物品对象不为空 +- 物品增加堆叠:旧物品对象的`type` == 新物品对象的`type`,且旧物品对象的`count` < 新物品对象的`count` +- 物品减少堆叠:旧物品对象的`type` == 新物品对象的`type`,且旧物品对象的`count` > 新物品对象的`count` +- 替换物品:旧物品对象的`type` 不等于 新物品对象的`type`,且两物品对象均不为空 + +
+ +#### `"onProjectileHitBlock"` - 方块被弹射物击中 + +- 监听函数原型 + `function(block,source)` +- 参数: + - block : `Block` + 被击中的方块对象 + - source : `Entity` + 发射的弹射物实体(如箭) +- 拦截事件:不可以拦截 + +
+ +#### `"onRedStoneUpdate"` - 发生红石更新 + +- 监听函数原型 + `function(block,level,isActive)` +- 参数: + - block : `Block` + 发生红石更新的方块对象 + - level : `Integer` + 更新的红石能量等级(0-15) + - isActive : `Boolean` + 表示红石更新是激活还是熄灭 + - 为`true`表示红石变为激活状态 + - 为`false`表示红石变为熄灭状态 +- 拦截事件:函数返回`false` + +目前可以监测红石更新的方块种类有:红石线、红石火把、红石中继器、红石比较器 + +
+ +#### `"onHopperSearchItem"` - 漏斗(漏斗矿车)检测可否吸取物品 + +- 监听函数原型 + `function(pos,isMinecart,item)` +- 参数: + - pos : `FloatPos` + 漏斗(漏斗矿车)所在的位置 + - isMinecart : `bool` + 是否为漏斗矿车 + - item : `Item` + 检测到的物品对象 +- 拦截事件:函数返回`false` + +注:在放置漏斗之后,会在服务端反复不断触发这个事件 +当你拦截事件之后,漏斗就会无法吸取这个物品 + +
+ +#### `"onHopperPushOut"` - 漏斗输出物品 + +- 监听函数原型 + `function(pos,isMinecart,item)` +- 参数: + - pos : `FloatPos` + 漏斗(漏斗矿车)所在的位置 + - isMinecart : `bool` + 是否为漏斗矿车 + - item : `Item` + 准备输出的物品对象 +- 拦截事件:函数返回`false` + +
+ +#### `"onPistonTryPush"` - 活塞尝试推动 + +- 监听函数原型 + `function(pistonPos,block)` +- 参数: + - pistonPos : `IntPos` + 正在工作的活塞坐标 + - block : `Block` + 尝试被推动的方块对象 +- 拦截事件:函数返回`false` + +若活塞被方块阻挡无法推动,此事件将会不停地循环触发 + +
+ +#### `"onPistonPush"` - 活塞推动 + +- 监听函数原型 + `function(pistonPos,block)` +- 参数: + - pistonPos : `IntPos` + 正在工作的活塞坐标 + - block : `Block` + 被推动的方块对象 +- 拦截事件:无法拦截 + +注:此事件与上事件不同,上一个Try事件在活塞推动前尝试时触发,此事件在推动完毕后触发 + +
+ +#### `"onFarmLandDecay"` - 耕地退化 + +- 监听函数原型 + `function(pos,entity)` +- 参数: + - pos : `IntPos` + 退化的耕地的坐标 + - entity : `Entity` + 造成耕地退化的实体 +- 拦截事件:函数返回`false` + +
+ +#### `"onUseFrameBlock"` - 操作物品展示框 + +- 监听函数原型 + `function(player,block)` +- 参数: + - player : `Player` + 操作物品展示框的玩家对象 + - block : `Block` + 被操作的物品展示框方块对象 +- 拦截事件:函数返回`false` + +注:操作包括放置物品、取下物品、旋转物品。 + +
+ +#### `"onLiquidFlow"` - 液体方块流动 + +- 监听函数原型 + `function(from,to)` +- 参数: + - from : `Block` + 水源方块对象 + - to : `IntPos` + 即将流经的方块位置 +- 拦截事件:函数返回`false` + diff --git a/docs/apis/EventAPI/EconomicEvents.md b/docs/apis/EventAPI/EconomicEvents.md new file mode 100644 index 00000000..f49a5bf4 --- /dev/null +++ b/docs/apis/EventAPI/EconomicEvents.md @@ -0,0 +1,108 @@ +## 💰 Economic System Events + +Here are the economic change events related to the LLSE built-in economic system: + +#### `"beforeMoneyAdd"` - Pre-Money Adding Event + +- Listener function prototype + `function(xuid,money)` +- Parameters: + - xuid : `String` + The XUID of the player whose amount of money changed. + - money : `Integer` + The amount of money being given. +- Intercept events: Function returns `false` + +
+ +#### `"onMoneyAdd"` - Money Adding Event + +- Listener function prototype + `function(xuid,money)` +- Parameters: + - xuid : `String` + The XUID of the player whose amount of money changed. + - money : `Integer` + The amount of money being given. + +
+ +#### `"beforeMoneyReduce"` - Pre-Money Reduction Event + +- Listener function prototype + `function(xuid,money)` +- Parameters: + - xuid : `String` + The XUID of the player whose amount of money changed. + - money : `Integer` + The amount of money being taken. +- Intercept events: Function returns `false` + +
+ +#### `"onMoneyReduce"` - Money Reduction Event + +- Listener function prototype + `function(xuid,money)` +- Parameters: + - xuid : `String` + The XUID of the player whose amount of money changed. + - money : `Integer` + The amount of money being taken. + +
+ +#### `"beforeMoneyTrans"` - Pre-Player Money Transfer Event + +- Listener function prototype + `function(from,to,money)` +- Parameters: + - from : `String` + The XUID of the player initating the transfer. + - to : `String` + The XUID of the player accepting the transfer. + - money : `Integer` + The amount of money being transferred. +- Intercept events: Function returns `false` + +
+ +#### `"onMoneyTrans"` - Player Money Transfer Event + +- Listener function prototype + `function(from,to,money)` +- Parameters: + - from : `String` + The XUID of the player initating the transfer. + - to : `String` + The XUID of the player accepting the transfer. + - money : `Integer` + The amount of money being transferred. + +**Notice: When `onMoneyReduce` or `onMoneyAdd` was triggered, this event will be also triggered** +
+ +#### `"beforeMoneySet"` - Pre-Player Money Setting Event + +- Listener function prototype + `function(xuid,money)` +- Parameters: + - xuid : `String` + The XUID of the player whose amount of money changed. + - money : `Integer` + The amount of money being set. +- Intercept events: Function returns `false` + +
+ +#### `"onMoneySet"` - Player Money Setting Event + +- Listener function prototype + `function(xuid,money)` +- Parameters: + - xuid : `String` + The XUID of the player whose amount of money changed. + - money : `Integer` + The amount of money being set. + +
\ No newline at end of file diff --git a/docs/apis/EventAPI/EconomicEvents.zh.md b/docs/apis/EventAPI/EconomicEvents.zh.md new file mode 100644 index 00000000..9cd34939 --- /dev/null +++ b/docs/apis/EventAPI/EconomicEvents.zh.md @@ -0,0 +1,108 @@ +## 💰 经济系统事件 + +此处为脚本引擎内置经济系统相关的经济变动事件 + +#### `"beforeMoneyAdd"` - 玩家金额增加前事件 + +- 监听函数原型 + `function(xuid,money)` +- 参数: + - xuid : `String` + 金额变动的玩家的XUID + - money : `Integer` + 增加的金额 +- 拦截事件:函数返回`false` + +
+ +#### `"onMoneyAdd"` - 玩家金额增加事件 + +- 监听函数原型 + `function(xuid,money)` +- 参数: + - xuid : `String` + 金额变动的玩家的XUID + - money : `Integer` + 增加的金额 + +
+ +#### `"beforeMoneyReduce"` - 玩家金额减少前事件 + +- 监听函数原型 + `function(xuid,money)` +- 参数: + - xuid : `String` + 金额变动的玩家的XUID + - money : `Integer` + 减少的金额 +- 拦截事件:函数返回`false` + +
+ +#### `"onMoneyReduce"` - 玩家金额减少事件 + +- 监听函数原型 + `function(xuid,money)` +- 参数: + - xuid : `String` + 金额变动的玩家的XUID + - money : `Integer` + 减少的金额 + +
+ +#### `"beforeMoneyTrans"` - 玩家转账前事件 + +- 监听函数原型 + `function(from,to,money)` +- 参数: + - from : `String` + 发起转账的玩家的XUID + - to : `String` + 接受转账的玩家的XUID + - money : `Integer` + 转账的金额 +- 拦截事件:函数返回`false` + +
+ +#### `"onMoneyTrans"` - 玩家转账事件 + +- 监听函数原型 + `function(from,to,money)` +- 参数: + - from : `String` + 发起转账的玩家的XUID + - to : `String` + 接受转账的玩家的XUID + - money : `Integer` + 转账的金额 + +**注意: 当 `onMoneyReduce` 或 `onMoneyAdd` 被触发时,该事件也会被触发** +
+ +#### `"beforeMoneySet"` - 设置玩家金额前事件 + +- 监听函数原型 + `function(xuid,money)` +- 参数: + - xuid : `String` + 金额变动的玩家的XUID + - money : `Integer` + 被设置的金额 +- 拦截事件:函数返回`false` + +
+ +#### `"onMoneySet"` - 直接设置玩家金额事件 + +- 监听函数原型 + `function(xuid,money)` +- 参数: + - xuid : `String` + 金额变动的玩家的XUID + - money : `Integer` + 被设置的金额 + +
\ No newline at end of file diff --git a/docs/apis/EventAPI/EntityEvents.md b/docs/apis/EventAPI/EntityEvents.md new file mode 100644 index 00000000..fc540c46 --- /dev/null +++ b/docs/apis/EventAPI/EntityEvents.md @@ -0,0 +1,226 @@ +## 🎈 Entity Related Events + +#### `"onMobDie"` - Mob/Player Death Event + +- Listener function prototype + `function(mob,source,cause)` +- Parameters: + - mob : `Entity` + Dead entity object. + - source : `Entity` + The entity object that dealt the last damage (may be `Null`). + - cause : `Integer` + Cause of injury +- Intercept event: cannot be intercepted. + +Note that when the player dies, in addition to triggering `onPlayerDie` event, this event will also be triggered once. + +
+ +#### `"onMobHurt"` - Mob/Player Hurt Event + +- Listener function prototype + `function(mob,source,damage,cause)` +- Parameters: + - mob : `Entity` + The damaged entity. + - source : `Entity` + The entity that dealt the damage (may be `Null`). + - damage : `Integer` + The amount of damage dealt. + - cause : `Integer` + Cause of injury + +- Intercept events: function returns `false` + +
+ +#### `"onEntityExplode"` - Entity Explosion Event + +- Listener function prototype + `function(source,pos,radius,maxResistance,isDestroy,isFire)` +- Parameters: + - source : `Entity` + The entity object that caused the explosion. + - pos : `FloatPos` + The coordinates of the explosion. + - radius : `Float` + Blast radius. + - maxResistance : `Float` + The maximum resistance of blocks that will break. + - isDestroy : `Boolean` + Does the explosion destroy blocks. + - isFire : `Boolean` + Does the explosion produce flames. + +- Intercept events: function returns `false` + +
+ +#### `"onTryMobSpawn"` - Mob try Naturally Spawn Event + +- Listener function prototype + `function(typeName,pos)` +- Parameters: + - typeName : `string` + Entity Name + - pos : `FloatPos` + The coordinates of the spawn. + +- Intercept events: function returns `false` + +
+ +#### `"onMobSpawned"` - Mob Naturally Spawn Finished Event + +- Listener function prototype + `function(entity,pos)` +- Parameters: + - entity: `Entity` + The entity that spawned. + - pos : `FloatPos` + The coordinates of the spawn. + +- Intercept events: cannot be intercepted. + +You can use entity.despawn() or entity.remove() to intercept this event. + +
+ +#### `"onProjectileHitEntity"` - Entity Hit by Projectile Event + +- Listener function prototype + `function(entity,source)` +- Parameters: + - entity: `Entity` + The entity that was hit with a projectile. + - source : `Entity` + The projecticle entity (like arrows). +- Intercept event: cannot be intercepted. + +
+ +#### `"onWitherBossDestroy"` - Block Broken by Wither Event + +- Listener function prototype + `function(witherBoss,AAbb,aaBB)` +- Parameters: + - witherBoss: `Entity` + The Wither entity object. + - AAbb: `IntPos` + The area that the wither will destroy (box), the A coordinate of the diagonal point. + - aaBB: `IntPos` + The area that the wither will destroy (box), the B coordinate of the diagonal point. + +- Intercept events: function returns `false` + +Note that this event does not include wither explosion damage. + +
+ +#### `"onRide"` - Mob Ride Event + +- Listener function prototype + `function(entity1,entity2)` +- Parameters: + - entity1 : `Entity` + The entity that is riding the other entity. + - entity2 : `Entity` + The entity that is being ridden. +- Intercept events: function returns `false` + +Note: Riding includes minecart, boat, horse, pig, etc. + +
+ +#### `"onStepOnPressurePlate"` - Pressure Plate Step Event + +- Listener function prototype + `function(entity,pressurePlate)` +- Parameters: + - entity : `Entity` + The entity that stepped on the plate. + - pressurePlate : `Block` + The pressed pressure plate block. +- Intercept events: function returns `false` + +Note: When a creature steps on a pressure plate, this event will be triggered repeatedly. + +
+ +#### `"onSpawnProjectile"` - Projectile Spawn Event + +- Listener function prototype + `function(shooter,type)` +- Parameters: + - shooter : `Entity` + The entity that fired the projectile. + - type : `String` + Projectile Standard Type Name. + +- Intercept events: function returns `false` + +Note: Projectiles known to be intercepted are eggs, ender pearls, snowballs, tridents, arrows, and fishing rods (fish hooks). + +
+ +#### `"onProjectileCreated"` - Projectile Created Event + +- Listener function prototype + `function(shooter,entity)` +- Parameters: + - shooter : `Entity` + The entity that created the projectile. + - entity : `Entity` + The projectile entity object being created. + +- Intercept event: cannot be intercepted. + +
+ +#### `"onNpcCmd"` - NPC Command Execution Event + +- Listener function prototype + `function(npc,pl,cmd)` +- Parameters: + - npc : `Entity` + The NPC entity that executed the command. + - pl : `Player` + The player that triggered the execution of the NPC command. + - cmd : `String` + The command being executed by NPCs. +- Intercept events: function returns `false` + +
+ +#### `"onChangeArmorStand"` - Armor Stand Change Event + +- Listener function prototype + `function(as,pl,slot)` + +- Parameters: + + - as: `Entity` + Manipulated Armor Stand entity object. + - pl : `Player` + The player that manipulated the armor stand. + - slot : `Number` + Equipment slot number. + +- Intercept events: function returns `false` + +
+ +#### `"onEntityTransformation"` - Entity Transformation Event + +- Listener function prototype + `function(uniqueId,entity)` +- Parameters: + + - uniqueId: `String` + Unique identifer of the pre-transformed entity. + - entity : `Entity` + The transformed entity. +- Intercept event: cannot be intercepted. + +Note: This event is triggered when the `TransformationComponent` of the entity in `Addons` is activated, and is mostly used for the interaction between the engine and the Addon. Only `UniqueId` is provided since the entity pointer before the transition is destroyed quickly. diff --git a/docs/apis/EventAPI/EntityEvents.zh.md b/docs/apis/EventAPI/EntityEvents.zh.md new file mode 100644 index 00000000..30525124 --- /dev/null +++ b/docs/apis/EventAPI/EntityEvents.zh.md @@ -0,0 +1,274 @@ +## 🎈 实体相关事件 + +#### `"onMobDie"` - 生物死亡 + +- 监听函数原型 + `function(mob,source,cause)` +- 参数: + - mob : `Entity` + 死亡的实体对象 + - source : `Entity` + 伤害来源的实体对象(可能为`Null`) + - cause : `Integer` + 死亡原因 + +- 拦截事件:不可以拦截 + +注意,当玩家死亡时,除了触发`onPlayerDie`事件,这个事件同样也会被触发一次 + +
+ +#### `"onMobHurt"` - 生物受伤(包括玩家) + +- 监听函数原型 + `function(mob,source,damage,cause)` +- 参数: + - mob : `Entity` + 受伤的实体对象 + - source : `Entity` + 伤害来源的实体对象(可能为`Null`) + - damage : `Float` + 受到的伤害数值 + - cause : `DamageCause` + 受伤原因 +- 拦截事件:函数返回`false` + +DamageCause 为伤害原因枚举,枚举值如下,有问号的待验证,???待补充 +|伤害原因|枚举值|解释| +|--|--|--| +| None | -0x01 | 其他 | +| Override | 0x00 | 非正常方式(如脚本直接设置血量为0),这种方式的伤害不会被盔甲与buff吸收 | +| Contact | 0x01 | 接触伤害(如仙人掌) | +| EntityAttack | 0x02 | 实体攻击 | +| Projectile | 0x03 | 抛射物攻击 | +| Suffocation | 0x04 | 窒息(密封空间) | +| Fall | 0x05 | 掉落 | +| Fire | 0x06 | 燃烧 | +| FireTick | 0x07 | 点燃 | +| Lava | 0x08 | 熔岩 | +| Drowning | 0x09 | 溺水 | +| BlockExplosion | 0x0A | 方块爆炸 | +| EntityExplosion | 0x0B | 实体爆炸 | +| Void | 0x0C | 虚空 | +| Suicide | 0x0D | 自杀 | +| Magic | 0x0E | 尖牙对生物造成的伤害、守卫者对生物造成的魔法伤害和药水伤害等 | +| Wither | 0x0F | 凋零效果 | +| Starve | 0x10 | 饥饿 | +| Anvil | 0x11 | 下落的铁砧 | +| Thorns | 0x12 | 荆棘 | +| FallingBlock | 0x13 | 下落的方块 | +| Piston | 0x14 | 活塞 | +| FlyIntoWall | 0x15 | 动能(滑翔撞墙) | +| Magma | 0x16 | 岩浆块 | +| Fireworks | 0x17 | 烟花 | +| Lightning | 0x18 | 闪电 | +| Charging | 0x19 | 充能(?) | +| Temperature | 0x1A | 温度 (雪人?) | +| Freezing | 0x1B | 冰冻 | +| Stalactite | 0x1C | 被钟乳石砸到 | +| Stalagmite | 0x1D | 掉落到石笋上 | +| All | 0x1F | 所有 | + + +
+ +#### `"onEntityExplode"` - 发生由实体引起的爆炸 + +- 监听函数原型 + `function(source,pos,radius,maxResistance,isDestroy,isFire)` +- 参数: + - source : `Entity` + 爆炸来源的实体对象 + - pos : `FloatPos` + 爆炸发生的坐标 + - radius : `Float` + 爆炸波及的半径 + - maxResistance : `Float` + 爆炸可破坏的方块爆炸抗性上限 + - isDestroy : `Boolean` + 爆炸是否破坏方块 + - isFire : `Boolean` + 爆炸是否产生火焰 + +- 拦截事件:函数返回`false` + +
+ +#### `"onMobTrySpawn"` - 发生于实体尝试自然生成 + +- 监听函数原型 + `function(typeName,pos)` +- 参数: + - typeName : `string` + 生成实体名称 + - pos : `FloatPos` + 生成的坐标 + +- 拦截事件:函数返回`false` + +
+ +#### `"onMobSpawned"` - 发生于实体自然生成完成 + +- 监听函数原型 + `function(entity,pos)` +- 参数: + - entity : `Entity` + 生成的实体对象 + - pos : `FloatPos` + 生成的坐标 + +- 拦截事件:不可拦截 + +此事件为实体成功生成后触发,不可直接拦截,如需拦截请使用entity.despawn()或entity.remove() + +
+ +#### `"onProjectileHitEntity"` - 实体被弹射物击中 + +- 监听函数原型 + `function(entity,source)` +- 参数: + - entity: `Entity` + 被击中的实体对象 + - source : `Entity` + 发射的弹射物实体(如箭) +- 拦截事件:不可以拦截 + +
+ +#### `"onWitherBossDestroy"` - 凋灵破坏方块 + +- 监听函数原型 + `function(witherBoss,AAbb,aaBB)` +- 参数: + - witherBoss: `Entity` + 凋灵的实体对象 + + - AAbb: `IntPos` + + 凋灵将破坏的区域(长方体),对角点A坐标 + + - aaBB: `IntPos` + + 凋灵将破坏的区域(长方体),对角点B坐标 + +- 拦截事件:函数返回`false` + +注意,此事件不包括凋灵爆炸的破坏。 + +
+ +#### `"onRide"` - 生物骑乘 + +- 监听函数原型 + `function(entity1,entity2)` +- 参数: + - entity1 : `Entity` + 尝试骑乘的实体对象 + - entity2 : `Entity` + 被骑乘的实体对象 +- 拦截事件:函数返回`false` + +注:骑乘包括坐矿车、坐船、骑马、骑猪等。 + +
+ +#### `"onStepOnPressurePlate"` - 生物踩压力板 + +- 监听函数原型 + `function(entity,pressurePlate)` +- 参数: + - entity : `Entity` + 踩压力板的实体对象 + - pressurePlate : `Block` + 被踩的压力板方块对象 +- 拦截事件:函数返回`false` + +注:生物踩压力板时,将会反复多次触发此事件。 + +
+ +#### `"onSpawnProjectile"` - 弹射物创建 + +- 监听函数原型 + `function(shooter,type)` +- 参数: + + - shooter : `Entity` + 发射弹射物的的实体对象 + + - type : `String` + 弹射物标准类型名 + +- 拦截事件:函数返回 `false` + +注:已知可拦截的弹射物有鸡蛋、末影珍珠、雪球、三叉戟、箭、钓竿(鱼钩)。 + +
+ +#### `"onProjectileCreated"` - 弹射物创建完毕 + +- 监听函数原型 + `function(shooter,entity)` +- 参数: + + - shooter : `Entity` + 创建此弹射物的的实体对象 + + - entity : `Entity` + 被创建的弹射物实体对象 + +- 拦截事件:不可以拦截 + +
+ +#### `"onNpcCmd"` - NPC执行命令 + +- 监听函数原型 + `function(npc,pl,cmd)` +- 参数: + - npc : `Entity` + 执行命令的NPC实体对象 + - pl : `Player` + 触发NPC命令执行的玩家对象 + - cmd : `String` + NPC执行的命令 +- 拦截事件:函数返回`false` + +
+ +#### `"onChangeArmorStand"` - 操作盔甲架 + +- 监听函数原型 + `function(as,pl,slot)` + +- 参数: + + - as: `Entity` + 被操作的盔甲架实体对象 + + - pl : `Player` + 操作盔甲架的玩家对象 + + - slot : `Number` + + 装备栏编号 + +- 拦截事件:函数返回`false` + +
+ +#### `"onEntityTransformation"` - 实体转变 + +- 监听函数原型 + `function(uniqueId,entity)` +- 参数: + + - uniqueId: `String` + 转变前的实体的唯一标识符 + - entity : `Entity` + 转换完成的实体 +- 拦截事件:不可以拦截 + +注:此事件为 `Addons` 中实体的 `TransformationComponent` 激活时触发,多用于引擎与Addon交互。由于转变前的实体指针很快被销毁,因此只提供`UniqueId`。 diff --git a/docs/apis/EventAPI/Listen.md b/docs/apis/EventAPI/Listen.md new file mode 100644 index 00000000..32fa94fb --- /dev/null +++ b/docs/apis/EventAPI/Listen.md @@ -0,0 +1,40 @@ +# LLSE - Event Listening Documentation + +> The event system allows plugins to **respond** to certain game events, allowing you to execute code when certain events occur. + +The following APIs provide the ability to listen to **game events** and respond to them. + +## 🔔 Monitor API + +Register the specified listener function. +When a certain event in the game occurs, the corresponding listener function you set will be called by the engine, and you can process the related event at this time. + +### Add a Listener + +`mc.listen(event,callback)` + +- Parameters: + - event : `String` + The name of the event to listen for (see the list of listening events below). + - callback : `Function` + Registered listener function (see below for function-related parameters). + When the specified event occurs, BDS will call the listener function you give and pass in the corresponding parameters. +- Return value: Whether the event was successfully monitored. +- Return value type: `Boolean` + +
+ +### Intercept Event + +In LLSE's event monitoring system, generally you can pass `return false` to intercept an event that can be intercepted. Intercepting an event means that after the script intercepts the BDS will no longer handle the event as if it never happened. +For example: intercepting a chat event will cause everyone to not see the chat message + +However, intercepting events is only valid for BDS. +That is to say, intercepting an event does not affect other LLSE scripts that have corresponding listeners to process this event, but BDS can no longer receive it. + +
+ +### Avoid Mistakes + +Sometimes, calling a specific API inside some event listeners will cause an infinite loop to collapse. Please avoid these situations. +Example: If you use the `onConsoleCmd` event listener, and you call `mc.runcmd(Ex)`, it will trigger another `onConsoleCmd` event, which will lead to an infinite loop. \ No newline at end of file diff --git a/docs/apis/EventAPI/Listen.zh.md b/docs/apis/EventAPI/Listen.zh.md new file mode 100644 index 00000000..e05d0672 --- /dev/null +++ b/docs/apis/EventAPI/Listen.zh.md @@ -0,0 +1,42 @@ +# 脚本引擎 - 事件监听文档 + +> 事件系统让插件可以 **响应** 特定的游戏事件,让你可以在特定事件发生时执行代码 + +下面这些API,提供了监听**游戏事件**并做出响应的相关能力。 + +## 🔔 监听 API + +注册指定的监听函数。 +当游戏中的某种事件发生时,你设置的对应的监听函数将被引擎调用,这时候你可以对相关事件进行处理。 + +### 注册监听器 + +`mc.listen(event,callback)` + +- 参数: + + - event : `String` + 要监听的事件名(见下方监听事件列表) + + - callback : `Function` + 注册的监听函数(函数相关参数见下) + 当指定的事件发生时,BDS会调用你给出的监听函数,并传入相应的参数 +- 返回值:是否成功监听事件 +- 返回值类型:`Boolean` + +
+ +### 拦截事件 + +在脚本引擎的事件监听系统中,一般你可以通过`return false`来拦截某个可以被拦截的事件。拦截事件意味着在脚本拦截之后BDS将不再处理这个事件,就像他从没发生过一样。 +举例:拦截某条聊天事件,会造成所有人都看不到这条聊天消息 + +不过,拦截事件仅对BDS有效。 +也就是说,拦截事件并不影响其他有对应监听的脚本引擎脚本处理这个事件,只是BDS无法再接收到它。 + +
+ +### 避开误区 + +有些时候,在某些事件监听内部调用特定的API会造成死循环崩服,请务必避免这些情况的发生 +举例:在`onConsoleCmd`事件监听中调用`mc.runcmd(Ex)`系列函数执行后台指令,将导致死循环 \ No newline at end of file diff --git a/docs/apis/EventAPI/OtherEvents.md b/docs/apis/EventAPI/OtherEvents.md new file mode 100644 index 00000000..e5acfcf8 --- /dev/null +++ b/docs/apis/EventAPI/OtherEvents.md @@ -0,0 +1,60 @@ +## 🔊 Other Events + +#### `"onScoreChanged"` - Player Scoreboard Change Event + +- Listener function prototype + `function(player,num,name,disName)` +- Parameters: + - player : `Player` + The player whose scoreboard values have changed. + - num: `Integer` + The changed scoreboard value. + - name : `String` + The name of the scoreboard scoring item. + - disName : `String` + The display name of the scoreboard item. +- Intercept event: cannot be intercepted. + +
+ +#### `"onTick"` - Tick Event + +- Listener function prototype + `function()` +- Parameters: + - None +- Intercept events: function returns `false` + +
+ +#### `"onServerStarted"` - Server Start Event + +- Listener function prototype + `function()` +- Parameters: + - None +- Intercept event: cannot be intercepted. + +
+ +#### `"onConsoleCmd"` - Server Command Event + +- Listener function prototype + `function(cmd)` +- Parameters: + - cmd : `String` + The console command being executed. + +- Intercept events: function returns `false` + +
+ +#### `"onConsoleOutput"` - Console Output Event + +- Listener function prototype + `function(cmd)` +- Parameters: + - cmd : `String` + The console output. + +- Intercept events: function returns `false` \ No newline at end of file diff --git a/docs/apis/EventAPI/OtherEvents.zh.md b/docs/apis/EventAPI/OtherEvents.zh.md new file mode 100644 index 00000000..59f94075 --- /dev/null +++ b/docs/apis/EventAPI/OtherEvents.zh.md @@ -0,0 +1,60 @@ +## 🔊 其他事件 + +#### `"onScoreChanged"` - 玩家计分板数值改变 + +- 监听函数原型 + `function(player,num,name,disName)` +- 参数: + - player : `Player` + 计分板数值改变的玩家 + - num: `Integer` + 改变后的计分板数值 + - name : `String` + 计分板计分项名称 + - disName : `String` + 计分板计分项的显示名称 +- 拦截事件:不可以拦截 + +
+ +#### `"onTick"` - 每个游戏刻触发 + +- 监听函数原型 + `function()` +- 参数: + - 无 +- 拦截事件:函数返回`false` + +
+ +#### `"onServerStarted"` - 服务器启动完毕 + +- 监听函数原型 + `function()` +- 参数: + - 无 +- 拦截事件:不可以拦截 + +
+ +#### `"onConsoleCmd"` - 服务端执行后台命令 + +- 监听函数原型 + `function(cmd)` +- 参数: + - cmd : `String` + 执行的后台命令 + +- 拦截事件:函数返回`false` + +
+ +#### `"onConsoleOutput"` - 控制台产生命令输出 + +- 监听函数原型 + `function(cmd)` +- 参数: + - cmd : `String` + 输出的命令结果信息 + +- 拦截事件:函数返回`false` \ No newline at end of file diff --git a/docs/apis/EventAPI/PlayerEvents.md b/docs/apis/EventAPI/PlayerEvents.md new file mode 100644 index 00000000..28631439 --- /dev/null +++ b/docs/apis/EventAPI/PlayerEvents.md @@ -0,0 +1,587 @@ +## 📜 Listen Event List + +Here is a list of the various events that LLSE supports listening for. + +Tip: You can obtain relevant information about the game objects obtained by listening, such as the coordinates of the block, the name of the entity, and so on. +At the same time, the member functions of these objects can also be called. + +> Notice! Some of the callback parameters passed in may sometimes be Null, which requires a good judgment check when writing code. + +## 🏃‍♂️ Player Related Events + +#### `"onPreJoin"` - Player Connection Event + +- Listener function prototype + `function(player)` +- Parameters: + - player : `Player` + The player that is connecting to the server. +- Intercept events: function returns `false` + +Note: Only some basic information of players can be obtained in this monitoring function, such as name, IP, XUID, etc. Because the player has not fully entered the server at this time. + +
+ +#### `"onJoin"` - Player Join Event + +- Listener function prototype + `function(player)` +- Parameters: + - player : `Player` + The player that enters the game. +- Intercept event: cannot be intercepted. + +
+ +#### `"onLeft"` - Player Leave Event + +- Listener function prototype + `function(player)` +- Parameters: + - player : `Player` + The player that left the game. + +- Intercept event: cannot be intercepted. + +
+ +#### `"onRespawn"` - Player Respawn Event + +- Listener function prototype + `function(player)` +- Parameters: + - player : `Player` + The player being respawned. +- Intercept event: cannot be intercepted. + +
+ +#### `"onPlayerDie"` - Player Death Event + +- Listener function prototype + `function(player,source)` +- Parameters: + - player : `Player` + The player that died. + - source : `Entity` + The entity that dealt the damage that killed the player (may be `Null`). + +- Intercept event: cannot be intercepted. + +
+ +#### `"onPlayerCmd"` - Player Command Execution Event + +- Listener function prototype + `function(player,cmd)` +- Parameters: + - player : `Player` + The player that executed the command. + - cmd : `String` + The command that is being executed. + +- Intercept events: function returns `false` + +
+ +#### `"onChat"` - Player Chat Event + +- Listener function prototype + `function(player,msg)` +- Parameters: + - player : `Player` + The player that sent the message. + - msg : `String` + The message that was sent. + +- Intercept events: function returns `false` + +
+ +#### `"onChangeDim"` - Player Dimension Switch Event + +- Listener function prototype + `function(player,dimid)` +- Parameters: + - player : `Player` + The player that switched dimensions. + - dimid : `Integer` + Go to the dimension ID of the dimension, 0 is the main world, 1 is the nether, and 2 is the end. +- Intercept event: cannot be intercepted. + +Reminder: This event does not fire when the player returns to the Overworld from the End via a return portal. + +
+ +#### `"onJump"` - Player Jump Event + +- Listener function prototype + `function(player)` +- Parameters: + - player : `Player` + The player that jumped. + +- Intercept event: cannot be intercepted. + +
+ +#### `"onSneak"` - Player Sneak Event + +- Listener function prototype + `function(player,isSneaking)` +- Parameters: + - player : `Player` + The player that toggled their sneak state. + - isSneaking : `Boolean` + `True` indicates that the player is sneaking,`False` indicates that the player is no longer sneaking. + +- Intercept event: cannot be intercepted. + +
+ +#### `"onAttackEntity"` - Player Attack Other Event + +- Listener function prototype + `function(player,entity,damage)` +- Parameters: + - player : `Player` + The player that attacked an entity. + - entity : `Entity` + The entity that is being attacked. + - damage : `float` + The damage dealt by this attack. + +- Intercept events: function returns `false` + +
+ +#### `"onAttackBlock"` - Player Attack Block Event + +- Listener function prototype + `function(player,block,item)` + +- Parameters: + + - player : `Player` + The player that attacked the block. + - entity : `Block` + Attacked block. + - item: `Item` + Item used to attack the block. + +- Intercept events: function returns `false` + +
+ +#### `"onUseItem"` - Player Item Use Event + +- Listener function prototype + `function(player,item)` +- Parameters: + - player : `Player` + The player that used the item. + - item : `Item` + The item that was used. +- Intercept events: function returns `false` + +
+ +#### `"onUseItemOn"` - Player Use Item on Block Event (Right-Click) + +- Listener function prototype + `function(player,item,block,side,pos)` +- Parameters: + - player : `Player` + The player that used the item. + - item : `Item` + The item being used. + - block : `Block` + The block that was right-clicked. + - side : `Number` + The face of the object that was clicked. + The faces: `0`-Down `1`-Up `2`-North `3`-South `4`-West `5`-East + - pos : `FloatPos` + The position that was right-clicked. + +- Intercept events: function returns `false` + +Note: Win10 client right-clicking on the player will trigger this event on the server multiple times in a row. + +
+ +#### `"onUseBucketPlace"` - Players use bucket to pour things out on Block Event + +- Listener function prototype + `function(player,item,block,side,pos)` +- Parameters: + - player : `Player` + The player that used the item. + - item : `Item` + The item being used. + - block : `Block` + The block that was right-clicked. + - side : `Number` + The face of the object that was clicked. + The faces: `0`-Down `1`-Up `2`-North `3`-South `4`-West `5`-East + - pos : `FloatPos` + The position that was right-clicked. + +- Intercept events: function returns `false` + +Note: The player may trigger this event on the server multiple times in a row. + +
+ +#### `"onUseBucketTake"` - Players use bucket to pack in things Event + +- Listener function prototype + `function(player,item,target,side,pos)` +- Parameters: + - player : `Player` + The player that used the item. + - item : `Item` + The item being used. + - target : `Block` / `Entity` + The block or entity that was right-clicked. + - side : `Number` + The face of the object that was clicked. + The faces: `0`-Down `1`-Up `2`-North `3`-South `4`-West `5`-East + - pos : `FloatPos` + The position that was right-clicked. + +- Intercept events: function returns `false` + +Note: The player may trigger this event on the server multiple times in a row. + +
+ +#### `"onTakeItem"` - Player Pickup Item Event + +- Listener function prototype + `function(player,entity,item)` +- Parameters: + + - player : `Player` + The player that picked up the item. + - entity: `Entity` + The dropped entity of the item about to be picked up. + - item : `Item` + The item about to be picked up. + +- Intercept events: function returns `false` + +
+ +#### `"onDropItem"` - Player Drop Item Event + +- Listener function prototype + `function(player,item)` +- Parameters: + - player : `Player` + The player that dropped the item. + - item : `Item` + The item being dropped. + +- Intercept events: function returns `false` + +
+ +#### `"onEat"` - Player Eating Event + +- Listener function prototype + `function(player,item)` +- Parameters: + - player : `Player` + The player that is eating. + - item : `Item` + The item being eaten. + +- Intercept events: function returns `false` + +**Food** here is a broad concept of items, including conventional food, potions, milk, medicines and other items that can be ingested. + +
+ +#### `"onAte"` - Player Ate Event + +- Listener function prototype + `function(player,item)` +- Parameters: + - player : `Player` + The player that has eaten. + - item : `Item` + The item which has been eaten. + +- Intercept events: function returns `false` + +#### `"onConsumeTotem"` - Player Consume Totem Event + +- Listener function prototype + `function(player)` +- Parameters: + - player : `Player` + The player that consumes the totem. +- Intercept events: function returns `false` + - After intercepting here, the resurrection effect of the totem will still be triggered, but the totem will not be consumed. + +
+ +#### `"onEffectAdded"` - Player Effect Added Event + +- Listener function prototype + `function(player,effectName,amplifier,duration)` +- Parameters: + - player : `Player` + The player who gets the effect. + - effectName : `String` + Obtained effect name: **minecraft:effect.EffectName** + - amplifier : `Number` + Obtained effect amplifier (effect level -1) + - duration : `Number` + Obtained effect duration (ticks) + +- Intercept events: function returns `false` + +
+ +#### `"onEffectRemoved"` - Player Effect Removed Event + +- Listener function prototype + `function(player,effectName)` +- Parameters: + - player : `Player` + Player with the removed effect. + - effectName : `String` + Removed effect name: **minecraft:effect.EffectName** + +- Intercept events: function returns `false` + +
+ +#### `"onEffectUpdated"` - Player Effect Updated Event + +- Listener function prototype + `function(player,effectName,amplifier,duration)` +- Parameters: + - player : `Player` + The player that updated the effect. + - effectName : `String` + Refreshed effect name: **minecraft:effect.EffectName** + - amplifier : `Number` + Obtained effect amplifier (effect level -1) + - duration : `Number` + Obtained effect duration (ticks) + +- Intercept events: function returns `false` + +
+ +#### `"onStartDestroyBlock"` - Player Start Breaking Block Event + +- Listener function prototype + `function(player,block)` +- Parameters: + - player : `Player` + The player that is breaking the block. + - block : `Block` + The block that is being destroyed. + +- Intercept event: cannot be intercepted. + +
+ +#### `"onDestroyBlock"` - Player Destroyed Block Event + +- Listener function prototype + `function(player,block)` +- Parameters: + - player : `Player` + The player that broke the block. + - block : `Block` + The broken block. + +- Intercept events: function returns `false` + +
+ +#### `"onPlaceBlock"` - Player Try Places Block Event + +- Listener function prototype + `function(player,block)` +- Parameters: + - player : `Player` + The player that placed the block. + - block : `Block` + The block that was placed. + +- Intercept events: function returns `false` + +> **ATTENTION** This event will always fire when the player tries to place a block. + +
+ +#### `"afterPlaceBlock"` - Player Placed Block Event + +- Listener function prototype + `function(player,block)` +- Parameters: + - player : `Player` + The player that placed the block. + - block : `Block` + The block that was placed. + +- Intercept events: function returns `false` + +
+ +#### `"onOpenContainer"` - Player Opens Container Event + +- Listener function prototype + `function(player,block)` +- Parameters: + - player : `Player` + The player that opened the container. + - block : `Block` + The opened container block. +- Intercept events: function returns `false` + +The **container** here is a broad concept of container, including boxes, buckets and other containers that can store items can trigger this event. + +
+ +#### `"onCloseContainer"` - Player Closes Container Event + +- Listener function prototype + `function(player,block)` +- Parameters: + - player : `Player` + The player that closes the container. + - block : `Block` + The container that was closed. +- Intercept events: function returns `false` + +Due to the limitation of the monitoring function, the containers that currently support monitoring and closing are: chests (`minecraft:chest`), and wooden barrels (`minecraft:barrel`). + +
+ +#### `"onInventoryChange"` - Player Inventory Change Event + +- Listener function prototype + `function(player,slotNum,oldItem,newItem)` +- Parameters: + - player : `Player` + The player whose inventory changed. + - slotNum : `Integer` + The slot position of the inventory operation. + - oldItem : `Item` + The original item in the grid. + - newItem : `Item` + The new item in the grid. +- Intercept event: cannot be intercepted. + +Explanation of callback parameters: +There are many different combinations of old item objects and new item objects, indicating different changes in the grid. + +- Put item: the old item object is empty, the new item object is not empty. +- Take out the item: the old item object is not empty, the new item object is empty. +- Item Increase Stack: Old Item Object's `type` == new item object's `type`, old item's `count` < new item's `count`. +- Item Reduce Stack: Old Item Object's `type` == new item object's `type`, old item's `count` > new item's `count`. +Replacement Item: Old Item Object's `type` does not equal the new item's `type`, and neither item stack is empty. + +
+ +#### `"onChangeSprinting"` - Player Sprint State Change Event + +- Listener function prototype + `function(player,sprinting)` +- Parameters: + - player : `Player` + The player that started or stopped sprinting. + - sprinting : `Boolean` + Whether the player is now sprinting. +- Intercept event: cannot be intercepted. + +Note: Player.setSprinting (false) can be executed in the next game tick to achieve the interception effect. + +
+ +#### `"onSetArmor"` - Player Armor Change Event + +- Listener function prototype + `function(player,slotNum,item)` +- Parameters: + - player : `Player` + Player object that changes armor. + - slotNum : `Integer` + The armor column number, range from 0 to 3. + - item : `Item` + The item in the armor slot. +- Intercept event: function returns `false` +- Warning: After interception, you will take off your original equipment when you enter the game. + +
+ +#### `"onUseRespawnAnchor"` - Player Respawn Anchor Use Event + +- Listener function prototype + `function(player,pos)` +- Parameters: + - player : `Player` + The player using the respawn anchor. + - pos : `IntPos` + The position of the respawn anchor that was used. +- Intercept events: function returns `false` + +
+ +#### `"onOpenContainerScreen"` - Player Opens Container GUI Event + +- Listener function prototype + `function(player)` +- Parameters: + - player : `Player` + The player that opened the GUI. +- Intercept events: function returns `false` + +Note: This event is so powerful that it can even intercept and open backpacks. + +
+ +#### `"onExperienceAdd"` - Player Get Experience + +- Listener function prototype + `function(player,exp)` +- Parameters: + - player : `Player` + Players with experience. + - exp : `Integer` + Amount of experience gained by the player. +- Intercept events: function returns `false` + +
+ +#### `"onPlayerPullFishingHook"` - Player Pull Closer Entity Using Fishing Hook + +- Listener function prototype + `function(player,entity,item)` +- Parameters: + - player : `Player` + Player using fishing hook. + - entity : `Entity` + Entity that player pull closer + - item : `Item` + Item that player pull closer(If this entity is not item entity, this parameter will be null) +- Intercept events: function returns `false` + +
+ +#### `"onBedEnter"` - Player Enters Bed + +- Listener function prototype + `function(player,pos)` +- Parameters: + - player : `Player` + The player using the bed. + - pos : `IntPos` + The position of the bed used. +- Intercept events: function returns `false` diff --git a/docs/apis/EventAPI/PlayerEvents.zh.md b/docs/apis/EventAPI/PlayerEvents.zh.md new file mode 100644 index 00000000..6153f625 --- /dev/null +++ b/docs/apis/EventAPI/PlayerEvents.zh.md @@ -0,0 +1,606 @@ +## 📜 监听事件列表 + +这里给出了脚本引擎支持监听的各种事件的列表。 + +提示:你可以根据监听得到的游戏对象来获取他们的相关信息,比如说方块的坐标、实体的名字等等。 +同时,这些对象的成员函数也都可以被调用。 + +> 注意!传入的回调参数中,有些有时候可能为 Null,这需要在编写代码的时候做好判断检查 + +## 🏃‍♂️ 玩家相关事件 + +#### `"onPreJoin"` - 玩家开始连接服务器 + +- 监听函数原型 + `function(player)` +- 参数: + - player : `Player` + 正在连接服务器的玩家对象 +- 拦截事件:函数返回`false` + +注:在这个监听函数中只能获取一些玩家的基础信息,比如名字、IP、XUID等。因为此时玩家尚未完全进服 + +
+ +#### `"onJoin"` - 玩家进入游戏(加载世界完成) + +- 监听函数原型 + `function(player)` +- 参数: + - player : `Player` + 进入游戏的玩家对象 +- 拦截事件:不可以拦截 + +
+ +#### `"onLeft"` - 玩家离开游戏 + +- 监听函数原型 + `function(player)` +- 参数: + - player : `Player` + 离开游戏的玩家对象 + +- 拦截事件:不可以拦截 + +
+ +#### `"onRespawn"` - 玩家重生 + +- 监听函数原型 + `function(player)` +- 参数: + - player : `Player` + 重生的玩家对象 +- 拦截事件:不可以拦截 + +
+ +#### `"onPlayerDie"` - 玩家死亡 + +- 监听函数原型 + `function(player,source)` +- 参数: + - player : `Player` + 死亡的玩家对象 + - source : `Entity` + 伤害来源的实体对象(可能为`Null`) + +- 拦截事件:不可以拦截 + +
+ +#### `"onPlayerCmd"` - 玩家执行命令 + +- 监听函数原型 + `function(player,cmd)` +- 参数: + - player : `Player` + 执行命令的玩家对象 + + - cmd : `String` + 执行的命令 + +- 拦截事件:函数返回`false` + +
+ +#### `"onChat"` - 玩家发送聊天信息 + +- 监听函数原型 + `function(player,msg)` +- 参数: + - player : `Player` + 发送聊天信息的玩家对象 + + - msg : `String` + 发送的聊天消息 + +- 拦截事件:函数返回`false` + +
+ +#### `"onChangeDim"` - 玩家切换维度 + +- 监听函数原型 + `function(player,dimid)` +- 参数: + - player : `Player` + 切换维度的玩家对象 + - dimid : `Integer` + 前往维度的维度ID,0为主世界,1为下界,2为末地 +- 拦截事件:不可以拦截 + +提醒:当玩家从末地通过返回传送门返回主世界时,不会触发此事件。 + +
+ +#### `"onJump"` - 玩家跳跃 + +- 监听函数原型 + `function(player)` +- 参数: + - player : `Player` + 跳跃的玩家对象 + +- 拦截事件:不可以拦截 + +
+ +#### `"onSneak"` - 玩家切换潜行状态 + +- 监听函数原型 + `function(player,isSneaking)` +- 参数: + - player : `Player` + 切换潜行状态的玩家对象 + - isSneaking : `Boolean` + `True`表示玩家进入潜行状态,`False`表示玩家退出潜行状态 + +- 拦截事件:不可以拦截 + +
+ +#### `"onAttackEntity"` - 玩家攻击实体 + +- 监听函数原型 + `function(player,entity,damage)` +- 参数: + - player : `Player` + 攻击实体的玩家对象 + + - entity : `Entity` + 被攻击的实体对象 + + - damage : `float` + 攻击所造成的伤害 + +- 拦截事件:函数返回`false` + +
+ +#### `"onAttackBlock"` - 玩家攻击方块 + +- 监听函数原型 + `function(player,block,item)` + +- 参数: + + - player : `Player` + 攻击方块的玩家对象 + + - entity : `Block` + 被攻击的方块对象 + + - item:`Item` + + 手持的物品对象 + +- 拦截事件:函数返回`false` + +
+ +#### `"onUseItem"` - 玩家使用物品 + +- 监听函数原型 + `function(player,item)` +- 参数: + - player : `Player` + 使用物品的玩家对象 + - item : `Item` + 被使用的物品对象 +- 拦截事件:函数返回`false` + +
+ +#### `"onUseItemOn"` - 玩家对方块使用物品(点击右键) + +- 监听函数原型 + `function(player,item,block,side,pos)` +- 参数: + - player : `Player` + 使用物品的玩家对象 + - item : `Item` + 被使用的物品对象 + - block : `Block` + 被点击到的方块对象 + - side : `Number` + 方块被点击的面 + 依次为:`0`-下 `1`-上 `2`-北 `3`-南 `4`-西 `5`-东 + - pos : `FloatPos` + 被点击的浮点位置 + +- 拦截事件:函数返回`false` + +注:Win10客户端玩家右键会在服务端连续多次激发这个事件 + +
+ +#### `"onUseBucketPlace"` - 玩家使用桶倒出东西 + +- 监听函数原型 + `function(player,item,block,side,pos)` +- 参数: + - player : `Player` + 使用物品的玩家对象 + - item : `Item` + 被使用的物品对象 + - block : `Block` + 被点击到的方块对象 + - side : `Number` + 方块被点击的面 + 依次为:`0`-下 `1`-上 `2`-北 `3`-南 `4`-西 `5`-东 + - pos : `FloatPos` + 被点击的浮点位置 + +- 拦截事件:函数返回`false` + +注:无论是手机还是Win10玩家,可能会连续多次激发这个事件 + +
+ +#### `"onUseBucketTake"` - 玩家使用桶装进东西 + +- 监听函数原型 + `function(player,item,target,side,pos)` +- 参数: + - player : `Player` + 使用物品的玩家对象 + - item : `Item` + 被使用的物品对象 + - target : `Block` / `Entity` + 被点击到的方块对象或者实体对象 + - side : `Number` + 方块被点击的面 + 依次为:`0`-下 `1`-上 `2`-北 `3`-南 `4`-西 `5`-东 + - pos : `FloatPos` + 被点击的浮点位置 + +- 拦截事件:函数返回`false` + +注:无论是手机还是Win10玩家,可能会连续多次激发这个事件 + +
+ +#### `"onTakeItem"` - 玩家捡起物品 + +- 监听函数原型 + `function(player,entity,item)` +- 参数: + + - player : `Player` + 捡起物品的玩家对象 + - entity: `Entity` + 即将被捡起的物品的掉落物实体 + - item : `Item` + 即将被捡起的物品对象 + +- 拦截事件:函数返回`false` + +
+ +#### `"onDropItem"` - 玩家丢出物品 + +- 监听函数原型 + `function(player,item)` +- 参数: + - player : `Player` + 丢出物品的玩家对象 + + - item : `Item` + 被丢出的物品对象 + +- 拦截事件:函数返回`false` + +
+ +#### `"onEat"` - 玩家正在吃食物 + +- 监听函数原型 + `function(player,item)` +- 参数: + - player : `Player` + 正在吃的玩家对象 + - item : `Item` + 被吃的物品对象 + +- 拦截事件:函数返回`false` + +此处的 **食物** 为宽泛物品的概念,包括常规食物、药水、牛奶、药品等多种可以被摄取的物品 + +
+ +#### `"onAte"` - 玩家吃下食物 + +- 监听函数原型 + `function(player,item)` +- 参数: + - player : `Player` + 正在吃的玩家对象 + - item : `Item` + 被吃的物品对象 + +- 拦截事件:不可以拦截 + +
+ +#### `"onConsumeTotem"` - 玩家消耗图腾 + +- 监听函数原型 + `function(player)` +- 参数: + - player : `Player` + 消耗图腾的玩家对象 +- 拦截事件:函数返回`false` + - 此处拦截后,仍会触发图腾的复活效果,但不会消耗图腾 + +
+ +#### `"onEffectAdded"` - 玩家获得效果 + +- 监听函数原型 + `function(player,effectName,amplifier,duration)` +- 参数: + - player : `Player` + 获得效果的玩家对象 + - effectName : `String` + 获得的效果名称 **minecraft:effect.效果** + - amplifier : `Number` + 获得的效果倍率 (效果等级 -1) + - duration : `Number` + 获得的效果时长 (单位:tick) + +- 拦截事件:函数返回`false` + +
+ +#### `"onEffectRemoved"` - 玩家移除效果 + +- 监听函数原型 + `function(player,effectName)` +- 参数: + - player : `Player` + 被移除效果的玩家对象 + - effectName : `String` + 被移除的效果名称 **minecraft:effect.效果** + +- 拦截事件:函数返回`false` + +
+ +#### `"onEffectUpdated"` - 玩家刷新效果 + +- 监听函数原型 + `function(player,effectName,amplifier,duration)` +- 参数: + - player : `Player` + 刷新效果的玩家对象 + - effectName : `String` + 获得的效果名称 **minecraft:effect.效果** + - amplifier : `Number` + 获得的效果倍率 (效果等级 -1) + - duration : `Number` + 获得的效果时长 (单位:tick) + +- 拦截事件:函数返回`false` + +
+ +#### `"onStartDestroyBlock"` - 玩家开始破坏方块 / 点击左键 + +- 监听函数原型 + `function(player,block)` +- 参数: + - player : `Player` + 正在破坏方块的玩家对象 + + - block : `Block` + 正在被破坏的方块对象 + +- 拦截事件:不可以拦截 + +
+ +#### `"onDestroyBlock"` - 玩家破坏方块完成 + +- 监听函数原型 + `function(player,block)` +- 参数: + - player : `Player` + 破坏方块的玩家对象 + + - block : `Block` + 被破坏的方块对象 + +- 拦截事件:函数返回`false` + +
+ +#### `"onPlaceBlock"` - 玩家尝试放置方块 + +- 监听函数原型 + `function(player,block)` +- 参数: + - player : `Player` + 放置方块的玩家对象 + + - block : `Block` + 将要放置的方块对象 + +- 拦截事件:函数返回`false` + +> **存在问题** +> +> 1. 当玩家尝试放置方块时,该事件将持续被触发。 +> 2. 方块对象为准星对准的方块,并非将放置方块对象。 + +
+ +#### `"afterPlaceBlock"` - 玩家放置方块 + +- 监听函数原型 + `function(player,block)` +- 参数: + - player : `Player` + 放置方块的玩家对象 + + - block : `Block` + 被放置的方块对象 + +- 拦截事件:不可以拦截 + +
+ +#### `"onOpenContainer"` - 玩家打开容器方块 + +- 监听函数原型 + `function(player,block)` +- 参数: + - player : `Player` + 打开容器方块的玩家对象 + + - block : `Block` + 被打开的容器方块对象 +- 拦截事件:函数返回`false` + +此处的 **容器** 为宽泛容器的概念,包括箱子、桶等多种可以储存物品的容器都可以触发此事件 + +
+ +#### `"onCloseContainer"` - 玩家关闭容器方块 + +- 监听函数原型 + `function(player,block)` +- 参数: + - player : `Player` + 关闭容器方块的玩家对象 + + - block : `Block` + 被关闭的容器方块对象 +- 拦截事件:函数返回`false` + +由于监听函数下限制,目前支持监听关闭的容器有:箱子(`minecraft:chest`)、木桶(`minecraft:barrel`) + +
+ +#### `"onInventoryChange"` - 玩家物品栏变化 + +- 监听函数原型 + `function(player,slotNum,oldItem,newItem)` +- 参数: + - player : `Player` + 操作物品栏的玩家对象 + - slotNum : `Integer` + 操作物品栏的格子位置(第slotNum个格子) + - oldItem : `Item` + 格子中的原来旧物品对象 + - newItem : `Item` + 格子中新的物品对象 +- 拦截事件:不可以拦截 + +对回调参数的解释: +旧物品对象与新物品对象有多种不同的组合情况,表示格子内不同的变化情况 + +- 放入物品:旧物品对象为空,新物品对象不为空 +- 取出物品:旧物品对象不为空,新物品对象为空 +- 物品增加堆叠:旧物品对象的`type` == 新物品对象的`type`,且旧物品对象的`count` < 新物品对象的`count` +- 物品减少堆叠:旧物品对象的`type` == 新物品对象的`type`,且旧物品对象的`count` > 新物品对象的`count` +- 替换物品:旧物品对象的`type` 不等于 新物品对象的`type`,且两物品对象均不为空 + +
+ +#### `"onChangeSprinting"` - 玩家改变疾跑状态 + +- 监听函数原型 + `function(player,sprinting)` +- 参数: + - player : `Player` + 要改变疾跑状态的玩家对象 + - sprinting : `Boolean` + 要改变成的疾跑状态 +- 拦截事件:不可以拦截 + +注:可在下一游戏刻执行player.setSprinting(false)达到拦截效果 + +
+ +#### `"onSetArmor"` - 玩家改变盔甲栏 + +- 监听函数原型 + `function(player,slotNum,item)` +- 参数: + - player : `Player` + 改变盔甲栏的玩家对象 + - slotNum : `Integer` + 盔甲栏序号,范围0-3 + - item : `Item` + 盔甲栏中的物品对象 +- 拦截事件:函数返回`false` +- 注:拦截后,进入游戏时会脱下原先的装备 + +
+ +#### `"onUseRespawnAnchor"` - 玩家使用重生锚 + +- 监听函数原型 + `function(player,pos)` +- 参数: + - player : `Player` + 使用重生锚的玩家对象 + - pos : `IntPos` + 被使用的重生锚的位置 +- 拦截事件:函数返回`false` + +
+ +#### `"onOpenContainerScreen"` - 玩家打开容器类GUI + +- 监听函数原型 + `function(player)` +- 参数: + - player : `Player` + 尝试打开GUI的玩家对象 +- 拦截事件:函数返回`false` + +注:此事件非常强力,甚至可以拦截打开背包。 + +
+ +#### `"onExperienceAdd"` - 玩家获得经验 + +- 监听函数原型 + `function(player,exp)` +- 参数: + - player : `Player` + 获得经验的玩家对象 + - exp : `Integer` + 获得的经验值 +- 拦截事件:函数返回`false` + +
+ +#### `"onPlayerPullFishingHook"` - 玩家使用钓鱼竿钓起实体 + +- 监听函数原型 + `function(player,entity,item)` +- 参数: + - player : `Player` + 使用钓鱼竿的玩家对象 + - entity : `Entity` + 钓起的实体(鱼钩拉起任意实体都会触发该事件,不一定是物品实体) + - item : `Item` + 钓起的物品对象(如果钓到的不是物品则返回null) +- 拦截事件:函数返回`false` + +
+ +#### `"onBedEnter"` - 玩家上床 + +- 监听函数原型 + `function(player,pos)` +- 参数: + - player : `Player` + 上床的玩家对象 + - pos : `IntPos` + 床的位置 +- 拦截事件:函数返回`false` diff --git a/docs/apis/GameAPI/Basic.md b/docs/apis/GameAPI/Basic.md new file mode 100644 index 00000000..055a2fff --- /dev/null +++ b/docs/apis/GameAPI/Basic.md @@ -0,0 +1,186 @@ +# 🎨 LLSE - Game Element Interface Documentation + +> The following APIs provide the ability to **modify** and **extension** game content. + +Obviously, the game element interface is at the core of the entire plug-in system, which is related to the ability to control and expand game content. +LLSE provides a rich and powerful interface of game elements to facilitate your creativity. + +## 🔮 Game Element Objects + +For the indexing of game elements, LLSE uses a special type of variable to keep track of each game element, and calls it "xx objects", such as "player objects" or "block objects". +You can think of it as a unique identifier for a game element. + +Currently, LLSE has the following game element objects: + +| Object Type Name | Object Name | Purpose of Object | +| ---------------- | --------------- | ------------------------------------------ | +| `IntPos` | Integer Coordinate Object | Identifies integer location (like block coordinates) | +| `FloatPos` | Floating Point Coordinate Object | Identifies a floating point position (like entity coordinates) | +| `DirectionAngle` | Direction Object| Identifies angle information (such as the direction a player is facing) | +| `Player` | Player Object | Identify player or access player attributes | +| `Entity` | Entity Object | Identify entity or access entity attributes | +| `Block` | Block Object | Identify Block or access block attributes | +| `Item` | Item Object | Identifies an item in an inventory | +| `Container` | Container Object | Identifies a container that can store items| +| `BlockEntity` | Block Entity Object| Identifies a block entity | +| `Objective` | Scoring Item Objective | Identifies the scoring items of a scoreboard system| + +You will come across them frequently in subsequent documentation. + +
+ +
+ +## 🎯 Coordinate Object + +In games, numerous APIs require coordinates. +The engine uses objects of type `IntPos` and `FloatPos` to indicate coordinates, called "coordinate objects". +Each member of the coordinate object is **readable and writable**. + +1. `IntPos` object + Its members are all **integers**, which are mostly used to represent **block coordinates** and other positions represented by integers. + For a variable pos of type `IntPos`, there are the following members: + + | Member | Meaning | Data Type | + | --------- | ---------- | --------- | + | pos.x | x coordinate | `Integer` | + | pos.y | y coordinate | `Integer` | + | pos.z | z coordinate | `Integer` | + | pos.dim | Dimension name | `String` | + | pos.dimid | Dimension ID | `Integer` | + + Among them, the value of the **dimension ID** attribute is: `0` represents the Main World, `1` represents The Nether, and `2` represents The End. + + **Dimension text name:** The values of the attributes are: "Main World", "Nether", "End". + + If in some cases the dimension is invalid, or cannot be obtained, you will find that the value of `dimid` is `-1`. + +
+ +2. `FloatPos`object + Its members are all **floating point numbers**, which are mostly used to represent **entity coordinates** and other positions that cannot be represented by integers + For a variable pos of type `FloatPos`, there are the following members: + + | Member | Meaning | Data Type | + | --------- | ---------- | --------- | + | pos.x | x coordinate | `Float` | + | pos.y | y coordinate | `Float` | + | pos.z | z coordinate | `Float` | + | pos.dim | Dimension Name | `String` | + | pos.dimid | Dimension ID | `Integer` | + + Among them, the value of the **dimension ID** attribute is: `0` represents The Main World, `1` represents The Nether, and `2` represents The End. + + **Dimension text name:** The values of the attributes are: "Main World", "Nether", "End" + + If in some case the dimension is invalid, or cannot be obtained, you will find that the value of `dimid` is `-1`. + +
+ +### Coordinate Object Auxiliary Interface + +For scripting languages ​​that naturally support object-oriented, you can directly construct the coordinate object and pass in the x, y, z, dimid parameters. +For some languages ​​that support general object orientation, LLSE also provides auxiliary interfaces to help generate a coordinate object more easily. + +#### Generate an Integer Coordinate Object + +[JavaScript] `new FloatPos(x,y,z,dimid)` +[Lua] `FloatPos(x,y,z,dimid)` + +- Parameters: + - x : `Integer` + x coordinate + - y : `Integer` + y coordinate + - z : `Integer` + z coordinate + - dimid : `Integer` + Dimension ID: `0` representing the overworld, `1` represents The Nether, `2` represents The End. +- Return value: An Integer coordinate object. +- Return value type: `IntPos` + +#### Generate a Floating Point Coordinate Object + +[JavaScript] `new FloatPos(x,y,z,dimid)` +[Lua] `FloatPos(x,y,z,dimid)` + +- Parameters: + - x : `Float` + x coordinate + - y : `Float` + y coordinate + - z : `Float` + z coordinate + - dimid : `Integer` + Dimension ID: `0` representing the overworld, `1` represents The Nether, `2` represents The End. +- Return value: A floating point coordinate object. +- Return value type: `FloatPos` + +
+ +## 📐 Bearing Angle Object + +The engine uses a `DirectionAngle` object to denote an Euler angle, called a "direction angle object". +Its two members are **floating point numbers**, which are mostly used to represent the direction data such as the orientation of the entity. +Each member of the direction angle object is **readable and writable**. + +For a `DirectionAngle` type variable ang, there are the following members: + +| Member | Meaning | Data Type | +| --------- | ---------- | --------- | +| ang.pitch | Pitch angle (-90° ~ 90°) | `Float` | +| ang.yaw | Yaw angle (rotation angle) | `Float` | + +Since there is no concept of rotation in the entity system of MC, there is no data related to the rollover angle. + +
+ +##### Create Direction Angle + +[JavaScript] `new DirectionAngle(pitch, yaw)` +[Lua] `DirectionAngle(pitch, yaw)` + +- Parameters: + - pitch : `Float` + pitch angle + - yaw : `Float` + yaw angle +- Return value: A floating point coordinate object. +- Return value type: `FloatPos` + +
+ +##### Convert Direction Angle to Base Heading + +`ang.toFacing()` + +- Return value: The basic orientation indicated by the current bearing object. +- Return value type: `Integer` + +The return value is `0-3`, representing the four basic orientations of **North, East, South, West**. Used to quickly determine the general direction an entity is facing. + +## Get Structure NBT + +`mc.getStructure(pos1, pos2, ignoreBlocks = false, ignoreEntities = false)` + +- Parameters: + + - pos1 : `IntPos` diagonal coordinate 1, filled in similarly to the `from` parameter of the [fill command](https://minecraft.wiki/w/Commands/fill "view in wikipedia") + - pos2 : `IntPos` diagonal coordinate 2, filled in similarly to the `to` parameter of the [fill command](https://minecraft.wiki/w/Commands/fill "View in Wikipedia") + - ignoreBlocks : `Boolean` Ignore blocks + - ignoreEntities : `Boolean` Ignore entities +- Return value type : `NbtCompound` + +## Set Structure NBT + +`mc.setStructure(nbt, pos, mirror = 0, rotation = 0)` + +- Parameters: + + - nbt : `NbtCompound` + - pos : `IntPos` place coordinates + - mirror : `number` mirror mode + - `0: no mirror` `1: X-axis` `2: Z-axis` `3: XZ-axis` + - rotation : `number` rotation angle + - `0: no rotation` `1: rotation 90°` `2: rotation 180°` `3: rotation 270°` +- Return value type : `Boolean` diff --git a/docs/apis/GameAPI/Basic.zh.md b/docs/apis/GameAPI/Basic.zh.md new file mode 100644 index 00000000..85c3872c --- /dev/null +++ b/docs/apis/GameAPI/Basic.zh.md @@ -0,0 +1,172 @@ +# 🎨 脚本引擎 - 游戏元素接口文档 + +> 下列这些API,提供了对游戏内容进行 **修改** 和 **扩展** 的能力。 + +显然,游戏元素接口处于整个插件体系中的核心位置,关乎到对游戏内容的控制和扩展能力。 +脚本引擎提供了丰富强大的游戏元素接口,为你发挥创意提供方便。 + +## 🔮 游戏元素对象 + +对于游戏元素的索引,脚本引擎使用专门类型的变量来跟踪每一个游戏元素,并称其为「xx对象」,如「玩家对象」或者「方块对象」。 +你可以将其理解为游戏元素的唯一标识符。 + +目前,脚本引擎拥有的游戏元素对象如下: + +| 对象类型名 | 对象称呼 | 对象实际意义 | +| ---------------- | --------------- | ------------------------------------------ | +| `IntPos` | 整数 坐标对象 | 标识一个整数位置(如方块坐标) | +| `FloatPos` | 浮点数 坐标对象 | 标识一个浮点数位置(如实体坐标) | +| `DirectionAngle` | 方向角对象 | 标识一个欧拉角角度信息(如玩家朝向) | +| `Player` | 玩家对象 | 标识一个玩家 | +| `Entity` | 实体对象 | 标识一个实体 | +| `Block` | 方块对象 | 标识一个具体的方块 | +| `Item` | 物品栏物品对象 | 标识一个物品栏中的物品 | +| `Container` | 容器对象 | 标识一个拥有格子、可以储存和放置物品的容器 | +| `BlockEntity` | 方块实体对象 | 标识一个方块实体 | +| `Objective` | 记分项对象 | 标识一个记分板系统的记分项 | + +在后续的文档中,你会频繁地接触到他们。 + +## 🎯 坐标对象 + +在游戏中,数量众多的 API 都需要提供坐标。 +引擎采用 `IntPos` 和 `FloatPos` 类型的对象来标示坐标,称之为「坐标对象」。 +坐标对象的各个成员都是**可读写**的。 + +1. `IntPos`对象 + 它的成员均为**整数**,多用来表示**方块坐标**等用整数表示的位置 + 对于某个 `IntPos` 类型变量 pos,有如下这些成员: + + | 成员 | 含义 | 类型 | + | --------- | ---------- | --------- | + | pos.x | x 坐标 | `Integer` | + | pos.y | y 坐标 | `Integer` | + | pos.z | z 坐标 | `Integer` | + | pos.dim | 维度文字名 | `String` | + | pos.dimid | 维度ID | `Integer` | + + 其中,**维度ID** 属性的取值为:`0` 代表主世界,`1` 代表下界,`2` 代表末地 + **维度文字名** 属性的取值分别为:"主世界","下界","末地" + + 如果某种情况下维度无效,或者无法获取,你会发现`dimid`的值为-1 + +
+ +2. `FloatPos`对象 + 它的成员均为**浮点数**,多用来表示**实体坐标**等用无法用整数表示的位置 + 对于某个 `FloatPos` 类型变量 pos,有如下这些成员: + + | 成员 | 含义 | 类型 | + | --------- | ---------- | --------- | + | pos.x | x 坐标 | `Float` | + | pos.y | y 坐标 | `Float` | + | pos.z | z 坐标 | `Float` | + | pos.dim | 维度文字名 | `String` | + | pos.dimid | 维度ID | `Integer` | + + 其中,**维度ID** 属性的取值为:`0` 代表主世界,`1` 代表下界,`2` 代表末地 + **维度文字名** 属性的取值分别为:"主世界","下界","末地" + + 如果某种情况下维度无效,或者无法获取,你会发现`dimid`的值为-1 + +### 坐标对象辅助接口 + +对于自然支持面向对象的脚本语言,你可以直接构造坐标对象,并传入x, y, z, dimid参数 +对于某些对面向对象支持一般的语言,脚本引擎也提供了辅助接口,帮助更方便地生成一个坐标对象 + +#### 生成一个整数坐标对象 + +[JavaScript] `new IntPos(x,y,z,dimid)` +[Lua] `IntPos(x,y,z,dimid)` + +- 参数: + - x : `Integer` + x 坐标 + - y : `Integer` + y 坐标 + - z : `Integer` + z 坐标 + - dimid : `Integer` + 维度ID:`0` 代表主世界,`1` 代表下界,`2` 代表末地 +- 返回值:一个整数坐标对象 +- 返回值类型:`IntPos` + +#### 生成一个浮点数坐标对象 + +[JavaScript] `new FloatPos(x,y,z,dimid)` +[Lua] `FloatPos(x,y,z,dimid)` + +- 参数: + - x : `Float` + x 坐标 + - y : `Float` + y 坐标 + - z : `Float` + z 坐标 + - dimid : `Integer` + 维度ID:`0` 代表主世界,`1` 代表下界,`2` 代表末地 +- 返回值:一个浮点数坐标对象 +- 返回值类型:`FloatPos` + +## 📐 方向角对象 + +引擎采用 `DirectionAngle` 对象来标示一个欧拉角,称之为「方向角对象」。 +它的两个成员均为**浮点数**,多用来表示实体的朝向等方向数据 +方向角对象的各个成员都是**可读写**的。 + +对于某个 `DirectionAngle` 类型变量 ang,有如下这些成员: + +| 成员 | 含义 | 类型 | +| --------- | ---------- | --------- | +| ang.pitch | 俯仰角(-90° ~ 90°) | `Float` | +| ang.yaw | 偏航角(旋转角) | `Float` | + +由于MC的实体系统不存在 自转 的概念,所以没有翻滚角相关数据 + +#### 创建偏航角 + +[JavaScript] `new DirectionAngle(pitch, yaw)` +[Lua] `DirectionAngle(pitch, yaw)` + +- 参数: + - pitch : `Float` + 俯仰角 + - yaw : `Float` + 偏航角(旋转角) +- 返回值:一个方向角对象 +- 返回值类型:`DirectionAngle` + +#### 将偏航角转换为基本朝向 + +`ang.toFacing()` + +- 返回值:当前方向角对象所指示的基本朝向 +- 返回值类型:`Integer` + +返回值为`0-3`,代表 **北东南西** 四个基本朝向。用于快速确定实体面向的大致方向 + +## 获取结构NBT + +`mc.getStructure(pos1, pos2, ignoreBlocks = false, ignoreEntities = false)` + +- 参数: + + - pos1 : `IntPos` 对角坐标1,填写方式与 [fill命令](https://minecraft.fandom.com/zh/wiki/%E5%91%BD%E4%BB%A4/fill?so=search#%E5%8F%82%E6%95%B0 "在维基百科中查看") 的 `from` 参数类似 + - pos2 : `IntPos` 对角坐标2,填写方式与 [fill命令](https://minecraft.fandom.com/zh/wiki/%E5%91%BD%E4%BB%A4/fill?so=search#%E5%8F%82%E6%95%B0 "在维基百科中查看") 的 `to` 参数类似 + - ignoreBlocks : `Boolean` 忽略方块 + - ignoreEntities : `Boolean` 忽略实体 +- 返回值类型:`NbtCompound` + +## 放置结构NBT + +`mc.setStructure(nbt, pos, mirror = 0, rotation = 0)` + +- 参数: + + - nbt : `NbtCompound` + - pos : `IntPos` 放置坐标 + - mirror : `number` 镜像模式 + - `0: 不镜像` `1: X轴` `2: Z轴` `3: XZ轴` + - rotation : `number` 旋转角度 + - `0: 不旋转` `1: 旋转90°` `2: 旋转180°` `3: 旋转270°` +- 返回值类型:`Boolean` diff --git a/docs/apis/GameAPI/Block.md b/docs/apis/GameAPI/Block.md new file mode 100644 index 00000000..d0d1aebe --- /dev/null +++ b/docs/apis/GameAPI/Block.md @@ -0,0 +1,202 @@ +## 📦 Block Object API + +In LLSE, use "block objects" to manipulate and obtain information about a certain type of block. + +### Get a Block Object + +#### Get From Event or API + +By registering the **event listener** function, or calling some **returning a block object** function, you can get the block object related to the related event given by the BDS +For details, see [Event listener documentation - EventAPI](/LLSEPluginDevelopment/EventAPI/Listen.md) + +#### Obtained by Block Coordinates + +Use this function to manually generate objects. Note that the block you want to get must be in the range that has been loaded, otherwise there will be problems. + +`mc.getBlock(pos)` +`mc.getBlock(x,y,z,dimid)` + +- Parameters: + - pos : `IntPos ` + The coordinates of the block (or use x, y, z, dimid to determine the block position) +- Return value: The generated `Block` object. +- Return value type: `Block` + - If the return value is `Null`, it means that the block acquisition failed. + +> Note: Do not save a block object **long-term**. +> When the block corresponding to the block object is destroyed, the corresponding block object will become invalid. Therefore, if there is a need to operate a certain block for a long time, please obtain the real-time block object through the above method. +
+ + +### Block Object - Properties + +Every block object contains some fixed object properties. for a specific block object `bl`, has the following properties: + +| Attributes | Meaning | Data Type | +| ----------------------- | ------------------------------------------- | --------- | +| bl.name | The name of the block displayed in the game | `String` | +| bl.type | Block standard type name | `String` | +| bl.id | The in-game id of the block | `Integer` | +| bl.pos | The coordinates of the block | `IntPos` | +| bl.tileData | The block's data value | `Integer` | +| bl.variant | The block variant | `Integer` | +| bl.translucency | The block translucency | `Integer` | +| bl.thickness | The block thickness | `Integer` | +| bl.isAir | Whether the block is air | `Boolean` | +| bl.isBounceBlock | Whether the block is bounce | `Boolean` | +| bl.isButtonBlock | Whether the block is button | `Boolean` | +| bl.isCropBlock | Whether the block is crop | `Boolean` | +| bl.isDoorBlock | Whether the block is door | `Boolean` | +| bl.isFenceBlock | Whether the block is fence | `Boolean` | +| bl.isFenceGateBlock | Whether the block is fence gate | `Boolean` | +| bl.isThinFenceBlock | Whether the block is thin fence block | `Boolean` | +| bl.isHeavyBlock | Whether the block is heavy | `Boolean` | +| bl.isStemBlock | Whether the block is stem | `Boolean` | +| bl.isSlabBlock | Whether the block is slab | `Boolean` | +| bl.isUnbreakable | Whether the block is unbreakable | `Boolean` | +| bl.isWaterBlockingBlock | Whether the block is can block water | `Boolean` | + +These object properties are read-only and cannot be modified. + +
+ +#### Destroy The Block + +`bl.destroy(drop)` + +- Parameters: + - drop : `Boolen` + Whether to generate drops +- Return value: Whether the destroy was successful or not. +- Return value type: `Boolean` + +
+ +### Block Object - Function + +Each block object contains some member functions (member methods) that can be executed. for a specific block object `bl`, you can perform some operations on this block through the following functions. + +#### Get the Block's NBT Object + +`bl.getNbt()` + +- Return value: NBT object of the block +- Return value type: `NbtCompound` + +
+ +#### Write to the Block's NBT Object + +`bl.setNbt(nbt)` + +- Parameters: + - nbt : `NbtCompound` + NBT objects +- Return value: Whether the write was successful or not. +- Return value type: `Boolean` + +For more usage of NBT objects, please refer to [NBT Interface Documentation](/LLSEPluginDevelopment/NbtAPI/NBT.md) +Note: Use this api with caution, consider using mc.setBlock() instead. + +
+ +#### Get the BlockState of the Block + +`bl.getBlockState()` + +- Return value: The BlockState of the Block. +- Return value type: `Object` + +Convenience function to help parse block BlockState and convert it to `Object` for easy reading and parsing +Equivalent to script executing `block.getNbt().getTag("states").toObject()` + +
+ +#### Determine if a Block Has a Container + +`bl.hasContainer()` + +- Return value: whether this block has a container +- Return value type: `Boolean` + +Such as boxes, buckets and other containers; they each have a container object of their own. + +
+ +#### Get the Container Object Owned by the Block + +`bl.getContainer()` + +- Return value: The container object owned by this block +- Return value type: `Container` + +For more usage of container objects, please refer to [Container Object API Documentation](/LLSEPluginDevelopment/GameAPI/Container.md) + +
+ +#### Determine if a Block Has a Block Entity + +`bl.hasBlockEntity()` + +- Return value: Whether the block has a block entity +- Return value type: `Boolean` + +
+ +#### Get the Block Entity Owned by the Block + +`bl.getBlockEntity()` + +- Return value: The block entity owned by this block +- Return value type: `BlockEntity` + +
+ +#### Remove the Block Entity Owned by the Block + +`bl.removeBlockEntity()` + +- Return value: Whether the deletion was successful +- Return value type: `Boolean` + +For more usage of block entity object, please refer to [Block entity object API documentation](/LLSEPluginDevelopment/GameAPI/BlockEntity.md) + +
+ +### Other Block Function API + +The following APIs provide APIs for interacting with blocks at specified locations in the game: + +#### Set the Block at the Specified Location + +`mc.setBlock(pos,block,tiledata)` +`mc.setBlock(x,y,z,dimid,block,tiledata)` + +- Parameters: + - pos : `IntPos ` + Target block position (or use x, y, z, dimid to determine block position) + - block : `Block` ,`String` or `NBTCompound` + The block object to set to, the block standard type name (e.g. `minecraft:stone`) or block NBT data + - tiledata : `Integer` + Block state value, same as tiledata of vanilla /setBlock command, default is 0, only valid when placing blocks by block type name. +- Return value: Whether the setting is successful or not. +- Return value type: `Boolean` + +Through this function, set the block corresponding to one coordinate to another, similar to the command `/setblock` + +
+ +#### Generate Particle Effects at Specified Locations + +`mc.spawnParticle(pos,type)` +`mc.spawnParticle(x,y,z,dimid,type)` + +- Parameters: + - pos : `IntPos `/ `FloatPos` + Target spawn position (or use x, y, z, dimid to determine block position) + - type : `String` + The name of the particle effect to generate (check the wiki for details) +- Return value: Whether it was successfully generated +- Return value type: `Boolean` + +Particle effect names can be found in the [Minecraft Wiki](https://minecraft.wiki/w/Particles#Types_of_particles), don't forget the namespace prefix when passing in parameters. similar to `minecraft:heart_particle` \ No newline at end of file diff --git a/docs/apis/GameAPI/Block.zh.md b/docs/apis/GameAPI/Block.zh.md new file mode 100644 index 00000000..2e6a2aad --- /dev/null +++ b/docs/apis/GameAPI/Block.zh.md @@ -0,0 +1,203 @@ +## 📦 方块对象 API + +在脚本引擎中,使用「方块对象」来操作和获取某一类方块的相关信息。 + +### 获取一个方块对象 + +#### 从事件或API获取 + +通过注册**事件监听**函数,或者调用某些**返回方块对象**的函数,获取到BDS给出的与相关事件有关的方块对象 +详见 [事件监听文档 - EventAPI](LLSEPluginDevelopment/EventAPI/Listen.md) + +#### 通过方块坐标获取 + +通过此函数来手动生成对象,注意,你要获取的方块必须处于已被加载的范围中,否则会出现问题 + +`mc.getBlock(pos)` +`mc.getBlock(x,y,z,dimid)` + +- 参数: + - pos : `IntPos ` + 方块所在坐标(或者使用x, y, z, dimid来确定方块位置) +- 返回值:生成的方块对象 +- 返回值类型:`Block` + - 如返回值为 `Null` 则表示获取方块失败 + +> 注意:不要**长期保存**一个方块对象 +> 当方块对象对应的方块被销毁时,对应的方块对象将同时释放。因此,如果有长期操作某个方块的需要,请通过上述途径获取实时的方块对象 + +
+ + +### 方块对象 - 属性 + +每一个方块对象都包含一些固定的对象属性。对于某个特定的方块对象`bl`,有以下这些属性 + +| 属性 | 含义 | 类型 | +| ----------------------- | -------------------- | --------- | +| bl.name | 游戏内显示的方块名称 | `String` | +| bl.type | 方块标准类型名 | `String` | +| bl.id | 方块的游戏内id | `Integer` | +| bl.pos | 方块所在坐标 | `IntPos` | +| bl.tileData | 方块数据值 | `Integer` | +| bl.variant | The block variant | `Integer` | +| bl.translucency | 方块透明度 | `Integer` | +| bl.thickness | 方块厚度 | `Integer` | +| bl.isAir | 方块是否为空气 | `Boolean` | +| bl.isBounceBlock | 是否为可弹跳方块 | `Boolean` | +| bl.isButtonBlock | 是否为按钮方块 | `Boolean` | +| bl.isCropBlock | 是否为农作物方块 | `Boolean` | +| bl.isDoorBlock | 是否为门方块 | `Boolean` | +| bl.isFenceBlock | 是否为栅栏方块 | `Boolean` | +| bl.isFenceGateBlock | 是否为栅栏门方块 | `Boolean` | +| bl.isThinFenceBlock | 是否为细栅栏方块 | `Boolean` | +| bl.isHeavyBlock | 是否为重的方块 | `Boolean` | +| bl.isStemBlock | 是否为干方块 | `Boolean` | +| bl.isSlabBlock | 是否为半转方块 | `Boolean` | +| bl.isUnbreakable | 方块是否为不可破坏 | `Boolean` | +| bl.isWaterBlockingBlock | 方块是否可阻挡水 | `Boolean` | + +这些对象属性都是只读的,无法被修改 + +
+ +### 方块对象 - 函数 + +每一个方块对象都包含一些可以执行的成员函数(成员方法)。对于某个特定的方块对象`bl`,可以通过以下这些函数对这个方块进行一些操作 + +#### 破坏方块 + +`bl.destroy(drop)` + +- 参数: + - drop : `Boolen` + 是否生成掉落物 +- 返回值:是否成功破坏 +- 返回值类型:`Boolen` + +
+ +#### 获取方块对应的NBT对象 + +`bl.getNbt()` + +- 返回值:方块的NBT对象 +- 返回值类型:`NbtCompound` + +
+ +#### 写入方块对应的NBT对象 + +`bl.setNbt(nbt)` + +- 参数: + - nbt : `NbtCompound` + NBT对象 +- 返回值:是否成功写入 +- 返回值类型:`Boolean` + +关于NBT对象的更多使用,请参考 [NBT接口文档](LLSEPluginDevelopment/NbtAPI/NBT.md) +注意:慎重使用此api,请考虑使用 `mc.setBlock()` 代替 + +
+ +#### 获取方块的BlockState + +`bl.getBlockState()` + +- 返回值:方块的`BlockState` +- 返回值类型:`Object` + +方便函数,协助解析方块`BlockState`并转换为`Object`,方便读取与解析 +等价于脚本执行`block.getNbt().getTag("states").toObject()` + +
+ +#### 判断方块是否拥有容器 + +`bl.hasContainer()` + +- 返回值:这个方块是否拥有容器 +- 返回值类型:`Boolean` + +如箱子、桶等容器,他们各自拥有一个属于自己的容器对象 + +
+ +#### 获取方块所拥有的容器对象 + +`bl.getContainer()` + +- 返回值:这个方块所拥有的容器对象 +- 返回值类型:`Container` + +关于容器对象的更多使用,请参考 [容器对象 API文档](LLSEPluginDevelopment/GameAPI/Container.md) + +
+ +#### 判断方块是否拥有方块实体 + +`bl.hasBlockEntity()` + +- 返回值:这个方块是否拥有方块实体 +- 返回值类型:`Boolean` + +
+ +#### 获取方块所拥有的方块实体 + +`bl.getBlockEntity()` + +- 返回值:这个方块所拥有的方块实体 +- 返回值类型:`BlockEntity` + +
+ +#### 删除方块所拥有的方块实体 + +`bl.removeBlockEntity()` + +- 返回值:是否成功删除 +- 返回值类型:`Boolean` + +关于方块实体对象的更多使用,请参考 [方块实体对象 API文档](LLSEPluginDevelopment/GameAPI/BlockEntity.md) + +
+ +### 其他方块函数 API + +下面这些API提供了与游戏中指定位置方块互动的API + +#### 设置指定位置的方块 + +`mc.setBlock(pos,block,tiledata)` +`mc.setBlock(x,y,z,dimid,block,tiledata)` + +- 参数: + - pos : `IntPos` + 目标方块位置(或者使用x, y, z, dimid来确定方块位置) + - block : `Block` 、`String` 或 `NBTCompound` + 要设置成的方块对象、方块标准类型名(如`minecraft:stone`)或方块NBT数据 + - tiledata : `Integer` + 方块状态值,同原版 /setBlock 指令的 tiledata,默认为0,仅通过方块类型名放置方块时有效 +- 返回值:是否成功设置 +- 返回值类型:`Boolean` + +通过此函数,将一个坐标对应的方块设置成另一个,类似于命令 `/setblock` + +
+ +#### 在指定位置生成粒子效果 + +`mc.spawnParticle(pos,type)` +`mc.spawnParticle(x,y,z,dimid,type)` + +- 参数: + - pos : `IntPos` / `FloatPos` + 目标生成位置(或者使用x, y, z, dimid来确定方块位置) + - type : `String` + 要生成的粒子效果名称(可查阅wiki得知) +- 返回值:是否成功生成 +- 返回值类型:`Boolean` + +粒子效果名称可以查阅[Minecraft Wiki](https://minecraft.fandom.com/zh/wiki/%E7%B2%92%E5%AD%90?variant=zh#.E7.B1.BB.E5.9E.8B)得知,在传入参数的时候不要忘记命名空间前缀。类似于 `minecraft:heart_particle` \ No newline at end of file diff --git a/docs/apis/GameAPI/BlockEntity.md b/docs/apis/GameAPI/BlockEntity.md new file mode 100644 index 00000000..71711b62 --- /dev/null +++ b/docs/apis/GameAPI/BlockEntity.md @@ -0,0 +1,73 @@ +## 📮 Block Entity Object API + +In LLSE, "block entity objects" are used to manipulate and obtain additional data associated with a particular block. +Note: **Block Entity Object** is not a **Entity**! There is no special relationship between them. + +### Get a Block Entity Object + +#### Obtained From Blocks + + +For an existing block object `bl`, there are: + +`bl.getBlockEntity()` + +- Return type: The block's block entity object. +- Return value type: `BlockEntity` + - If the return value is `Null`, it means that obtaining the block entity object failed, or this block **doesn't** have a corresponding entity object. + +> Note: Do not save a block entity object. +> When the block corresponding to the block object is destroyed, the corresponding block entity object will become invalid. Therefore, if there is a need to operate a certain block entity for a long time, please obtain the real-time block entity object through the above method. + +
+ + +### Block Entity Object - Properties + +Each block entity object contains some fixed object properties. For a particular block entity object `be`, there are the following properties: + +| Attributes | Meaning | Data Type | +| ------- | -------------------------- | --------- | +| be.name | The block entity name (example: `container.chest`) | `String` | +| be.pos | The coordinates where the block entity is located. | `IntPos` | +| be.type | The Type ID of the block entity object. | `Integer` | + +These object properties are read-only and cannot be modified. + +
+ +### Block Entity Object - Function + +Each block entity object contains some member functions (member methods) that can be executed. For a specific block entity object `be`, you can perform some operations on this block entity through the following functions: + +#### Get the Block Entity's NBT Object + +`be.getNbt()` + +- Return type: NBT object of the block entity. +- Return value type: `NbtCompound` + +
+ +#### Write to the Block Entity's NBT object + +`be.setNbt(nbt)` + +- Parameters: + - nbt : `NbtCompound` + NBT objects. +- Return type: Whether the write was successful or not. +- Return value type: `Boolean` + +For more usage of NBT objects, please refer to [NBT Interface Documentation](/LLSEPluginDevelopment/NbtAPI/NBT.md) + +
+ +#### Get the Block Entity's Block Object + +`be.getBlock()` + +- Return type: The block entity's block object. +- Return value type: `Block` + +
\ No newline at end of file diff --git a/docs/apis/GameAPI/BlockEntity.zh.md b/docs/apis/GameAPI/BlockEntity.zh.md new file mode 100644 index 00000000..515315b6 --- /dev/null +++ b/docs/apis/GameAPI/BlockEntity.zh.md @@ -0,0 +1,73 @@ +## 📮 方块实体对象 API + +在脚本引擎中,使用「方块实体对象」来操作和获取与特定方块关联的附加数据。 +注意:**方块实体对象** 不是一种 **实体**!他们之间并没有特别的关系 + +### 获取一个方块实体对象 + +#### 通过方块获取 + + +对于已存在的方块对象`bl`,有 + +`bl.getBlockEntity()` + +- 返回值:此方块对象对应的方块实体对象 +- 返回值类型:`BlockEntity` + - 如返回值为 `Null` 则表示获取方块实体对象失败,或者此方块**没有**对应的实体对象 + +> 注意:不要**长期保存**一个方块实体对象 +> 当方块对象对应的方块被销毁时,对应的方块实体对象将同时释放。因此,如果有长期操作某个方块实体的需要,请通过上述途径获取实时的方块实体对象 + +
+ + +### 方块实体对象 - 属性 + +每一个方块实体对象都包含一些固定的对象属性。对于某个特定的方块实体对象`be`,有以下这些属性 + +| 属性 | 含义 | 类型 | +| ------- | -------------------------- | --------- | +| be.name | The block entity name (example: `container.chest`) | `String` | +| be.pos | 方块实体对应方块所在的坐标 | `IntPos` | +| be.type | 方块实体对象的类型ID | `Integer` | + +这些对象属性都是只读的,无法被修改 + +
+ +### 方块实体对象 - 函数 + +每一个方块实体对象都包含一些可以执行的成员函数(成员方法)。对于某个特定的方块实体对象`be`,可以通过以下这些函数对这个方块实体进行一些操作 + +#### 获取方块实体对应的NBT对象 + +`be.getNbt()` + +- 返回值:方块实体的NBT对象 +- 返回值类型:`NbtCompound` + +
+ +#### 写入方块实体对应的NBT对象 + +`be.setNbt(nbt)` + +- 参数: + - nbt : `NbtCompound` + NBT对象 +- 返回值:是否成功写入 +- 返回值类型:`Boolean` + +关于NBT对象的更多使用,请参考 [NBT接口文档](LLSEPluginDevelopment/NbtAPI/NBT.md) + +
+ +#### 获取方块实体对应的方块对象 + +`be.getBlock()` + +- 返回值:方块实体对应的方块对象 +- 返回值类型:`Block` + +
\ No newline at end of file diff --git a/docs/apis/GameAPI/Command.md b/docs/apis/GameAPI/Command.md new file mode 100644 index 00000000..d0a071c9 --- /dev/null +++ b/docs/apis/GameAPI/Command.md @@ -0,0 +1,435 @@ +## 🎯 Command Related API + +The following APIs provide interfaces for registering and listening to custom commands in the game: + +### Execute a Background Command + +`mc.runcmd(cmd)` + +- Parameters: + - cmd : `String` + The command to be executed. +- Return value: Whether the execution was successful. +- Return value type: `Boolean` + +[JavaScript] +```js +mc.runcmd("say Hello!"); +``` +[Lua] +```lua +mc.runcmd("say Hello!") +``` + +### Execute a Background Command (Enhanced Version) + +`mc.runcmdEx(cmd)` + +- Parameters: + + - cmd : `String` + The command to be executed. +- Return value: Command Execution Result `Object` +- Return value type: `Object` + + - For a returned execution result object res, there are the following members: + + | Members | Meaning | Data Type | + | ----------- | ------------------------------------------------- | --------- | + | res.success | Whether the execution was successful. | `Boolean` | + | res.output | The output result after BDS executes the command. | `String` | + + +> [!NOTE] +> The implementation of runcmdEx is very different from ordinary runcmd. The Enhanced version has a **hidden execution** mechanism, and the execution result will not be output to the console. Therefore, if necessary, you must manually use the log function to output the result. + +[JavaScript] +```js +var result = mc.runcmdEx("say Hello!"); +log(result.output); +``` + +## Command Registration API + +An interface for registering custom commands is provided here. By docking with the built-in command system of BDS, the commands you register can be used by players, consoles, command blocks, NPCs and other objects that can execute commands in games. In addon, you can also use the commands registered here. +> [!WARNING] +> Except for variable parameters (String, RawText, Message, etc.), the commands cannot contain non-English lowercase letters! + +### Register a Top-Level Command + +`mc.newCommand(cmd,description[,permission,flag,alias])` + +- Parameters: + + - cmd : `String` + The command that will be registered. + - description : `String` + The description text for the command. + - permission : `PermType` + (Optional parameter) + + | Execution Permission | Meaning | + | ---------------------- | --------------------------------------------------- | + | `PermType.Any` | Anyone can execute the command. | + | `PermType.GameMasters` | Only the OP can execute the command.(Default value) | + | `PermType.Console` | Only the console can execute the command. | + + - flag : `Integer` + (Optional parameter) Default value is `0x80` + At present, you can directly press this input, and related modifications will be made in the future. + - alias : `String` + (Optional argument) Add an alias for the command. + Multiple aliases can be set for a command, which is equivalent to triggering the same command when executed. +- Return value: Command Object. +- Return value type: `Command` + +> [!TIP] +> +> Top-level commands, i.e. something like `list` `gamerule`, the first input after the `/` character. +> +> After registering the top-level command, this function returns a command object. Next, the function expansion of this command needs to be carried out in this command object. + +### Command Object - Function + +Through the command object, you can register various forms and functions for this command. Suppose there is a `Command`. The command object has the following member functions. + +#### Set Command Alias + +`Command.setAlias(alias)` +- Parameters: + - alias : `String` + Command alias. +- Return value: Whether creating the alias succeeded or not. +- Return value type: `Boolean` + +#### Add Command Enumerations + +`Command.setEnum(name,values)` +- Parameters: + - name : `String` + Enumeration name, used to distinguish the enumeration when setting parameters. + - values : `Array` + Valid values ​​for enumeration. +- Return value: New enumeration option identification name. +- Return value type: `String` + +#### Add a Required Parameter + +`Command.mandatory(name,type[,enumName,identifier,enumOptions])` +- Parameters: + - name : `String` + Parameter name, used to identify the parameter when executing the command. + - type : `ParamType` + Command parameter type. + - enumName : `String` + Enumeration name (only valid when `ParamType` is `Enum`, used to distinguish enumeration options). + - identifier : `String` + Parameter identifier, used to uniquely identify parameters in special cases, generally can be replaced by `enumName` or `name`. + - enumOptions : `Integer` + Parameter options, set to `1` to expand enumeration options in the command prompt. + For example `` will become ``. +- Return value: Whether setting succeeded or not. +- Return value type: `Boolean` + +#### Add an Optional Parameter + +`Command.optional(name,type[,enumName,identifier,enumOptions])` + +- Parameters: + - name : `String` + Parameter name, used to identify the parameter when executing the command. + - type : `ParamType` + Command parameter type. + - enumName : `String` + Enumeration name (only valid when `ParamType` is `Enum`, used to distinguish enumeration options). + - identifier : `String` + Parameter identifier, used to uniquely identify parameters in special cases, generally can be replaced by `enumName` or `name`. + - enumOptions : `Integer` + Parameter options, set to `1` to expand enumeration options in the command prompt. + For example `` will become ``. +- Return value: Whether setting succeeded or not. +- Return value type: `Boolean` + +#### Valid Command Parameter Types and Explanations + +| Command Parameter Type | Meaning | +| ---------------------- | --------------------------------------------------------------------------------------------------------------- | +| `ParamType.Bool` | Boolean Parameter | +| `ParamType.Int` | Integer Parameter | +| `ParamType.Float` | Floating point Parameter | +| `ParamType.String` | String Parameter | +| `ParamType.Actor` | Entity Target Selector Parameter | +| `ParamType.Player` | Player Target Selector Parameter | +| `ParamType.BlockPos` | Integer Coordinate Parameters | +| `ParamType.Vec3` | Floating Point Coordinate Parameter | +| `ParamType.RawText` | Raw String Arguments (May contain special characters like comma spaces, Can only be used as the last parameter) | +| `ParamType.Message` | Message Type Parameter (Same as `/Say` Command Parameter, Will Automatically Expand the Target Selector, Etc.) | +| `ParamType.JsonValue` | `JSON` string parameter | +| `ParamType.Item` | Item Type Parameter | +| `ParamType.Block` | Block Type Parameter | +| `ParamType.Effect` | Effect Type Parameter | +| `ParamType.Enum` | Enum Parameter | +| `ParamType.SoftEnum` | Variable Enum Parameter | +| `ParamType.ActorType` | Entity Type Parameter | +| `ParamType.Command` | Command Name Parameter (For Testing Only) | + +#### Add a New Command Overload + +`Command.overload(params)` + +- Parameters: + - params : `Array` + Parameter identifier, parameter list used by overloading, available parameter identifier, enumeration name, parameter name. + Note that you cannot use identifiers that cannot distinguish specific parameters. For example, both parameters are called `action` but the enumeration options are different. In this case, the enumeration name should be used instead of the parameter name. +- Return value: Whether setting succeeded or not. +- Return value type: `Boolean` + +> [!TIP] +> +> Command overloading is the method used by BDS to distinguish different command forms, and each different command form corresponds to a command overloading. +> As you can see, the parameter names provided in the command overload form a new command form. + +#### Set Command Callback + +`Command.setCallback(callback)` +- Parameters: + - callback : `Function(cmd,origin,output,results)` + When the registered command is executed, the interface automatically calls the callback function. +- Return value: Whether setting succeeded or not. +- Return value type: `Boolean` + +> [!TIP] +> +> The parameters of the command callback function are relatively complex, which will be explained in detail below. + +#### Installation Instructions + +After all the configuration of the command is completed, use this function to register the command to the BDS command system. + +`Command.setup()` + +- Return value: Whether the installation was successful. +- Return value type: `Boolean` + +## Command Callback Function + +The **command callback function** mentioned above is a relatively complex callback function, and some explanations of the parameters are given below. +Command callback function prototype: `Function(cmd,origin,output,results)` + +#### Parameters `cmd` : Own Command Object + +This parameter gives the directive object with which you registered this command. + +#### Parameters `origin` : The Executor of the Command + +The parameter `origin` is of type `CommandOrigin` object. This object represents the executor of this command. Through this object, some operations can be performed on the executor. +For a particular `CommandOrigin` object `ori`, there are the following properties: + +| Members | Meaning | Data Types | +| ------------ | ---------------------------------------------------- | ------------ | +| ori.type | Command Execution Body Type | `OriginType` | +| ori.name | The name of the command execution body | `String` | +| ori.pos | The coordinates of the command exection body | `FloatPos` | +| ori.blockPos | The block coordinates of the command execution body | `IntPos` | +| ori.entity | The entity that executes the command (may be `Null`) | `Entity` | +| ori.player | The player who executed the command (may be `Null`) | `Player` | + +#### Parameter `output` : Output the Execution Result of the Command to the Command Executor + +Parameter `output` is of type `CommandOutput` object. Through this object, the execution result of the command can be output to the command executor. +For a particular `CommandOutput` object `outp`, the following member methods are available: + +##### Output a Success Message + +`outp.success([msg][, parm])` + +- Parameters: + - msg : `String` + The message to output. + - parm : `Array` + Parameters to be replaced +- Return value: Whether the output is successful. +- Return value type: `Boolean` + +##### Output an Error Message + +`outp.error(msg[, parm])` + +- Parameters: + - msg : `String` + The message to output. + - parm : `Array` + Parameters to be replaced +- Return value: Whether the output is successful. +- Return value type: `Boolean` + +##### Output a General Message + +`outp.addMessage(msg[, parm])` + +- Parameters: + - msg : `String` + The message to output. + - parm : `Array` + Parameters to be replaced +- Return value: Whether the output is successful. +- Return value type: `Boolean` + +#### Parameter `result` : The Result Obtained by Each Parameter of the Command + +The content of `results` is `object` key-value pair. The `command parameter name` is the `name` value of the parameter set when the command is registered, and the `data value` is the content filled in by the executor in the position of the current command parameter. + +The relationship between command parameter types and data value types is as follows: + +| Command Parameter Type | Data Value Type | Meaning | +| ---------------------- | --------------- | --------------------------------------------------------------------------------------------------------------- | +| `ParamType.Bool` | `Boolean` | Boolean Value | +| `ParamType.Int` | `Integer` | Integer Value | +| `ParamType.Float` | `Float` | Floating Point Value | +| `ParamType.String` | `String` | String | +| `ParamType.Actor` | `Array` | The entity selected by the entity target selector | +| `ParamType.Player` | `Array` | The entity selected by the player's target selector | +| `ParamType.BlockPos` | `IntPos` | Integer Coordinate Object | +| `ParamType.Vec3` | `FloatPos` | Floating Point Coordinate Object | +| `ParamType.RawText` | `String` | Raw String Arguments (May contain special characters like comma spaces, Can only be used as the last parameter) | +| `ParamType.Message` | `String` | Message Type String (same as `/say` command parameters, will automatically expand target selectors, etc.) | +| `ParamType.JsonValue` | `String` | `JSON` String | +| `ParamType.Item` | `Item` | Item Type | +| `ParamType.Block` | `Block` | Block Type | +| `ParamType.Effect` | `String` | Effect Type String | +| `ParamType.Enum` | `String` | Enumerated String | +| `ParamType.SoftEnum` | `String` | Mutable Enumerated String | +| `ParamType.ActorType` | `String` | Entity Type String | +| `ParamType.Command` | `String` | Command Name (For testing only) | + +### Command Registration Example + +[JavaScript] +```js +mc.listen("onServerStarted", () => { + let cmd = mc.newCommand("manager", "Command Description", PermType.GameMasters); + cmd.setAlias("mgr"); + cmd.setEnum("ChangeAction", ["add", "remove"]); + cmd.setEnum("ListAction", ["list"]); + cmd.mandatory("action", ParamType.Enum, "ChangeAction", 1); + cmd.mandatory("action", ParamType.Enum, "ListAction", 1); + cmd.mandatory("name", ParamType.RawText); + cmd.overload(["ChangeAction", "name"]); + cmd.overload(["ListAction"]); + cmd.setCallback((_cmd, _ori, out, res) => { + switch (res.action) { + case "add": + return out.success(`add "${res.name}"`); + case "remove": + return out.success(`remove "${res.name}"`); + case "list": + return out.success(`Name List:`); + } + }); + cmd.setup(); +}); +``` + +## Fake Command API + +The fake command API here is reserved for **downward compatibility**. It is recommended to use the **true command** API written in the above document. + +> [!WARNING] +> +> Although it looks relatively simple, fake commands have some important disadvantages, including that they can only be executed by the player or console, other objects (such as command blocks, NPCs, etc.) cannot be executed, all parameter data needs to be parsed by themselves, etc. +> +> Please try to use the real command API. + +### Register a New Player Command (Fake Command) + +`mc.regPlayerCmd(cmd,description,callback[,level])` + +- Parameters: + - cmd : `String` + The command that will be registered. + - description : `String` + Command Description Text. + - callback : `Function(player,args)` + When the registered command is executed, the interface automatically calls the callback function. + - level : `Integer` + (Optional parameter) The registration level of the command, the default is 0, that is, everyone can execute it. + If the command registration level is set to 1, only the OP can execute this command. +- Return value: Whether the registration was successful. +- Return value type: `Boolean` + +Note: The callback function prototype of the parameter callback: `function(player, args)` + +- player : `Player` + The player that executes the command. +- args : `Array` + Arguments following the target command. Divide by spaces to form a string array. + If a custom command `land set` is registered, when `/land set abc 2333` is executed, the value of args will be `[ "abc","2333" ]` + +[JavaScript] +```js +mc.regPlayerCmd("fly on","Turn on the fly mode",function(pl,args){ + pl.tell("Flying enabled."); + //...... +}); +``` + + +### Register a New Background Console Command (Fake Command) + +`mc.regConsoleCmd(cmd,description,callback)` + +- Parameters: + - cmd : `String` + The command that will be registered. + + - description : `String` + Command Description Text. + + - callback : `Function` + When the registered command is executed, the interface automatically calls the callback function. +- Return value: Whether the registration was successful. +- Return value type: `Boolean` + +Note: The callback function prototype of the parameter callback: `function(args)` + +- args : `Array` + Arguments following the target command. Divide by spaces to form a string array. + If a custom command `land set` is registered, when `/land set abc 2333` is executed, the value of args will be `['abc','2333']` + +[JavaScript] +```js +mc.regConsoleCmd("backup","Start the backup",function(args){ + log("ID of this backup is:",args[0]); + //...... +}); +``` + +> [!TIP|label:Instructions on Fake Order Registration] +> +> After setting the callback function, the callback function will be called when the fake command you registered is executed. +> LLSE will automatically split the command arguments into arrays for you before calling them. +> +> Take the JavaScript language as an example: +> +> Execute command +> `mc.regPlayerCmd("land buy", "land buy", function(pl,args){ .... }, 0 );` +> after that, +> This callback function will be called when you use the command `/land buy abcde 12345`. +> The parameter args of the callback function is passed in an array: [ "abcde" , "12345" ] +> As you can see, the values contained in `args` are **sequentially split** command arguments. +> If you have quotes in your command (for example to handle player names with spaces in them), LLSE will also do this when splitting. + +
+ +## Other APIs Related to the Command System + +### The Simulation Produces a Console Command Output + +`mc.sendCmdOutput(output)` + +- Parameters: + - output : `String` + The command output produced by the simulation. + +- Return value: Whether the exection was successful. +- Return value type: `Boolean` diff --git a/docs/apis/GameAPI/Command.zh.md b/docs/apis/GameAPI/Command.zh.md new file mode 100644 index 00000000..c2c1ab59 --- /dev/null +++ b/docs/apis/GameAPI/Command.zh.md @@ -0,0 +1,444 @@ +## 🎯 命令相关 API + +下面这些API提供了在游戏中注册、监听自定义命令的接口 + +### 执行一条后台命令 + +`mc.runcmd(cmd)` + +- 参数: + - cmd : `String` + 待执行的命令 +- 返回值:是否执行成功 +- 返回值类型: `Boolean` + +[JavaScript] +```js +mc.runcmd("say Hello!"); +``` +[Lua] +```lua +mc.runcmd("say Hello!") +``` + +### 执行一条后台命令(强化版) + +`mc.runcmdEx(cmd)` + +- 参数: + + - cmd : `String` + 待执行的命令 + +- 返回值:命令执行结果`Object` + +- 返回值类型: `Object` + + - 对于返回的某个执行结果对象res,有如下这些成员: + + | 成员 | 含义 | 类型 | + | ----------- | ----------------------- | --------- | + | res.success | 是否执行成功 | `Boolean` | + | res.output | BDS执行命令后的输出结果 | `String` | + + +> [!NOTE] +> runcmdEx 与普通 runcmd 实现区别非常大,在于 Ex 版本拥有**隐藏输出**的机制,执行结果不会输出至控制台,因此如果有需要,要手动用 log 函数将结果输出 + +[JavaScript] +```js +var result = mc.runcmdEx("say Hello!"); +log(result.output); +``` + +## 命令注册 API + +这里提供了注册自定义命令的接口。通过对接 BDS 内置的命令系统,你注册的命令可以由玩家、控制台、命令方块、NPC等各种游戏中可以执行命令的对象所使用,在 addon 中,也可以使用这里所注册的命令。 +> [!WARNING] +> 命令中除了可变参数(String, RawText, Message等)外,均不能包含非英文小写字母! + +### 注册一条顶层命令 + +`mc.newCommand(cmd,description[,permission,flag,alias])` + +- 参数: + + - cmd : `String` + 待注册的命令 + + - description : `String` + 命令描述文本 + + - permission : `PermType` + (可选参数)指令执行所需权限 + + | 执行权限 | 含义 | + | ---------------------- | -------------------------------- | + | `PermType.Any` | 任何人都可以执行这条指令 | + | `PermType.GameMasters` | 只有OP可以执行这条指令(默认值) | + | `PermType.Console` | 只有控制台可以执行这条指令 | + + - flag : `Integer` + (可选参数)默认值 `0x80` + 目前直接按此输入即可,后续会进行相关修改 + + - alias : `String` + (可选参数)命令的别名 + 可以为命令设置多个别名,执行的时候相当于触发同一条命令 + +- 返回值:指令对象 + +- 返回值类型:`Command` + +> [!TIP] +> +> 顶层命令,也就是类似 `list` `gamerule` 这种,在 / 之后第一个输入的部分 +> +> 注册完顶层命令后,此函数会返回一个指令对象。接下来,对于这个命令的功能扩展都需要在这个指令对象中进行 + +### 指令对象 - 函数 + +通过指令对象,你可以为这个命令注册各式各样的形式、功能。假设有一个叫 `Command` 的指令对象,则有下面这些成员函数 + +#### 设置指令别名 + +`Command.setAlias(alias)` +- 参数: + - alias : `String` + 指令别名 +- 返回值:是否成功设置 +- 返回值类型:`Boolean` + +#### 新增一个指令枚举选项 + +`Command.setEnum(name,values)` +- 参数: + - name : `String` + 枚举名,用于设置参数时区分枚举 + - values : `Array` + 枚举的有效值 +- 返回值:新增枚举选项的标识名称 +- 返回值类型:`String` + +#### 新增一个必选参数 + +`Command.mandatory(name,type[,enumName,identifier,enumOptions])` +- 参数: + - name : `String` + 参数名,用于执行指令时识别参数 + - type : `ParamType` + 命令参数类型 + - enumName : `String` + 枚举名(仅 `ParamType` 为 `Enum` 时有效,用于区分枚举选项) + - identifier : `String` + 参数标识,特殊情况下用于唯一识别参数,一般可用 `enumName` 或 `name` 代替 + - enumOptions : `Integer` + 参数选项,设置为 `1` 可在指令提示中展开枚举选项 + 如 `` 会变成 `` +- 返回值:是否成功设置 +- 返回值类型:`Boolean` + +#### 新增一个可选参数 + +`Command.optional(name,type[,enumName,identifier,enumOptions])` + +- 参数: + - name : `String` + 参数名,用于执行指令时识别参数 + - type : `ParamType` + 命令参数类型 + - enumName : `String` + 枚举名(仅 `ParamType` 为 `Enum` 时有效,用于区分枚举选项) + - identifier : `String` + 参数标识,特殊情况下用于唯一识别参数,一般可用 `enumName` 或 `name` 代替 + - enumOptions : `Integer` + 参数选项,设置为 `1` 可在指令提示中展开枚举选项 + 如 `` 会变成 `` +- 返回值:是否成功设置 +- 返回值类型:`Boolean` + +#### 有效的命令参数类型及解释 + +| 命令参数类型 | 含义 | +| --------------------- | -------------------------------------------------------------------- | +| `ParamType.Bool` | 布尔值参数 | +| `ParamType.Int` | 整数参数 | +| `ParamType.Float` | 浮点数参数 | +| `ParamType.String` | 字符串参数 | +| `ParamType.Actor` | 实体目标选择器参数 | +| `ParamType.Player` | 玩家目标选择器参数 | +| `ParamType.BlockPos` | 整数坐标参数 | +| `ParamType.Vec3` | 浮点数坐标参数 | +| `ParamType.RawText` | 原始字符串参数(可包含特殊字符,如逗号空格,只能作为最后一个参数使用) | +| `ParamType.Message` | 消息类型参数(同 `/say` 指令参数,会自动展开目标选择器等) | +| `ParamType.JsonValue` | JSON字符串参数 | +| `ParamType.Item` | 物品类型参数 | +| `ParamType.Block` | 方块类型参数 | +| `ParamType.Effect` | 效果类型参数 | +| `ParamType.Enum` | 枚举参数 | +| `ParamType.SoftEnum` | 可变枚举参数 | +| `ParamType.ActorType` | 实体类型参数 | +| `ParamType.Command` | 指令名称参数(仅供测试) | + +#### 新增一条指令重载 + +要想让命令正常运行,必须至少添加一条重载。所谓重载,本质上相当于参数的组合,譬如重载`['a', 'b', 'c']`相当于命令可以被执行为`/cmd `,而重载`[]`相当于可以被执行为`/cmd`。重载的参数标识符可以是参数名、枚举名、参数标识符,但不能使用无法区分具体参数的标识符,如两个参数都叫 `action` 但枚举选项不同,此时应该使用枚举名而不是参数名。 + +`Command.overload(params)` + +- 参数: + - params : `Array` + 参数标识符,重载所用到的参数列表,可用 参数标识符、枚举名、参数名。 + 注意不能使用无法区分具体参数的标识符,如两个参数都叫 `action` 但枚举选项不同,此时应该使用枚举名而不是参数名 +- 返回值:是否成功设置 +- 返回值类型:`Boolean` + +> [!TIP] +> +> 指令重载是 BDS 区分不同指令形式的方法,每一种不同的指令形式对应着一种指令重载。 +> 如你所见,指令重载中提供的各项参数名组成了一种新的指令形式 + +#### 设置指令回调 + +`Command.setCallback(callback)` +- 参数: + - callback : `Function(cmd,origin,output,results)` + 注册的这个命令被执行时,接口自动调用的回调函数。 +- 返回值:是否成功设置 +- 返回值类型:`Boolean` + +> [!TIP] +> +> 指令回调函数的参数相对复杂,在下面将进行详细解释 + +#### 安装指令 + +在对命令的所有配置完成之后,使用此函数将命令注册到 BDS 的命令系统当中 + +`Command.setup()` + +- 返回值:是否成功安装 +- 返回值类型:`Boolean` + +## 指令回调函数 + +上文提到的 **指令回调函数** 是一个比较复杂的回调函数,下面对其中的各项参数进行一些解释 +指令回调函数原型: `Function(cmd,origin,output,results)` + +#### 参数 `cmd` : 自身的指令对象 + +这个参数给出了你注册这个命令时使用的指令对象。 + +#### 参数 `origin` :命令的执行者 + +参数 `origin`的类型为 `CommandOrigin` 对象。此对象表示此次命令的执行者,通过这个对象,可以对执行者进行一些操作 +对于某个特定的 `CommandOrigin` 对象`ori`,有以下这些属性 + +| 属性 | 含义 | 类型 | +| ------------ | ---------------------- | ------------ | +| ori.type | 指令执行主体类型 | `OriginType` | +| ori.name | 指令执行主体的名称 | `String` | +| ori.pos | 指令执行主体的坐标 | `FloatPos` | +| ori.blockPos | 指令执行主体的方块坐标 | `IntPos` | +| ori.entity | 执行指令的实体(可空) | `Entity` | +| ori.player | 执行指令的玩家(可空) | `Player` | + +#### 参数 `output` :向命令执行者输出命令的执行结果 + +参数`output`的类型为`CommandOutput` 对象。通过这个对象,可以向命令执行者输出命令的执行结果。 +对于某个特定的 `CommandOutput` 对象`outp`,有以下这些成员方法 + +##### 输出一条成功信息 + +`outp.success([msg][, parm])` + +- 参数: + - msg : `String` + 要输出的信息 + - parm : `Array` + 要替换的参数 +- 返回值:是否成功输出 +- 返回值类型:`Boolean` + +##### 输出一条错误信息 + +`outp.error(msg[, parm])` + +- 参数: + - msg : `String` + 要输出的信息 + - parm : `Array` + 要替换的参数 +- 返回值:是否成功输出 +- 返回值类型:`Boolean` + +##### 输出一条普通信息 + +`outp.addMessage(msg[, parm])` + +- 参数: + - msg : `String` + 要输出的信息 + - parm : `Array` + 要替换的参数 +- 返回值:是否成功输出 +- 返回值类型:`Boolean` + +#### 参数 `result` :命令各项参数获取的结果 + +`results` 的内容为 `object<命令参数名-数据值>` 键值对。其中 `命令参数名` 为命令注册时设置的参数的 `name`值,而`数据值`即为执行者在当前命令参数的位置填上的内容 + +命令参数类型 和 数据值类型 的对应关系如下 + +| 命令参数类型 | 数据值类型 | 含义 | +| --------------------- | --------------- | ---------------------------------------------------------------- | +| `ParamType.Bool` | `Boolean` | 布尔值 | +| `ParamType.Int` | `Integer` | 整数 | +| `ParamType.Float` | `Float` | 浮点数 | +| `ParamType.String` | `String` | 字符串 | +| `ParamType.Actor` | `Array` | 实体目标选择器 选中的实体 | +| `ParamType.Player` | `Array` | 玩家目标选择器 选中的实体 | +| `ParamType.BlockPos` | `IntPos` | 整数坐标对象 | +| `ParamType.Vec3` | `FloatPos` | 浮点数坐标对象 | +| `ParamType.RawText` | `String` | 原始字符串(可包含特殊字符,如逗号空格,只能作为最后一个参数使用) | +| `ParamType.Message` | `String` | 消息类型字符串(同 `/say` 指令参数,会自动展开目标选择器等) | +| `ParamType.JsonValue` | `String` | JSON字符串 | +| `ParamType.Item` | `Item` | 物品类型 | +| `ParamType.Block` | `Block` | 方块类型 | +| `ParamType.Effect` | `String` | 效果类型字符串 | +| `ParamType.Enum` | `String` | 枚举字符串 | +| `ParamType.SoftEnum` | `String` | 可变枚举字符串 | +| `ParamType.ActorType` | `String` | 实体类型字符串 | +| `ParamType.Command` | `String` | 指令名称(仅供测试) | + +### 命令注册样例 + +[JavaScript] +```js +mc.listen("onServerStarted", () => { + const cmd = mc.newCommand("manager", "Command Description", PermType.GameMasters); + cmd.setAlias("mgr"); + cmd.setEnum("ChangeAction", ["add", "remove"]); + cmd.setEnum("ListAction", ["list"]); + cmd.mandatory("action", ParamType.Enum, "ChangeAction", 1); + cmd.mandatory("action", ParamType.Enum, "ListAction", 1); + cmd.mandatory("name", ParamType.RawText); + cmd.overload(["ChangeAction", "name"]); + cmd.overload(["ListAction"]); + cmd.setCallback((_cmd, _ori, out, res) => { + switch (res.action) { + case "add": + return out.success(`add "${res.name}"`); + case "remove": + return out.success(`remove "${res.name}"`); + case "list": + return out.success(`Name List:`); + } + }); + cmd.setup(); +}); +``` + +## 假命令 API + +这里的假命令API为 **向下兼容** 而留存,推荐使用上面文档所写的的 **真命令** API + +> [!WARNING] +> +> 尽管看起来比较简单,但是假命令有一些很重要的缺点,包括只能由玩家或控制台执行,其他对象(如命令方块、NPC等)都无法执行、所有参数数据都需要自行解析等等。 +> +> 请尽量使用 真命令API + +### 注册一个新的玩家命令(假命令) + +`mc.regPlayerCmd(cmd,description,callback[,level])` + +- 参数: + - cmd : `String` + 待注册的命令 + - description : `String` + 命令描述文本 + - callback : `Function(player,args)` + 注册的这个命令被执行时,接口自动调用的回调函数。 + - level : `Integer` + (可选参数)命令的注册等级,默认为 0 ,即所有人都可以执行 + 如果设置命令注册等级为1,则只有OP可以执行此命令 +- 返回值:是否成功注册 +- 返回值类型:`Boolean` + +注:参数callback的回调函数原型:`function(player,args)` + +- player : `Player` + 执行命令的玩家对象 +- args : `Array` + 目标命令后面的参数。按空格为分界分割,组成字符串数组。 + 如注册了自定义命令 `land set`,当执行 `/land set abc 2333` 时,args的值将为 `[ "abc","2333" ]` + +[JavaScript] +```js +mc.regPlayerCmd("fly on","Turn on the fly mode",function(pl,args){ + pl.tell("Flying enabled."); + //...... +}); +``` + + +### 注册一个新的控制台命令(假命令) + +`mc.regConsoleCmd(cmd,description,callback)` + +- 参数: + - cmd : `String` + 待注册的命令 + + - description : `String` + 命令描述文本 + + - callback : `Function` + 注册的这个命令被执行时,接口自动调用的回调函数。 +- 返回值:是否成功注册 +- 返回值类型:`Boolean` + +注:参数callback的回调函数原型:`function(args)` + +- args : `Array` + 目标命令后面的参数。按空格为分界分割,组成字符串数组。 + 如注册了自定义命令 `land set`,当执行 `/land set abc 2333` 时,args的值将为 `['abc','2333']` + +[JavaScript] +```js +mc.regConsoleCmd("backup","Start the backup",function(args){ + log("ID of this backup is:",args[0]); + //...... +}); +``` + +> [!TIP|label:假命令注册相关说明] +> +> 设置了回调函数之后,在你注册的这个假命令被执行的时候,回调函数就会被调用。 +> 在调用之前,脚本引擎会自动帮你把命令参数分割成数组。 +> +> 以JavaScript语言为例: +> +> 执行命令 +> `mc.regPlayerCmd("land buy", "购买领地", function(pl,args){ .... }, 0 );` +> 之后, +> 当你使用命令 `/land buy abcde 12345`的时候,这个回调函数就会被调用。 +> 回调函数的参数args被传入一个数组:[ "abcde" , "12345" ] +> 正如所见,`args` 中包含的值是被 **按顺序分割好的** 命令参数。 +> 如果你的命令中有引号(比如说为了处理含有空格的玩家名字),脚本引擎在分割时也会做处理。 + +
+ +## 其他与命令系统有关的 API + +### 模拟产生一个控制台命令输出 + +`mc.sendCmdOutput(output)` + +- 参数: + - output : `String` + 模拟产生的命令输出 + +- 返回值:是否成功执行 +- 返回值类型:`Boolean` diff --git a/docs/apis/GameAPI/Container.md b/docs/apis/GameAPI/Container.md new file mode 100644 index 00000000..fb60423e --- /dev/null +++ b/docs/apis/GameAPI/Container.md @@ -0,0 +1,154 @@ +## 👜 Container Object API + +In LLSE, "container objects" are used to manipulate information about containers that have grids and can store and place items. +The **container** here is a broad concept. In addition to the traditional containers such as boxes and barrels, such as player inventory, boxes carried by alpaca, etc. can also be handled as "containers", obtained and used. Container APIs corresponding to the container + +### Get a Container Object + +#### Get From Event or API + +Obtain the container object given by BDS by registering the **event listener** function, or calling some **returning container object** functions. +For details, see [Event listener documentation - EventAPI](/LLSEPluginDevelopment/EventAPI/Listen.md) + +#### Get By Entity + +Obtain a **container object** corresponding to a player's item bar, armor bar, and ender box through each member function of the player object +See [Player Object API](/LLSEPluginDevelopment/GameAPI/Player.md) + +#### Obtained From Blocks + +For a block that can hold items, the corresponding **container object** is obtained through the member function of the block object. +See [Block Object API](/LLSEPluginDevelopment/GameAPI/Block.md) + +> Note: Do not save a container object long-term. +> When the entity/block corresponding to the container object is destroyed, the corresponding container object will become invalid. Therefore, if there is a need to operate a certain container for a long time, please obtain the real-time container object through the above methods. + +
+ +### Container Info Object - Properties + +Each container information object contains some fixed object properties. for a specific container object `ct`, has the following properties: + +| Attributes| Meaning | Data Types | +| ------- | ------------------ | --------- | +| ct.size | The total number of spaces the container has | `Integer` | +| ct.type | The type of container | `String` | + +
+ +### Container Object - Function + +Each container object contains some member functions (member methods) that can be executed. for a specific container object `ct`, you can perform some operations on this container through the following functions: + +> Attention! After modifying the items corresponding to the player's inventory, don't forget to use the member function `pl.refreshItems` of the player object to refresh the player's inventory displayed by the client. + +#### Put the Item Object Into the Container + +`ct.addItem(item[, amount])` + +- Parameters: + - item : `Item` + The item to add to the container. + + - amount : `Integer` + + (optional) If provided this para, the original count property of the item will be ignored +- Return type: Whether the item was added successfully or not. +- Return value type: `Boolean` + +
+ +#### Put the Item Object Into the First Empty Space of the Container + +`ct.addItemToFirstEmptySlot(item)` + +- Parameters: + - item : `Item` + The item to add to the container. +- Return type: Whether the item was added successfully or not. +- Return value type: `Boolean` + +Unlike the above function, this function will not stack to the existing item stack in the container. + +
+ +#### Check to See if (There Is Room) In the Container for This Item + +`ct.hasRoomFor(item)` + +- Parameters: + - item : `Item` + The item to be placed in the container. +- Return type: Whether the item can be placed in the container. +- Return value type: `Boolean` + +
+ +#### Reduce an Item Object in a Container + +`ct.removeItem(index,count)` + +- Parameters: + - index : `Integer` + The grid number in the container where the item is placed. + - count : `Integer` + The amount of items to remove from the container. If it is equal to or greater than the amount of that item in the container, the item stack will be cleared. +- Return type: Whether the item removal was successful. +- Return value type: `Boolean` + +
+ +#### Get the Item Object of a Grid in the Container + +`ct.getItem(index)` + +- Parameters: + - index : `Integer` + The container grid location where the item is palced. +- Return type: The item object at the grid location. +- Return value type: `Item` + +The item object obtained here is a reference. That is to say, modifying the item object returned here, or using its API, is equivalent to directly manipulating the corresponding item in the container. + +
+ +#### Set the Item Object of a Grid in the Container + +`ct.setItem(index,item)` + +- Parameters: + - index : `Integer` + The container grid location where the item will be placed. + - item : `Item` + The item that will be placed in the container. +- Return type: Whether placing the item in the container was successful. +- Return value type: `Boolean` + +
+ +#### Get the List of Item Objects in All Grids of the Container + +`ct.getAllItems()` + +- Return type: All item objects in the container. +- Return value type: `Array` + +The item objects obtained here are all references. That is to say, modifying the item object returned here, or using its API, is equivalent to directly manipulating the corresponding item in the container. + +
+ +#### Empty The Container + +`ct.removeAllItems()` + +- Return type: Whether the container was successfully cleared. +- Return value type: `Boolean` + +
+ +#### Check if the Container Is Empty + +`ct.isEmpty()` + +- Return type: Whether the container is empty. +- Return value type: `Boolean` \ No newline at end of file diff --git a/docs/apis/GameAPI/Container.zh.md b/docs/apis/GameAPI/Container.zh.md new file mode 100644 index 00000000..65bb501b --- /dev/null +++ b/docs/apis/GameAPI/Container.zh.md @@ -0,0 +1,154 @@ +## 👜 容器对象 API + +在脚本引擎中,使用「容器对象」来操作拥有格子、可以储存和放置物品的容器的相关信息。 +此处的 **容器** 是一种宽泛的概念,除了箱子、桶这些传统的容器之外,如玩家物品栏、羊驼携带的箱子等这些也统统可以作为「容器」处理,获取并使用容器对应的API + +### 获取一个容器对象 + +#### 从事件或API获取 + +通过注册**事件监听**函数,或者调用某些**返回容器对象**的函数,来获取到BDS给出的容器对象 +详见 [事件监听文档 - EventAPI](LLSEPluginDevelopment/EventAPI/Listen.md) + +#### 通过实体获取 + +通过玩家对象的各个成员函数,来获取一个玩家物品栏、盔甲栏、末影箱对应的**容器对象** +详见 [玩家对象 API](LLSEPluginDevelopment/GameAPI/Player.md) + +#### 通过方块获取 + +对于可以容纳物品的方块,通过方块对象的成员函数,来他所对应的对应的**容器对象** +详见 [方块对象 API](LLSEPluginDevelopment/GameAPI/Block.md) + +> 注意:不要**长期保存**一个容器对象 +> 当容器对象对应的实体 / 方块被销毁时,对应的容器对象将同时释放。因此,如果有长期操作某个容器的需要,请通过上述途径获取实时的容器对象 + +
+ +### 容器信息对象 - 属性 + +每一个容器信息对象都包含一些固定的对象属性。对于某个特定的容器对象`ct`,有以下这些属性 + +| 属性 | 含义 | 类型 | +| ------- | ------------------ | --------- | +| ct.size | 容器拥有的格子总数 | `Integer` | +| ct.type | 容器的类型名 | `String` | + +
+ +### 容器对象 - 函数 + +每一个容器对象都包含一些可以执行的成员函数(成员方法)。对于某个特定的容器对象`ct`,可以通过以下这些函数对这个容器进行一些操作 + +> 注意!在修改完玩家物品栏对应的物品之后,不要忘记使用玩家对象的成员函数`pl.refreshItems`,刷新客户端显示的玩家物品栏 + +#### 放入物品对象到容器中 + +`ct.addItem(item[, amount])` + +- 参数: + - item : `Item` + 待增加的物品对象 + + - amount: `Integer` + + (可选)欲添加物品数量,若提供此参数,item对象本身的count属性将被忽略。 +- 返回值:是否成功增加 +- 返回值类型:`Boolean` + +
+ +#### 放入物品对象到容器的第一个空格子 + +`ct.addItemToFirstEmptySlot(item)` + +- 参数: + - item : `Item` + 待增加的物品对象 +- 返回值:是否成功增加 +- 返回值类型:`Boolean` + +和上述函数不同,此函数将不会堆叠至容器内现有的物品堆中 + +
+ +#### 检查容器中是否(有空间)可以放入此物品 + +`ct.hasRoomFor(item)` + +- 参数: + - item : `Item` + 待放入的物品对象 +- 返回值:是否可以放入 +- 返回值类型:`Boolean` + +
+ +#### 减少容器中的某个物品对象 + +`ct.removeItem(index,count)` + +- 参数: + - index : `Integer` + 减少的物品对象所在的格子序号 + - count : `Integer` + 减少的数量。如果大于等于此格子物品堆叠的数量,则物品堆将被整个清除 +- 返回值:是否成功减少 +- 返回值类型:`Boolean` + +
+ +#### 获取容器某个格子的物品对象 + +`ct.getItem(index)` + +- 参数: + - index : `Integer` + 待获取的格子序号 +- 返回值:格子位置的物品对象 +- 返回值类型:`Item` + +此处获取的物品对象为引用。也就是说,修改此处返回的物品对象,或使用其API,就相当于直接操作容器中对应的物品 + +
+ +#### 设置容器某个格子的物品对象 + +`ct.setItem(index,item)` + +- 参数: + - index : `Integer` + 待设置的格子序号 + - item : `Item` + 待设置的物品对象 +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +
+ +#### 获取容器所有格子的物品对象列表 + +`ct.getAllItems()` + +- 返回值:容器中所有的物品对象 +- 返回值类型:`Array` + +此处获取的物品对象均为引用。也就是说,修改此处返回的物品对象,或使用其API,就相当于直接操作容器中对应的物品 + +
+ +#### 清空容器 + +`ct.removeAllItems()` + +- 返回值:是否成功清空 +- 返回值类型:`Boolean` + +
+ +#### 判断容器是否为空 + +`ct.isEmpty()` + +- 返回值:当前容器是否为空 +- 返回值类型:`Boolean` \ No newline at end of file diff --git a/docs/apis/GameAPI/Device.md b/docs/apis/GameAPI/Device.md new file mode 100644 index 00000000..586a8388 --- /dev/null +++ b/docs/apis/GameAPI/Device.md @@ -0,0 +1,74 @@ +## 📱 Device Information Object API + +In LLSE, the "device information object" is used to manipulate and obtain information about the game device used by a player. + +### Get a Device Info Object + +#### Acquired by the Player + +Get the **device information object** corresponding to a player through the `.getDevice` member function of the player object +See [Player Object API](/LLSEPluginDevelopment/GameAPI/Player.md) + +> Note: Do not save a device information object **long-term.** +> When the player corresponding to the device exits the game, the corresponding object will become invalid. Therefore, if there is a need to operate an object for a long time, please obtain the real-time device information object through the above methods. + +
+ + +### Device Information Object - Properties + +Each device information object contains some fixed object properties. for a specific entity object `dv`, has the following properties: + +| Attributes | Meaning | Data Types | +| ----------------- | --------------------------------------------- | ---------- | +| dv.ip | The IP address of the player's device | `String` | +| dv.avgPing | Average network latency for players (ms) | `Integer` | +| dv.avgPacketLoss | Player's average network packet loss rate (%) | `Float` | +| dv.lastPing | Network latency for players (ms) | `Integer` | +| dv.lastPacketLoss | Player's network packet loss rate (%) | `Float` | +| dv.os | The OS type of the player's device | `String` | +| dv.inputMode | Player's input mode | `Integer` | +| dv.playMode | Player's play mode | `Integer` | +| dv.serverAddress | The player's connection address | `String` | +| dv.clientId | ID of the player client | `String` | + +These object properties are read-only and cannot be modified + +Among them, the operating system type attribute returns a string that records the operating system of the player's device. The possible return values ​​are as follows: + +| dv.os | Device Operating System | +| -------------- | ----------------------------------------------- | +| `Android` | Google Android (Mobile phone) | +| `iOS` | Apple iOS (Mobile phone) or iPadOS | +| `OSX` | Apple macOS (Computer) | +| `Amazon` | Amazon FireOS | +| `GearVR` | Samsung GearVR | +| `Hololens` | Microsoft Hololens | +| `WIN10` | Microsoft Windows (Computer) | +| `Win32` | Microsoft Win32 (Education Edition?) (Computer) | +| `TVOS` | Apple tvOS | +| `PlayStation` | Sony PlayStation Host | +| `Nintendo` | Nintendo Switch Host | +| `Xbox` | Microsoft Xbox Host | +| `WindowsPhone` | Windows Mobile | +| `Dedicated` | Dedicated server (Device os spoofer) | +| `Unknown` | Unknown System | + +| Input mode ENUM | +| ---------------------------- | +| `InputMode.Mouse` | +| `InputMode.Touch` | +| `InputMode.GamePad` | +| `InputMode.MotionController` | + +| Play mode ENUM | +| ------------------------------------- | +| `ClientPlayMode.Normal` | +| `ClientPlayMode.Teaser` | +| `ClientPlayMode.Screen` | +| `ClientPlayMode.Viewer` | +| `ClientPlayMode.VR` | +| `ClientPlayMode.Placement` | +| `ClientPlayMode.LivingRoom` | +| `ClientPlayMode.ExitLevel` | +| `ClientPlayMode.ExitLevelLivingRoom ` | \ No newline at end of file diff --git a/docs/apis/GameAPI/Device.zh.md b/docs/apis/GameAPI/Device.zh.md new file mode 100644 index 00000000..cf9ddc74 --- /dev/null +++ b/docs/apis/GameAPI/Device.zh.md @@ -0,0 +1,73 @@ +## 📱 设备信息对象 API + +在脚本引擎中,使用「设备信息对象」来操作和获取某一个玩家使用的游戏设备的相关信息。 + +### 获取一个设备信息对象 + +#### 通过玩家获取 + +通过玩家对象的`.getDevice`成员函数,来获取一个玩家对应的**设备信息对象** +详见 [玩家对象 API](LLSEPluginDevelopment/GameAPI/Player.md) + +> 注意:不要**长期保存**一个设备信息对象 +> 当设备对应的玩家退出游戏时,对应的对象将同时释放。因此,如果有长期操作某个对象的需要,请通过上述途径获取实时的设备信息对象 + +
+ + +### 设备信息对象 - 属性 + +每一个设备信息对象都包含一些固定的对象属性。对于某个特定的实体对象`dv`,有以下这些属性 + +| 属性 | 含义 | 类型 | +| ----------------- | ---------------------------- | --------- | +| dv.ip | 玩家设备的IP地址 | `String` | +| dv.avgPing | 玩家的平均网络延迟时间(ms) | `Integer` | +| dv.avgPacketLoss | 玩家的平均网络丢包率(%) | `Float` | +| dv.lastPing | 玩家的网络延迟时间(ms) | `Integer` | +| dv.lastPacketLoss | 玩家的网络丢包率(%) | `Float` | +| dv.os | 玩家设备的操作系统类型 | `String` | +| dv.inputMode | 玩家的操作模式 | `Integer` | +| dv.playMode | 玩家的游玩模式 | `Integer` | +| dv.serverAddress | 玩家连接的地址 | `String` | +| dv.clientId | 玩家客户端的识别码ID | `String` | + +这些对象属性都是只读的,无法被修改 + +其中,操作系统类型属性返回一个字符串,记录了玩家设备的操作系统。可能返回的值如下表 + +| dv.os返回字符串 | 玩家设备的操作系统 | +| --------------- | ------------------------- | +| `Android` | 手机谷歌Android | +| `iOS` | 手机苹果iOS/平板iPadOS | +| `OSX` | 电脑苹果macOS | +| `Amazon` | 平板/电视亚马逊FireOS | +| `GearVR` | 头显三星GearVR | +| `Hololens` | 头显微软HoloLens | +| `Windows10` | 电脑微软Windows | +| `Win32` | 电脑微软Win32(教育版?) | +| `TVOS` | 机顶盒苹果tvOS | +| `PlayStation` | 主机索尼PlayStation | +| `Nintendo` | 掌机任天堂Switch | +| `Xbox` | 主机微软Xbox | +| `WindowsPhone` | 手机微软Windows Mobile | +| `Unknown` | 未知系统 | + +| Input mode ENUM | 备注 | +| ---------------------------- | ---------- | +| `InputMode.Mouse` | 鼠标 | +| `InputMode.Touch` | 触屏 | +| `InputMode.GamePad` | 手柄 | +| `InputMode.MotionController` | 运动控制器 | + +| Play mode ENUM | +| ------------------------------------- | +| `ClientPlayMode.Normal` | +| `ClientPlayMode.Teaser` | +| `ClientPlayMode.Screen` | +| `ClientPlayMode.Viewer` | +| `ClientPlayMode.VR` | +| `ClientPlayMode.Placement` | +| `ClientPlayMode.LivingRoom` | +| `ClientPlayMode.ExitLevel` | +| `ClientPlayMode.ExitLevelLivingRoom ` | \ No newline at end of file diff --git a/docs/apis/GameAPI/Entity.md b/docs/apis/GameAPI/Entity.md new file mode 100644 index 00000000..533d58ff --- /dev/null +++ b/docs/apis/GameAPI/Entity.md @@ -0,0 +1,693 @@ +## 🎈 Entity Object API + +In LLSE, "entity objects" are used to manipulate and obtain information about an entity. + +### In LLSE, “Entity Objects” Are Used to Manipulate and Obtain Information About an Entity. + +#### Get From Event or API + +Obtain the entity object given by BDS by registering the **event listener** function, or calling some **returning entity object** functions. +For details, see [Event listener documentation - EventAPI](/LLSEPluginDevelopment/EventAPI/Listen.md) + +#### Get All Currently Loaded Entities + +This function returns an array of entity objects, each of which corresponds to a loaded entity. + +`mc.getAllEntities()` + +- Return value: List of entity objects +- Return value type: `Array` + +#### Spawn New Creature and Get Its Entity Object + +Through this function, generate a new creature at the specified location and get its corresponding entity object. + +`mc.spawnMob(name,pos)` +`mc.spawnMob(name,x,y,z,dimid)` + +- Parameters: + - name : `String` + The namespace name of the creature, such as `minectaft:creeper` + - pos : `IntPos `/ `FloatPos` + A coordinate object of where the mob is spawned (or use x, y, z, dimid to determine where to spawn). +- Return value: The generated entity object. +- Return value type: `Entity` + - If the return value is `Null` it means that the generation failed + +> Note: Do not save an entity object **long-term**. +> When the entity corresponding to the entity object is destroyed, the corresponding entity object will become invalid. Therefore, if there is a need to operate an entity for a long time, please obtain the real-time entity object through the above methods. + +
+ +#### Clone A Creature and Get Its Entity Object + +Through this function, generate a new creature at the specified location and get its corresponding entity object. + +`mc.cloneMob(entity,pos)` +`mc.cloneMob(entity,x,y,z,dimid)` + +- Parameters: + - entity : `Entity` + Need clone entity object + - pos : `IntPos `/ `FloatPos` + A coordinate object of where the mob is spawned (or use x, y, z, dimid to determine where to spawn). +- Return value: The clone entity object. +- Return value type: `Entity` + - If the return value is `Null` it means that the generation failed + +> Note: Do not save an entity object **long-term**. +> When the entity corresponding to the entity object is destroyed, the corresponding entity object will become invalid. Therefore, if there is a need to operate an entity for a long time, please obtain the real-time entity object through the above methods. + +
+ +### Entity Object - Properties + +Every entity object contains some fixed object properties. for a specific entity object `en`, has the following properties: + +| Attributes | Meaning | Data Type | +| ------------------------ | ------------------------------------------------------ | ---------------- | +| en.name | Entity name | `String` | +| en.type | Entity type name | `String` | +| en.id | Entity's in-game ID | `Integer` | +| en.pos | Entity's coordinates | `FloatPos` | +| en.feetPos | The coordinates of the entity's leg | `FloatPos` | +| en.blockPos | The coordinates of the block the entity is standing on | `IntPos` | +| en.maxHealth | Entity's maximum health | `Integer` | +| en.health | Entity's current health | `Integer` | +| en.canFly | Can the entity fly | `Boolean` | +| en.canFreeze | Can entity be frozen | `Boolean` | +| en.canSeeDaylight | Can entitiy see daylight | `Boolean` | +| en.canPickupItems | Can entitiy pick up items | `Boolean` | +| en.inAir | Whether the entity is in the air | `Boolean` | +| en.inWater | Whether the entity is in the water | `Boolean` | +| en.inLava | Whether the entity is in the lava | `Boolean` | +| en.inRain | Whether the entity is in rain | `Boolean` | +| en.inSnow | Whether the entity is in snow | `Boolean` | +| en.inWall | Whether the entity is on the wall | `Boolean` | +| en.inWaterOrRain | Whether the entity is in water or rain | `Boolean` | +| en.inWorld | Whether the entity is in the world | `Boolean` | +| en.speed | Entity's current speed | `Float` | +| en.direction | Entity's orientation | `DirectionAngle` | +| en.uniqueId | Entity's unique identifier | `String` | +| en.isInvisible | Whether the entity is invisible | `Boolean` | +| en.isInsidePortal | Whether the entity is inside the portal | `Boolean` | +| en.isTrusting | Whether the entity is trusted | `Boolean` | +| en.isTouchingDamageBlock | Whether the entity touches the damage block | `Boolean` | +| en.isOnFire | Whether the entity is on fire | `Boolean` | +| en.isOnGround | Whether the entity is on the ground | `Boolean` | +| en.isOnHotBlock | Whether the entity is on a hot block (magma and etc.) | `Boolean` | +| en.isTrading | Whether the entity is trading | `Boolean` | +| en.isRiding | Whether the entity is riding | `Boolean` | +| en.isDancing | Whether the entity is dancing | `Boolean` | +| en.isSleeping | Whether the entity is sleeping | `Boolean` | +| en.isAngry | Whether the entity is angry | `Boolean` | +| en.isBaby | Whether the entity is baby | `Boolean` | +| en.isMoving | Whether the entity is moving | `Boolean` | + +These object properties are read-only and cannot be modified. + +- For a detailed explanation of the **entity's current orientation** attribute, see the [Basic Game Interface Documentation](/LLSEPluginDevelopment/GameAPI/Basic.md) +- **coordinates** and **leg coordinates**: if this entity is two blocks high, `pos` is different from `feetPos`, `pos` is the coordinate of the entity's view's height and `feetPos` is the coordinate of the block where the leg is located + +
+ +### Entity Object - Function + +Each entity object contains some member functions (member methods) that can be executed. for a specific entity object `en`, you can perform some operations on this entity through the following functions: + +#### Teleport Entity to Specified Location + +`en.teleport(pos[,rot])` +`en.teleport(x,y,z,dimid[,rot])` + +- Parameters: + - pos :`IntPos `/ `FloatPos` + Target position coordinates (or use x, y, z, dimid to determine entity position) + + - rot: `DirectionAngle` + + (Optional) The orientation of the entity after teleport, or the same orientation as before teleport if default +- Return value: Whether the teleport was successful or not. +- Return value type: `Boolean` + +
+ +#### Kill the Specified Entity + +`en.kill()` + +- Return value: Whether the entity execution was successful. +- Return value type: `Boolean` + +
+ +#### Make the Specified Entity Despawn + +`en.despawn()` + +- Return value: Whether the entity execution was successful. +- Return value type: `Boolean` + +
+ +#### Remove the Specified Entity + +`en.remove()` + +- Return value: Whether the entity execution was successful. +- Return value type: `Boolean` + +
+ +#### Inflict Damage to Entities + +`en.hurt(damage,type)` + +- Parameters: + - damage : `Float` + The amount of damage to deal to the entity. + - type : `Integer` + Actor Damage Cause +- Return value: Whether the damage was dealt. +- Return value type: `Boolean` + +Note that the damage dealt here is real damage and cannot be reduced by protective equipment such as armor. + +| ActorDamageCause ENUM | +| ------------------------ | +| `ActorDamageCause.Override`| +| `ActorDamageCause.Contact ` | +| `ActorDamageCause.EntityAttack` | +| `ActorDamageCause.Projectile` | +| `ActorDamageCause.Suffocation` | +| `ActorDamageCause.All` | +| `ActorDamageCause.Fire` | +| `ActorDamageCause.FireTick` | +| `ActorDamageCause.Lava` | +| `ActorDamageCause.Drowning ` | +| `ActorDamageCause.BlockExplosion` | +| `ActorDamageCause.EntityExplosion` | +| `ActorDamageCause.Void` | +| `ActorDamageCause.Suicide` | +| `ActorDamageCause.Magic` | +| `ActorDamageCause.Wither` | +| `ActorDamageCause.Starve` | +| `ActorDamageCause.Anvil` | +| `ActorDamageCause.Thorns` | +| `ActorDamageCause.FallingBlock` | +| `ActorDamageCause.Piston` | +| `ActorDamageCause.FlyIntoWall` | +| `ActorDamageCause.Magma` | +| `ActorDamageCause.Fireworks` | +| `ActorDamageCause.Lightning` | +| `ActorDamageCause.Charging` | +| `ActorDamageCause.Temperature` | +| `ActorDamageCause.Freezing` | +| `ActorDamageCause.Stalactite` | +| `ActorDamageCause.Stalagmite` | + +
+ +#### Heal the Entity + +`en.heal(health)` + +- Parameters: + - health : `Integer` + Number of hearts to heal. +- Return value: Whether heal was dealt. +- Return value type: `Boolean` + +
+ +#### Set Health for Entity + +`en.setHealth(health)` + +- Parameters: + - health : `Integer` + Number of hearts. +- Return value: Whether set health for entity was success. +- Return value type: `Boolean` + +
+ +#### Set Absorption Attribute for Entity + +`en.setAbsorption(value)` + +- Parameters: + - value : `Integer` + New value +- Return value: Whether set attribute value for entity was success. +- Return value type: `Boolean` + +
+ +#### Set Attack Damage Attribute for Entity + +`en.setAttackDamage(value)` + +- Parameters: + - value : `Integer` + New value +- Return value: Whether set attribute value for entity was success. +- Return value type: `Boolean` + +
+ +#### Set Maximal Attack Damage Attribute for Entity + +`en.setMaxAttackDamage(value)` + +- Parameters: + - value : `Integer` + New value +- Return value: Whether set attribute value for entity was success. +- Return value type: `Boolean` + +
+ +#### Set Follow Range Attribute for Entity + +`en.setFollowRange(value)` + +- Parameters: + - value : `Integer` + New value +- Return value: Whether set attribute value for entity was success. +- Return value type: `Boolean` + +
+ +#### Set Knockback Resistance Attribute for Entity + +`en.setKnockbackResistance(value)` + +- Parameters: + - value : `Integer` + New value (0 or 1) +- Return value: Whether set attribute value for entity was success. +- Return value type: `Boolean` + +
+ +#### Set Luck Attribute for Entity + +`en.setLuck(value)` + +- Parameters: + - value : `Integer` + New value +- Return value: Whether set attribute value for entity was success. +- Return value type: `Boolean` + +
+ +#### Set Movement Speed for Entity + +`en.setMovementSpeed(value)` + +- Parameters: + - value : `Integer` + New value +- Return value: Whether set attribute value for entity was success. +- Return value type: `Boolean` + +
+ +#### Set Underwater Movement Speed for Entity + +`en.setUnderwaterMovementSpeed(value)` + +- Parameters: + - value : `Integer` + New value +- Return value: Whether set attribute value for entity was success. +- Return value type: `Boolean` + +
+ +#### Set Lava Movement Speed for Entity + +`en.setLavaMovementSpeed(value)` + +- Parameters: + - value : `Integer` + New value +- Return value: Whether set attribute value for entity was success. +- Return value type: `Boolean` + +
+ +#### Set Max Health for Entity + +`en.setMaxHealth(health)` + +- Parameters: + - health : `Integer` + Number of hearts. +- Return value: Whether set max health for entity was success. +- Return value type: `Boolean` + +
+ +#### Set the Specified Entity on Fire + +`en.setFire(time, isEffect)` + +- Parameters: + - time : `Integer` + Fire time, in seconds. + - isEffect : `Boolean` + Will there be a fire effect? +- Return value: Whether the fire was set. +- Return value type: `Boolean` + +
+ +#### Put Out The Entity + +`en.stopFire()` + +- Return value: Has been extinguished. +- Return value type: `Boolean` + +
+ +#### Scale Entity + +`en.setScale(scale)` + +- Parameters: + - scale : `Integer` + New entity size +- Return value: Whether the entity was scaled. +- Return value type: `Boolean` + +
+ +#### Get Entity Distance To Pos + +`en.distanceTo(pos)` +`en.distanceToSqr(pos)` + +- Parameters: + - pos : `Entity` / `Player` / `IntPos` / `FloatPos` + The target position. +- Return value: Distance to coordinates (in blocks). +- Return value type: `Number` + +
+ +#### Determine if an Entity Object Is a Player + +`en.isPlayer()` + +- Return value: Whether the current entity object is a player. +- Return value type: `Boolean` + +
+ +#### Convert Entity Object to Player Object + +`en.toPlayer()` + +- Return value: The converted `Player` object. +- Return value type: `Player` + - Returns `Null` if this entity object does not point to a player, or if the transition fails. + +If the current entity object points to a player, you can use this function to convert the entity object to a player object to use more player-related APIs. + +
+ +#### Determine Whether an Entity Object Is a Dropped Item Entity + +`en.isItemEntity()` + +- Return value: Whether the current entity object is a dropped item entity. +- Return value type: `Boolean` + +
+ +#### Get the Item Object in the Drop Entity + +`en.toItem()` + +- Return value: The obtained `Item` object. +- Return value type: `Item` + - If this entity object is not a drop entity, or if the acquisition fails, return `Null` + +If the current entity object is a drop entity, you can use this function to get the item object in the drop entity to use more item-related APIs. + +
+ +#### Get the Block the Entity Is Currently Standing On + +`en.getBlockStandingOn()` + +- Return value: The block object the entity is standing on. +- Return value type: `Block` + +
+ +#### Gets the Container Object for the Mob’s Armor Slot + +`en.getArmor()` + +- Return value: The container object corresponding to the armor bar of this entity. +- Return value type: `Container` + +For more usage of container objects, please refer to [Container Object API Documentation](/LLSEPluginDevelopment/GameAPI/Container.md) + +
+ +#### Determines if a Mob Has a Container (Except for the Armor Slot) + +`en.hasContainer()` + +- Return value: Whether this biological entity has a container. +- Return value type: `Boolean` + +Such as the boxes on the alpaca, they each have their own container object. + +
+ +#### Get the Container Object Owned by the Mob (Except the Armor Slot) + +`en.getContainer()` + +- Return value: The container object owned by this biological entity. +- Return value type: `Container` + +For more usage of container objects, please refer to [Container Object API Documentation](/LLSEPluginDevelopment/GameAPI/Container.md) + +
+ +#### Refresh Creature Inventory, Armor Slot + +`en.refreshItems()` + +- Return value: Whether the refresh was successful. +- Return value type: `Boolean` + +After modifying the creature's items, in order to make the client take effect, it is necessary to refresh all the items of the creature. + +
+ +#### Add a Tag to the Entity + +`en.addTag(tag)` + +- Parameters: + - tag: `String` + The tag string to be added. +- Return value: Whether the `Tag` was added successfully. +- Return value type: `Boolean` + +
+ +#### Remove a Tag From an Entity + +`en.removeTag(tag)` + +- Parameters: + - tag: `String` + The tag string to remove. +- Return value: Whether the tag removal was successful. +- Return value type: `Boolean` + +
+ +#### Check if an Entity Has a Tag + +`en.hasTag(tag)` + +- Parameters: + - tag: `String` + Tag string to check +- Return value: Whether the entity has the tag. +- Return value type: `Boolean` + +
+ +#### Returns a List of All Tags Owned by the Entity + +`en.getAllTags()` + +- Return value: A list of all tag strings of the entity +- Return value type: `Array` + +
+ +#### Get the Entity's NBT Object + +`en.getNbt()` + +- Return value: NBT object of the entity. +- Return value type: `NbtCompound` + +
+ +#### Write to the Entity's NBT Object + +`en.setNbt(nbt)` + +- Parameters: + - nbt : `NbtCompound` + NBT objects +- Return value: Whether the write was successful or not. +- Return value type: `Boolean` + +For more usage of NBT objects, please refer to [NBT Interface Documentation](/LLSEPluginDevelopment/NbtAPI/NBT.md) + +
+ +#### Get the Entity's Biome ID + +`en.getBiomeId()` + +- Return value:Biome ID +- Return value type:`Integer` + +
+ +#### Get the Entity's Biome Name + +`en.getBiomeName()` + +- Return value:Biome Name +- Return value type:`String` + +
+ +#### Get entity's effects + +`pl.getAllEffects()` + +- Return value: effect ID which is entity owned +- Return type: `Array` + +
+ +#### Add an effect for entity + +`pl.addEffect(id, tick, level, showParticles)` +- Parameter: + - id : `Number` + Effect ID + - tick : `Number` + Lasting time + - level : `Number` + Effect's level + - showParticles : `Boolean` + Whether to show particles +- Return value: Whether succeed +- Return type: `Boolean` + +
+ +#### Remove an effect for entity + +`pl.removeEffect(id)` +- Parameter: + - id : `Number` + Effect ID +- Return value: Whether succeed +- Return type: `Boolean` + +| Name | ID | +| --------------- | ------ | +| speed | 1 | +| slowness | 2 | +| haste | 3 | +| mining_fatigue | 4 | +| strength | 5 | +| instant_health | 6 | +| instant_damage | 7 | +| jump_boost | 8 | +| nausea | 9 | +| regeneration | 10 | +| resistance | 11 | +| fire_resistance | 12 | +| water_breathing | 13 | +| invisibility | 14 | +| blindness | 15 | +| night_vision | 16 | +| hunger | 17 | +| weakness | 18 | +| poison | 19 | +| wither | 20 | +| health_boost | 21 | +| absorption | 22 | +| saturation | 23 | +| levitation | 24 | +| fatal_poison | 25 | +| conduit_power | 26 | +| slow_falling | 27 | +| bad_omen | 28 | +| village_hero | 29 | +| darkness | 30 | + +
+ +### Other Entity Function API + +The following APIs provide APIs for interacting with entities at specified locations in the game: + +#### Create an Explosion at the Specified Location + +`mc.explode(pos,source,power,range,isDestroy,isFire)` +`mc.explode(x,y,z,dimid,source,power,range,isDestroy,isFire)` + +- Parameters: + - pos : `IntPos `/ `FloatPos` + The coordinates of the location where the explosion occurred (or use x, y, z, dimid to determine entity location). + - source : `Entity` + Set the entity object of the explosion source, which can be `Null`. + - power : `Float` + The power value of the explosion, which affects the damage and damage range of the explosion. + - range : `Float` + The radius of the explosion, which affects the scope of the explosion. + - isDestroy : `Boolean` + Does the explosion destroy blocks. + - isFire : `Boolean` + Whether there is a burning flame left after the explosion. +- Return value: Whether the explosion was successfully created. +- Return value type: `Boolean` + +
+ + +#### Quick execute Molang expression + +`en.quickEvalMolangScript(str)` + +- Parameters: + - str : `String` + Molang expression string. +- Return value: The result of the Molang expression. +- Return value type: `Float` + +For detailed usage of Molang, refer to [MOLANG Doc bedrock.dev](https://bedrock.dev/zh/docs/stable/Molang) +
diff --git a/docs/apis/GameAPI/Entity.zh.md b/docs/apis/GameAPI/Entity.zh.md new file mode 100644 index 00000000..249e4d7e --- /dev/null +++ b/docs/apis/GameAPI/Entity.zh.md @@ -0,0 +1,730 @@ +## 🎈 实体对象 API + +在脚本引擎中,使用「实体对象」来操作和获取某一个实体的相关信息。 + +### 获取一个实体对象 + +#### 从事件或API获取 + +通过注册**事件监听**函数,或者调用某些**返回实体对象**的函数,来获取到BDS给出的实体对象 +详见 [事件监听文档 - EventAPI](LLSEPluginDevelopment/EventAPI/Listen.md) + +#### 获取当前所有已加载的实体 + +此函数会返回一个实体对象的数组,其中每个对象都对应了一个已加载的实体 + +`mc.getAllEntities()` + +- 返回值:实体对象列表 +- 返回值类型:`Array` + +#### 生成新生物并获取 + +通过此函数,在指定的位置生成一个新生物,并获取它对应的实体对象 + +`mc.spawnMob(name,pos)` +`mc.spawnMob(name,x,y,z,dimid)` + +- 参数: + - name : `String` + 生物的命名空间名称,如 `minectaft:creeper` + - pos : `IntPos `/ `FloatPos` + 生成生物的位置的坐标对象(或者使用x, y, z, dimid来确定生成位置) +- 返回值:生成的实体对象 +- 返回值类型:`Entity` + - 如返回值为 `Null` 则表示生成失败 + +> 注意:不要**长期保存**一个实体对象 +> 当实体对象对应的实体被销毁时,对应的实体对象将同时释放。因此,如果有长期操作某个实体的需要,请通过上述途径获取实时的实体对象 + +
+ +#### 复制生物并获取 + +通过此函数,在指定的位置复制另一个实体,并获取它对应的实体对象 + +`mc.cloneMob(entity,pos)` +`mc.cloneMob(entity,x,y,z,dimid)` + +- 参数: + - entity : `Entity` + 需要复制的实体对象 + - pos : `IntPos `/ `FloatPos` + 生成生物的位置的坐标对象(或者使用x, y, z, dimid来确定生成位置) +- 返回值 复制的实体对象 +- 返回值类型:`Entity` + - 如返回值为 `Null` 则表示生成失败 + +> 注意:不要**长期保存**一个实体对象 +> 当实体对象对应的实体被销毁时,对应的实体对象将同时释放。因此,如果有长期操作某个实体的需要,请通过上述途径获取实时的实体对象 + +
+ + +### 实体对象 - 属性 + +每一个实体对象都包含一些固定的对象属性。对于某个特定的实体对象`en`,有以下这些属性 + +| 属性 | 含义 | 类型 | +| ------------------------ | ---------------------- | ---------------- | +| en.name | 实体名称 | `String` | +| en.type | 实体标准类型名 | `String` | +| en.id | 实体的游戏内id | `Integer` | +| en.pos | 实体所在坐标 | `FloatPos` | +| en.feetPos | 实体腿部所在坐标 | `FloatPos` | +| en.blockPos | 实体所在的方块坐标 | `IntPos` | +| en.maxHealth | 实体最大生命值 | `Integer` | +| en.health | 实体当前生命值 | `Integer` | +| en.canFly | 实体是否能飞行 | `Boolean` | +| en.canFreeze | 实体是否能被冻结 | `Boolean` | +| en.canSeeDaylight | 实体是否能看到天空 | `Boolean` | +| en.canPickupItems | 实体是否能拾取物品 | `Boolean` | +| en.inAir | 实体是否悬空 | `Boolean` | +| en.inWater | 实体是否在水中 | `Boolean` | +| en.inLava | 实体是否在岩浆中 | `Boolean` | +| en.inRain | 实体是否在雨中 | `Boolean` | +| en.inSnow | 实体是否在雪中 | `Boolean` | +| en.inWall | 实体是否在墙上 | `Boolean` | +| en.inWaterOrRain | 实体是否在水中或雨中 | `Boolean` | +| en.inWorld | 实体是否在世界中 | `Boolean` | +| en.speed | 实体当前速度 | `Float` | +| en.direction | 实体当前朝向 | `DirectionAngle` | +| en.uniqueId | 实体唯一标识符 | `String` | +| en.isInvisible | 实体是否不可见 | `Boolean` | +| en.isInsidePortal | 实体是否在门户内 | `Boolean` | +| en.isTrusting | 实体是否信任 | `Boolean` | +| en.isTouchingDamageBlock | 实体是否接触到伤害方块 | `Boolean` | +| en.isOnFire | 实体是否着火 | `Boolean` | +| en.isOnGround | 实体是否在地面 | `Boolean` | +| en.isOnHotBlock | 实体是否在热块上 | `Boolean` | +| en.isTrading | 实体是否在交易 | `Boolean` | +| en.isRiding | 实体是否正在骑行 | `Boolean` | +| en.isDancing | 实体是否在跳舞 | `Boolean` | +| en.isSleeping | 实体是否在睡觉 | `Boolean` | +| en.isAngry | 实体是否生气 | `Boolean` | +| en.isBaby | 实体是否为幼体 | `Boolean` | +| en.isMoving | 实体是否移动 | `Boolean` | + + +这些对象属性都是只读的,无法被修改 + +- **实体当前朝向** 属性的详细解释见 [基础游戏接口文档](LLSEPluginDevelopment/GameAPI/Basic.md) +- **坐标** 和 **腿部坐标**:如果这个实体为两格高,则`pos`与`feetPos`不同,`pos`为实体视角高度的坐标,`feetPos`为腿部所在格子的方块坐标 + +
+ +### 实体对象 - 函数 + +每一个实体对象都包含一些可以执行的成员函数(成员方法)。对于某个特定的实体对象`en`,可以通过以下这些函数对这个实体进行一些操作 + +#### 传送实体至指定位置 + +`en.teleport(pos[,rot])` +`en.teleport(x,y,z,dimid,[,rot])` + +- 参数: + - pos :`IntPos `/ `FloatPos` + 目标位置坐标(或者使用x, y, z, dimid来确定实体位置) + + - rot: `DirectionAngle` + + (可选参数)传送后实体的朝向,若缺省则与传送前朝向相同 +- 返回值:是否成功传送 +- 返回值类型:`Boolean` + +
+ +#### 杀死指定实体 + +`en.kill()` + +- 返回值:是否成功执行 +- 返回值类型:`Boolean` + +
+ +#### 使指定实体刷新消失 + +`en.despawn()` + +- 返回值:是否成功执行 +- 返回值类型:`Boolean` + +
+ +#### 移除指定实体 + +`en.remove()` + +- 返回值:是否成功执行 +- 返回值类型:`Boolean` + +
+ +#### 对实体造成伤害 + +`en.hurt(damage,type)` + +- 参数: + - damage : `Float` + 对实体造成的伤害数值 + - type : `Integer` + 伤害类型 +- 返回值:是否造成伤害 +- 返回值类型:`Boolean` + +注意,此处造成的伤害为真实伤害,无法被盔甲等保护装备减免 + + +| 伤害类型枚举 | +| ---------------------------------- | +| `ActorDamageCause.Override` | +| `ActorDamageCause.Contact ` | +| `ActorDamageCause.EntityAttack` | +| `ActorDamageCause.Projectile` | +| `ActorDamageCause.Suffocation` | +| `ActorDamageCause.All` | +| `ActorDamageCause.Fire` | +| `ActorDamageCause.FireTick` | +| `ActorDamageCause.Lava` | +| `ActorDamageCause.Drowning ` | +| `ActorDamageCause.BlockExplosion` | +| `ActorDamageCause.EntityExplosion` | +| `ActorDamageCause.Void` | +| `ActorDamageCause.Suicide` | +| `ActorDamageCause.Magic` | +| `ActorDamageCause.Wither` | +| `ActorDamageCause.Starve` | +| `ActorDamageCause.Anvil` | +| `ActorDamageCause.Thorns` | +| `ActorDamageCause.FallingBlock` | +| `ActorDamageCause.Piston` | +| `ActorDamageCause.FlyIntoWall` | +| `ActorDamageCause.Magma` | +| `ActorDamageCause.Fireworks` | +| `ActorDamageCause.Lightning` | +| `ActorDamageCause.Charging` | +| `ActorDamageCause.Temperature` | +| `ActorDamageCause.Freezing` | +| `ActorDamageCause.Stalactite` | +| `ActorDamageCause.Stalagmite` | +| `ActorDamageCause.All` | + +
+ +#### 治疗实体 + +`en.heal(health)` + +- 参数: + - int : `Integer` + 治疗的心数 +- 返回值: 是否治疗成功 +- 返回值类型: `Boolean` + +
+ +#### 设置实体的生命值 + +`en.setHealth(health)` + +- 参数: + - health : `Integer` + 生命值数 +- 返回值: 是否成功 +- 返回值类型: `Boolean` + +
+ +#### 为实体设置伤害吸收属性 + +`en.setAbsorption(value)` + +- 参数: + - value : `Integer` + 新的值 +- 返回值: 为实体设置属性值是否成功 +- 返回值类型: `Boolean` + +
+ +#### 为实体设置攻击伤害属性 + +`en.setAttackDamage(value)` + +- 参数: + - value : `Integer` + 新的值 +- 返回值: 为实体设置属性值是否成功 +- 返回值类型: `Boolean` + +
+ +#### 为实体设置最大攻击伤害属性 + +`en.setMaxAttackDamage(value)` + +- 参数: + - value : `Integer` + 新的值 +- 返回值: 为实体设置属性值是否成功 +- 返回值类型: `Boolean` + +
+ +#### 为实体设置跟随范围 + +`en.setFollowRange(value)` + +- 参数: + - value : `Integer` + 新的值 +- 返回值: 为实体设置属性值是否成功 +- 返回值类型: `Boolean` + +
+ +#### 为实体设置击退抵抗属性 + +`en.setKnockbackResistance(value)` + +- 参数: + - value : `Integer` + 新的值 (0 or 1) +- 返回值: 为实体设置属性值是否成功 +- 返回值类型: `Boolean` + +
+ +#### 为实体设置幸运属性 + +`en.setLuck(value)` + +- 参数: + - value : `Integer` + 新的值 +- 返回值: 为实体设置属性值是否成功 +- 返回值类型: `Boolean` + +
+ +#### 为实体设置移动速度属性 + +`en.setMovementSpeed(value)` + +- 参数: + - value : `Integer` + 新的值 +- 返回值: 为实体设置属性值是否成功 +- 返回值类型: `Boolean` + +
+ +#### 为实体设置水下移动速度属性 + +`en.setUnderwaterMovementSpeed(value)` + +- 参数: + - value : `Integer` + 新的值 +- 返回值: 为实体设置属性值是否成功 +- 返回值类型: `Boolean` + +
+ +#### 为实体设置岩浆上移动速度属性 + +`en.setLavaMovementSpeed(value)` + +- 参数: + - value : `Integer` + 新的值 +- 返回值: 为实体设置属性值是否成功 +- 返回值类型: `Boolean` + +
+ +#### 设置实体的最大生命值 + +`en.setMaxHealth(health)` + +- 参数: + - health : `Integer` + 生命值数 +- 返回值: 是否成功 +- 返回值类型: `Boolean` + +
+ +#### 设置特定实体为燃烧状态 + +`en.setFire(time, isEffect)` + +- 参数: + - time : `Integer` + 燃烧的时间,秒为单位 + - isEffect : `Boolean` + 是否有火焰效果 +- 返回值: 是否设置成功 +- 返回值类型: `Boolean` + +
+ +#### 熄灭实体 + +`en.stopFire()` + +- 返回值: 是否熄灭成功 +- 返回值类型: `Boolean` + +
+ +#### 缩放实体 + +`en.setScale(scale)` + +- 参数: + - scale : `Integer` + 新的实体体积 +- 返回值: 实体是否成功地被缩放 +- 返回值类型: `Boolean` + +
+ +#### 获取实体到坐标的距离 + +`en.distanceTo(pos)` +`en.distanceToSqr(pos)` + +- 参数: + - pos : `Entity` / `Player` / `IntPos` / `FloatPos` + 目标位置 +- 返回值: 到坐标的距离(方块) +- 返回值类型: `Number` + +> **注意** 若玩家的坐标与目标的坐标不在同一维度,将返回整数最大值。 + +
+ +#### 判断一个实体对象是不是玩家 + +`en.isPlayer()` + +- 返回值:当前实体对象是不是玩家 +- 返回值类型:`Boolean` + +
+ +#### 将实体对象转换玩家对象 + +`en.toPlayer()` + +- 返回值:转换成的玩家对象 +- 返回值类型:`Player` + - 如果此实体对象指向的不是某个玩家,或者转换失败,则返回 `Null` + +如果当前实体对象指向的是一个玩家,可以使用此函数将实体对象转换为玩家对象,以使用更多的玩家相关 API + +
+ +#### 判断一个实体对象是不是掉落物实体 + +`en.isItemEntity()` + +- 返回值:当前实体对象是不是掉落物实体 +- 返回值类型:`Boolean` + +
+ +#### 获取掉落物实体中的物品对象 + +`en.toItem()` + +- 返回值:获取到的物品对象 +- 返回值类型:`Item` + - 如果此实体对象不是掉落物实体,或者获取失败,则返回 `Null` + +如果当前实体对象是一个掉落物实体,可以使用此函数获取掉落物实体中的物品对象,以使用更多的物品相关 API + +
+ +#### 获取实体当前站立所在的方块 + +`en.getBlockStandingOn()` + +- 返回值:当前站立在的方块对象 +- 返回值类型:`Block` + +
+ +#### 获取生物盔甲栏的容器对象 + +`en.getArmor()` + +- 返回值:此实体盔甲栏对应的容器对象 +- 返回值类型:`Container` + +关于容器对象的更多使用,请参考 [容器对象 API文档](LLSEPluginDevelopment/GameAPI/Container.md) + +
+ +#### 判断生物是否拥有容器(盔甲栏除外) + +`en.hasContainer()` + +- 返回值:这个生物实体是否拥有容器 +- 返回值类型:`Boolean` + +如羊驼身上的箱子等,他们各自拥有一个属于自己的容器对象 + +
+ +#### 获取生物所拥有的容器对象(盔甲栏除外) + +`en.getContainer()` + +- 返回值:这个生物实体所拥有的容器对象 +- 返回值类型:`Container` + +关于容器对象的更多使用,请参考 [容器对象 API文档](LLSEPluginDevelopment/GameAPI/Container.md) + +
+ +#### 刷新生物物品栏、盔甲栏 + +`en.refreshItems()` + +- 返回值:是否成功刷新 +- 返回值类型:`Boolean` + +在修改生物物品之后,为了促使客户端生效,需要刷新生物所有的物品 + +
+ +#### 为实体增加一个Tag + +`en.addTag(tag)` + +- 参数: + - tag: `String` + 要增加的tag字符串 +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +
+ +#### 为实体移除一个Tag + +`en.removeTag(tag)` + +- 参数: + - tag: `String` + 要移除的tag字符串 +- 返回值:是否移除成功 +- 返回值类型:`Boolean` + +
+ +#### 检查实体是否拥有某个Tag + +`en.hasTag(tag)` + +- 参数: + - tag: `String` + 要检查的tag字符串 +- 返回值:是否拥有这个Tag +- 返回值类型:`Boolean` + +
+ +#### 返回实体拥有的所有Tag列表 + +`en.getAllTags()` + +- 返回值:实体所有的 tag 字符串列表 +- 返回值类型:`Array` + +
+ +#### 获取实体对应的NBT对象 + +`en.getNbt()` + +- 返回值:实体的NBT对象 +- 返回值类型:`NbtCompound` + +
+ +#### 写入实体对应的NBT对象 + +`en.setNbt(nbt)` + +- 参数: + - nbt : `NbtCompound` + NBT对象 +- 返回值:是否成功写入 +- 返回值类型:`Boolean` + +关于NBT对象的更多使用,请参考 [NBT接口文档](LLSEPluginDevelopment/NbtAPI/NBT.md) + +
+ +#### 获取视线方向实体 + +`en.getEntityFromViewVector([maxDistance])` + +- 参数: + - maxDistance : `Float` + 查找最大距离 +- 返回值:视线方向实体,如果获取失败,返回 `Null` +- 返回值类型:`Entity` + +
+ +#### 获取视线方向方块 + +`en.getBlockFromViewVector([includeLiquid,solidOnly,maxDistance,fullOnly])` + +- 参数: + - includeLiquid : `Boolean` + 是否包含液态方块 + - solidOnly : `Boolean` + 是否仅允许 `Solid` 类型的方块 + - maxDistance : `Float` + 查找最大距离 + - fullOnly : `Boolean` + 是否仅允许完整方块 +- 返回值:视线方向方块,如果获取失败,返回 `Null` +- 返回值类型:`Block` + +
+ +#### 获取生物所在群系ID + +`en.getBiomeId()` + +- 返回值:群系ID +- 返回值类型:`Integer` + +
+ +#### 获取生物所在群系名称 + +`en.getBiomeName()` + +- 返回值:群系名称 +- 返回值类型:`String` + +
+ +#### 获取实体全部药水效果 + +`en.getAllEffects()` + +- 返回值:实体所有的药水效果id(见下表) +- 返回值类型:`Array` + +
+ +#### 为实体添加一个药水效果 + +`en.addEffect(id, tick, level, showParticles)` +- 参数: + - id : `Number` + 药水效果的id(见下表) + - tick : `Number` + 持续时间 + - level : `Number` + 等级 + - showParticles : `Boolean` + 是否显示粒子 +- 返回值:操作是否成功 +- 返回值类型:`Boolean` + +
+ +#### 为实体移除一个药水效果 + +`en.removeEffect(id)` +- 参数: + - id : `Number` + 药水效果的id(见下表) +- 返回值:操作是否成功 +- 返回值类型:`Boolean` + +| 效果 | 名称 | 数字id | +| ------------ | --------------- | ------ | +| 迅捷 | speed | 1 | +| 缓慢 | slowness | 2 | +| 急迫 | haste | 3 | +| 挖掘疲劳 | mining_fatigue | 4 | +| 力量 | strength | 5 | +| 瞬间治疗 | instant_health | 6 | +| 瞬间伤害 | instant_damage | 7 | +| 跳跃提升 | jump_boost | 8 | +| 反胃 | nausea | 9 | +| 生命恢复 | regeneration | 10 | +| 抗性提升 | resistance | 11 | +| 抗火 | fire_resistance | 12 | +| 水下呼吸 | water_breathing | 13 | +| 隐身 | invisibility | 14 | +| 失明 | blindness | 15 | +| 夜视 | night_vision | 16 | +| 饥饿 | hunger | 17 | +| 虚弱 | weakness | 18 | +| 中毒 | poison | 19 | +| 凋零 | wither | 20 | +| 生命提升 | health_boost | 21 | +| 伤害吸收 | absorption | 22 | +| 饱和 | saturation | 23 | +| 飘浮 | levitation | 24 | +| 中毒(致命) | fatal_poison | 25 | +| 潮涌能量 | conduit_power | 26 | +| 缓降 | slow_falling | 27 | +| 不祥之兆 | bad_omen | 28 | +| 村庄英雄 | village_hero | 29 | +| 黑暗 | darkness | 30 | + +
+ +### 其他实体函数 API + +下面这些API提供了与游戏中指定位置实体互动的API + +#### 在指定位置制造一次爆炸 + +`mc.explode(pos,source,power,range,isDestroy,isFire)` +`mc.explode(x,y,z,dimid,source,power,range,isDestroy,isFire)` + +- 参数: + - pos : `IntPos `/ `FloatPos` + 引发爆炸的位置坐标(或者使用x, y, z, dimid来确定实体位置) + - source : `Entity` + 设置爆炸来源的实体对象,可以为`Null` + - power : `Float` + 爆炸的威力值,影响爆炸的伤害大小和破坏范围 + - range : `Float` + 爆炸的范围半径,影响爆炸的波及范围 + - isDestroy : `Boolean` + 爆炸是否破坏方块 + - isFire : `Boolean` + 爆炸结束后是否留下燃烧的火焰 +- 返回值:是否成功制造爆炸 +- 返回值类型:`Boolean` + +
+ + +#### 快速执行Molang表达式 + +`en.quickEvalMolangScript(str)` + +- 参数: + - str : `String` + Molang表达式 +- 返回值:表达式执行结果 +- 返回值类型:`Float` + +关于Molang的详细使用方法,请参考 [MOLANG文档 bedrock.dev](https://bedrock.dev/zh/docs/stable/Molang) + +
diff --git a/docs/apis/GameAPI/GameUtils.md b/docs/apis/GameAPI/GameUtils.md new file mode 100644 index 00000000..d85f9c54 --- /dev/null +++ b/docs/apis/GameAPI/GameUtils.md @@ -0,0 +1,58 @@ +## 🎮 Game Utilities API + +The following APIs provide some useful tool interfaces to help game content development, so that the development efficiency can be improved to a certain extent. + +### Format Code Utility + +MC provides format control capabilities such as color text, style modification, etc. in the game through the **formatting code** symbol. Formatting codes are divided into two types: color codes and format codes, which respectively provide color control and style control capabilities. + +The interface here is to help developers quickly get started with MC formatting code, without frequently looking up the table to use +Note: The interface here will only have an effect when passed to the BDS and displayed. + +#### Color Code Table + +| Color Code Symbols | Color Meaning | In-Game String Equivalent | +| ------------------------- | ----------------------- | ------------------ | +| `Format.Black` | The following text is black | §0 | +| `Format.DarkBlue` | The following text is dark blue | §1 | +| `Format.DarkGreen` | The following text is dark green | §2| +| `Format.DarkAqua` | The following text is lake blue | §3| +| `Format.DarkRed` | The following text is dark red | §4| +| `Format.DarkPurple` | The following text is purple | §5| +| `Format.Gold` | The following text is gold | §6| +| `Format.Gray` | The following text is gray | §7| +| `Format.DarkGray` | The following text is dark grey | §8| +| `Format.Blue` | The following text is blue | §9| +| `Format.Green` | The following text is light green | §a| +| `Format.Aqua` | The following text is sky blue | §b| +| `Format.Red` | The following text is red | §c| +| `Format.LightPurple` | The following text is light purple | §d| +| `Format.Yellow` | The following text is light yellow | §e| +| `Format.White` | The following text is white | §f| +| `Format.MinecoinGold` | The following text is coin gold | §g| + +
+ +#### Format Code Table + +| Format Code Symbol | Format Meaning | In-Game String Eqivalent | +| ---------------------- | ------------------------------- | ------------------ | +| `Format.Bold` | The following text is **Bold**| §l | +| `Format.Italics` | The following text is *Italic*| §o| +| `Format.Underline` | The following text is Underline| §n| +| `Format.StrikeThrough` | The following text is ~~Strikethrough~~ | §m | +| `Format.Random` | The following text is randomly flashed garbled characters | §k | +| `Format.Clear` | The following text clears all formatting| §r | + +
+ +The method used by the above code is a connection string, similar to: + +[JavaScript] +```js +mc.broadcast(Format.Red + Format.Bold + "Red & Bold " + Format.DarkGreen + Format.Underline + "DarkGreen & Underline" + Format.Clear + "Clear"); +``` +[Lua] +```lua +mc.broadcast(Format.Red .. Format.Bold .. "Red & Bold " .. Format.DarkGreen .. Format.Underline .. "DarkGreen & Underline" .. Format.Clear .. "Clear") +``` \ No newline at end of file diff --git a/docs/apis/GameAPI/GameUtils.zh.md b/docs/apis/GameAPI/GameUtils.zh.md new file mode 100644 index 00000000..6fcdcc4a --- /dev/null +++ b/docs/apis/GameAPI/GameUtils.zh.md @@ -0,0 +1,58 @@ +## 🎮 游戏实用工具 API + +下面这些API提供了某些帮助游戏内容开发的实用工具接口,让开发效率可以得到一定的提高。 + +### 格式化代码实用工具 + +MC通过 **格式化代码** 符号在游戏内提供颜色文字、样式修改等格式控制能力。格式化代码分为颜色代码与格式代码两种,分别提供颜色控制和样式控制两种能力。 + +此处的接口为了帮助开发者快速上手MC格式化代码,而不需要频繁查表才能使用 +注意:此处接口仅有在传递到BDS中并显示时才会产生效果 + +#### 颜色代码表 + +| 颜色代码符号 | 表示的颜色意义 | 游戏内对应的字符串 | +| ------------------------- | ----------------------- | ------------------ | +| `Format.Black` | 接下来的文字为 黑色 | §0 | +| `Format.DarkBlue` | 接下来的文字为 深蓝色 | §1 | +| `Format.DarkGreen` | 接下来的文字为 深绿色 | §2 | +| `Format.DarkAqua ` | 接下来的文字为 湖蓝色 | §3 | +| `Format.DarkRed` | 接下来的文字为 深红色 | §4 | +| `Format.DarkPurple` | 接下来的文字为 紫色 | §5 | +| `Format.Gold` | 接下来的文字为 金色 | §6 | +| `Format.Gray` | 接下来的文字为 灰色 | §7 | +| `Format.DarkGray` | 接下来的文字为 深灰色 | §8 | +| `Format.Blue` | 接下来的文字为 蓝色 | §9 | +| `Format.Green` | 接下来的文字为 浅绿色 | §a | +| `Format.Aqua` | 接下来的文字为 天蓝色 | §b | +| `Format.Red` | 接下来的文字为 浅红色 | §c | +| `Format.LightPurple` | 接下来的文字为 浅紫色 | §d | +| `Format.Yellow` | 接下来的文字为 浅黄色 | §e | +| `Format.White` | 接下来的文字为 白色 | §f | +| `Format.MinecoinGold ` | 接下来的文字为 硬币金色 | §g | + +
+ +#### 格式代码表 + +| 格式代码符号 | 表示的格式意义 | 游戏内对应的字符串 | +| ---------------------- | ------------------------------- | ------------------ | +| `Format.Bold` | 接下来的文字 **加粗** | §l | +| `Format.Italics` | 接下来的文字 *斜体* | §o | +| `Format.Underline` | 接下来的文字 下划线 | §n | +| `Format.StrikeThrough` | 接下来的文字 ~~删除线~~ | §m | +| `Format.Random` | 接下来的文字 随机闪烁的乱码字符 | §k | +| `Format.Clear` | 接下来的文字 清除所有格式 | §r | + +
+ +上述代码使用的方法为连接字符串,类似于: + +[JavaScript] +```js +mc.broadcast(Format.Red + Format.Bold + "Red & Bold " + Format.DarkGreen + Format.Underline + "DarkGreen & Underline" + Format.Clear + "Clear"); +``` +[Lua] +```lua +mc.broadcast(Format.Red .. Format.Bold .. "Red & Bold " .. Format.DarkGreen .. Format.Underline .. "DarkGreen & Underline" .. Format.Clear .. "Clear") +``` \ No newline at end of file diff --git a/docs/apis/GameAPI/Item.md b/docs/apis/GameAPI/Item.md new file mode 100644 index 00000000..b6c0b563 --- /dev/null +++ b/docs/apis/GameAPI/Item.md @@ -0,0 +1,231 @@ +## 🧰 Item Object API + +In LLSE, use "item objects" to manipulate and get information about an item in the inventory. + +### Get an Item Object + +#### Get From Event or API + +Obtain the item object given by BDS by registering the **event listener** function, or calling some **returning item object** functions. +For details, see [Event listener documentation - EventAPI](/LLSEPluginDevelopment/EventAPI/Listen.md) + +#### Generate New Item Object + +Through this function, a new item object is generated based on the given information. + +`mc.newItem(name,count)` + +- Parameters: + - name : `String` + The standard type name of the item, such as `minecraft:bread` + - count : `Integer` + The number of items to create, and the maximum value is `64` due to `unsigned __int8`. +- Return value: Generated item object. +- Return value type: `Item` + - If the return value is `Null`, the item generation has failed. + +#### Clone From an Existing Item Object + + +Through this function, clone a new item object based on an existing item object. +The new item object is not related to the old object. +For an existing item object item, there are functions: + +`item.clone()` + +- Return value: The cloned item object. +- Return value type: `Item` + - If the return value is `Null`, the item generation has failed. + +#### Generate Item Objects via **NBT** + +Through this function, a new item object is generated using NBT. + +`mc.newItem(nbt)` + +- Parameters: + - nbt : `NbtCompound` + The item NBT used to generate the item object. +- Return value: The generated item object. +- Return value type: `Item` + - If the return value is `Null`, the item generation has failed. + +> Note: Do not save an item object long-term. +> When the item corresponding to the item object is destroyed, the corresponding item object will become invalid. Therefore, if there is a need to operate an item for a long time, please obtain the real-time item object through the above methods. +
+ + +### Item Object - Properties + +Every item object contains some fixed object properties. For a specific item object `it`, there are the following attributes: + +| Attributes| Meaning | Data Type | +| -------- | ------------------------ | --------- | +| it.name | Item's in-game name | `String` | +| it.type | Item Standard Type Name | `String` | +| it.id | Item's in-game ID | `Integer` | +| it.count | Item's count | `Integer` | +| it.aux | Item's data value (for example, wool color or wood type) | `Integer` | +| it.lore | Item Lore | `Array` | +| it.damage | Item Current Damage | `Integer` | +| it.attackDamage | Item Attack Damage | `Integer` | +| it.maxDamage | Item Max Damage | `Integer` | +| it.isArmorItem | Whether the item is armor item | `Boolean` | +| it.isBlock | Whether the item is block | `Boolean` | +| it.isDamageableItem | Whether the item is damageable | `Boolean` | +| it.isDamaged | Whether the item is damaged | `Boolean` | +| it.isEnchanted | Whether the item is enchanted | `Boolean` | +| it.isEnchantingBook | Whether the item is Enchanting Book | `Boolean` | +| it.isFireResistant | Whether the item is fire resistant | `Boolean` | +| it.isFullStack | Whether the item have full stack | `Boolean` | +| it.isGlint | Whether the item is glint | `Boolean` | +| it.isHorseArmorItem | Whether the item is armor item for horse | `Boolean` | +| it.isLiquidClipItem | Whether the item is liquid clip | `Boolean` | +| it.isMusicDiscItem | Whether the item is music disc | `Boolean` | +| it.isOffhandItem | Whether the item can be on second hand | `Boolean` | +| it.isPotionItem | Whether the item is potion | `Boolean` | +| it.isStackable | Whether the item can be stackable | `Boolean` | +| it.isWearableItem | Whether the item can wearable | `Boolean` | + +These object properties are read-only and cannot be modified. + +
+ +### Item Object - Properties + +Each item object contains some member functions (member methods) that can be executed. For a specific item object `it`, you can perform some operations on this item through the following functions: + +> Note that after modifying the items corresponding to the player's inventory, don't forget to use the member function `pl.refreshItems()` of the player object to refresh the player's inventory displayed on the client. + +#### Check if the Item Object Is Empty + +`it.isNull()` + +For example, when there is no item in a grid, the item object you get is empty. + +- Return value: Whether this item object is empty. +- Return value type: `Boolean` + +
+ +#### Make This Item Object Empty (Delete Item) + +`it.setNull()` + +- Return value: Whether the deletion is successful. +- Return value type: `Boolean` + +
+ +#### Set This Item Object to Another Item + +`it.set(item)` + +- Parameters: + - item : `Item` + The item object to assign. +- Return value: Whether the assignment is successful. +- Return value type: `Boolean` + +
+ +#### Damage Item + +`it.setDamage(damage)` + +- Parameters: + - damage : `Integer` + Damage to highlight. +- Return value: Whether the assignment is successful. +- Return value type: `Boolean` + +
+ +#### Set the Data Value of an Item + +`it.setAux(aux)` + +- Parameters: + - aux : `Integer` + Item's auxiliary/data value (ex. Wool color, Wood plank type) +- Return value: Whether the data value was successfully set. +- Return value type: `Boolean` + +
+ +#### Generate Drop Entities From Item Objects + +Through this function, according to the item object, a drop entity with the same content is generated at the specified location. + +`mc.spawnItem(item,pos)` +`mc.spawnItem(item,x,y,z,dimid)` + +- Parameters: + - item : `Item` + The item object used to spawn the drop entity. + - pos : `IntPos `/ `FloatPos` + A coordinate object where the drop entity spawns (or use x, y, z, dimid to determine spawn position). +- Return value: The generated drop entity object. +- Return value type: `Entity` + - If the return value is `Null`, the item generation has failed. + +
+ +#### Get the Item's NBT Object + +`it.getNbt()` + +- Return value: The item's NBT object. +- Return value type: `NbtCompound` + +
+ +#### Write to the Item's NBT Object + +`it.setNbt(nbt)` + +- Parameters: + - nbt : `NbtCompound` + NBT objects. +- Return value: Whether the write was successful or not. +- Return value type: `Boolean` + +For more usage of NBT objects, please refer to [NBT Interface Documentation](/LLSEPluginDevelopment/NbtAPI/NBT.md) + +
+ +#### Set Custom Item Lore + +`it.setLore(names)` + +- Parameters: + - names : `Array` + The array of Lore strings to set. +- Return value: Whether setting the lore was successful. +- Return value type: `Boolean` + +
+ +#### Set Custom Item Name + +`it.setDisplayName(name)` + +- Parameters: + - name : `String` + New item name. +- Return value: Whether setting the name was successful. +- Return value type: `Boolean` + +
+ +#### Determine if it is the same kind of item + +`it.match(item)` + +- Parameters: + - item : `Item` + Judged items +- Return value: is the same kind of item +- Return value type: `Boolean` + +
\ No newline at end of file diff --git a/docs/apis/GameAPI/Item.zh.md b/docs/apis/GameAPI/Item.zh.md new file mode 100644 index 00000000..43ce420d --- /dev/null +++ b/docs/apis/GameAPI/Item.zh.md @@ -0,0 +1,232 @@ +## 🧰 物品对象 API + +在脚本引擎中,使用「物品对象」来操作和获取某一个物品栏物品的相关信息。 + +### 获取一个物品对象 + +#### 从事件或API获取 + +通过注册**事件监听**函数,或者调用某些**返回物品对象**的函数,来获取到BDS给出的物品对象 +详见 [事件监听文档 - EventAPI ](LLSEPluginDevelopment/EventAPI/Listen.md) + +#### 生成新的物品对象 + +通过此函数,根据给出的信息生成一个新的物品对象 + +`mc.newItem(name,count)` + +- 参数: + - name : `String` + 物品的标准类型名,如`minecraft:bread` + - count : `Integer` + 物品堆叠数量,由于 `unsigned __int8`,最大值为 `64` +- 返回值:生成的物品对象 +- 返回值类型:`Item` + - 如返回值为 `Null` 则表示生成失败 + +#### 从现有的物品对象克隆 + + +通过此函数,根据某个现有的物品对象克隆一个新的物品对象 +新的物品对象与旧的对象并无关联关系 +对于一个已经存在的物品对象item,有函数: + +`item.clone()` + +- 返回值:生成的新物品对象 +- 返回值类型:`Item` + - 如返回值为 `Null` 则表示生成失败 + +#### 通过 **NBT** 生成物品对象 + +通过此函数,根据某个NBT生成一个新的物品对象 + +`mc.newItem(nbt)` + +- 参数: + - nbt : `NbtCompound` + 生成物品对象所使用的物品NBT +- 返回值:生成的物品对象 +- 返回值类型:`Item` + - 如返回值为 `Null` 则表示生成失败 + +> 注意:不要**长期保存**一个物品对象 +> 当物品对象对应的物品被销毁时,对应的物品对象将同时释放。因此,如果有长期操作某个物品的需要,请通过上述途径获取实时的物品对象 + +
+ + +### 物品对象 - 属性 + +每一个物品对象都包含一些固定的对象属性。对于某个特定的物品对象`it`,有以下这些属性 + +| 属性 | 含义 | 类型 | +| -------- | ------------------------ | --------- | +| it.name | 游戏内显示的物品名称 | `String` | +| it.type | 物品标准类型名 | `String` | +| it.id | 物品的游戏内id | `Integer` | +| it.count | 这个物品对象堆叠的个数 | `Integer` | +| it.aux | 物品附加值(如羊毛颜色) | `Integer` | +| it.damage | 物品当前耐久 | `Integer` | +| it.attackDamage | 物品攻击伤害 | `Integer` | +| it.maxDamage | 物品最大耐久 | `Integer` | +| it.lore | 物品Lore | `Array` | +| it.isArmorItem | 物品是否为盔甲 | `Boolean` | +| it.isBlock | 物品是否为方块 | `Boolean` | +| it.isDamageableItem | 物品是否可被破坏 | `Boolean` | +| it.isDamaged | 物品耐久是否被消耗 | `Boolean` | +| it.isEnchanted | 物品是否已被附魔 | `Boolean` | +| it.isEnchantingBook | 物品是否为附魔书 | `Boolean` | +| it.isFireResistant | 物品是否防火 | `Boolean` | +| it.isFullStack | 物品是否已堆叠到最大堆叠数 | `Boolean` | +| it.isGlint | 物品是否闪烁 | `Boolean` | +| it.isHorseArmorItem | 物品是否为马铠 | `Boolean` | +| it.isLiquidClipItem | Whether the item is liquid clip | `Boolean` | +| it.isMusicDiscItem | 物品是否为唱片 | `Boolean` | +| it.isOffhandItem | 物品是否可设置到副手 | `Boolean` | +| it.isPotionItem | 物品是否为药水 | `Boolean` | +| it.isStackable | 物品是否可堆叠 | `Boolean` | +| it.isWearableItem | 物品是否可穿戴 | `Boolean` | + +这些对象属性都是只读的,无法被修改 + +
+ +### 物品对象 - 函数 + +每一个物品对象都包含一些可以执行的成员函数(成员方法)。对于某个特定的物品对象`it`,可以通过以下这些函数对这个物品进行一些操作 + +> 注意,在修改完玩家物品栏对应的物品之后,不要忘记使用玩家对象的成员函数`pl.refreshItems`,刷新客户端显示的玩家物品栏 + +#### 判断物品对象是否为空 + +`it.isNull()` + +比如说当某个格子没有任何物品的时候,你获取到的物品对象即是空 + +- 返回值:这个物品对象是否为空 +- 返回值类型: `Boolean` + +
+ +#### 将此物品对象置为空(删除物品) + +`it.setNull()` + +- 返回值:是否删除成功 +- 返回值类型: `Boolean` + +
+ +#### 将此物品对象设置为另一个物品 + +`it.set(item)` + +- 参数: + - item : `Item` + 要赋值的物品对象 +- 返回值:是否赋值成功 +- 返回值类型: `Boolean` + +
+ +#### 设置物品耐久度 + +`it.setDamage(damage)` + +- 参数: + - damage : `Integer` + 耐久度 +- 返回值: 是否设置成功 +- 返回值类型: `Boolean` + +
+ +#### 设置物品的附加值 + +`it.setAux(aux)` + +- 参数: + - aux : `Integer` + 物品附加值 +- 返回值:是否设置成功 +- 返回值类型: `Boolean` + +
+ +#### 根据物品对象生成掉落物实体 + +通过此函数,根据物品对象,在指定的位置生成一个同样内容的掉落物实体 + +`mc.spawnItem(item,pos)` +`mc.spawnItem(item,x,y,z,dimid)` + +- 参数: + - item : `Item` + 生成掉落物实体所使用的物品对象 + - pos : `IntPos `/ `FloatPos` + 生成掉落物实体的位置的坐标对象(或者使用x, y, z, dimid来确定生成位置) +- 返回值:生成的掉落物实体对象 +- 返回值类型:`Entity` + - 如返回值为 `Null` 则表示生成失败 + +
+ +#### 获取物品对应的NBT对象 + +`it.getNbt()` + +- 返回值:物品的NBT对象 +- 返回值类型:`NbtCompound` + +
+ +#### 写入物品对应的NBT对象 + +`it.setNbt(nbt)` + +- 参数: + - nbt : `NbtCompound` + NBT对象 +- 返回值:是否成功写入 +- 返回值类型:`Boolean` + +关于NBT对象的更多使用,请参考 [NBT接口文档](LLSEPluginDevelopment/NbtAPI/NBT.md) + +
+ +#### 设置自定义Lore + +`it.setLore(names)` + +- 参数: + - names : `Array` + 要设置的Lore字符串的数组 +- 返回值:是否设置成功 +- 返回值类型: `Boolean` + +
+ +#### 设置自定义物品名称 + +`it.setDisplayName(name)` + +- 参数: + - name : `String` + 新物品名称 +- 返回值: 设置物品名称是否成功 +- 返回值类型: `Boolean` + +
+ +#### 判断是否为同类物品 + +`it.match(item)` + +- 参数: + - item : `Item` + 被判断的物品 +- 返回值: 是否为同类物品 +- 返回值类型: `Boolean` + +
\ No newline at end of file diff --git a/docs/apis/GameAPI/Packet.md b/docs/apis/GameAPI/Packet.md new file mode 100644 index 00000000..a26e5ce2 --- /dev/null +++ b/docs/apis/GameAPI/Packet.md @@ -0,0 +1,139 @@ +## 🎓 Packet API + +The following objects and APIs provide the basic BDS packet interface for scripts. + +(Please refer to Nukkit, PokcetMine, BDS Reverse to know the packet structure) If the client crashes, it is a packet structure error, not a bug. + +The documentation does not list the packet ID and its structure, please check it yourself. + + +## 目录 +- 🔉 [Packet Object API](#🔉-Packet-Object-api) +- 🔌 [Binary stream object API](#🔌-Binary-stream-object-api) + +
+ +## 🔉 Packet Object API + +In LLSE, 「Packet Object」 is used to get information about packets. + +### Get a packet object + +#### Get from API + +Call some **return packet object** function to get to the packet object given by BDS +See [Binary Stream Objects](#🔌-binary-stream-object-api) for details + +
+ +### Packet Objects - Functions + +Every packet object contains some member functions (member methods) that can be executed. For a particular entity object `pkt`, some operations can be performed on this packet by these functions + +#### Get packet name + +`pkt.getName()` + +- Return value:packet name +- Return value type: `String` + +
+ +#### Get packet ID + +`pkt.getId()` + +- Return value:packet id +- Return value type: `Integer` + +
+ +## 🔌 Binary Stream Object API + +### Create a binary stream object + +[JavaScript] ```new BinaryStream()``` + +[Lua] ```BinaryStream()``` + +- Return value: Binary stream object +- Return value type: `BinaryStream` + +### Binary Stream Object - Functions + +Every binary stream object contains some member functions (member methods) that can be executed. For a particular entity object `bs`, some operations can be performed on this binary stream by these functions + +#### Resetting binary streams + +`bs.reset()` + +- Return value: success or not +- Return value type: `Boolean` + +
+ +#### Write to binary stream + +`bs.writexxxx(value)` + +- Parameters: + - value : `NULL` + Refer to the table below + +- Return value:success or not +- Return value type: `Boolean` + +| Available functions | Parameter Type | +| -------- | ------------------------ | +| writeBool | `Boolean` | +| writeByte | `Integer` | +| writeDouble |`Number` | +| writeFloat | `Float` | +| writeSignedBigEndianInt | `Number` | +| writeSignedInt | `Number` | +| writeSignedInt64 | `Number` | +| writeSignedShort | `Integer` | +| writeString | `String` | +| writeUnsignedChar | `Integer` | +| writeUnsignedInt | `Number` | +| writeUnsignedInt64 | `Number` | +| writeUnsignedShort | `Integer` | +| writeUnsignedVarInt | `Number` | +| writeUnsignedVarInt64 | `Number` | +| writeVarInt | `Number` | +| writeVarInt64 | `Number` | +| writeVec3 | `FloatPos` | +| writeCompountTag | `NbtCompound` | + +
+ +#### Building packet from binary stream + +`bs.createPacket(pktid)` + +- Parameters: + - pktid : `Integer` + Packet ID + +- Return value:Packet object +- Return value type: `Packet` + +
+ +### Dome Code + +Send TextPacket packets to a player +```js +mc.listen("onChat",function(pl,msg){ + const bs = new BinaryStream() + var text = "LLSE Packet Test" + bs.reserve(text.length + 8) + bs.writeUnsignedChar(0) + bs.writeBool(true) + bs.writeString(text) + bs.writeString("") + bs.writeString("") + var pkt = bs.createPacket(9) + pl.sendPacket(pkt) +}) +``` \ No newline at end of file diff --git a/docs/apis/GameAPI/Packet.zh.md b/docs/apis/GameAPI/Packet.zh.md new file mode 100644 index 00000000..7256c543 --- /dev/null +++ b/docs/apis/GameAPI/Packet.zh.md @@ -0,0 +1,139 @@ +## 🎓 数据包 API + +下面这些对象与API为脚本提供了基本的BDS数据包接口。 + +温馨提示:此类API需要部分逆向基础,了解数据包结构(可通过参考Nukkit,PokcetMine,BDS逆向得知数据包结构)如出现客户端崩溃,为数据包结构错误,并非BUG。 + +文档不列出数据包ID与其结构,请自行查询。 + + +## 目录 +- 🔉 [数据包对象 API](#🔉-数据包对象-api) +- 🔌 [二进制流对象 API](#🔌-二进制流对象-api) + +
+ +## 🔉 数据包对象 API + +在脚本引擎中,使用「数据包对象」来获取数据包的相关信息。 + +### 获取一个数据包对象 + +#### 从API获取 + +调用某些**返回数据包对象**的函数,来获取到BDS给出的数据包对象 +详见 [二进制流对象](#🔌-二进制流对象-api) + +
+ +### 数据包对象 - 函数 + +每一个数据包对象都包含一些可以执行的成员函数(成员方法)。对于某个特定的实体对象`pkt`,可以通过以下这些函数对这个数据包进行一些操作 + +#### 获取数据包名称 + +`pkt.getName()` + +- 返回值:数据包名称 +- 返回值类型: `String` + +
+ +#### 获取数据包ID + +`pkt.getId()` + +- 返回值:数据包ID +- 返回值类型: `Integer` + +
+ +## 🔌 二进制流对象 API + +### 创建一个二进制流对象 + +[JavaScript] ```new BinaryStream()``` + +[Lua] ```BinaryStream()``` + +- 返回值:二进制流对象 +- 返回值类型: `BinaryStream` + +### 二进制流对象 - 函数 + +每一个二进制流对象都包含一些可以执行的成员函数(成员方法)。对于某个特定的实体对象`bs`,可以通过以下这些函数对这个二进制流进行一些操作 + +#### 重置二进制流 + +`bs.reset()` + +- 返回值:是否成功 +- 返回值类型: `Boolean` + +
+ +#### 写入二进制流 + +`bs.writexxxx(value)` + +- 参数: + - value : `NULL` + 参考下面表格 + +- 返回值:是否成功 +- 返回值类型: `Boolean` + +| 可用函数 | 参数类型 | +|-------------------------|---------------| +| writeBool | `Boolean` | +| writeByte | `Integer` | +| writeDouble | `Number` | +| writeFloat | `Float` | +| writeSignedBigEndianInt | `Number` | +| writeSignedInt | `Number` | +| writeSignedInt64 | `Number` | +| writeSignedShort | `Integer` | +| writeString | `String` | +| writeUnsignedChar | `Integer` | +| writeUnsignedInt | `Number` | +| writeUnsignedInt64 | `Number` | +| writeUnsignedShort | `Integer` | +| writeUnsignedVarInt | `Number` | +| writeUnsignedVarInt64 | `Number` | +| writeVarInt | `Number` | +| writeVarInt64 | `Number` | +| writeVec3 | `FloatPos` | +| writeCompountTag | `NbtCompound` | + +
+ +#### 通过二进制流构建数据包 + +`bs.createPacket(pktid)` + +- 参数: + - pktid : `Integer` + 数据包ID + +- 返回值:数据包对象 +- 返回值类型: `Packet` + +
+ +### 演示代码 + +向一个玩家发送TextPacket数据包 +```js +mc.listen("onChat",function(pl,msg){ + const bs = new BinaryStream() + var text = "LLSE Packet Test" + bs.reserve(text.length + 8) + bs.writeUnsignedChar(0) + bs.writeBool(true) + bs.writeString(text) + bs.writeString("") + bs.writeString("") + var pkt = bs.createPacket(9) + pl.sendPacket(pkt) +}) +``` \ No newline at end of file diff --git a/docs/apis/GameAPI/Particle.md b/docs/apis/GameAPI/Particle.md new file mode 100644 index 00000000..a8647642 --- /dev/null +++ b/docs/apis/GameAPI/Particle.md @@ -0,0 +1,139 @@ +> [!WARNING] +> ParticleAPI is disabled by default, you need to change `ParticleAPI` to `true` in `plugins/LiteLoader/LiteLoader.json` + +## ✨ ParticleSpawner Object + + For a `ParticleSpawner` type variable ps, there are the following members: + + | members | type | + | ---------------- | --------- | + | ps.displayRadius | `Integer` | + | ps.highDetial | `Boolean` | + | ps.doubleSide | `Boolean` | + +### Particle Spawner Object + +`mc.newParticleSpawner(displayRadius = 4294967295, highDetial = true, doubleSide = true)` + +- Return value type: `ParticleSpawner` + +## Particle Color Enums + +| Particle Color Enums | +| ------------------------ | +| `ParticleColor.Black` | +| `ParticleColor.Indigo` | +| `ParticleColor.Lavender` | +| `ParticleColor.Teal` | +| `ParticleColor.Cocoa` | +| `ParticleColor.Dark` | +| `ParticleColor.Oatmeal` | +| `ParticleColor.White` | +| `ParticleColor.Red` | +| `ParticleColor.Apricot` | +| `ParticleColor.Yellow` | +| `ParticleColor.Green` | +| `ParticleColor.Vatblue` | +| `ParticleColor.Slate` | +| `ParticleColor.Pink` | +| `ParticleColor.Fawn` | + +## Direction Enums + +| Direction Enums | +| ----------------- | +| `Direction.NEG_Y` | +| `Direction.POS_Y` | +| `Direction.NEG_Z` | +| `Direction.POS_Z` | +| `Direction.NEG_X` | +| `Direction.POS_X` | + +## Generate named particles + +`ps.spawnParticle(pos, name)` + +- parameter: + - pos : Can be FloatPos or IntPos, IntPos will take the position of the center point of the block + - name : `String` +- Return value: true +- Return value type: `Boolean` + +> The following particles are all 2s display time + +## Generate point particles + +`ps.drawPoint(pos, pointSize = 4, color = ParticleColor.White)` + +- parameter: + - pos : Can be FloatPos or IntPos, IntPos will take the position of the center point of the block + - pointSize : `Number` + - Only 1, 2, 4, 8, 16 size optional + - color : `String` should use `ParticleColor` to fill +- Return value: true +- Return value type: `Boolean` + +## Generate digital particles + +`ps.drawNumber(pos, num, color = ParticleColor.White)` + +- parameter: + - pos : Can be FloatPos or IntPos, IntPos will take the position of the center point of the block + - num : if is `Number` , can only fill with 0~16, if is `String` , can fill with `0`~`16` or `A`~`F` + - color : `String` should use `ParticleColor` to fill +- Return value: true +- Return value type: `Boolean` + +## Generate Axial Segments + +`ps.drawAxialLine(pos, direction, length, color = ParticleColor.White)` + +- parameter: + - pos : segment start point, Can be FloatPos or IntPos, IntPos will take the position of the center point of the block + - direction : `Number`, should use `Direction` to fill + - length : `Number`, any real number + - color : `String` should use `ParticleColor` to fill +- Return value: true +- Return value type: `Boolean` + +## Generate directed line segments + +`ps.drawOrientedLine(start, end, lineWidth = 4, minSpacing = 1, maxParticlesNum = 64, color = ParticleColor.White)` + +- parameter: + - start : segment start point, Can be FloatPos or IntPos, IntPos will take the position of the center point of the block + - end : segment end point, Can be FloatPos or IntPos, IntPos will take the position of the center point of the block + - lineWidth : `Number` + - Only 1, 2, 4, 8, 16 size optional + - minSpacing : `Number`, any real number, Minimum interval between points of this line segment + - maxParticlesNum : `Number`, Integer, the maximum number of particles in this line segment, the interval will be automatically increased after reaching + - color : `String` should use `ParticleColor` to fill +- Return value: true +- Return value type: `Boolean` + +## Generate circle + +`ps.drawCircle(pos, facing, radius, lineWidth = 4, minSpacing = 1, maxParticlesNum = 64, color = ParticleColor.White)` + +- parameter: + - pos : center of circle, Can be FloatPos or IntPos, IntPos will take the position of the center point of the block + - facing : `Number`, should use `Direction` to fill + - radius : `Number`, any real number + - lineWidth : `Number` + - Only 1, 2, 4, 8, 16 size optional + - minSpacing : `Number`, any real number, Minimum interval between points of this line segment + - maxParticlesNum : `Number`, Integer, the maximum number of particles in this line segment, the interval will be automatically increased after reaching + - color : `String` should use `ParticleColor` to fill +- Return value: true +- Return value type: `Boolean` + +## generate cube + +`ps.drawCuboid(pos[,pos2], color = ParticleColor.White)` + +- parameter: + - pos : Can be floating point coordinates or integer coordinates, the integer coordinates will take the bottom position of the corner of the block, if there is only one coordinate, it will draw a 1×1×1 cube + - pos2 : Can be floating point coordinates or integer coordinates, the integer coordinates will take the top position of the corner of the block, and will draw a cube from the smallest corner pos to the largest corner pos2 + - color : `String` should use `ParticleColor` to fill +- Return value: true +- Return value type: `Boolean` diff --git a/docs/apis/GameAPI/Particle.zh.md b/docs/apis/GameAPI/Particle.zh.md new file mode 100644 index 00000000..0075c4da --- /dev/null +++ b/docs/apis/GameAPI/Particle.zh.md @@ -0,0 +1,140 @@ +> [!WARNING] +> 注意: ParticleAPI是默认关闭的,你需要启用`plugins/LiteLoader/LiteLoader.json`中的`ParticleAPI` + +## ✨ ParticleSpawner 对象 + + 对于某个 `ParticleSpawner` 类型变量 ps, 有如下这些成员: + + | 成员 | 含义 | 类型 | + | ---------------- | ------------- | --------- | + | ps.displayRadius | 粒子显示半径 | `Integer` | + | ps.highDetial | 需要高细节线条 | `Boolean` | + | ps.doubleSide | 需要双面粒子 | `Boolean` | + +### 生成一个粒子生成器对象 + +`mc.newParticleSpawner(displayRadius = 4294967295, highDetial = true, doubleSide = true)` + +- 返回值:一个粒子生成器对象 +- 返回值类型:`ParticleSpawner` + +## 粒子颜色枚举 + +| 粒子颜色枚举 | +| ------------------------ | +| `ParticleColor.Black` | +| `ParticleColor.Indigo` | +| `ParticleColor.Lavender` | +| `ParticleColor.Teal` | +| `ParticleColor.Cocoa` | +| `ParticleColor.Dark` | +| `ParticleColor.Oatmeal` | +| `ParticleColor.White` | +| `ParticleColor.Red` | +| `ParticleColor.Apricot` | +| `ParticleColor.Yellow` | +| `ParticleColor.Green` | +| `ParticleColor.Vatblue` | +| `ParticleColor.Slate` | +| `ParticleColor.Pink` | +| `ParticleColor.Fawn` | + +## 方向枚举 + +| 方向枚举 | +| ----------------- | +| `Direction.NEG_Y` | +| `Direction.POS_Y` | +| `Direction.NEG_Z` | +| `Direction.POS_Z` | +| `Direction.NEG_X` | +| `Direction.POS_X` | + +## 生成指定名称粒子 + +`ps.spawnParticle(pos, name)` + +- 参数: + - pos 可以是浮点坐标或者整数坐标, 整数坐标会取方块中心点位置 + - name : `String` +- 返回值:true +- 返回值类型:`Boolean` + +> 以下粒子均为 2s 显示时间 + +## 生成点粒子 + +`ps.drawPoint(pos, pointSize = 4, color = ParticleColor.White)` + +- 参数: + - pos 可以是浮点坐标或者整数坐标, 整数坐标会取方块中心点位置 + - pointSize : `Number` + - 只有 1, 2, 4, 8, 16 大小可选 + - color : `String` 应当使用 `ParticleColor` 枚举填充 +- 返回值:true +- 返回值类型:`Boolean` + +## 生成数字粒子 + +`ps.drawNumber(pos, num, color = ParticleColor.White)` + +- 参数: + - pos 可以是浮点坐标或者整数坐标, 整数坐标会取方块中心点位置 + - num : 若为`Number`只可填 0~16, 若为`String`可填 `0`~`16` 或 `A`~`F` + - color : `String`, 应当使用 `ParticleColor` 枚举填充 +- 返回值:true +- 返回值类型:`Boolean` + +## 生成轴向线段 + +`ps.drawAxialLine(pos, direction, length, color = ParticleColor.White)` + +- 参数: + - pos 线段起点, 可以是浮点坐标或者整数坐标, 整数坐标会取方块中心点位置 + - direction : `Number`, 应当使用 `Direction` 枚举填充 + - length : `Number`, 任意实数 + - color : `String`, 应当使用 `ParticleColor` 枚举填充 +- 返回值:true +- 返回值类型:`Boolean` + +## 生成有向线段 + +`ps.drawOrientedLine(start, end, lineWidth = 4, minSpacing = 1, maxParticlesNum = 64, color = ParticleColor.White)` + +- 参数: + - start 线段起点, 可以是浮点坐标或者整数坐标, 整数坐标会取方块中心点位置 + - end 线段终点, 可以是浮点坐标或者整数坐标, 整数坐标会取方块中心点位置 + - lineWidth : `Number` + - 只有 1, 2, 4, 8, 16 大小可选 + - minSpacing : `Number`, 任意实数, 此线段点最小间隔 + - maxParticlesNum : `Number`, 整数, 此线段最大粒子数,达到后会自动增加间隔 + - color : `String`, 应当使用 `ParticleColor` 枚举填充 +- 返回值:true +- 返回值类型:`Boolean` + +## 生成圆 + +`ps.drawCircle(pos, facing, radius, lineWidth = 4, minSpacing = 1, maxParticlesNum = 64, color = ParticleColor.White)` + +- 参数: + - pos 圆心, 可以是浮点坐标或者整数坐标, 整数坐标会取方块中心点位置 + - facing : `Number`, 应当使用 `Direction` 枚举填充 + - radius : `Number`, 任意实数, 半径 + - lineWidth : `Number` + - 只有 1, 2, 4, 8, 16 大小可选 + - minSpacing : `Number`, 任意实数, 此圆点最小间隔 + - maxParticlesNum : `Number`, 整数, 此圆最大粒子数,达到后会自动增加间隔 + - color : `String`, 应当使用 `ParticleColor` 枚举填充 +- 返回值:true +- 返回值类型:`Boolean` + +## 生成立方体 + +`ps.drawCuboid(pos[,pos2], color = ParticleColor.White)` + +- 参数: + - pos : 可以是浮点坐标或者整数坐标, 整数坐标会取方块角落底部位置, 若只有一个坐标,会画出 1×1×1 大小的立方体 + - pos2 : 可以是浮点坐标或者整数坐标, 整数坐标会取方块角落顶端位置, 会画出从最小角落 pos 到最大角落 pos2 的立方体 + - color : `String`, 应当使用 `ParticleColor` 枚举填充 +- 返回值:true +- 返回值类型:`Boolean` diff --git a/docs/apis/GameAPI/Player.md b/docs/apis/GameAPI/Player.md new file mode 100644 index 00000000..3267d61e --- /dev/null +++ b/docs/apis/GameAPI/Player.md @@ -0,0 +1,1360 @@ +## 🏃‍♂️ Player Object API + +In LLSE, use "player objects" to manipulate and obtain information about a player. + +### Get a Player Object + +#### Get From Event or API + +By registering the **event listener** function, get the player object related to the related event given by BDS. +For details, see [Event listener documentation - EventAPI](/LLSEPluginDevelopment/EventAPI/Listen.md) + +#### Acquired From Existing Players + +Manually generate player objects by **player information** +Use this function to manually generate objects. Note that the player you want to get must be online, otherwise the generation will fail. + +`mc.getPlayer(info)` + +- Parameters: + - info : `String` + Player's name or XUID or uniqueId. +- Return value: The generated player object. +- Return value type: `Player` + - If the return value is `Null`, it means that getting the player failed. + +#### Get All Online Players + +This function returns an array of player objects, each of which corresponds to a player on the server. + +`mc.getOnlinePlayers()` + +- Return value: List of online `Player` objects. +- Return value type: `Array` + +> Note: Do not save a `Player` object **long-term**. +> When the player exits the server, the corresponding player object will become invalid. Therefore, if there is a need to operate a player for a long time, please obtain the real-time player object through the above methods. + +
+ +### Player Object - Properties + +Each player object contains some fixed object properties. For a particular player object `pl`, there are these properties. + +| Attributes | Meaning | Data Type | +| ------------------------ | ------------------------------------------------------------ | ---------------- | +| pl.name | Player's name | `String` | +| pl.pos | Player's coordinates | `FloatPos` | +| pl.feetPos | The coordinates of the player's leg | `FloatPos` | +| pl.blockPos | The coordinates of the block that the player is standing on. | `IntPos` | +| pl.lastDeathPos | The coordinates of the block that the player last died. | `IntPos` | +| pl.realName | Player's Real Name | `String` | +| pl.xuid | Player XUID String | `String` | +| pl.uuid | Player Uuid string | `String` | +| pl.permLevel | Player's permission level (0 - 4) | `Integer` | +| pl.gameMode | Player's game mode (0 - 2, 6) | `Integer` | +| pl.canSleep | Whether the player can sleep | `Boolean` | +| pl.canFly | Whether the player can fly | `Boolean` | +| pl.canBeSeenOnMap | Whether the player can be seen on map | `Boolean` | +| pl.canFreeze | Whether the player can freeze | `Boolean` | +| pl.canSeeDaylight | Whether the player can see daylight | `Boolean` | +| pl.canShowNameTag | Whether the player can show name tag | `Boolean` | +| pl.canStartSleepInBed | Whether the player can start sleep in bed | `Boolean` | +| pl.canPickupItems | Whether the player can pickup items | `Boolean` | +| pl.maxHealth | Player's maximum health | `Integer` | +| pl.health | Player's current health | `Integer` | +| pl.inAir | Whether the player is in the air | `Boolean` | +| pl.inWater | Whether the player is in water | `Boolean` | +| pl.inLava | Whether the player is in lava | `Boolean` | +| pl.inRain | Whether the player is in rain | `Boolean` | +| pl.inSnow | Whether the player is in snow | `Boolean` | +| pl.inWall | Whether the player is in wall | `Boolean` | +| pl.inWaterOrRain | Whether the player is in water or rain | `Boolean` | +| pl.inWorld | Whether the player is in world | `Boolean` | +| pl.inClouds | Whether the player is in clouds | `Boolean` | +| pl.speed | Player's current speed | `Float` | +| pl.direction | Player's current orientation | `DirectionAngle` | +| pl.uniqueId | Player's (entity's) unique identifier | `String` | +| pl.isLoading | Player is loading | `Boolean` | +| pl.isInvisible | Player is invisible | `Boolean` | +| pl.isInsidePortal | Player is inside portal | `Boolean` | +| pl.isHurt | Player is hurt | `Boolean` | +| pl.isTrusting | Player is trusting | `Boolean` | +| pl.isTouchingDamageBlock | Player is touching the damage block | `Boolean` | +| pl.isHungry | Player is hungry | `Boolean` | +| pl.isOnFire | Player is on fire | `Boolean` | +| pl.isOnGround | Player is on ground | `Boolean` | +| pl.isOnHotBlock | Player is on hot block (magma and etc.) | `Boolean` | +| pl.isTrading | Player is trading | `Boolean` | +| pl.isAdventure | Player is in Adventure Mode | `Boolean` | +| pl.isGliding | Player is gliding | `Boolean` | +| pl.isSurvival | Player is in Survival Mode | `Boolean` | +| pl.isSpectator | Player is in Spectator Mode | `Boolean` | +| pl.isRiding | Player is riding | `Boolean` | +| pl.isDancing | Player is dancing | `Boolean` | +| pl.isCreative | Player is in Creative Mode | `Boolean` | +| pl.isFlying | Player is flying | `Boolean` | +| pl.isSleeping | Player is sleeping | `Boolean` | +| pl.isMoving | Player is moving | `Boolean` | +| pl.isSneaking | Player is sneaking | `Boolean` | + +These object properties are read-only and cannot be modified. in: + +- **coordinates** and **leg coordinates**: player is two blocks high, and `pos` are the coordinates of the player's view's height, `feetPos` are the coordinates of the block position displayed in the game +- The value of the **Player Game Mode** attribute is: `0` for survival mode, `1` for creative mode, `2` for adventure mode, `3` for spectator mode +- **Player's real name** attribute stored strings can be considered reliable, they will not be changed by name changes +- **Player device IP address** attribute stores the player's device IP and port number, the format is similar to `12.34.567.89:1111` +- For a detailed explanation of the **player's current orientation** attribute, see [Basic Game Interface Documentation](/LLSEPluginDevelopment/GameAPI/Basic.md) +- The comparison table of **operation authority level** attributes is as follows: + +| Permission Level | Corresponding Authority | +| ---------------- | ------------------------ | +| 0 | Ordinary Member | +| 1 | OP permissions | +| 4 | OP + Console permissions | + +
+ +### Player Object - Function + +Each player object contains some member functions (member methods) that can be executed. For a specific player object `pl`, you can perform some operations on this player through the following functions. + +#### Determine if the Player Is OP + +`pl.isOP()` + +- Return value: Whether the player is an OP. +- Return value type: `Boolean` + +[JavaScript] +```js +// For a `Player` object pl +var open = pl.isOP(); +``` + +#### Disconnect Player + +`pl.kick([msg])` +`pl.disconnect([msg])` + +- Parameters: + - msg : `String` + (Optional parameter) The reason for the disconnection displayed to the kicked player. + Defaults to "disconnecting from server". +- Return value: Whether the connection was successfully disconnected. +- Return value type: `Boolean` + +[JavaScript] +```js +//For a `Player` object pl +pl.kick(); +``` +[Lua] +```lua +pl:kick() +``` + +#### Send a Text Message to the Player + +`pl.tell(msg[,type])` +`pl.sendText(msg[,type])` + +- Parameters: + + - msg : `String` + The message to be sent. + + - type : `Integer` + (Optional parameter) The type of text message to send, default is `0`. + + | Type Parameter | Message Type | + | -------------- | --------------------------------- | + | 0 | Normal Message (Raw) | + | 1 | Chat Message (Chat) | + | 4 | Music Box Message (Popup) | + | 5 | Message Above the Inventory (Tip) | + | 9 | JSON format message (JSON) | + +- Return value: Whether the message was sent successfully. + +- Return value type: `Boolean` + +[JavaScript] +```js +//For a `Player` object pl +pl.tell("Welcome back ~ ",5); +``` + +#### Set Title Message to the Player + +`pl.setTitle(content[,type[,fadeInTime,stayTime,fadeOutTime]])` + +- Parameter: + + - content : `String` + The title content. + + - type : `Integer` + (optional) The title type, default = 2. + + | Types | Description | + | ----- | ------------------- | + | 0 | Clear | + | 1 | Reset | + | 2 | SetTitle | + | 3 | SetSubTitle | + | 4 | SetActionBar | + | 5 | SetDurations | + | 6 | TitleTextObject | + | 7 | SubtitleTextObject | + | 8 | ActionbarTextObject | + + - fadeInTime : `Integer` + (optional) Fade in time, in `Tick` , default is 10 + + - stayTime: `Integer` + + (optional) Stay time, in `Tick` , default is 10 + + - fadeOutTime:`Integer` + + (optional) Fade out time, in `Tick` , default is 10 + +- Return value: Is send successfully? + +- Return value type: `Boolean` + +#### Broadcast a Text Message to All Players + +`mc.broadcast(msg[,type])` + +- Parameters: + + - msg : `String` + The message to be sent. + + - type : `Integer` + (Optional parameter) The type of text message to send, default is `0`. + + | Type Parameter | Message Type | + | -------------- | --------------------------------- | + | 0 | Normal Message (Raw) | + | 1 | Chat Message (Chat) | + | 4 | Music Box Message (Popup) | + | 5 | Message Above the Inventory (Tip) | + | 9 | JSON format message (JSON) | + +- Return value: Whether the message was sent successfully. + +- Return value type: `Boolean` + +[JavaScript] +```js +mc.broadcast("Hello everyone ~ "); +``` + +#### Display a toast to the top of the screen + +`pl.sendToast(title,message)` + +- Parameters: + + - title : `String` + The title of the toast. + + - message : `string` + the message that the toast may contain alongside the title. + +- Return value: Whether the message was sent successfully. +- Return value type: `Boolean` + +[JavaScript] +```js +pl.sendToast("Hello","everyone ~"); +``` + + +#### Execute a Command as a Player + +`pl.runcmd(cmd)` + +- Parameters: + - cmd : `String` + The command to be executed. +- Return value: Whether the execution was successful. +- Return value type: `Boolean` + +[JavaScript] +```js +//For a `Player` object pl +var open = pl.runcmd("tp ~ ~+50 ~"); +``` + +#### Speak as a Player + +`pl.talkAs(text)` + +- Parameters: + - text : `String` + The text the player will be made to say. +- Return value: Whether the execution was successful. +- Return value type: `Boolean` + +
+ +#### Get Player Distance To Pos + +`pl.distanceTo(pos)` +`pl.distanceToSqr(pos)` + +- Parameters: + - pos : `Entity` / `Player` / `IntPos` / `FloatPos` + The target position. +- Return value: Distance to coordinates (in blocks). +- Return value type: `Number` + +
+ +#### Speak to a Player as a Player + +`pl.talkAs(target,text)` + +- Parameters: + - target : `Player` + The player who will be spoken to. + - text : `String` + The text the player will be made to say. +- Return value: Whether the execution was successful. +- Return value type: `Boolean` + +
+ +#### Teleport the Player to the Specified Location + +`pl.teleport(pos[,rot])` +`pl.teleport(x,y,z,dimid[,rot])` + +- Parameters: + - pos: `IntPos `/ `FloatPos` + Target position coordinates (or use x, y, z, dimid to determine player position) + + - rot: `DirectionAngle` + + (Optional) The orientation of the player after teleport, or the same orientation as before teleport if default + +- Return value: Whether the teleport was successful or not. + +- Return value type: `Boolean` + +[JavaScript] +```js +//For a `Player` object pl, a coordinate object pos +pl.teleport(pos); +``` + +#### Kill the Player + +`pl.kill()` + +- Return value: Whether the execution was successful. +- Return value type: `Boolean` + +[JavaScript] +```js +[JavaScript] +//For a `Player` object pl +pl.kill(); +[Lua] + +``` + +#### Damage the Player + +`pl.hurt(damage)` + +- Parameters: + - damage : `Integer` + The amount of damage dealt to the player . +- Return value: Whether damage was dealt. +- Return value type: `Boolean` + +Note that the damage dealt here is real damage and cannot be reduced by protective equipment such as armor. + +
+ +#### Heal the Player + +`pl.heal(health)` + +- Parameters: + - health : `Integer` + Number of hearts to heal. +- Return value: Whether heal was dealt. +- Return value type: `Boolean` + +
+ +#### Set Health for Player + +`pl.setHealth(health)` + +- Parameters: + - health : `Integer` + Number of hearts. +- Return value: Whether set health for player was success. +- Return value type: `Boolean` + +
+ +#### Set Absorption Attribute for Player + +`pl.setAbsorption(value)` + +- Parameters: + - value : `Integer` + New value +- Return value: Whether set attribute value for player was success. +- Return value type: `Boolean` + +
+ +#### Set Attack Damage Attribute for Player + +`pl.setAttackDamage(value)` + +- Parameters: + - value : `Integer` + New value +- Return value: Whether set attribute value for player was success. +- Return value type: `Boolean` + +
+ +#### Set Maximal Attack Damage Attribute for Player + +`pl.setMaxAttackDamage(value)` + +- Parameters: + - value : `Integer` + New value +- Return value: Whether set attribute value for player was success. +- Return value type: `Boolean` + +
+ +#### Set Follow Range Attribute for Player + +`pl.setFollowRange(value)` + +- Parameters: + - value : `Integer` + New value +- Return value: Whether set attribute value for player was success. +- Return value type: `Boolean` + +
+ +#### Set Knockback Resistance Attribute for Player + +`pl.setKnockbackResistance(value)` + +- Parameters: + - value : `Integer` + New value (0 or 1) +- Return value: Whether set attribute value for player was success. +- Return value type: `Boolean` + +
+ +#### Set Luck Attribute for Player + +`pl.setLuck(value)` + +- Parameters: + - value : `Integer` + New value +- Return value: Whether set attribute value for player was success. +- Return value type: `Boolean` + +
+ +#### Set Movement Speed for Player + +`pl.setMovementSpeed(value)` + +- Parameters: + - value : `Integer` + New value +- Return value: Whether set attribute value for player was success. +- Return value type: `Boolean` + +
+ +#### Set Underwater Movement Speed for Player + +`pl.setUnderwaterMovementSpeed(value)` + +- Parameters: + - value : `Integer` + New value +- Return value: Whether set attribute value for player was success. +- Return value type: `Boolean` + +
+ +#### Set Lava Movement Speed for Player + +`pl.setLavaMovementSpeed(value)` + +- Parameters: + - value : `Integer` + New value +- Return value: Whether set attribute value for player was success. +- Return value type: `Boolean` + +
+ +#### Set Max Health for Player + +`pl.setMaxHealth(health)` + +- Parameters: + - health : `Integer` + Number of hearts. +- Return value: Whether set max health for player was success. +- Return value type: `Boolean` + +
+ +#### Set Hunger for Player + +`pl.setHungry(hunger)` + +- Parameters: + - hunger : `Integer` + Number of hunger. +- Return value: Whether set hunger for player was success. +- Return value type: `Boolean` + +
+ +#### Set the Specified Player on Fire + +`pl.setFire(time,isEffect)` + +- Parameters: + - time : `Integer` + Fire time, in seconds. + - isEffect : `Boolean` + Will there be a fire effect? +- Return value: Whether the player was set on fire. +- Return value type: `Boolean` + +
+ +#### Put Out The Player + +`pl.stopFire()` + +- Return value: Has been extinguished. +- Return value type: `Boolean` + +
+ +#### Scale Player + +`pl.setScale(scale)` + +- Parameters: + - scale : `Integer` + New player size +- Return value: Whether the player was scaled. +- Return value type: `Boolean` + +
+ +#### Rename Player + +`pl.rename(newname)` + +- Parameters: + - newname : `String` + Player's new name. +- Return value: WHether the rename was successful. +- Return value type: `Boolean` + +[JavaScript] +```js +//For a `Player` object pl +pl.rename("newname"); +``` + +#### Get the Block the Player Is Currently Standing On + +`pl.getBlockStandingOn()` + +- Return value: The `Block` object currently standing on. +- Return value type: `Block` + +
+ +#### Get the Player's Device Information Object + +`pl.getDevice()` + +- Return value: Device information object corresponding to the player +- Return value type: `Device` + +The device information object stores certain information about the player's device, such as device IP address, device type, network latency, etc. +For additional information about device information objects, please refer to [Device Information Objects API](/LLSEPluginDevelopment/GameAPI/Device.md) + +
+ +#### Get the Item Object in the Player’s Main Hand + +`pl.getHand()` + +- Return value: The item object in the player's main hand. +- Return value type: `Item` + +The item object obtained here is a reference. That is to say, modifying the item object returned here, or using its API, is equivalent to directly operating the corresponding item in the player's main hand. + +
+ +#### Get the Item Object of the Player’s Off-Hand + +`pl.getOffHand()` + +- Return value: The item object in the player's off-hand +- Return value type: `Item` + +The item object obtained here is a reference. That is to say, modifying the item object returned here, or using its API, is equivalent to directly operating the corresponding item in the player's off hand. + +
+ +#### Get the Container Object of the Player’s Inventory + +`pl.getInventory()` + +- Return value: The container object corresponding to the player's inventory +- Return value type: `Container` + +For more usage of container objects, please refer to [Container Object API Documentation](/LLSEPluginDevelopment/GameAPI/Container.md) + +
+ +#### Gets the Container Object for the Player’s Armor Bar + +`pl.getArmor()` + +- Return value: The container object corresponding to the player's armor bar +- Return value type: `Container` + +For more usage of container objects, please refer to [Container Object API Documentation](/LLSEPluginDevelopment/GameAPI/Container.md) + +
+ +#### Get the Container Object of the Player’s Ender Chest + +`pl.getEnderChest()` + +- Return value: The container object corresponding to the player's ender chest. +- Return value type: `Container` + +For more usage of container objects, please refer to [Container Object API Documentation](/LLSEPluginDevelopment/GameAPI/Container.md) + +
+ +#### Get the Player’s Respawn Coordinates + +`pl.getRespawnPosition()` + +- Return value: Respawn point coordinates +- Return value type: `IntPos` + +
+ +#### Modify the Player’s Respawn Coordinates + +`mc.setRespawnPosition(pos)` +`mc.setRespawnPosition(x,y,z,dimid)` + +- Parameters: + - pos : `IntPos` + Respawn coordinates (or use x, y, z, dimid to determine respawn position) +- Return value: Whether the modification was successful. +- Return value type: `Boolean` + +
+ +#### Give the Player an Item + +`pl.giveItem(item[, amount])` + +- Parameters: + - item : `Item` + The item being given. + + - amount: `Integer` + + (Optional) The number of item given. If this parameter is provided, the Count property of the item object itself will be ignored. +- Return value: Whether the item was given. +- Return value type: `Boolean` + +If the player's inventory is full, excess items will be drop. + +
+ +#### Clears All Items of the Specified Type From the Player’s Backpack + +`pl.clearItem(type[, count)` + +- Parameters: + - type : `String` + Item object type name to clear + - count : `Integer` + (Optional)Item count to be clear +- Return value: The number of items cleared +- Return value type: `Integer` + +Compares the type attribute of all items in the player's inventory, main hand, off-hand, and armor to this string. +If found, clear this item. + +
+ +#### Refresh Player Inventory, Armor Bar + +`pl.refreshItems()` + +- Return value: Whether the refresh was successful +- Return value type: `Boolean` + +After modifying the player's items, in order for the client to take effect, it is necessary to refresh all the player's items. + +
+ +#### Refresh All Chunks Loaded by the Player + +`pl.refreshChunks()` + +- Return value: Whether the refresh was successful. +- Return value type: `Boolean` + +
+ +#### Modify Player Operation Permissions + +`pl.setPermLevel(level)` + +- Parameters: + + - level : `Integer` + Target operation authority level + + | Player Permission Level | Corresponding Permission Authority | + | ----------------------- | ---------------------------------- | + | 0 | Ordinary Member Permissions | + | 1 | OP Permissions | + | 4 | OP + Console Permissions | + +- Return value: Whether the modification was successful. + +- Return value type: `Boolean` + +[JavaScript] +```js +//For a `Player` object pl +pl.setPermLevel(1); +``` + +#### Modify Player Game Mode + +`pl.setGameMode(mode)` + +- Parameters: + + - mode : `Integer` + Target game mode, `0` is survival mode, `1` is creative mode, `2` is adventure mode. `6` is spectator mode. +- Return value: Whether the modification was successful. +- Return value type: `Boolean` + +[JavaScript] +```js +//For a `Player` object pl +pl.setGameMode(1); +``` + +#### Increase Player Experience Level + +`pl.addLevel(count)` + +- Parameters: + - count : `Integer` + The number of experience levels to add. +- Return value: Whether the setting was successful. +- Return value type: `Boolean` + +[JavaScript] +```js +//For a `Player` object pl +pl.addLevel(6); +``` +#### Decreases Player Experience Level + +`pl.reduceLevel(count)` + +- Parameters: + - count : `Integer` + The number of experience levels to reduce. +- Return value: Whether the setting was successful. +- Return value type: `Boolean` + +
+ +#### Get Player Experience Level + +`pl.getLevel()` + +- Return value: The player's experience level. +- Return value type: `Integer` + +[JavaScript] +```js +//For a `Player` object pl +pl.getLevel(); +``` +[Lua] +```lua +--For a `Player` object pl +pl.getLevel() +``` +#### Set Player Experience Level + +`pl.setLevel(count)` + +- Parameters + - count : `Integer` + The number of experience levels to set. +- Return value: Whether the setting was successful. +- Return value type: `Boolean` + +
+ +#### Reset Player Experience + +`pl.resetLevel()` + +- Return value: Whether the setting was successful. +- Return value type: `Boolean` + +[JavaScript] +```js +//For a `Player` object pl +pl.resetLevel(); +``` +[Lua] +```lua +--For a `Player` object pl +pl:resetLevel() +``` + +#### Get Player Current Experience Points + +`pl.getCurrentExperience()` + +- Return value: The player's current experience points. +- Return value type: `Integer` + +
+ +#### Set Player Current Experience Points + +`pl.setCurrentExperience(count)` + +- Parameters + - count : `Integer` + The number of experience points to set. +- Return value: Whether the setting was successful. +- Return value type: `Boolean` + +
+ +#### Get Player Total Experience Points + +`pl.getTotalExperience()` + +- Return value: The player's total experience points. +- Return value type: `Integer` + +
+ +#### Set Player Total Experience Points + +`pl.getTotalExperience(count)` + +- Parameters + - count : `Integer` + The number of experience points to set. +- Return value: Whether the setting was successful. +- Return value type: `Boolean` + +
+ +#### Increase Player Experience Points + +`pl.addExperience(count)` + +- Parameters: + - count : `Integer` + The amount of experience points to give to the player. +- Return value: Whether the setting was successful. +- Return value type: `Boolean` + +[JavaScript] +```js +//For a `Player` object pl +pl.addExperience(6); +``` +[Lua] +```lua +--For a `Player` object pl +pl:addExperience(6) +``` + +#### Decreases Player Experience Points + +`pl.reduceExperience(count)` + +- Parameters: + - count : `Integer` + The number of experience points to reduce. +- Return value: Whether the setting was successful. +- Return value type: `Boolean` + +
+ +#### Get the Experience Points Needed for Players to Level Up + +`pl.getXpNeededForNextLevel()` + +- Return value: The amount of experience points required for the player to level up. +- Return value type: `Integer` + +Note that this method ignores the experience value that exceeds the level when calculating. + +[JavaScript] +```js +//For a `Player` object pl +pl.getXpNeededForNextLevel(); +``` +[Lua] +```lua +--For a `Player` object pl +pl.getXpNeededForNextLevel() +``` + +#### Send the Player to the Specified Server + +`pl.transServer(server,port)` + +- Parameters: + - server : `String` + Target server IP / domain name + + - port : `Integer` + Target server port +- Return value: Whether the transfer was successful or not. +- Return value type: `Boolean` + +[JavaScript] +```js +//For a `Player` object pl +pl.transServer("123.45.67.89",23333); +``` + +#### Crash the Player Client + +`pl.crash()` + +- Return value: Whether the execution was successful. +- Return value type: `Boolean` + +[JavaScript] +```js +//For a `Player` object pl +pl.crash(); +``` +[Lua] +```lua +--For a `Player` object pl +pl:crash() + +``` +#### Set Player Custom Sidebar + +`pl.setSidebar(title,data[,sortOrder])` + +- Parameters: + + - title : `String` + Sidebar Title + - data : `Object` + Sidebar Object Content Object + Each key-value pair in the object will be set as a row of the sidebar content. + - sortOrder : `Number` + (Optional) Sort order for sidebar content. `0` In ascending order of scores, `1` in descending order by score. Default is `1`. + +- Return value: Whether the setting was successful or not. + +- Return value type: `Boolean` + +[JavaScript] +```js +//For a `Player` object pl +pl.setSidebar("title",{"aaaa":3,"bbb":12,"cc":7}); +``` + +#### Remove Player Customization Sidebar + +`pl.removeSidebar()` + +- Return value: Whether the removal was successful. +- Return value type: `Boolean` + +[JavaScript] +```js +//For a `Player` object pl +pl.removeSidebar(); +``` + +#### Sets the Custom Boss Health Bar That the Player Sees + +`pl.setBossBar(uid,title,percent,colour)` + +- Parameters: + - uid : `Number` + Unique identifier, no conflicting duplicates! One uid for one line of bar + - title : `String` + Custom Health Bar Title + - percent : `Integer` + The percentage of health in the boss bar, the valid range is 0~100. `0` is empty boss bar, `100` is full. + - colour : `Integer` + Health bar color (default is 2 (RED)) +- Return value: Whether the setting was successful or not. +- Return value type: `Boolean` + +[JavaScript] +```js +//For a `Player` object pl +pl.setBossBar(1145141919,"Hello ~ ",80,0); +``` + +#### Remove the Player’s Custom Boss Health Bar + +`pl.removeBossBar(uid)` + +- Parameters: + - uid : `Number` + Identifier, corresponding to setBossBar! +- Return value: Whether the removal was successful. +- Return value type: `Boolean` + +[JavaScript] +```js +//For a `Player` object pl +pl.removeBossBar(1145141919); +``` + +#### Get an Online Player's NBT Object + +`pl.getNbt()` + +- Return value: Player's NBT object. +- Return value type: `NbtCompound` + +
+ +#### Write to an Online Player's NBT Object + +`pl.setNbt(nbt)` + +- Parameters: + - nbt : `NbtCompound` + NBT objects +- Return value: Whether the write was successful or not. +- Return value type: `Boolean` + +For more usage of NBT objects, please refer to [NBT Interface Documentation](/LLSEPluginDevelopment/NbtAPI/NBT.md) + +
+ +#### Get an Player's NBT Object + +`mc.getPlayerNbt(uuid)` + +- Parameters: + - uuid : `String` + Player`s UUID +- Return value: Player's NBT object. +- Return value type: `NbtCompound` + +Using this API, you can operate offline player`s nbt. + +
+ +#### Write to an Player's NBT Object + +`mc.setPlayerNbt(uuid,nbt)` + +- Parameters: + - uuid : `String` + Player`s UUID + - nbt : `NbtCompound` + NBT objects +- Return value: Whether the write was successful or not. +- Return value type: `Boolean` + +Using this API, you can operate offline player`s nbt. + +
+ +#### Write Data to Some Special Tags of an Player's NBT Object + +`mc.setPlayerNbtTags(uuid,nbt,tags)` + +- Parameters: + - uuid : `String` + Player`s UUID + - nbt : `NbtCompound` + NBT objects + - tags : `Array` + Tags need to write +- Return value: Whether the write was successful or not. +- Return value type: `Boolean` + +Using this API, you can operate offline player`s nbt. + +
+ +#### Delete an Player's NBT Object + +`mc.deletePlayerNbt(uuid)` + +- Parameters: + - uuid : `String` + Player`s UUID +- Return value: Whether the delete was successful or not. +- Return value type: `Boolean` + +Using this API, you can operate offline player`s nbt. + +
+ +#### Add a Tag for the Player + +`pl.addTag(tag)` + +- Parameters: + - tag: `String` + The tag string to be added. +- Return value: Whether the setting was successful. +- Return value type: `Boolean` + +
+ +#### Remove a Tag for a player + +`pl.removeTag(tag)` + +- Parameters: + - tag: `String` + The tag string to remove. +- Return value: Whether the removal was successful. +- Return value type: `Boolean` + +
+ +#### Check if the Player Has a Tag + +`pl.hasTag(tag)` + +- Parameters: + - tag: `String` + Tag string to check +- Return value: Whether the player has the tag. +- Return value type: `Boolean` + +
+ +#### Get a List of All Tags Player the Player Has + +`pl.getAllTags()` + +- Return value: List of all tag strings of the player. +- Return value type: `Array` + +
+ +#### Get a List of the Player’s Abilities (From the Player’s NBT) + +`pl.getAbilities()` + +- Return value: A list object of key-value pairs of all player ability information. +- Return value type: `object` + +Each item in the list of key-value pairs looks like: `"mayfly": 1` etc. +
+ +#### Get a list of the player's Attributes (from the player's NBT) + +`pl.getAttributes()` + +- Return value: An array of all property objects of the player. +- Return value type: `Array` + +Each item in the array is a key-value pair list object `Object`, and the Attributes object contains several contents such as `Base` `Current` `DefaultMax` `DefaultMin` `Max` `Min` `Name` by default. Its content looks like: +```json +{ + "Base": 0, + "Current": 0, + "DefaultMax": 1024, + "DefaultMin": -1024, + "Max": 1024, + "Min": -1024, + "Name": "minecraft:luck" +} +``` + +(Here it's displayed visually using JSON format) + +
+ +#### Get Player Sprint Status + +`pl.isSprinting()` + +- Return value: Player's sprint state +- Return value type: `Boolean` + +
+ +#### Set Player Sprint State + +`pl.setSprinting(sprinting)` + +- Parameters: + - sprinting : `Boolean` + Sprinting state. +- Return value: Whether the setting was successful. +- Return value type: `Boolean` + +
+ +#### Sending packets to the player + +`pl.sendPacket(packet)` + +- Parameters: + - packet : `Packet` + Packet +- Return value: Whether the setting was successful. +- Return value type: `Boolean` + +
+ +#### Get the player's Biome ID + +`pl.getBiomeId()` + +- Return value: Biome ID +- Return value type: `Integer` + +
+ +#### Get the player's Biome Name + +`pl.getBiomeName()` + +- Return value: Biome Name +- Return value type: `String` + +
+ +#### Set Player Ability + +`pl.setAbility(AbilityID,Value)` +- Parameters: + - AbilityID : `Integer` + Ability's ID + - Value : `Boolean` + Whether to turn on +- Return value: None +- Return value type: `Boolean` + +#### Get player's effects + +`pl.getAllEffects()` + +- Return value: effect ID which is player owned +- Return type: `Array` + +
+ +#### Add an effect for player + +`pl.addEffect(id, tick, level, showParticles)` +- Parameter: + - id : `Number` + Effect ID + - tick : `Number` + Lasting time + - level : `Number` + Effect's level + - showParticles : `Boolean` + Whether to show particles +- Return value: Whether succeed +- Return type: `Boolean` + +
+ +#### Remove an effect for player + +`pl.removeEffect(id)` +- Parameter: + - id : `Number` + Effect ID +- Return value: Whether succeed +- Return type: `Boolean` + +| Name | ID | +| --------------- | ------ | +| speed | 1 | +| slowness | 2 | +| haste | 3 | +| mining_fatigue | 4 | +| strength | 5 | +| instant_health | 6 | +| instant_damage | 7 | +| jump_boost | 8 | +| nausea | 9 | +| regeneration | 10 | +| resistance | 11 | +| fire_resistance | 12 | +| water_breathing | 13 | +| invisibility | 14 | +| blindness | 15 | +| night_vision | 16 | +| hunger | 17 | +| weakness | 18 | +| poison | 19 | +| wither | 20 | +| health_boost | 21 | +| absorption | 22 | +| saturation | 23 | +| levitation | 24 | +| fatal_poison | 25 | +| conduit_power | 26 | +| slow_falling | 27 | +| bad_omen | 28 | +| village_hero | 29 | +| darkness | 30 | \ No newline at end of file diff --git a/docs/apis/GameAPI/Player.zh.md b/docs/apis/GameAPI/Player.zh.md new file mode 100644 index 00000000..da4439e7 --- /dev/null +++ b/docs/apis/GameAPI/Player.zh.md @@ -0,0 +1,2071 @@ +## 🏃‍♂️ 玩家对象 API + +在脚本引擎中,使用「玩家对象」来操作和获取某一个玩家的相关信息。 + +### 获取一个玩家对象 + +#### 从事件或API获取 + +通过注册**事件监听**函数,获取到BDS给出的与相关事件有关的玩家对象 +详见 [事件监听文档 - EventAPI](LLSEPluginDevelopment/EventAPI/Listen.md) + +#### 从现有玩家获取 + +通过**玩家信息**手动生成玩家对象 +通过此函数来手动生成对象,注意,你要获取的玩家必须是在线状态,否则会生成失败 + +`mc.getPlayer(info)` + +- 参数: + - info : `String` + 玩家的名字或者XUID或者uniqueId +- 返回值:生成的玩家对象 +- 返回值类型:`Player` + - 如返回值为 `Null` 则表示获取玩家失败 + +#### 获取所有在线玩家 + +此函数会返回一个玩家对象的数组,其中每个对象都对应了一个服务器中的玩家 + +`mc.getOnlinePlayers()` + +- 返回值:在线的玩家对象列表 +- 返回值类型:`Array` + +> 注意:不要**长期保存**一个玩家对象 +> 当玩家退出服务器时,对应的玩家对象将同时释放。因此,如果有长期操作某个玩家的需要,请通过上述途径获取实时的玩家对象 + +
+ +### 玩家对象 - 属性 + +每一个玩家对象都包含一些固定的对象属性。对于某个特定的玩家对象`pl`,有以下这些属性 + +| 属性 | 含义 | 类型 | +| ------------------------ | --------------------------------- | ---------------- | +| pl.name | 玩家名 | `String` | +| pl.pos | 玩家所在坐标 | `FloatPos` | +| pl.feetPos | 玩家腿部所在坐标 | `FloatPos` | +| pl.blockPos | 玩家所在的方块坐标 | `IntPos` | +| pl.lastDeathPos | 玩家上次死亡的坐标 | `IntPos` | +| pl.realName | 玩家的真实名字 | `String` | +| pl.xuid | 玩家XUID字符串 | `String` | +| pl.uuid | 玩家Uuid字符串 | `String` | +| pl.permLevel | 玩家的操作权限等级(0 - 4) | `Integer` | +| pl.gameMode | 玩家的游戏模式(0 - 2, 6) | `Integer` | +| pl.canFly | 玩家是否可以飞行 | `Boolean` | +| pl.canSleep | 玩家是否可以睡觉 | `Boolean` | +| pl.canBeSeenOnMap | 玩家是否可以在地图上看到 | `Boolean` | +| pl.canFreeze | 玩家是否可以冻结 | `Boolean` | +| pl.canSeeDaylight | 玩家是否能看到日光 | `Boolean` | +| pl.canShowNameTag | 玩家是否可以显示姓名标签 | `Boolean` | +| pl.canStartSleepInBed | 玩家是否可以开始在床上睡觉 | `Boolean` | +| pl.canPickupItems | 玩家是否可以拾取物品 | `Boolean` | +| pl.maxHealth | 玩家最大生命值 | `Integer` | +| pl.health | 玩家当前生命值 | `Integer` | +| pl.inAir | 玩家当前是否悬空 | `Boolean` | +| pl.inWater | 玩家当前是否在水中 | `Boolean` | +| pl.inLava | 玩家是否在熔岩中 | `Boolean` | +| pl.inRain | 玩家是否下雨 | `Boolean` | +| pl.inSnow | 玩家是否在雪中 | `Boolean` | +| pl.inWall | 玩家是否在墙上 | `Boolean` | +| pl.inWaterOrRain | 玩家是否在水中或雨中 | `Boolean` | +| pl.inWorld | 玩家是否在世界 | `Boolean` | +| pl.inClouds | 玩家是否在云端 | `Boolean` | +| pl.speed | 玩家当前速度 | `Float` | +| pl.direction | 玩家当前朝向 | `DirectionAngle` | +| pl.uniqueId | 玩家(实体的)唯一标识符 | `String` | +| pl.langCode | 玩家设置的语言的标识符(形如zh_CN) | `String` | +| pl.isLoading | 玩家是否正在加载 | `Boolean` | +| pl.isInvisible | 玩家是否隐身中 | `Boolean` | +| pl.isInsidePortal | 玩家在传送门中 | `Boolean` | +| pl.isHurt | 玩家是否受伤 | `Boolean` | +| pl.isTrusting | 未知 | `Boolean` | +| pl.isTouchingDamageBlock | 玩家是否在能造成伤害的方块上 | `Boolean` | +| pl.isHungry | 玩家是否饿了 | `Boolean` | +| pl.isOnFire | 玩家是否着火 | `Boolean` | +| pl.isOnGround | 玩家是否在地上 | `Boolean` | +| pl.isOnHotBlock | 玩家是否在高温方块上(岩浆等) | `Boolean` | +| pl.isTrading | 玩家在交易 | `Boolean` | +| pl.isAdventure | 玩家是否是冒险模式 | `Boolean` | +| pl.isGliding | 玩家在滑行 | `Boolean` | +| pl.isSurvival | 玩家是否是生存模式 | `Boolean` | +| pl.isSpectator | 玩家是否是观众模式 | `Boolean` | +| pl.isRiding | 玩家是否在骑行 | `Boolean` | +| pl.isDancing | 玩家在跳舞? | `Boolean` | +| pl.isCreative | 玩家是否是创造模式 | `Boolean` | +| pl.isFlying | 玩家是否在飞行 | `Boolean` | +| pl.isSleeping | 玩家是否正在睡觉 | `Boolean` | +| pl.isMoving | 玩家是否正在移动 | `Boolean` | +| pl.isSneaking | 玩家是否正在潜行 | `Boolean` | + +这些对象属性都是只读的,无法被修改。其中: + +- **坐标** 和 **腿部坐标**:玩家为两格高,`pos`为玩家视角高度的坐标,`feetPos`为游戏内显示的方块坐标 +- **玩家游戏模式** 属性的取值为:`0` 代表生存模式,`1` 代表创造模式,`2` 代表冒险模式,`3` 代表旁观者模式 +- **玩家真实名字** 属性储存的字符串可以被认为是可靠的,他们不会被改名而变动 +- **玩家设备IP地址** 属性储存了玩家的设备IP以及端口号,格式类似`12.34.567.89:1111` +- **玩家当前朝向** 属性的详细解释见 [基础游戏接口文档](LLSEPluginDevelopment/GameAPI/Basic.md) +- **操作权限等级** 属性的对照表如下: + +| 操作权限等级 | 对应操作权限 | +| ------------ | --------------- | +| 0 | 普通成员权限 | +| 1 | OP权限 | +| 4 | OP + 控制台权限 | + +
+ +### 玩家对象 - 函数 + +每一个玩家对象都包含一些可以执行的成员函数(成员方法)。对于某个特定的玩家对象`pl`,可以通过以下这些函数对这个玩家进行一些操作 + +#### 判断玩家是否为OP + +`pl.isOP()` + +- 返回值:玩家是否为OP +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + var open = pl.isOP(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + open = pl:isOP() + ``` + +#### 断开玩家连接 + +`pl.kick([msg])` +`pl.disconnect([msg])` + +- 参数: + - msg : `String` + (可选参数)被踢出玩家出显示的断开原因。 + 如果不传入,默认为“正在从服务器断开连接” +- 返回值:是否成功断开连接 +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.kick(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:kick() + ``` + +#### 发送一个文本消息给玩家 + +`pl.tell(msg[,type])` +`pl.sendText(msg[,type])` + +- 参数: + + - msg : `String` + 待发送的文本 + + - type : `Integer` + (可选参数)发送的文本消息类型,默认为0 + + | type参数 | 消息类型 | + | -------- | ----------------------- | + | 0 | 普通消息(Raw) | + | 1 | 聊天消息(Chat) | + | 4 | 音乐盒消息(Popup) | + | 5 | 物品栏上方的消息(Tip) | + | 9 | JSON格式消息(JSON) | + +- 返回值:是否成功发送 + +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + //对于一个玩家对象pl + pl.tell("Welcome back ~ ", 5); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:tell("Welcome back ~ ", 5) + ``` + +#### 设置玩家显示标题 + +`pl.setTitle(content[,type[,fadeInTime,stayTime,fadeOutTime]])` + +- 参数: + + - content : `String` + 欲设置标题内容 + + - type : `Integer` + (可选参数)设置的标题类型,默认为2 + + | type参数 | 消息类型 | + | -------- | -------------------------------------- | + | 0 | 清空(Clear) | + | 1 | 重设(Reset) | + | 2 | 设置主标题(SetTitle) | + | 3 | 设置副标题(SetSubTitle) | + | 4 | 设置Actionbar(SetActionBar) | + | 5 | 设置显示时间(SetDurations) | + | 6 | Json型主标题(TitleTextObject) | + | 7 | Json型副标题(SubtitleTextObject) | + | 8 | Json型Actionbar(ActionbarTextObject) | + + - fadeInTime : `Integer` + (可选参数)淡入时间,单位为 `Tick` ,默认为10 + + - stayTime: `Integer` + + (可选参数)停留时间,单位为 `Tick` ,默认为70 + + - fadeOutTime:`Integer` + + (可选参数)淡出时间,单位为 `Tick`,默认为20 + +- 返回值:是否成功发送 + +- 返回值类型:`Boolean` + +#### 广播一个文本消息给所有玩家 + +`mc.broadcast(msg[,type])` + +- 参数: + + - msg : `String` + 待发送的文本 + + - type : `Integer` + (可选参数)发送的文本消息类型,默认为0 + + | type参数 | 消息类型 | + | -------- | ----------------------- | + | 0 | 普通消息(Raw) | + | 1 | 聊天消息(Chat) | + | 5 | 物品栏上方的消息(Tip) | + | 9 | JSON格式消息(JSON) | + +- 返回值:是否成功发送 + +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + mc.broadcast("Hello everyone ~ "); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + mc.broadcast("Hello everyone ~ ") + ``` + +#### 在屏幕上方显示消息(类似于成就完成) + +`pl.sendToast(title,message)` + +- 参数: + + - title : `String` + 待发送的标题 + + - message : `String` + 待发送的文本 + +- 返回值:是否成功发送 + +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.sendToast("Hello", "everyone ~"); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:sendToast("Hello", "everyone ~") + ``` + +#### 以某个玩家身份执行一条命令 + +`pl.runcmd(cmd)` + +- 参数: + - cmd : `String` + 待执行的命令 +- 返回值:是否执行成功 +- 返回值类型: `Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.runcmd("tp ~ ~50 ~"); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:runcmd("tp ~ ~50 ~") + ``` + +#### 以某个玩家身份说话 + +`pl.talkAs(text)` + +- 参数: + - text : `String` + 模拟说话内容 +- 返回值:是否执行成功 +- 返回值类型: `Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.talkAs("Hello everyone ~ "); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:talkAs("Hello everyone ~ ") + ``` + +#### 获取玩家到坐标的距离 + +`pl.distanceTo(pos)` +`pl.distanceToSqr(pos)` + +- 参数: + - pos : `Entity` / `Player` / `IntPos` / `FloatPos` + 目标位置 +- 返回值: 到坐标的距离(方块) +- 返回值类型: `Number` + +> **注意** 若玩家的坐标与目标的坐标不在同一维度,将返回整数最大值。 + +#### 以某个玩家身份向某玩家说话 + +`pl.talkAs(target,text)` + +- 参数: + - target : `Player` + 模拟说话对象 + - text : `String` + 模拟说话内容 +- 返回值:是否执行成功 +- 返回值类型: `Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.talkAs(anotherpl, "Hello ~ "); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:talkAs(anotherpl, "Hello everyone ~ ") + ``` + +#### 传送玩家至指定位置 + +`pl.teleport(pos[,rot])` +`pl.teleport(x,y,z,dimid[,rot])` + +- 参数: + - pos: `IntPos `/ `FloatPos` + 目标位置坐标 (或者使用x, y, z, dimid来确定玩家位置) + + - rot: `DirectionAngle` + + (可选参数)传送后玩家的朝向,若缺省则与传送前朝向相同 + +- 返回值:是否成功传送 + +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + //对于一个玩家对象pl + pl.teleport(pos); + ``` + - Lua + ```lua + pl:teleport(pos) + ``` + +#### 杀死玩家 + +`pl.kill()` + +- 返回值:是否成功执行 +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.kill(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:kill() + ``` + +#### 对玩家造成伤害 + +`pl.hurt(damage)` + +- 参数: + - damage : `Integer` + 对玩家造成的伤害数值 +- 返回值:是否造成伤害 +- 返回值类型:`Boolean` + +注意,此处造成的伤害为真实伤害,无法被盔甲等保护装备减免 + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.hurt(20); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:hurt(20) + ``` + +#### 治疗玩家 + +`pl.heal(health)` + +- 参数: + - int : `Integer` + 治疗的心数 +- 返回值: 治疗是否成功 +- 返回值类型: `Boolean` + + +#### 设置玩家的生命值 + +`pl.setHealth(health)` + +- 参数: + - health : `Integer` + 生命值数 +- 返回值: 是否成功 +- 返回值类型: `Boolean` + +#### 为玩家设置伤害吸收属性 + +`pl.setAbsorption(value)` + +- 参数: + - value : `Integer` + 新的值 +- 返回值: 为玩家设置属性值是否成功 +- 返回值类型: `Boolean` + +
+ +#### 为玩家设置攻击伤害属性 + +`pl.setAttackDamage(value)` + +- 参数: + - value : `Integer` + 新的值 +- 返回值: 为玩家设置属性值是否成功 +- 返回值类型: `Boolean` + +
+ +#### 为玩家设置最大攻击伤害属性 + +`pl.setMaxAttackDamage(value)` + +- 参数: + - value : `Integer` + 新的值 +- 返回值: 为玩家设置属性值是否成功 +- 返回值类型: `Boolean` + +
+ +#### 为玩家设置跟随范围 + +`pl.setFollowRange(value)` + +- 参数: + - value : `Integer` + 新的值 +- 返回值: 为玩家设置属性值是否成功 +- 返回值类型: `Boolean` + +
+ +#### 为玩家设置击退抵抗属性 + +`pl.setKnockbackResistance(value)` + +- 参数: + - value : `Integer` + 新的值 (0 or 1) +- 返回值: 为玩家设置属性值是否成功 +- 返回值类型: `Boolean` + +
+ +#### 为玩家设置幸运属性 + +`pl.setLuck(value)` + +- 参数: + - value : `Integer` + 新的值 +- 返回值: 为玩家设置属性值是否成功 +- 返回值类型: `Boolean` + +
+ +#### 为玩家设置移动速度属性 + +`pl.setMovementSpeed(value)` + +- 参数: + - value : `Integer` + 新的值 +- 返回值: 为玩家设置属性值是否成功 +- 返回值类型: `Boolean` + +
+ +#### 为玩家设置水下移动速度属性 + +`pl.setUnderwaterMovementSpeed(value)` + +- 参数: + - value : `Integer` + 新的值 +- 返回值: 为玩家设置属性值是否成功 +- 返回值类型: `Boolean` + +
+ +#### 为玩家设置岩浆上移动速度属性 + +`pl.setLavaMovementSpeed(value)` + +- 参数: + - value : `Integer` + 新的值 +- 返回值: 为玩家设置属性值是否成功 +- 返回值类型: `Boolean` + +
+ + +#### 设置玩家最大生命值 + +`pl.setMaxHealth(health)` + +- 参数: + - health : `Integer` + 生命值数 +- 返回值: 是否成功 +- 返回值类型: `Boolean` + + +#### 设置玩家饥饿值 + +`pl.setHungry(hunger)` + +- 参数: + - hunger : `Integer` + 饥饿值数 +- 返回值: 是否成功 +- 返回值类型: `Boolean` + + +#### 使指定玩家着火 + +`pl.setFire(time,isEffect)` + +- 参数: + - time : `Integer` + 着火时长,单位秒 + - isEffect : `Boolean` + 会不会有火的效果 +- 返回值:是否成功着火 +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.setFire(20,true); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:setFire(20,true) + ``` + +#### 熄灭玩家 + +`pl.stopFire()` + +- 返回值: 是否已被熄灭 +- 返回值类型: `Boolean` + +#### 缩放玩家 + +`pl.setScale(scale)` + +- 参数: + - scale : `Integer` + 新的玩家体积 +- 返回值: 玩家是否成功地被缩放 +- 返回值类型: `Boolean` + +#### 重命名玩家 + +`pl.rename(newname)` + +- 参数: + - newname : `String` + 玩家的新名字 +- 返回值:是否重命名成功 +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.rename("Steve"); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:rename("Steve") + ``` + +#### 获取玩家当前站立所在的方块 + +`pl.getBlockStandingOn()` + +- 返回值:当前站立在的方块对象 +- 返回值类型:`Block` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + var bl = pl.getBlockStandingOn(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + bl = pl:getBlockStandingOn() + ``` + +#### 获取玩家对应的设备信息对象 + +`pl.getDevice()` + +- 返回值:玩家对应的设备信息对象 +- 返回值类型:`Device` + +设备信息对象储存了与玩家设备有关的某些信息,如设备IP地址、设备类型、网络延迟等信息。 +关于设备信息对象的其他信息请参考 [设备信息对象 API](LLSEPluginDevelopment/GameAPI/Device.md) + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + var dv = pl.getDevice(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + dv = pl:getDevice() + ``` + +#### 获取玩家主手中的物品对象 + +`pl.getHand()` + +- 返回值:玩家主手中的物品对象 +- 返回值类型:`Item` + +此处获取的物品对象为引用。也就是说,修改此处返回的物品对象,或使用其API,就相当于直接操作玩家主手中对应的物品 + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + var it = pl.getHand(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + it = pl:getHand() + ``` + +#### 获取玩家副手的物品对象 + +`pl.getOffHand()` + +- 返回值:玩家副手中的物品对象 +- 返回值类型:`Item` + +此处获取的物品对象为引用。也就是说,修改此处返回的物品对象,或使用其API,就相当于直接操作玩家副手中对应的物品 + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + var it = pl.getOffHand(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + it = pl:getOffHand() + ``` + +#### 获取玩家物品栏的容器对象 + +`pl.getInventory()` + +- 返回值:玩家物品栏对应的容器对象 +- 返回值类型:`Container` + +关于容器对象的更多使用,请参考 [容器对象 API文档](LLSEPluginDevelopment/GameAPI/Container.md) + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + var ct = pl.getInventory(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + ct = pl:getInventory() + ``` + +#### 获取玩家盔甲栏的容器对象 + +`pl.getArmor()` + +- 返回值:玩家盔甲栏对应的容器对象 +- 返回值类型:`Container` + +关于容器对象的更多使用,请参考 [容器对象 API文档](LLSEPluginDevelopment/GameAPI/Container.md) + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + var ct = pl.getArmor(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + ct = pl:getArmor() + ``` + +#### 获取玩家末影箱的容器对象 + +`pl.getEnderChest()` + +- 返回值:玩家末影箱对应的容器对象 +- 返回值类型:`Container` + +关于容器对象的更多使用,请参考 [容器对象 API文档](LLSEPluginDevelopment/GameAPI/Container.md) + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + var ct = pl.getEnderChest(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + ct = pl:getEnderChest() + ``` + +#### 获取玩家的重生坐标 + +`pl.getRespawnPosition()` + +- 返回值:重生点坐标 +- 返回值类型:`IntPos` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + var pos = pl.getRespawnPosition(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pos = pl:getRespawnPosition() + ``` + +#### 修改玩家的重生坐标 + +`mc.setRespawnPosition(pos)` +`mc.setRespawnPosition(x,y,z,dimid)` + +- 参数: + - pos : `IntPos` + 重生坐标(或者使用x, y, z, dimid来确定重生位置) +- 返回值:是否成功修改 +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + mc.setRespawnPosition(pos); + ``` + - Lua + ```lua + mc.setRespawnPosition(pos) + ``` + +#### 给予玩家一个物品 + +`pl.giveItem(item[, amount])` + +- 参数: + - item : `Item` + 给予的物品对象 + + - amount: `Integer` + + (可选参数)给予物品对象的数量,若提供此参数则物品对象自身的Count属性将被忽略 +- 返回值:是否成功给予 +- 返回值类型:`Boolean` + +如果玩家物品栏已满,将抛出多余物品 + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.giveItem(item); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:giveItem(item) + ``` + +#### 清除玩家背包中所有指定类型的物品 + +`pl.clearItem(type[, count])` + +- 参数: + - type : `String` + 要清除的物品对象类型名 + - count : `Integer` + (可选参数)要清除的物品数量 +- 返回值:清除的物品个数 +- 返回值类型:`Integer` + +将玩家物品栏、主手、副手、盔甲栏中所有物品的type属性与此字符串进行比较 +如果相等,则清除此物品 + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.clearItem("minecraft:dirt"); + pl.clearItem("minecraft:dirt", 114514); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:clearItem("minecraft:dirt") + pl:clearItem("minecraft:dirt", 1919) + ``` + +#### 刷新玩家物品栏、盔甲栏 + +`pl.refreshItems()` + +- 返回值:是否成功刷新 +- 返回值类型:`Boolean` + +在修改玩家物品之后,为了促使客户端生效,需要刷新玩家所有的物品 + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.refreshItems(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:refreshItems() + ``` + +#### 刷新玩家加载的所有区块 + +`pl.refreshChunks()` + +- 返回值:是否成功刷新 +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.refreshChunks(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:refreshChunks() + ``` + +#### 修改玩家操作权限 + +`pl.setPermLevel(level)` + +- 参数: + + - level : `Integer` + 目标操作权限等级 + + | 操作权限等级 | 对应操作权限 | + | ------------ | --------------- | + | 0 | 普通成员权限 | + | 1 | OP权限 | + | 4 | OP + 控制台权限 | + +- 返回值:是否成功修改 + +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.setPermLevel(0); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:setPermLevel(0) + ``` + +#### 修改玩家游戏模式 + +`pl.setGameMode(mode)` + +- 参数: + + - mode : `Integer` + 目标游戏模式,0为生存模式,1为创造模式,2为冒险模式, 3为观察者模式 + +- 返回值:是否成功修改 + +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.setGameMode(0); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:setGameMode(0) + ``` + +#### 提高玩家经验等级 + +`pl.addLevel(count)` + +- 参数: + - count : `Integer` + 要提高的经验等级 +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.addLevel(1); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:addLevel(1) + ``` + +#### 降低玩家经验等级 + +`pl.reduceLevel(count)` + +- 参数: + - count : `Integer` + 要降低的经验等级 +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.reduceLevel(1); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:reduceLevel(1) + ``` + +#### 获取玩家经验等级 + +`pl.getLevel()` + +- 返回值:玩家的经验等级 +- 返回值类型:`Integer` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + var lv = pl.getLevel(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + lv = pl:getLevel() + ``` + +#### 设置玩家经验等级 + +`pl.setLevel(count)` + +- 参数: + - count : `Integer` + 要设置的经验等级 +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.setLevel(1); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:setLevel(1) + ``` + +#### 重置玩家经验 + +`pl.resetLevel()` + +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.resetLevel(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:resetLevel() + ``` + +#### 获取玩家当前经验值 + +`pl.getCurrentExperience()` + +- 返回值:玩家当前经验值 +- 返回值类型:`Integer` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.getCurrentExperience(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:getCurrentExperience() + ``` + +#### 设置玩家当前经验值 + +`pl.setCurrentExperience(count)` + +- 参数: + - count : `Integer` + 要设置的经验值 +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.setCurrentExperience(1); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:setCurrentExperience(1) + ``` + +#### 获取玩家总经验值 + +`pl.getTotalExperience()` + +- 返回值:玩家总经验值 +- 返回值类型:`Integer` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + var xp = pl.getTotalExperience(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + xp = pl:getTotalExperience() + ``` + +#### 设置玩家总经验值 + +`pl.setTotalExperience(count)` + +- 参数: + - count : `Integer` + 要设置的经验值 +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.setTotalExperience(1); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:setTotalExperience(1) + ``` + +#### 提高玩家经验值 + +`pl.addExperience(count)` + +- 参数: + - count : `Integer` + 要提高的经验值 +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.addExperience(1); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:addExperience(1) + ``` + +#### 降低玩家经验值 + +`pl.reduceExperience(count)` + +- 参数: + - count : `Integer` + 要降低的经验值 +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.reduceExperience(1); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:reduceExperience(1) + ``` + +#### 获取玩家升级所需的经验值 + +`pl.getXpNeededForNextLevel()` + +- 返回值:玩家升级所需的经验值 +- 返回值类型:`Integer` + +注意,此方法在计算时会忽略当前经验值 + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + var ndxp = pl.getXpNeededForNextLevel(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + ndxp = pl:getXpNeededForNextLevel() + ``` + +#### 传送玩家至指定服务器 + +`pl.transServer(server,port)` + +- 参数: + - server : `String` + 目标服务器IP / 域名 + + - port : `Integer` + 目标服务器端口 +- 返回值:是否成功传送 +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.transServer("123.45.67.89", 23333); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:transServer("123.45.67.89", 23333) + ``` + +#### 使玩家客户端崩溃 + +`pl.crash()` + +- 返回值:是否成功执行 +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.crash(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:crash() + ``` + +#### 设置玩家自定义侧边栏 + +`pl.setSidebar(title,data[,sortOrder])` + +- 参数: + + - title : `String` + 侧边栏标题 + - data : `Object` + 侧边栏对象内容对象 + 对象中的每个键 - 值对将被设置为侧边栏内容的一行 + - sortOrder : `Number` + (可选参数)侧边栏内容的排序顺序。`0`为按分数升序,`1`为按分数降序。默认值为`1` + +- 返回值:是否成功设置 + +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.setSidebar("title", { + aaaa: 3, + bbb: 12, + cc: 7, + }); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:setSidebar("title", { + "aaaa" = 3, + "bbb" = 12, + "cc" = 7 + }) + ``` + +#### 移除玩家自定义侧边栏 + +`pl.removeSidebar()` + +- 返回值:是否成功移除 +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.removeSidebar(); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:removeSidebar() + ``` + +#### 设置玩家看到的自定义Boss血条 + +`pl.setBossBar(uid,title,percent,colour)` + +- 参数: + - uid : `Number` + 唯一标识符,不可冲突重复!一个uid对于一行bar + - title : `String` + 自定义血条标题 + - percent : `Integer` + 血条中的血量百分比,有效范围为0~100。0为空血条,100为满 + - colour : `Integer` + 血条颜色(默认值为2(RED)) +- 返回值:是否成功设置 +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.setBossBar(1145141919, "Hello ~ ", 80, 0); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:setBossBar(1145141919, "Hello ~ ", 80, 0) + ``` + +#### 移除玩家的自定义的指定Boss血条 + +`pl.removeBossBar(uid)` +- 参数: + - uid : `Number` + 标识符,与setBossBar对应! + +- 返回值:是否成功移除 +- 返回值类型:`Boolean` + +- 示例: + - JavaScript + ```js + // 对于一个玩家对象pl + pl.removeBossBar(1145141919); + ``` + - Lua + ```lua + -- 对于一个玩家对象pl + pl:removeBossBar(1145141919) + ``` + +#### 获取在线玩家对应的NBT对象 + +`pl.getNbt()` + +- 返回值:玩家的NBT对象 +- 返回值类型:`NbtCompound` + +
+ +#### 写入在线玩家对应的NBT对象 + +`pl.setNbt(nbt)` + +- 参数: + - nbt : `NbtCompound` + NBT对象 +- 返回值:是否成功写入 +- 返回值类型:`Boolean` + +关于NBT对象的更多使用,请参考 [NBT接口文档](LLSEPluginDevelopment/NbtAPI/NBT.md) + +
+ +#### 获取玩家对应的NBT对象 + +`mc.getPlayerNbt(uuid)` + +- 参数: + - uuid : `String` + 玩家的UUID +- 返回值:玩家的NBT对象 +- 返回值类型:`NbtCompound` + +此API的好处是可以获取到离线玩家NBT,无需玩家在线,无需玩家对象。 + +
+ +#### 写入玩家对应的NBT对象 + +`mc.setPlayerNbt(uuid,nbt)` + +- 参数: + - uuid : `String` + 玩家的UUID + - nbt : `NbtCompound` + NBT对象 +- 返回值:是否成功写入 +- 返回值类型:`Boolean` + +此API的好处是可以操作离线玩家NBT,无需玩家在线,无需玩家对象。 + +
+ +#### 覆盖玩家对应的NBT对象的特定NbtTag + +`mc.setPlayerNbtTags(uuid,nbt,tags)` + +- 参数: + - uuid : `String` + 玩家的UUID + - nbt : `NbtCompound` + NBT对象 + - tags : `Array` + 需要覆盖的NbtTag (String) +- 返回值:是否成功覆盖对应的Tag +- 返回值类型:`Boolean` + +此API的好处是可以操作离线玩家NBT,无需玩家在线,无需玩家对象。 + +
+ +#### 从存档中删除玩家对应的NBT对象的全部内容 + +`mc.deletePlayerNbt(uuid)` + +- 参数: + - uuid : `String` + 玩家的UUID +- 返回值:是否删除成功 +- 返回值类型:`Boolean` + +此API的好处是可以操作离线玩家NBT,无需玩家在线,无需玩家对象。 + +
+ +#### 为玩家增加一个Tag + +`pl.addTag(tag)` + +- 参数: + - tag: `String` + 要增加的tag字符串 +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +
+ +#### 为玩家移除一个Tag + +`pl.removeTag(tag)` + +- 参数: + - tag: `String` + 要移除的tag字符串 +- 返回值:是否移除成功 +- 返回值类型:`Boolean` + +
+ +#### 检查玩家是否拥有某个Tag + +`pl.hasTag(tag)` + +- 参数: + - tag: `String` + 要检查的tag字符串 +- 返回值:是否拥有这个Tag +- 返回值类型:`Boolean` + +
+ +#### 获取玩家拥有的所有Tag列表 + +`pl.getAllTags()` + +- 返回值:玩家所有的 tag 字符串列表 +- 返回值类型:`Array` + +
+ +#### 获取玩家的Abilities能力列表(来自玩家NBT) + +`pl.getAbilities()` + +- 返回值:玩家所有能力信息的键 - 值对列表对象 +- 返回值类型:`object` + +键 - 值对列表中的每一项形如:`"mayfly": 1` 等等 + +
+ +#### 获取玩家的Attributes属性列表(来自玩家NBT) + +`pl.getAttributes()` + +- 返回值:玩家所有属性对象的数组 +- 返回值类型:`Array` + +数组中的每一项为一个键 - 值对列表对象`Object`,Attributes对象默认含有`Base` `Current` `DefaultMax` `DefaultMin` `Max` `Min` `Name` 等几种内容 。其内容形如: + +```js +{ + Base: 0, + Current: 0, + DefaultMax: 1024, + DefaultMin: -1024, + Max: 1024, + Min: -1024, + Name: "minecraft:luck" +} +``` + +
+ +#### 获取玩家疾跑状态 + +`pl.isSprinting()` + +- 返回值:玩家疾跑状态 +- 返回值类型:`Boolean` + +
+ +#### 设置玩家疾跑状态 + +`pl.setSprinting(sprinting)` + +- 参数: + - sprinting : `Boolean` + 是否为疾跑状态 +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +
+ +#### 获取视线方向实体 + +`pl.getEntityFromViewVector([maxDistance])` + +- 参数: + - maxDistance : `Float` + 查找最大距离 +- 返回值:视线方向实体,如果获取失败,返回 `Null` +- 返回值类型:`Entity?` + +
+ +#### 获取视线方向方块 + +`pl.getBlockFromViewVector([includeLiquid,solidOnly,maxDistance,fullOnly])` + +- 参数: + - includeLiquid : `Boolean` + 是否包含液态方块 + - solidOnly : `Boolean` + 是否仅允许 `Solid` 类型的方块 + - maxDistance : `Float` + 查找最大距离 + - fullOnly : `Boolean` + 是否仅允许完整方块 +- 返回值:视线方向方块,如果获取失败,返回 `Null` +- 返回值类型:`Block?` + +
+ +#### 向玩家发送数据包 + +`pl.sendPacket(packet)` + +- 参数: + - packet : `Packet` + 数据包 +- 返回值:是否成功,如果pl不存在,返回Null +- 返回值类型:`Bool` + +
+ +#### 获取玩家所在群系ID + +`pl.getBiomeId()` + +- 返回值:群系ID +- 返回值类型:`Integer` + +
+ +#### 获取玩家所在群系名称 + +`pl.getBiomeName()` + +- 返回值:群系名称 +- 返回值类型:`String` + +
+ +#### 设置玩家Ability属性 + +`pl.setAbility(AbilityID,value)` +- 参数: + - AbilityID : `Integer` + Ability的ID + - value : `Boolean` + 是否开启 +- 返回值:无作用 +- 返回值类型:`Boolean` + +
+ +#### 获取玩家全部药水效果 + +`pl.getAllEffects()` + +- 返回值:玩家所有的药水效果id(见下表) +- 返回值类型:`Array` + +
+ +#### 为玩家添加一个药水效果 + +`pl.addEffect(id, tick, level, showParticles)` +- 参数: + - id : `Number` + 药水效果的id(见下表) + - tick : `Number` + 持续时间 + - level : `Number` + 等级 + - showParticles : `Boolean` + 是否显示粒子 +- 返回值:操作是否成功 +- 返回值类型:`Boolean` + +
+ +#### 为玩家移除一个药水效果 + +`pl.removeEffect(id)` +- 参数: + - id : `Number` + 药水效果的id(见下表) +- 返回值:操作是否成功 +- 返回值类型:`Boolean` + +| 效果 | 名称 | 数字id | +| ------------ | --------------- | ------ | +| 迅捷 | speed | 1 | +| 缓慢 | slowness | 2 | +| 急迫 | haste | 3 | +| 挖掘疲劳 | mining_fatigue | 4 | +| 力量 | strength | 5 | +| 瞬间治疗 | instant_health | 6 | +| 瞬间伤害 | instant_damage | 7 | +| 跳跃提升 | jump_boost | 8 | +| 反胃 | nausea | 9 | +| 生命恢复 | regeneration | 10 | +| 抗性提升 | resistance | 11 | +| 抗火 | fire_resistance | 12 | +| 水下呼吸 | water_breathing | 13 | +| 隐身 | invisibility | 14 | +| 失明 | blindness | 15 | +| 夜视 | night_vision | 16 | +| 饥饿 | hunger | 17 | +| 虚弱 | weakness | 18 | +| 中毒 | poison | 19 | +| 凋零 | wither | 20 | +| 生命提升 | health_boost | 21 | +| 伤害吸收 | absorption | 22 | +| 饱和 | saturation | 23 | +| 飘浮 | levitation | 24 | +| 中毒(致命) | fatal_poison | 25 | +| 潮涌能量 | conduit_power | 26 | +| 缓降 | slow_falling | 27 | +| 不祥之兆 | bad_omen | 28 | +| 村庄英雄 | village_hero | 29 | +| 黑暗 | darkness | 30 | + +
+ +#### 判断是否为模拟玩家 + +`pl.isSimulatedPlayer()` + +- 返回值:是否为模拟玩家 +- 返回值类型:`Boolean` + +
+ +## 模拟玩家(由于与玩家API重合过多,未生成新的模拟玩家类) + +### 创建一个模拟玩家 + +`mc.spawnSimulatedPlayer(name,pos)` +`mc.spawnSimulatedPlayer(name,x,y,z,dimid)` + +- 参数: + - name : `String` + 模拟玩家名称 + - pos : `IntPos `/ `FloatPos` + 生成生物的位置的坐标对象(或者使用x, y, z, dimid来确定生成位置) +- 返回值:生成的(模拟)玩家对象 +- 返回值类型:`Player` + - 如返回值为 `Null` 则表示生成失败 + +### 模拟玩家 - 函数 +每一个模拟玩家对象都包含一些可以执行的成员函数(成员方法)。对于某个特定的模拟玩家对象`sp`,可以通过以下这些函数对这个模拟玩家进行一些操作 + + +#### 模拟攻击 + +`sp.simulateAttack([target])` + +- 参数: + + - target : `Entity` + (可选参数)攻击目标,默认为视线方向上的实体 + +- 返回值:是否成功模拟操作 +- 返回值类型:`Boolean` + +参考:[mojang-gametest docs](https://docs.microsoft.com/zh-cn/minecraft/creator/scriptapi/mojang-gametest/simulatedplayer#attack) + + +#### 模拟破坏 + +`sp.simulateDestroy([pos,face])` +`sp.simulateDestroy([block,face])` +- 参数: + + - pos :`IntPos` + (可选参数)要破坏的方块的坐标,默认为视线方向上的方块 + - block :`Block` + (可选参数)要破坏的方块,默认为视线方向上的方块 + - face :`Integer` + (可选参数)从哪面破坏, + +- 返回值:是否成功模拟操作 +- 返回值类型:`Boolean` + +参考:[mojang-gametest docs](https://docs.microsoft.com/zh-cn/minecraft/creator/scriptapi/mojang-gametest/simulatedplayer#breakblock) + + +#### 模拟断开连接 + +`sp.simulateDisconnect()` + +- 返回值:是否成功模拟操作 +- 返回值类型:`Boolean` + +#### 模拟交互 +`sp.simulateInteract([target])` +`sp.simulateInteract([pos,face])` +`sp.simulateInteract([block,face])` + +- 参数: + + - target : `Entity` + (可选参数)模拟交互目标,默认为视线方向上的方块或实体 + - pos :`IntPos` + (可选参数)模拟交互目标,默认为视线方向上的方块或实体 + - block :`Block` + (可选参数)模拟交互目标,默认为视线方向上的方块或实体 + - face :`Number` + (可选参数)模拟交互目标方块的面 + +- 返回值:是否成功模拟操作 +- 返回值类型:`Boolean` + +参考:[mojang-gametest docs](https://docs.microsoft.com/zh-cn/minecraft/creator/scriptapi/mojang-gametest/simulatedplayer#interact) + + +#### 模拟跳跃 + +`sp.simulateJump()` + +- 返回值:是否成功模拟操作 +- 返回值类型:`Boolean` + +参考:[mojang-gametest docs](https://docs.microsoft.com/zh-cn/minecraft/creator/scriptapi/mojang-gametest/simulatedplayer#jump) + + +#### 模拟看向某方块或实体 + +`sp.simulateLookAt(pos)` +`sp.simulateLookAt(entity)` +`sp.simulateLookAt(block)` + +- 参数: + + - target : `Entity` + 要看向的实体 + - pos :`IntPos` / `FloatPos` + 要看向的坐标 + - block :`Block` + 要看向的方块 + +- 返回值:是否成功模拟操作 +- 返回值类型:`Boolean` + +参考:[mojang-gametest docs](https://docs.microsoft.com/zh-cn/minecraft/creator/scriptapi/mojang-gametest/simulatedplayer#lookatblock) + + +#### 模拟设置身体角度 + +`sp.simulateSetBodyRotation(rot)` + +- 参数: + + - rot : `Number` + 要设置的角度 + +- 返回值:是否成功模拟操作 +- 返回值类型:`Boolean` + +参考:[mojang-gametest docs](https://docs.microsoft.com/zh-cn/minecraft/creator/scriptapi/mojang-gametest/simulatedplayer#lookatblock) + + +#### 相对玩家坐标系移动 + +`sp.simulateLocalMove()` + +- 参数: + - pos : `IntPos` / `FloatPos` + 移动方向 + - speed : `Number` + (可选参数)移动速度,默认为1 + +- 返回值:是否请求移动成功 +- 返回值类型:`Boolean` + + +#### 相对世界坐标系移动 + +`sp.simulateWorldMove()` + +- 参数: + - pos : `IntPos` / `FloatPos` + 移动方向 + - speed : `Number` + (可选参数)移动速度,默认为1 + +- 返回值:是否请求移动成功 +- 返回值类型:`Boolean` + + +#### 直线移动到坐标 + +`sp.simulateMoveTo()` + +- 参数: + - pos : `IntPos` / `FloatPos` + 目标位置 + - speed : `Number` + (可选参数)移动速度,默认为1 + +- 返回值:是否请求移动成功 +- 返回值类型:`Boolean` + +参考:[mojang-gametest docs](https://docs.microsoft.com/zh-cn/minecraft/creator/scriptapi/mojang-gametest/simulatedplayer#movetolocation) +注:如需自动寻路,请考虑使用 `模拟导航移动` + +#### 模拟导航移动 + +`sp.simulateNavigateTo(entity[,speed)` +`sp.simulateNavigateTo(pos[,speed])` + +- 参数: + + - entity : `Entity` + 导航目标 + - pos : `IntPos` / `FloatPos` + 导航目标 + - speed : `Number` + (可选参数)移动速度,默认为1 + +- 返回值:是否能到达指定位置以及导航路径,结构:{isFullPath:`Boolean`,path:`Number[3][]`} +- 返回值类型:`Object` + +参考:[mojang-gametest docs](https://docs.microsoft.com/zh-cn/minecraft/creator/scriptapi/mojang-gametest/simulatedplayer#navigatetoblock) +返回值示例: +```js +{ + isFullPath: false, + path: [ + [ + -8, + 0, + -3 + ], + [ + -7, + 0, + -2 + ], + [ + -6, + 0, + -2 + ], + [ + -5, + 0, + -2 + ], + [ + -4, + 0, + -1 + ], + [ + -3, + 0, + -1 + ], + [ + -2, + 0, + -1 + ], + [ + -1, + 0, + 0 + ] + ] +} +``` +此数据的目标坐标为(0,2,0),路径终点为(-1,0,0),所以isFullPath为false,但由于路径不为空,所以模拟玩家将会移动至(-1,0,0)坐标 + + +#### 模拟导航移动(多目标) + +`sp.simulateNavigateTo(posArray[,speed])` + +- 参数: + + - posArray : `IntPos[]` / `FloatPos[]` + 导航目标 + - speed : `Number` + (可选参数)移动速度,默认为1 + +- 返回值:是否成功模拟操作 +- 返回值类型:`Boolean` + +参考:[mojang-gametest docs](https://docs.microsoft.com/zh-cn/minecraft/creator/scriptapi/mojang-gametest/simulatedplayer#navigatetolocations) + + +#### 模拟使用物品 + +`sp.simulateUseItem([slot,pos,face,relative])` +`sp.simulateUseItem([item,pos,face,relative])` + +- 参数: + + - item : `Item` + (可选参数)要使用的物品,默认为选中物品 + - slot : `Number` + (可选参数)要使用的物品所在的槽,默认为选中物品 + - pos : `IntPos` + (可选参数)目标坐标,默认为朝向方块坐标 + - face : `Number` + (可选参数)目标方块的面,默认为0 + - relative : `FloatPos` + (可选参数)相对方块偏移坐标,默认为{0.5,0.5,0.5} + +- 返回值:是否成功模拟操作 +- 返回值类型:`Boolean` + +参考:[mojang-gametest docs](https://docs.microsoft.com/zh-cn/minecraft/creator/scriptapi/mojang-gametest/simulatedplayer#useitem) + + +#### 模拟停止破坏方块 + +`sp.simulateStopDestroyingBlock()` + +- 返回值:是否成功模拟操作 +- 返回值类型:`Boolean` + +参考:[mojang-gametest docs](https://docs.microsoft.com/zh-cn/minecraft/creator/scriptapi/mojang-gametest/simulatedplayer#stopbreakingblock) + + +#### 模拟停止交互 + +`sp.simulateStopInteracting()` + +- 返回值:是否成功模拟操作 +- 返回值类型:`Boolean` + +参考:[mojang-gametest docs](https://docs.microsoft.com/zh-cn/minecraft/creator/scriptapi/mojang-gametest/simulatedplayer#stopinteracting) + + +#### 模拟停止移动 + +`sp.simulateStopMoving()` + +- 返回值:是否成功模拟操作 +- 返回值类型:`Boolean` + +参考:[mojang-gametest docs](https://docs.microsoft.com/zh-cn/minecraft/creator/scriptapi/mojang-gametest/simulatedplayer#stopmoving) + + +#### 模拟停止使用物品 + +`sp.simulateStopUsingItem()` + +- 返回值:是否成功模拟操作 +- 返回值类型:`Boolean` + +参考:[mojang-gametest docs](https://docs.microsoft.com/zh-cn/minecraft/creator/scriptapi/mojang-gametest/simulatedplayer#stopusingitem) + diff --git a/docs/apis/GameAPI/ScoreBoard.md b/docs/apis/GameAPI/ScoreBoard.md new file mode 100644 index 00000000..6b3c5a7b --- /dev/null +++ b/docs/apis/GameAPI/ScoreBoard.md @@ -0,0 +1,258 @@ +## 📝 Scoreboard API + +In LLSE, use the "score object" to operate and obtain a specific scoring variable, and provide many other common interfaces for manipulating the scoreboard. + +MC uses **score items** as the core of the scoreboard system, each of which has a name and can be used to track specific players, entities or even string targets. In the scoring item, the corresponding score of each tracking target is recorded. + +### Get a Scoring Item Object + +Obtain a scoring item object through the following interface and perform related operations: + +#### Create a New Scoring Item + +`mc.newScoreObjective(name,displayName)` + +- Parameters: + - name : `String` + Scoring item name. + - displayName : `String` + Scoring item display name. +- Return type: The newly created scoring item object. +- Return value type: `Objective` + - If it returns `Null`, it means the creation failed. + +This interface acts like a command `/scoreboard objectives add dummy` + +
+ +#### Get an Existing Scoring Item + +`mc.getScoreObjective(name)` + +- Parameters: + - name : `String` + The name of the score to get. +- Return type: The corresponding scoring item object. +- Return value type: `Objective` + - If `Null` is returned, it means the scoring item does not exist. + +
+ +#### Get All Scoring Items + +`mc.getAllScoreObjectives()` + +- Return type: All score object objects recorded by the scoreboard system. +- Return value type: `Array` + +This interface acts like a command `/scoreboard objectives list` + +
+ +#### Get a Scoring Item That Is Displayed + +`mc.getDisplayObjective(slot)` + +- Parameters: + - slot : `String` + Display slot name to be queried, which can be `"sidebar"`/`"belowname"`/`"list"` +- Return type: Scoring items being displayed in the `slot` slot. +- Return value type: `Objective` + - If it returns `Null`, it means that the corresponding slot does not display the scoring item. + +
+ + +### Scoring Object - Properties + +Each scoring item object contains some fixed object properties. for a specific scoring item object `ob`, has the following properties: + +| Attributes | Meaning | Data Type | +| -------------- | ---------------- | -------- | +| ob.name | Scoring item name| `String` | +| ob.displayName | Display name of the scoring item | `String` | + +These object properties are read-only and cannot be modified. + +
+ +### Scoring Item Object - Function + +Each scoring item object contains some member functions (member methods) that can be executed. for a specific scoring item object `ob`, you can perform some operations on this scoring item through the following functions: + +#### Get the Score for a Tracked Goal + +`ob.getScore(target)` + +- Parameters: + - target : `Player` / `String` + The tracking target to be queried, which can be passed in a player object or any string. +- Return type: The target/player's score for this scoring item. +- Return value type: `Integer` + +**Make sure the score is existing before using this API** +
+ +#### Modify the Score of a Goal + +Set score: `ob.setScore(target,score)` +Increase score: `ob.addScore(target,score)` +Reduce score: `ob.reduceScore(target,score)` + +- Parameters: + - target : `Player` / `String` + The target tracked by the scoring item, which can be passed in a player object or an arbitrary string. + - score : `Integer` + Score to set/increase/decrease. +- Return type: The score of the target after the set/increase/decrease operation. +- Return value type: `Integer` + - If `Null` is returned, the operation failed. + +[!warning] +If the score doesn't exist, will try creating a score, then return `0`(If *target* is `String`) or `null`(If *target* is `Player`) +Reason: [#971](https://github.com/LiteLDev/LiteLoaderBDSv2/issues/971#issuecomment-1385047649) +
+ +#### Stop Tracking a Target + +`ob.deleteScore(target)` + +- Parameters: + - target : `Player` / `String` + The target tracked by the scoring item, which can be passed in a player object or an arbitrary string. +- Return type: Whether the target was deleted successfully. +- Return value type: `Boolean` + +Stop tracking will directly delete the value of the goal's scoring item. You need to create it again if you need to access it again. + +
+ +#### Set the Display State of the Scoring Item + +`ob.setDisplay(slot[,sortOrder=0])` + +- Parameters: + - slot : `String` + Displays the slot name string, which can be `"sidebar"`/`"belowname"`/`"list"` + - sortOrder : `Integer` + (Optional parameter) the sorting method, which can be `0` (ascending) or `1`(descending order), the default is `0` +- Return type: Whether setting the display was successful. +- Return value type: `Boolean` + +
+ +### Other Scoreboard APIs + +The following APIs provide more APIs for operating the scoreboard system: + +#### Get the Score of a online Player’s Scoring Item (Convenience Function) + +`pl.getScore(name)` + +- Parameters: + - name : `String` + Scoring item name. +- Return type: The numerical value on the scoreboard. +- Return value type: `Integer` + +Before using, you must ensure that the corresponding scoring item already exists. + +```js +//For a player object pl: +log("You have money:",pl.getScore("money")); +``` + +#### Get the Score of a Player’s Scoring Item (Include the Offline Players) + +`mc.getPlayerScore(uuid, name)` + +- Parameters: + - uuid : `String` + Player`s UUID. + - name : `String` + Scoring item name. +- Return type: The numerical value on the scoreboard. +- Return value type: `Integer` + +#### Modify the Score of a Online Player’s Scoring Item (Convenience Function) + +Set score: `pl.setScore(name,value)` +Increase score: `pl.addScore(name,value)` +Reduce score: `pl.reduceScore(name,value)` + +- Parameters: + - name : `String` + Scoring item name + - value : `Integer` + The value to set/increase/decrease +- Return type: Whether the setting was successful. +- Return value type: `Boolean` + +If the score doesn't exist, will return `false` and create the score + +```js +//For a player object pl: +pl.setScore("money",10000); +pl.addScore("money",100); +pl.reduceScore("money",50); +``` + +#### Modify the Score of a Player’s Scoring Item (Include the Offline Players) + +Set score: `mc.setPlayerScore(uuid, name, value)` +Increase score: `mc.addPlayerScore(uuid, name, value)` +Reduce score: `mc.reducePlayerScore(uuid, name, value)` +Delete score: `mc.deletePlayerScore(uuid, name)` + +- Parameters: + - uuid : `String` + Player`s UUID. + - name : `String` + Scoring item name + - value : `Integer` + The value to set/increase/decrease +- Return type: Whether the setting was successful. +- Return value type: `Boolean + +#### Player Stops Tracking Scoring Items (Convenience Function) + +`pl.deleteScore(name)` + +- Parameters: + - name : `String` + Scoring item name +- Return type: Whether the removal was successful. +- Return value type: `Boolean` + +Before using, you must ensure that the corresponding scoring item already exists. + +```js +//For a player object pl: +pl.deleteScore("what"); +``` + +#### Remove an Existing Scoring Item + +`mc.removeScoreObjective(name)` + +- Parameters: + - name : `String` + Scoring item name +- Return type: Whether the removal was successful. +- Return value type: `Boolean` + +This interface acts like a command `/scoreboard objectives remove ` + +
+ +#### Stop Scoring Items From Showing + +`mc.clearDisplayObjective(slot)` + +- Parameters: + - slot : `String` + Displays the slot name string, which can be `"sidebar"`/`"belowname"`/`"list"` +- Return type: Whether the display objective was cleared successfully. +- Return value type: `Boolean` + +
diff --git a/docs/apis/GameAPI/ScoreBoard.zh.md b/docs/apis/GameAPI/ScoreBoard.zh.md new file mode 100644 index 00000000..502bc585 --- /dev/null +++ b/docs/apis/GameAPI/ScoreBoard.zh.md @@ -0,0 +1,263 @@ +## 📝 计分板 API + +在脚本引擎中,使用「计分项对象」来操作和获取某一个特定的计分项变量,并且提供了很多其他操作计分板的通用接口 + +MC使用 **计分项** 作为计分板系统的核心,每一个计分项拥有一个名字,并可以用来跟踪特定的玩家、实体甚至字符串目标。计分项中,记录着每一个跟踪目标各自对应的分数。 + +### 获取一个计分项对象 + +通过下面的接口,来获取一个计分项对象,并进行相关操作 + +#### 创建一个新的计分项 + +`mc.newScoreObjective(name,displayName)` + +- 参数: + - name : `String` + 计分项名称 + - displayName : `String` + 计分项显示名称 +- 返回值:新增创建的计分项对象 +- 返回值类型:`Objective` + - 如果返回`Null`,则代表创建失败 + +此接口的作用类似命令 `/scoreboard objectives add dummy` + +
+ +#### 获取某个已存在的计分项 + +`mc.getScoreObjective(name)` + +- 参数: + - name : `String` + 要获取的计分项名称 +- 返回值:对应的计分项对象 +- 返回值类型:`Objective` + - 如果返回`Null`,则代表计分项不存在 + +
+ +#### 获取所有计分项 + +`mc.getAllScoreObjectives()` + +- 返回值:计分板系统记录的所有计分项对象 +- 返回值类型:`Array` + +此接口的作用类似命令 `/scoreboard objectives list` + +
+ +#### 获取某个处于显示状态的计分项 + +`mc.getDisplayObjective(slot)` + +- 参数: + - slot : `String` + 待查询的显示槽位名称,可以为`"sidebar"`/`"belowname"`/`"list"` +- 返回值:正在`slot`槽位显示的计分项 +- 返回值类型:`Objective` + - 如果返回`Null`,则代表对应槽位未显示计分项 + +
+ + +### 计分项对象 - 属性 + +每一个计分项对象都包含一些固定的对象属性。对于某个特定的计分项对象`ob`,有以下这些属性 + +| 属性 | 含义 | 类型 | +| -------------- | ---------------- | -------- | +| ob.name | 计分项名称 | `String` | +| ob.displayName | 计分项的显示名称 | `String` | + +这些对象属性都是只读的,无法被修改 + +
+ +### 计分项对象 - 函数 + +每一个计分项对象都包含一些可以执行的成员函数(成员方法)。对于某个特定的计分项对象`ob`,可以通过以下这些函数对这个计分项进行一些操作 + +#### 获取跟踪的某个目标的分数 + +`ob.getScore(target)` + +- 参数: + - target : `Player` / `String` + 待查询的跟踪目标,可传入玩家对象或者任意字符串 +- 返回值:该目标/玩家在此计分项中的分数 +- 返回值类型:`Integer` + +**使用前请保证计分项存在** +
+ +#### 修改某个目标的分数 + +设置分数 `ob.setScore(target,score)` +增加分数 `ob.addScore(target,score)` +减少分数 `ob.reduceScore(target,score)` + +- 参数: + - target : `Player` / `String` + 计分项跟踪的目标,可传入玩家对象或者任意字符串 + - score : `Integer` + 要设置/增加/减少的分数 +- 返回值:该目标在经过设置/增加/减少操作后的分数 +- 返回值类型:`Integer` + - 如果返回`Null`,则代表操作失败 + +[!warning] +若计分项不存在,则会尝试创建计分项,此时会返回`0`(当*target*为`String`时)或`null`(当*target*为`Player`时) +原因参见: [#971](https://github.com/LiteLDev/LiteLoaderBDSv2/issues/971#issuecomment-1385047649) +
+ +#### 停止跟踪某个目标 + +`ob.deleteScore(target)` + +- 参数: + - target : `Player` / `String` + 计分项跟踪的目标,可传入玩家对象或者任意字符串 +- 返回值:是否停止成功 +- 返回值类型:`Boolean` + +停止跟踪将直接删除这个目标对应的计分项数值,下次如需要访问需要再次创建 + +
+ +#### 设置计分项的显示状态 + +`ob.setDisplay(slot[,sortOrder=0])` + +- 参数: + - slot : `String` + 显示槽位名称字符串,可以为`"sidebar"`/`"belowname"`/`"list"` + - sortOrder : `Integer` + (可选参数)排序方式,可以为`0`(升序)或`1`(降序),默认值为`0` +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +
+ +### 其他计分板 API + +下面这些API提供了更多操作计分板系统的API + +#### 获取在线玩家计分项的分数(方便函数) + +`pl.getScore(name)` + +- 参数: + - name : `String` + 计分项名称 +- 返回值:计分板上的数值 +- 返回值类型:`Integer` + +使用前,必须保证对应的计分项已经存在 + +[JavaScript] +```js +//对于一个玩家对象pl +log("You have money:",pl.getScore("money")); +``` + +#### 获取玩家计分项的分数(可查询离线玩家计分板) + +`mc.getPlayerScore(uuid, name)` + +- 参数: + - uuid : `String` + 玩家的UUID + - name : `String` + 计分项名称 +- 返回值:计分板上的数值 +- 返回值类型:`Integer` + +#### 修改在线玩家计分项的分数(方便函数) + +设置分数 `pl.setScore(name,value)` +增加分数 `pl.addScore(name,value)` +减少分数 `pl.reduceScore(name,value)` + +- 参数: + - name : `String` + 计分项名称 + - value : `Integer` + 要设置 / 增加 / 减少的数值 +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +若计分项不存在,则会返回`false`并创建计分项 + +[JavaScript] +```js +//对于一个玩家对象pl +pl.setScore("money",10000); +pl.addScore("money",100); +pl.reduceScore("money",50); +``` + +#### 修改玩家计分项的分数(可修改离线玩家计分板) + +设置分数 `mc.setPlayerScore(uuid, name, value)` +增加分数 `mc.addPlayerScore(uuid, name, value)` +减少分数 `mc.reducePlayerScore(uuid, name, value)` +移除分数 `mc.deletePlayerScore(uuid, name)` + +- 参数: + - uuid : `String` + 玩家的UUID + - name : `String` + 计分项名称 + - value : `Integer` + 要设置 / 增加 / 减少的数值 +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +#### 玩家停止跟踪计分项(方便函数) + +`pl.deleteScore(name)` + +- 参数: + - name : `String` + 计分项名称 +- 返回值:是否移除成功 +- 返回值类型:`Boolean` + +使用前,必须保证对应的计分项已经存在 + +[JavaScript] +```js +//对于一个玩家对象pl +pl.deleteScore("what"); +``` + +#### 移除一个已存在的计分项 + +`mc.removeScoreObjective(name)` + +- 参数: + - name : `String` + 计分项名称 + +- 返回值:是否移除成功 +- 返回值类型:`Boolean` + +此接口的作用类似命令 `/scoreboard objectives remove ` + +
+ +#### 使计分项停止显示 + +`mc.clearDisplayObjective(slot)` + +- 参数: + - slot : `String` + 显示槽位名称字符串,可以为`"sidebar"`/`"belowname"`/`"list"` + +- 返回值:是否清除成功 +- 返回值类型:`Boolean` + +
diff --git a/docs/apis/GameAPI/Server.md b/docs/apis/GameAPI/Server.md new file mode 100644 index 00000000..96975f9d --- /dev/null +++ b/docs/apis/GameAPI/Server.md @@ -0,0 +1,92 @@ +## 💻 Server Settings API + +The following APIs provide interfaces for customizing some server settings: + +### Get the Version Number of the BDS Server + +`mc.getBDSVersion()` + +- Return value: The server version number string, formatted like this: `v1.17.10` +- Return value type: `String` + +
+ +### Get BDS Server Protocol Version + +`mc.getServerProtocolVersion()` + +- Return value: Server protocol version +- Return value type: `Number` + +
+ +### Set Server Motd String + +`mc.setMotd(motd)` + +- Parameters: + - motd : `String` + The desired Motd string. +- Return value: Whether the setting was successful. +- Return value type: `Boolean` + +
+ +### Set the Maximum Number of Players on the Server + +`mc.setMaxPlayers(num)` + +- Parameters: + - num : `Number` + The maximum number of players. +- Return value: Whether the setting was successful. +- Return value type: `Boolean` + +
+ +### Get Sever time + +`mc.getTime(TimeID)` + +- Parameters: + - TimeID : `Integer` + Specifies the time to get. Must be 0, 1 or 2. (0 represents daytime, 1 represents gametime, 2 represents day) +- Return value: Current time +- Return value type: `Integer` + +Among them, daytime is the number of game ticks since dawn, gametime is the age of the world in game ticks, day is the number of in-game days passed. + +
+ +### Set Sever time + +`mc.setTime(tick)` + +- Parameters: + - tick : `Integer` + The time you want to set +- Return value: Whether the setting was successful. +- Return value type: `Boolean` + +
+ +### Get Sever Weather + +`mc.getWeather()` + +- Return value: Current weather (0 represents Clear, 1 represents Rain, 2 represents Thunder) +- Return value type: `Integer` + +
+ +### Set Sever Weather + +`mc.setWeather(WeatherID)` + +- Parameters: + - WeatherID : `Integer` + The weather you want to set (0 represents Clear, 1 represents Rain, 2 represents Thunder) +- Return value: Whether the setting was successful. +- Return value type: `Boolean` + +
diff --git a/docs/apis/GameAPI/Server.zh.md b/docs/apis/GameAPI/Server.zh.md new file mode 100644 index 00000000..380a4d86 --- /dev/null +++ b/docs/apis/GameAPI/Server.zh.md @@ -0,0 +1,92 @@ +## 💻 服务端设置 API + +下面这些API提供了自定义某些服务器设置的接口 + +### 获取服务器版本号 + +`mc.getBDSVersion()` + +- 返回值:服务端版本号字符串,格式形如`v1.17.10` +- 返回值类型:`String` + +
+ +### 获取服务器协议版本 + +`mc.getServerProtocolVersion()` + +- 返回值:服务端协议版本 +- 返回值类型:`Number` + +
+ +### 设置服务器MOTD字符串 + +`mc.setMotd(motd)` + +- 参数: + - motd : `String` + 目标MOTD字符串 +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +
+ +### 设置服务器最大玩家数 + +`mc.setMaxPlayers(num)` + +- 参数: + - num : `Number` + 最大玩家数 +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +
+ +### 获取服务器游戏时间 + +`mc.getTime(TimeID)` + +- 参数: + - TimeID : `Integer` + 想要查询的时间 (0 代表daytime,1 代表gametime,2 代表day) +- 返回值:获取到的时间 +- 返回值类型:`Integer` + +其中,daytime 代表自当天日出后流逝的游戏刻数,gametime 代表世界总共流逝的游戏刻数,day 代表已流逝的游戏天数。 + +
+ +### 设置服务器游戏时间 + +`mc.setTime(tick)` + +- 参数: + - tick : `Integer` + 想要设置的时间 +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +
+ +### 获取服务器天气 + +`mc.getWeather()` + +- 返回值:当前天气 (0 代表晴天,1 代表雨天,2 代表雷暴) +- 返回值类型:`Integer` + +
+ +### 设置服务器天气 + +`mc.setWeather(WeatherID)` + +- 参数: + - WeatherID : `Integer` + 想要设置的天气 (0 代表晴天,1 代表雨天,2 代表雷暴) +- 返回值:是否设置成功 +- 返回值类型:`Boolean` + +
diff --git a/docs/apis/GuiAPI/Form.md b/docs/apis/GuiAPI/Form.md new file mode 100644 index 00000000..e2893fc6 --- /dev/null +++ b/docs/apis/GuiAPI/Form.md @@ -0,0 +1,111 @@ +# LLSE - GUI Form Interface Documentation + +> This API allows you to create, modify or affect the **GUI interface** in the game. + +Obviously, the clear and intuitive UI interface helps players quickly get started with the use of plugins and provides a good user experience. + +## 📊 Form Related API + +for a specific player object `pl`, the following form interfaces are available: + +### Send a Modal Form to the Player + +A modal form contains a title, a text display, and two buttons. + +`pl.sendModalForm(title,content,confirmButton,cancelButton,callback)` + +- Parameters: + - title : `String` + Form title. + - content : `String` + Form content. + - confirmButton : `String` + Button 1 text. + - cancelButton : `String` + Button 2 text. + - callback : `Function` + Function called after player clicks a button. +- Return value: The ID of the sent form. +- Return value type: `Integer` + - If the return value is `Null`, it means the sending failed. + +- Parameter `callback` The callback function prototype: `function(player,result)` + + - player : `Player` + The player object that interacts with the form. + + - result : `Boolean` + Player clicks **Confirm** button is `true`, **Cancel** button is `false`. + + If the id is `Null`, the player cancels the form. + +
+ +### Send a Normal Form to the Player + +A normal form contains a title, a text display box and several buttons, and the icon displayed on the button can be set. +Due to the relatively complex content setup of buttons, it is recommended to use the form builder API in the next section to better accomplish this task. + +`pl.sendSimpleForm(title,content,buttons,images,callback)` + +- Parameters: + + - title : `String` + Form title. + - content : `String` + Form Content. + - buttons : `Array` + String array of individual button texts. + - images : `Array` + Image path corresponding to each button. + - callback : `Function` + The function called after the player clicks a button. +- Return value: The sent form ID. +- Return value type: `Integer` + - If the return value is `Null`, it means the sending failed. + +Parameter `callback` The callback function prototype: `function(player,id)` + +- player : `Player` + The player object that interacts with the form. +- id : `Integer` + The serial number of the form button that the player clicked, starting from 0. + If the id is `Null`, the player cancels the form. + +
+ +Use the texture pack path or URL `images` to identify the icon corresponding to the button. +For each button on the form, set the corresponding icon as follows: + +1. If using a texture pack path, the image path should look like `textures/items/apple` +2. If you use a URL path, you can put the full URL here, like `https://www.baidu.com/img/flexible/logo/pc/result.png` +3. If you don't need to display an image for this button, set the corresponding image path to an empty string. + +
+ +### Send Custom Form to Player (JSON Format) + +Custom forms can contain rich custom controls. +Since the relevant JSON definition format is relatively complex, it is recommended to use the form builder API in the next section to better accomplish this task. + +`pl.sendCustomForm(json,callback)` + +- Parameters: + - json : `String` + Custom form JSON string. + - callback : `Function` + Callback function to be called after the player submits the form. +- Return value: The sent form ID. +- Return value type: `Integer` + - If the return value is Null, it means the sending failed. + +Parameter `callback` The callback function prototype: `function(player,data)` + +- player : `Player` + The player object that interacts with the form. +- data : `Array<...>` + The returned form content array. + In the array, the first item must be `Null`, starting from the second item, the content of each control is stored in the order of the controls on the form. + If data is only `Null`, the player cancels the form. + +
\ No newline at end of file diff --git a/docs/apis/GuiAPI/Form.zh.md b/docs/apis/GuiAPI/Form.zh.md new file mode 100644 index 00000000..12e4d99b --- /dev/null +++ b/docs/apis/GuiAPI/Form.zh.md @@ -0,0 +1,111 @@ +# 脚本引擎 - GUI表单界面文档 + +> 这里API使你可以在游戏中创建、修改或者影响 **GUI界面** + +很明显,清晰直观的UI界面有助于玩家快速上手插件的使用,提供良好的用户体验。 + +## 📊 表单相关 API + +对于某个特定的玩家对象`pl`,有以下这些表单接口可用 + +### 向玩家发送模式表单 + +模式表单包含一个标题、一个文本显示框以及两个按钮 + +`pl.sendModalForm(title,content,confirmButton,cancelButton,callback)` + +- 参数: + - title : `String` + 表单标题 + - content : `String` + 表单内容 + - confirmButton : `String` + 按钮1文本的字符串 + - cancelButton : `String` + 按钮2文本的字符串 + - callback : `Function` + 玩家点击按钮之后被调用的回调函数。 +- 返回值:发送的表单ID +- 返回值类型:`Integer` + - 如果返回值为`Null`,则代表发送失败 + +- 参数`callback`的回调函数原型:`function(player,result)` + + - player : `Player` + 与表单互动的玩家对象 + + - result : `Boolean` + 玩家点击**确定**按钮为`true`,**取消**按钮为`false` + + 如果id为`Null`,则代表玩家取消了表单 + +
+ +### 向玩家发送普通表单 + +普通表单包含一个标题、一个文本显示框以及若干按钮,可以设置按钮上显示的图标 +由于按钮的内容设置相对复杂,建议使用下一节的表单构建器API更好地完成这项任务。 + +`pl.sendSimpleForm(title,content,buttons,images,callback)` + +- 参数: + + - title : `String` + 表单标题 + - content : `String` + 表单内容 + - buttons : `Array` + 各个按钮文本的字符串数组 + - images : `Array` + 各个按钮对应的图片路径 + - callback : `Function` + 玩家点击按钮之后被调用的回调函数。 +- 返回值:发送的表单ID +- 返回值类型:`Integer` + - 如果返回值为`Null`,则代表发送失败 + +参数`callback`的回调函数原型:`function(player,id)` + +- player : `Player` + 与表单互动的玩家对象 +- id : `Integer` + 玩家点击的表单按钮的序号,从0开始编号 + 如果id为`Null`,则代表玩家取消了表单 + +
+ +图片路径参数 `images` 使用材质包路径或者URL来标识按钮对应的图标。 +对于表单上的每个按钮,如下设置对应的图标 + +1. 如果使用材质包路径,图片路径应该形如 `textures/items/apple` +2. 如果使用URL路径,那么在这里放入完整的URL即可,形如 `https://www.baidu.com/img/flexible/logo/pc/result.png` +3. 如果这个按钮你不需要显示图片,那将对应的图片路径设置为空字符串即可 + +
+ +### 向玩家发送自定义表单(JSON格式) + +自定义表单可以包含丰富的自定义控件。 +由于相关JSON定义格式相对复杂,建议使用下一节的表单构建器API更好地完成这项任务。 + +`pl.sendCustomForm(json,callback)` + +- 参数: + - json : `String` + 自定义表单json字符串 + - callback : `Function` + 玩家提交表单之后被调用的回调函数。 +- 返回值:发送的表单ID +- 返回值类型:`Integer` + - 如果返回值为`Null`,则代表发送失败 + +参数`callback`的回调函数原型:`function(player,data)` + +- player : `Player` + 与表单互动的玩家对象 +- data : `Array<...>` + 返回的表单内容数组 + 数组中,第一项一定为`Null`,从第二项开始,按表单上的控件顺序储存了每一个控件的内容 + 如果data只为`Null`,则代表玩家取消了表单 + +
\ No newline at end of file diff --git a/docs/apis/GuiAPI/FormBuilder.md b/docs/apis/GuiAPI/FormBuilder.md new file mode 100644 index 00000000..4998de0e --- /dev/null +++ b/docs/apis/GuiAPI/FormBuilder.md @@ -0,0 +1,262 @@ +## 📃 Normal Form Builder API + +> These APIs can assist developers to easily construct a common form. + +LLSE provides a **normal form object** to easily create a custom form and send it to a specific player. + +### Create Form Object + +Before using these APIs, you need to use this function to create a blank normal form object: + +`mc.newSimpleForm()` + +- Return value: Newly created blank form object. +- Return value type: `SimpleForm` + +
+ +### Add Form Elements + +Once created, you can use the following member functions (member methods) to add new form elements to the object. +For a specific form object `fm`, the following functions are available: + +#### Set the Title of the Form + +`fm.setTitle(title)` + +- Parameter: + - title : `String` + Title of the form. +- Return value: The processed form object (for other operations in the chain). +- Return value type: `SimpleForm` + +
+ +#### Set the Content of the Form + +`fm.setContent(content)` + +- Parameter: + - content: `String` + Text content of the form. +- Return value: The processed form object (for other operations in the chain). +- Return value type: `SimpleForm` + +
+ +#### Add a Row of Buttons to the Form + +`fm.addButton(text[,image])` + +- Parameters: + - text : `String` + String of button text. + - image: `String` + (Optional parameter) the path where the button image is located. +- Return value: The processed form object (for other operations in the chain). +- Return value type: `SimpleForm` + +
+ +Use the texture pack path or URL `image` to identify the icon corresponding to the button. +For each button on the form, set the corresponding icon as follows: + +1. If using a texture pack path, the image path should look like `textures/items/apple` +2. If you use a URL path, you can put the full URL here, like `https://www.baidu.com/img/flexible/logo/pc/result.png` +3. If you don't need to display an image for this button, just don't pass in this parameter. + +
+ +### Send Form + +Finally, when everything is in place, you can send the configured form object to the player and listen for player interaction messages. +Form objects can be sent repeatedly, each time a different form ID is returned, and the respective callback functions are called when there is player interaction, without fighting. + +For a player object `pl`, using the function: + +`pl.sendForm(fm,callback)` + +- Parameters: + - fm : `SimpleForm` + The configured form object. + - callback : `Function` + Callback function to be called after the player interacts with the form element. +- Return value: The sent form ID. +- Return value type: `Integer` + - If the return value is `Null`, it means the sending failed. + +Parameter `callback` The callback function prototype: `function(player,id)` + +- player : `Player` + The player object that interacts with the form +- id : `Integer` + The serial number of the form button that the player clicked, starting from 0. + If id is `Null`, the player canceled the form. + +
+ +## 📰 Custom Form Builder API + +> These APIs can assist developers to easily construct a custom form, no longer need to worry about writing JSON + +LLSE provides a **Custom Form Object** to easily create a custom form and send it to a specific player. + +### Create Form Object + +Before using these APIs, you need to use this function to create a blank custom form object. + +`mc.newCustomForm()` + +- Return value: Newly created blank form object. +- Return value type: `CustomForm` + +
+ +### Add Form Elements + +Once created, you can use the following member functions (member methods) to add new form elements to the object. +For a specific form object `fm`, the following functions are available: + +#### Set the Title of the Form + +`fm.setTitle(title)` + +- Parameters: + - title : `String` + Title of the form. +- Return value: The processed form object (for other operations in the chain). +- Return value type: `CustomForm` + +
+ +#### Add a Line of Text to the Form + +`fm.addLabel(text)` + +- Parameters: + - text : `String` + Line of text. +- Return value: The processed form object (for other operations in the chain). +- Return value type: `CustomForm` + +
+ +#### Add a Row of Input Boxes to the Form + +`fm.addInput(title[,placeholder,default])` + +- Parameters: + + - title : `String` + Description text in an input box. + - placeholder : `String` + (Optional parameter) The default prompt in the input box. + - default : `String` + (Optional parameter) the default input in the input box. +- Return value: The processed form object (for other operations in the chain). +- Return value type: `CustomForm` + +
+ +#### Add a Row of Switch Options to the Form + +`fm.addSwitch(title[,default])` + +- Parameters: + - title : `String` + Description text for a switch option. + - default : `Boolean` + (Optional parameter) Default state of the switch on/off. +- Return value: The processed form object (for other operations in the chain). +- Return value type: `CustomForm` + +
+ +#### Add a Drop-Down Menu to the Form + +`fm.addDropdown(title,items[,default])` + +- Parameters: + + - title : `String` + Description text for a dropdown menu. + + - items : `Array` + List of option texts in the drop down menu. + + - default : `Integer` + (Optional parameter) The number of the list item selected by default in the drop-down menu. + The sequence number starts from 0. The default is 0, that is, the first item in the list is selected by default. +- Return value: The processed form object (for other operations in the chain). +- Return value type: `CustomForm` + +
+ +#### Add a Row of Cursor Sliders to the Form + +`fm.addSlider(title,min,max[,step,default])` + +- Parameters: + - title : `String` + Description text for a Slider. + - min : `Integer` + Slider minimum value. + - max : `Integer` + Slider maximum value. + - step : `Integer` + (Optional parameter) The minimum division value of the cursor slider adjustment, the default is 1. + - default : `Integer` + (Optional parameter) The default initial grid number of the cursor slider, the value must be between the minimum and maximum grid number. + Defaults to 0, i.e. the slider is at the beginning of the slider row. +- Return value: The processed form object (for other operations in the chain). +- Return value type: `CustomForm` + +
+ +#### Add a Row of Step Sliders to the Form + +`fm.addStepSlider(title,items[,default])` + +- Parameters: + - title : `String` + Description text for a step slider. + + - items : `Array` + List of option texts for the step slider. + + - default : `Integer` + (Optional parameter) Default initial options for step slider. Serial numbers start from 0. + Defaults to 0, i.e. the slider is at the beginning of the slider row. +- Return value: The processed form object (for other operations in the chain). +- Return value type: `CustomForm` + +
+ +### Send Form + +Finally, when everything is in place, you can send the configured form object to the player and listen for player interaction messages. +Form objects can be sent repeatedly, each time a different form ID is returned, and the respective callback functions are called when there is player interaction, without fighting. + +For a player object `pl`, using the function: + +`pl.sendForm(fm,callback)` + +- Parameters: + - fm : `CustomForm` + Configured custom form object. + - callback : `Function` + Callback function to be called after the player submits the form. +- Return value: The sent form ID. +- Return value type: `Integer` + - If the return value is `Null`, it means the sending failed. + +Parameter `callback` The callback function prototype: `function(player,data)` + +- player : `Player` + The player object that interacts with the form. +- data : `Array<...>` + The returned form content array. + The contents of each control are stored in the array in the order of the controls on the form. + if data is `Null`, the player cancels the form. + +
\ No newline at end of file diff --git a/docs/apis/GuiAPI/FormBuilder.zh.md b/docs/apis/GuiAPI/FormBuilder.zh.md new file mode 100644 index 00000000..e3a98d43 --- /dev/null +++ b/docs/apis/GuiAPI/FormBuilder.zh.md @@ -0,0 +1,262 @@ +## 📃 普通表单构建器 API + +> 这些API可以协助开发者方便地构造一个普通表单 + +脚本引擎提供了**普通表单对象**来方便地创建一个自定义表单并发送至指定玩家。 + +### 创建表单对象 + +在使用这些API之前,你需要先用这个函数创建一个空白的普通表单对象 + +`mc.newSimpleForm()` + +- 返回值:新创建的空白表单对象 +- 返回值类型:`SimpleForm` + +
+ +### 添加表单元素 + +创建完之后,你就可以用下面这些成员函数(成员方法)向对象中增加新的表单元素。 +对于某个特定的表单对象`fm`,有以下这些函数可以使用: + +#### 设置表单的标题 + +`fm.setTitle(title)` + +- 参数: + - title : `String` + 表单的标题 +- 返回值:处理完毕的表单对象(便于连锁进行其他操作) +- 返回值类型:`SimpleForm` + +
+ +#### 设置表单的内容 + +`fm.setContent(content)` + +- 参数: + - content: `String` + 表单的文本内容 +- 返回值:处理完毕的表单对象(便于连锁进行其他操作) +- 返回值类型:`SimpleForm` + +
+ +#### 向表单内增加一行按钮 + +`fm.addButton(text[,image])` + +- 参数: + - text : `String` + 按钮文本的字符串 + - image: `String` + (可选参数)按钮图片所在路径 +- 返回值:处理完毕的表单对象(便于连锁进行其他操作) +- 返回值类型:`SimpleForm` + +
+ +图片路径参数 `image` 使用材质包路径或者URL来标识按钮对应的图标。 +对于表单上的每个按钮,如下设置对应的图标 + +1. 如果使用材质包路径,图片路径应该形如 `textures/items/apple` +2. 如果使用URL路径,那么在这里放入完整的URL即可,形如 `https://www.baidu.com/img/flexible/logo/pc/result.png` +3. 如果这个按钮你不需要显示图片,那不传入此参数即可 + +
+ +### 发送表单 + +最后,在一切就绪之后,你可以将配置好的表单对象发送给玩家,并监听玩家的互动消息 +表单对象可以被反复发送,每次发送都会返回一个不同的表单ID,并在有玩家互动时调用各自设置的回调函数,不会打架。 + +对于某个玩家对象`pl`,使用函数: + +`pl.sendForm(fm,callback)` + +- 参数: + - fm : `SimpleForm` + 配置好的表单对象 + - callback : `Function` + 玩家与表单元素互动之后被调用的回调函数。 +- 返回值:发送的表单ID +- 返回值类型:`Integer` + - 如果返回值为`Null`,则代表发送失败 + +参数`callback`的回调函数原型:`function(player,id)` + +- player : `Player` + 与表单互动的玩家对象 +- id : `Integer` + 玩家点击的表单按钮的序号,从0开始编号 + 如果id为`Null`,则代表玩家取消了表单 + +
+ +## 📰 自定义表单构建器 API + +> 这些API可以协助开发者方便地构造一个自定义表单,不再需要为编写JSON麻烦而头疼 + +脚本引擎提供了**自定义表单对象**来方便地创建一个自定义表单并发送至指定玩家。 + +### 创建表单对象 + +在使用这些API之前,你需要先用这个函数创建一个空白的自定义表单对象 + +`mc.newCustomForm()` + +- 返回值:新创建的空白表单对象 +- 返回值类型:`CustomForm` + +
+ +### 添加表单元素 + +创建完之后,你就可以用下面这些成员函数(成员方法)向对象中增加新的表单元素。 +对于某个特定的表单对象`fm`,有以下这些函数可以使用: + +#### 设置表单的标题 + +`fm.setTitle(title)` + +- 参数: + - title : `String` + 表单的标题 +- 返回值:处理完毕的表单对象(便于连锁进行其他操作) +- 返回值类型:`CustomForm` + +
+ +#### 向表单内增加一行文本 + +`fm.addLabel(text)` + +- 参数: + - text : `String` + 一行文本 +- 返回值:处理完毕的表单对象(便于连锁进行其他操作) +- 返回值类型:`CustomForm` + +
+ +#### 向表单内增加一行输入框 + +`fm.addInput(title[,placeholder,default])` + +- 参数: + + - title : `String` + 输入框描述文本 + - placeholder : `String` + (可选参数)输入框内的提示字符 + - default : `String` + (可选参数)输入框中默认存在的内容 +- 返回值:处理完毕的表单对象(便于连锁进行其他操作) +- 返回值类型:`CustomForm` + +
+ +#### 向表单内增加一行开关选项 + +`fm.addSwitch(title[,default])` + +- 参数: + - title : `String` + 开关选项描述文本 + - default : `Boolean` + (可选参数)开关的默认状态 开 / 关 +- 返回值:处理完毕的表单对象(便于连锁进行其他操作) +- 返回值类型:`CustomForm` + +
+ +#### 向表单内增加一行下拉菜单 + +`fm.addDropdown(title,items[,default])` + +- 参数: + + - title : `String` + 下拉菜单描述文本 + + - items : `Array` + 下拉菜单中的选项文本列表 + + - default : `Integer` + (可选参数)下拉菜单默认选中的列表项序号。 + 序号从0开始编号。默认为0,即默认选中列表的第一项 +- 返回值:处理完毕的表单对象(便于连锁进行其他操作) +- 返回值类型:`CustomForm` + +
+ +#### 向表单内增加一行游标滑块 + +`fm.addSlider(title,min,max[,step,default])` + +- 参数: + - title : `String` + 游标滑块描述文本 + - min : `Integer` + 游标滑块最小值 + - max : `Integer` + 游标滑块最大值 + - step : `Integer` + (可选参数)游标滑块调整的最小分度值,默认为1 + - default : `Integer` + (可选参数)游标滑块默认初始格数,数值必须在最小和最大格数之间。 + 默认为0,即滑块位于滑块行的开头 +- 返回值:处理完毕的表单对象(便于连锁进行其他操作) +- 返回值类型:`CustomForm` + +
+ +#### 向表单内增加一行步进滑块 + +`fm.addStepSlider(title,items[,default])` + +- 参数: + - title : `String` + 步进滑块描述文本 + + - items : `Array` + 步进滑块的选项文本列表 + + - default : `Integer` + (可选参数)步进滑块默认初始选项。序号从0开始编号 + 默认为0,即滑块位于滑块行的开头 +- 返回值:处理完毕的表单对象(便于连锁进行其他操作) +- 返回值类型:`CustomForm` + +
+ +### 发送表单 + +最后,在一切就绪之后,你可以将配置好的表单对象发送给玩家,并监听玩家的互动消息 +表单对象可以被反复发送,每次发送都会返回一个不同的表单ID,并在有玩家互动时调用各自设置的回调函数,不会打架。 + +对于某个玩家对象`pl`,使用函数: + +`pl.sendForm(fm,callback)` + +- 参数: + - fm : `CustomForm` + 配置好的自定义表单对象 + - callback : `Function` + 玩家提交表单之后被调用的回调函数。 +- 返回值:发送的表单ID +- 返回值类型:`Integer` + - 如果返回值为`Null`,则代表发送失败 + +参数`callback`的回调函数原型:`function(player,data)` + +- player : `Player` + 与表单互动的玩家对象 +- data : `Array<...>` + 返回的表单内容数组 + 数组中中按表单上的控件顺序储存了每一个控件的内容 + 如果data为`Null`,则代表玩家取消了表单 + +
\ No newline at end of file diff --git a/docs/apis/LLSEJSPlugin.md b/docs/apis/LLSEJSPlugin.md new file mode 100644 index 00000000..d08f6e7b --- /dev/null +++ b/docs/apis/LLSEJSPlugin.md @@ -0,0 +1,60 @@ +# LLSE - Using JavaScript to Create Your First Plugin + +> This guide serves to demonstrate the very simple and straight forward process to creating your first plugin - as well as some best practices when thinking about what to make and how to do it. Experience using JavaScript previously is recommended, but not required. JavaScript is a very beginner friendly language, so don't get overwhelmed! + +## Prerequisites + +Before developing your first plugin, we will need to set up your developer environment (IDE). The choice of software you use to program is yours, but trusted and reliable software is recommended. [Atom](https://atom.io/) is lightweight editor that works well for this tutorial, otherwise [VSCode](https://code.visualstudio.com/) is also a widely used editor with a lot of powerful features. + +You will also need to set up a clean LiteLoaderBDS installation, details on how to install LiteLoaderBDS can be found [here](https://docs.litebds.com/en/#/Usage). This server will be used to test your plugin. + +With your IDE in hand, and the server installation complete, you are ready to begin! + +## What Do I Do Now? + +Developing a LLSE Plugin begins with creating your plugin's file. This file should be named "LLMyPlugin.js", replacing "MyPlugin" with what you would like to call your plugin. It should be placed in the plugins folder of your server installation. Some IDEs will allow you to create a new file and choose a location, while others will allow you to choose only after hitting "Save As". + +The first line you will need in that file is the one below. For information on parameters for this method, and information on the Script Assist API, you can go [here](https://docs.litebds.com/en/#/LLSEPluginDevelopment/ScriptAPI/ScriptHelp). + +`ll.registerPlugin(name, introduction, version, otherInformation)` + +This might confuse some developers, as `ll` should be undefined. However, this file is going to be utilized by the LiteLoaderBDS ScriptX Engine. `ll` will be automatically included during the script's runtime. This is the same with any other variables/classes you see referenced without a definition. + +Now that we have created our .js file, and registered the plugin, all we have to do from here is create an event listener. We do that by utilizing `mc`. + + +```js +mc.listen("onJoin", (player) => { + log(`${player.name} has joined the server.`); +}); +``` +> Reference: https://docs.litebds.com/en/#/LLSEPluginDevelopment/EventAPI/Listen + +In order to test your plugin, simply start the server and the server should be able to identify your plugin and successfully load it. LiteLoaderBDS console will log any logs you create, as well as any errors if your plugin, or the API fails. Iteration while developing is important. Test frequently and each step of the way to ensure that when an issue does pop up, you know exactly what you changed and can come up with a solution to fix it. + +You can reference the `mc` class as well as other special classes and constructors. The `mc` class is the bread and butter of your plugin and will allow you to do a lot of cool things. The Game Content interface has all the methods and properties available to you. +> Reference: https://docs.litebds.com/en/#/LLSEPluginDevelopment/GameAPI/Basic + +For example, we can use the player object and directly act on it to send information/manipulate a Player. + +```js +mc.listen("onJoin", (player) => { + log(`${player.name} has joined the server.`); + player.sendToast('Welcome!', 'Thanks for joining the server!'); +}); +``` + +We can reference player object properties and use that to execute other actions. + +```js +mc.listen("onJoin", (player) => { + log(`${player.name} has joined the server.`); + player.sendToast('Welcome!', 'Thanks for joining the server!'); + let loginReward = mc.newItem('minecraft:diamond', 1); + mc.spawnItem(loginReward, player.pos); +}); +``` + +This brings us to the final considerations. When making plugins, try to think of something simple and self-enclosing. Every developer wants to build a massive plugin with a ton of features, but such projects are prone to abandonment as they never truly get finished. Make a series of small plugins that have specific purpose. Add features to those plugins to enable configuration and customization. Find features or things you wish the game had and use the methods available in LiteLoaderBDS to make them happen. There are truly unlimited possibilities with LiteLoader's API. + +If you run into any issues while developing, questions, comments or concerns can be answered by joining the [Discord](https://discord.gg/5HU3cJsVZ5) - or by opening an issue on the LiteLoaderBDS Github Repo. diff --git a/docs/apis/LLSEJSPlugin.zh.md b/docs/apis/LLSEJSPlugin.zh.md new file mode 100644 index 00000000..eebced37 --- /dev/null +++ b/docs/apis/LLSEJSPlugin.zh.md @@ -0,0 +1,62 @@ +# 使用JavaScript创造你的首个脚本插件 + +> 本指南旨在展示创建你的第一个插件的非常简单和直接的过程--以及在考虑做什么和如何做时的一些最佳做法。建议有使用JavaScript的经验,但不是必须的。JavaScript是一种对初学者非常友好的语言,所以不要被淹没了! + +## 先决条件 + +在开发你的第一个插件之前,我们需要设置你的开发环境。你用来编程的软件由你自己选择,但建议使用可信和可靠的软件。 +- [Atom](https://atom.io/) 是轻量级的编辑器,在本教程中很好用。 +- [VSCode](https://code.visualstudio.com/) 也是一个广泛使用的编辑器,具有很多强大的功能。 + +
+ +你还需要建立一个干净的LiteLoaderBDS安装,关于如何安装LiteLoaderBDS的细节可以在[这里](https://docs.litebds.com/zh-Hans/#/Usage)找到。这个服务器将被用来测试你的插件。 + +有了你的开发环境,并完成了服务器的安装,你就可以开始了! + +## 我现在该做什么? + +开发一个脚本插件,首先要创建你的插件文件。这个文件应该命名为 "LLMyPlugin.js",将 "MyPlugin" 替换为你想要的插件名称。它应该被放在你的服务器安装的插件文件夹中。有些开发环境会允许你创建一个新文件并选择一个位置,而其他开发环境则允许你在点击 "另存为" 后才选择。 + +你在该文件中需要的第一行是下面这行。关于这个方法的参数信息,以及关于Script Assist API的信息,你可以去[这里](https://docs.litebds.com/zh-Hans/#/LLSEPluginDevelopment/ScriptAPI/ScriptHelp)。 + +`ll.registerPlugin(name, introduction, version, otherInformation)`。 + +这可能会使一些开发者感到困惑,因为`ll`应该是未定义的。然而,这个文件将被LiteLoaderBDS ScriptX引擎所利用。`ll`将在脚本运行时自动包含。这与你看到的任何其他没有定义的变量/类的引用是一样的。 + +现在我们已经创建了我们的.js文件,并注册了插件,我们要做的就是创建一个事件监听器。我们通过使用`mc`来实现。 + + +```js +mc.listen("onJoin", (player) => log(`${player.name}已经加入服务器。`)); +``` +> 参考资料: https://docs.litebds.com/zh-Hans/#/LLSEPluginDevelopment/EventAPI/Listen + +为了测试你的插件,只需启动服务器,服务器应该能够识别你的插件并成功加载它。LiteLoaderBDS控制台将记录您创建的任何日志,以及您的插件或API失败时的任何错误。开发时的迭代很重要。经常测试,每一步都要确保当问题出现时,你清楚地知道你改变了什么,并能想出解决方案来解决它。 + +你可以引用`mc`类,以及其他特殊的类和构造函数。`mc`类是你的插件的面包和黄油,将允许你做很多很酷的事情。游戏内容接口有所有的方法和属性供你使用。 +>参考:https://docs.litebds.com/en/#/LLSEPluginDevelopment/GameAPI/Basic + +例如,我们可以使用玩家对象并直接对其采取行动,以发送信息/操纵玩家。 + +```js +mc.listen("onJoin", (player) => { + log(`${player.name}已经加入服务器。`)。 + player.sendToast('欢迎!', '感谢您游玩本服!'); +}); +``` + +我们可以引用玩家对象的属性,并使用它来执行其他动作。 + +```js +mc.listen("onJoin", (player) => { + log(`${player.name}已经加入服务器。`)。 + player.sendToast('欢迎!', '感谢您游玩本服!'); + let loginReward = mc.newItem('minecraft:diamond', 1); + mc.spawnItem(loginReward, player.pos)。 +}); +``` + +这给我们带来了最后的考虑。在制作插件时,尽量想一些简单的、自我封闭的东西。每个开发者都想建立一个具有大量功能的大型插件,但这样的项目很容易被放弃,因为它们从未真正完成。做一系列有特定目的的小插件。为这些插件添加功能,以实现配置和定制。找到你希望游戏拥有的功能或事物,并使用LiteLoaderBDS中的方法来实现它们。使用LiteLoaderBDS的API确实有无限可能。 + +如果您在开发过程中遇到任何问题,可以通过加入[Telegram](https://t.me/LiteLoaderBDSChs)/[Discord](https://discord.gg/5HU3cJsVZ5)--或在LiteLoaderBDS Github 仓库上开立一个问题,来回答您的问题、意见或担忧。 \ No newline at end of file diff --git a/docs/apis/LanguageSupport.md b/docs/apis/LanguageSupport.md new file mode 100644 index 00000000..2e91a397 --- /dev/null +++ b/docs/apis/LanguageSupport.md @@ -0,0 +1,104 @@ +# 📋 LLSE - Multi development Language Support + +## 🌏 Current Status + +With the support of the [ScriptX](https://github.com/Tencent/ScriptX) project, LLSE adapts to multiple development languages using the same set of source code. +At the same time, the API remains consistent, allowing various languages to share the same development document. It greatly reducing maintenance difficulties. + +Currently, LLSE supports writing plugins in the following languages: + +| Language backend | Remarks | +| ---------------- | ------------------------------------------------------------ | +| `JavaScript` | Using QuickJS engine, with support for ES Modules | +| `Lua` | Using CLua engine | +| `Node.js` | Modify Node.js to work with embedding, with support for npm package management | +| `Python` | Using CPython engine, with support for pip package management | + +> [!INFO] +> +> If you need to write plugins in compiled languages such as C++, Go, .NET, etc., please go to [Home](../zh-Hans) for other language documentation + +## JavaScript language support description + +- Support for simple JavaScript plugins using the QuickJS engine, a lightweight engine with a low resource footprint +- The current version of QuickJS supports up to ES2020, and natively supports ES Modules which allows developers to easily manage projects. +- Package management is not supported. If needed, you can use Node.js for plugin development and use npm for package management +- Use `jsdebug` command in the BDS console to enter and exit the QuickJs interactive command line environment. This feature facilitates some simple testing when writing plugins + +
+ +## Lua language support description + +- Use the CLua engine, support require +- Since the Rocks package management mechanism requires the introduction of a compiler, the implementation is not available at this time. If you need to depend on extensions, you can compile them manually and introduce them into your project (e.g. SQLite) +- Use `luadebug` command in the BDS console to enter and exit the Lua interactive command line environment. This feature facilitates some simple testing when writing plugins + +
+ +## Node.js support description + +- LLSE makes it possible to work in embedded mode by implementing the Node.js starter code itself, and isolates the execution environment for different plugins +- Created interface to implement programmic support for npm. Support installing third-party extension dependencies via package.json + +#### ⭐ **Node.js Plugin Development** + +1. First, install NodeJs +2. Create a new directory for plugin development. Launch the terminal in this directory and execute `npm init`. Follow npm to create a new project and fill in the information about the project. +3. Write the plugin code in the filled entry point file +4. If necessary, create multiple source files and bring them in via require. Properly splitting the source code into files can help improve the clarity of the project structure and facilitate further maintenance and expansion of the plugin. + +#### ⭐ **Node.js Plugin Packaging & Deployment** + +- After the plugin is finish, package `package.json` and all the plugin source code into a zip archive and **change the file name suffix to .llplugin** +- The `node_modules` directory should not be packed in the archive +- Distribute the **.llplugin** file as a plugin. When installing the plugin, just place this file directly into the plugins directory +- LLSE will automatically recognize the **.llplugin** file when BDS launch, extract it to the `plugins/nodejs/` directory, and automatically execute `npm install` in the directory to install the dependency packages. No manual intervention is needed for the whole process + +
+ +## Python language support description + +- Use CPython engine, Python version 3.10.9. Support for installing third-party extension dependencies for plugins using pip package management. Support for multi-file plugin development and import. Support for modern project management. +- Use `pydebug` command in the BDS console to enter and exit the Python interactive command line environment. This feature facilitates some simple testing when writing plugins + +#### **Python Single-File Plugin Development ** + +- To help developers unfamiliar with Python to get started quickly, we provide a way to write and load single-file Python plugin. +- Single file plugins are similar to QuickJs and Lua plugins: Just write a single .py file as a plugin, place the plugin directly into the plugins directory, and it will be loaded and run when BDS is started. +- It has many disadvantages: does not support plugin metadata storage, does not support source code in multiple files, does not support pip third-party packages. Only for developers familiar with LLSE's Python environment, or to develop very simple plugins to use. + +#### ⭐ **Python Multi-File Plugin Development** + +- For formal Python plugins, this method is highly recommended. Multi-file plugins support all full Python features. +- LLSE uses the `pyproject.toml` project file for metadata storage (similar to `package.json` in Node.Js). This project file is recommended to be automatically generated using PDM package manager ([pdm-project/pdm](https://github.com/pdm-project/pdm)), which supports modern project features to facilitate plugin project creation and maintenance. + +##### **The turtorial for Python plugins development: ** +1. First, install Python 3.10.9 +2. Run `pip install --user pdm` in terminal to install the pdm package management tool +3. Create a new directory for plugin development. Launch the terminal in this directory and execute `pdm init`. Follow the prompts of the pdm tool to create a new project and fill in the information about the project. + - If you need to install dependency packages, execute `pdm add ` in the project directory + - All project metadata and dependency data will be automatically stored in `pyproject.toml`. No need to write it manually. You can also open this file to change metadata information such as version number, description, etc. + - In addition to using the `pdm add` command, you can also manually write the project dependencies directly to `requirements.txt`. When installing the plugin, the dependencies described in `pyproject.toml` and `requirements.txt` will be processed and installed automatically. + +3. Next, create the `__init__.py` file and write the plugin code in it. When loading the plugin, the Python interpreter will read and execute this file. +4. If necessary, you can create multiple source files and use import to include them. Properly splitting the source code into files helps improve the clarity of the project structure and facilitates further maintenance and extension of the plugin. + +#### ⭐ **Python Plugin Packaging & Deployment** + +- After the plugin is finished, package `pyproject.toml` and all plugin source code into a zip archive and **change the filename suffix to .llplugin** +- Do not include the `__pycache__` and `__pypackages__` directories in the zip archive +- Distribute the **.llplugin** file as a plugin. When installing the plugin, place it directly into the `plugins` directory. +- The scripting engine will automatically recognize the **.llplugin** file and unzip it to the `plugins/python/plugin name` directory, and automatically execute `pip install` to install the dependencies. No manual intervention is needed for the whole process. + +#### **Known issues with Python plugin development** + +To be fair, the quality and maintenance of CPython's code is in a somewhat worrisome state. Given below are some problems to be aware of when developing Python plugins, many of which are caused by bugs in CPython itself: + +1. Do not use `threading`, `asyncio` and other features for the time being + - LLSE uses CPython's sub-interpreter as the core unit of engine scheduling, but CPython itself has long had bad support for the sub-interpreter, and there are many bugs that are hard to explain. The GIL api that is currently used for these mechanisms does not take into account the existence of sub-interpreters, so deadlocks and crashes will occur once they are used. + - Developers with parallel computing needs can temporarily use `multiprocess` to parallelize multiple processes. + - Python 3.12 is scheduled to have targeted fixes for sub-interpreter and GIL-related bugs, and LLSE will adapt CPython 3.12 to address this issue after its release. +2. `sys.stdin` is disabled for all Python engines + - This is another CPython bug, see https://github.com/python/cpython/issues/83526 for details + - In addition, even if the CPython engine is not loaded in the above case, there will be a problem of stdin grabbing, causing some tools that use the input redirection to fail + - Therefore, we hit a patch to disable `sys.stdin` for all Python engines. We will not restore it until future versions of CPython to completely solve this series of bugs. diff --git a/docs/apis/LanguageSupport.zh.md b/docs/apis/LanguageSupport.zh.md new file mode 100644 index 00000000..549695ed --- /dev/null +++ b/docs/apis/LanguageSupport.zh.md @@ -0,0 +1,111 @@ +# 📋 脚本引擎 - 特定脚本语言开发须知 + +## 🌏 开发语言支持情况 + +通过 [ScriptX](https://github.com/Tencent/ScriptX) 项目的支持,脚本引擎使用同一套源代码,对多种开发语言进行了适配。 +同时,由于API保持一致,使各种语言得以共享一份开发文档,大大降低了维护难度。 + +目前,脚本引擎支持使用如下语言编写插件: + +| 语言后端 | 备注 | +| ------------------ | ---------------------------------------------- | +| `JavaScript` | 使用 QuickJS 引擎运行插件,支持 ES Module 机制 | +| `Lua` | 使用 CLua 引擎运行插件 | +| `Node.js` | 改造 Node.js 使其适合嵌入工作,支持 npm 包管理 | +| `Python` | 使用 CPython 引擎运行插件,支持 pip 包管理 | + +> [!INFO] +> +> 如果需要使用 C++、Go、.NET 等编译式语言编写插件,请移步 [主页](zh_CN/) 查看其他语言文档 + +## JavaScript 语言支持说明 + +- 使用 QuickJS 引擎对简单的 JavaScript 插件提供支持,轻量级引擎资源占用较少 +- QuickJS 当前版本支持到 ES2020 语言特性,同时原生支持 ESModule 模块机制,可以方便开发者进行项目管理 +- 暂不支持包管理机制,如果需要请使用 Node.js 进行插件开发,使用 npm 包管理 +- 在BDS控制台中使用`jsdebug`命令进入和退出 QuickJs 交互式命令行环境。此功能便于编写插件时进行一些简单的测试 + +
+ +## Lua 语言支持说明 + +- 使用 CLua 引擎,支持使用 require 进行简单的项目管理 +- 由于 Rocks 包管理机制需要引入编译器,因此暂不提供相关实现。如果需要依赖扩展可以手动编译后引入项目进行使用(如 SQLite 等常用库) +- 在BDS控制台中使用`luadebug`命令进入和退出 Lua 交互式命令行环境。此功能便于编写插件时进行一些简单的测试 + +
+ +## Node.js 支持说明 + +- LLSE 通过自行实现 Node.js 启动代码,使其可以在嵌入式模式下工作,并实现了不同插件的执行环境隔离 +- 自行编写接口实现了对 npm 的 programmic 支持。支持通过 package.json 安装第三方扩展依赖包 + +#### ⭐ **Node.js 插件开发方法** + +1. 首先,安装NodeJs +2. 创建一个新的目录进行插件开发。在此目录启动终端执行`npm init`命令。根据 npm 的提示创建新项目,填写项目的相关信息。 +3. 在填写的入口点文件中编写插件代码 +4. 如果有需要,可以创建多个源码文件,并且通过 require 来引入他们。合理的对源码进行分文件拆分编写有助于提高项目结构的清晰度,方便后续对插件进行进一步的维护和扩展。 + +#### ⭐ **Node.js 插件打包 & 部署方法** + +- 在插件编写完成之后,请将 `package.json` 以及所有插件源码打包为一个zip压缩包,并**将文件名后缀修改为 .llplugin** +- `node_modules` 目录请勿打包在压缩包之中 +- 将 **.llplugin** 文件作为插件分发,安装插件时直接将此文件放置到 plugins 目录即可 +- 在开服时,脚本引擎会自动识别 **.llplugin** 文件,将其解压到`plugins/nodejs/插件名`目录,并在目录中自动执行 `npm install`安装依赖包,整个过程无需人工干预 + +
+ +## Python 语言支持说明 + +- 使用 CPython 引擎,Python版本为3.10.9。支持使用 pip 包管理机制为插件安装第三方扩展依赖包,支持多文件插件开发和 import,支持现代项目管理机制 +- 在BDS控制台中使用`pydebug`命令进入和退出 Python 交互式命令行环境。此功能便于编写插件时进行一些简单的测试 + +#### **Python 单文件插件开发方法** + +- 为了方便不熟悉Python的开发者快速上手,我们提供了一种简单的 Python 插件支持:单文件插件。 +- 单文件插件类似QuickJs和Lua插件。只要编写单个.py文件作为插件,将插件直接放置到 plugins目录中,在开服时就会被加载运行 +- 单文件插件缺点:不支持插件元数据储存、不支持源码分文件、不支持pip第三方包。单文件插件仅用于开发者熟悉LLSE的Python环境,或者开发非常简易的插件而使用。 + +#### ⭐ **Python 多文件插件开发方法** + +- 对于大型、正式的Python插件,强烈建议使用此方法进行开发。多文件插件支持所有完整的Python特性。 +- LLSE 使用`pyproject.toml` 项目文件进行元数据储存(类似 Node.Js 的`package.json`)。此项目文件推荐使用支持现代项目特性的 PDM 包管理器([pdm-project/pdm](https://github.com/pdm-project/pdm))自动生成,以便于进行插件项目的创建和维护。 + +##### **下面是具体的插件开发流程:** + +1. 首先,安装Python 3.10.9 + +2. 在终端中执行`pip install --user pdm`命令安装 pdm 包管理工具 + +3. 创建一个新的目录进行插件开发。在此目录启动终端执行`pdm init`命令。根据pdm工具的提示创建新项目,填写项目的相关信息。 + + - 如果需要安装依赖包,在项目目录执行`pdm add <依赖包名>`即可 + + - 所有的项目元数据和依赖数据都会被自动储存在`pyproject.toml` 中,无需手动编写。你也可以打开此文件修改版本号、描述等元数据信息 + + - 除了使用`pdm add`命令之外,你也可以直接把项目依赖手动写在`requirements.txt`当中。在安装插件时,`pyproject.toml`和`requirements.txt`中描述的依赖都将被处理并自动安装。 + +4. 接下来创建`__init__.py`文件,并在其中编写插件代码。加载插件时,Python解释器会首先读取并执行这个文件。 + +5. 如果有需要,可以创建多个源码文件,并且通过 import 来引入他们。合理的对源码进行分文件拆分编写有助于提高项目结构的清晰度,方便后续对插件进行进一步的维护和扩展。 + +#### ⭐ **Python 多文件插件打包 & 部署方法** + +- 在插件编写完成之后,请将 `pyproject.toml`以及所有插件源码打包为一个zip压缩包,并**将文件名后缀修改为 .llplugin** +- `__pycache__` 和`__pypackages__` 等目录请勿打包在压缩包之中 +- 将 **.llplugin** 文件作为插件分发,安装插件时直接将此文件放置到 plugins 目录即可 +- 在开服时,脚本引擎会自动识别 **.llplugin** 文件,将其解压到`plugins/python/插件名`目录,并在目录中自动执行 `pip install`安装依赖包,整个过程无需人工干预 + +#### **Python插件开发的已知问题** + +平心而论,CPython的代码质量和维护状况有些堪忧。下面给出了一些开发Python插件时需要注意的地方,其中有不少都是由CPython本身的Bug引起的: + +1. 暂时不要使用`threading` `asyncio`等特性 + - LLSE使用CPython的子解释器作为引擎调度的核心单位,然而CPython自身长期以来对子解释器机制的支持并不完善,存在众多Bug,令人一言难尽。目前上面这些机制所需要使用到的GIL api内部并没有考虑到子解释器的存在,因此一旦使用会发生死锁、崩溃等问题。 + - 如果有并行计算需求的开发者可以暂时使用`multiprocess`进行多进程并行 + - Python3.12 按计划将对子解释器和GIL相关bug做出针对性的修复,届时LLSE将对CPython3.12进行适配,解决此问题。Py3.12预计在2023年10月份左右推出,请耐心等待 +2. 所有Python引擎的`sys.stdin`被禁用 + - 这是另外一个CPython的bug,具体详见:https://github.com/python/cpython/issues/83526 + - 另外,即使不是上述情况下加载的CPython引擎,也会出现抢夺stdin的问题,导致部分使用了输入重定向机制的工具失效 + - 因此我们打patch禁用了所有Python引擎的`sys.stdin`,等待后续版本CPython将此系列bug彻底解决之后,再视情况恢复 diff --git a/docs/apis/NativeAPI/NativeFunction.zh.md b/docs/apis/NativeAPI/NativeFunction.zh.md new file mode 100644 index 00000000..8ebbb857 --- /dev/null +++ b/docs/apis/NativeAPI/NativeFunction.zh.md @@ -0,0 +1,116 @@ +## NativeFunction原生函数 + +此API集包含如下两种类型`NativeFunction`和`NativeHook`,其中`NativeHook`为特化的实现,只包含`call`,`address`两个属性 + +### Symbol获得函数 + +自动解析Symbol并得到一个可调用的函数,如解析失败,抛出异常 + +`static NativeFunction.fromSymbol(symbol)` + +- 参数: + - String: `symbol` + 需要解析的函数 +- 返回值:原生函数实例 +- 返回值类型:`NativeFunction` + +
+ +### Describe获得函数 + +描述函数类型并得到一个不可调用的函数,如需调用,则还需手动设置Address属性 + +`static NativeFunction.fromDescription(ReturnValue: NativeTypes.Void, Params: [NativeType.Int......])` + +- 参数: + - Enum-NativeTypes: `ReturnValue` + 返回值类型 + - Enum-NativeTypes...: `Params` + 参数类型,从左到右直接传递 +- 返回值:原生函数实例 +- 返回值类型:`NativeFunction` + +
+ +### Script获得函数 + +描述函数类型并得到一个来自脚本的函数,其被包装为可直接在本机代码中调用的函数 + +`static NativeFunction.fromScript(ReturnValue: NativeTypes.Void, Params: [NativeType.Int......], Callback: func(Params...){})` + +- 参数: + - Enum-NativeTypes: `ReturnValue` + 返回值类型 + - Enum-NativeTypes...: `Params` + 参数类型,从左到右直接传递 + - Function: `Callback` + 回调函数,当该原生包装函数被调用后,会调用此函数 +- 返回值:原生函数实例 +- 返回值类型:`NativeFunction` + +
+ +### Hook函数钩子 + +改写指定地址函数的头部,设置回调函数,当原函数调用时则会调用回调函数 +如果需要保留原始功能,请记得在回调函数内调用原函数 + +`NativeFunction.hook(function)` + +- 参数: + - Function: `function` + 回调函数,请注意保持参数类型与NativeFunction描述的一致 +- 返回值:原函数 +- 返回值类型:`NativeHook` + +
+ +### call功能 + +通过虚拟对象call,调用对应函数 + +`NativeFunction.call(params...)` + +- 参数: + - Parameters: `params` + 对应NativeFunction所描述的函数参数 +- 返回值: 对应NativeFunction所描述的返回类型 +- 返回值类型:`Value` + +
+ +### address属性 + +函数指针的指针值 + +`NativeFunction.address` + +- Setter: + - NativePointer + - int64 +- Getter + - int64 + +
+ +## NativeType参数类型 + +此Enum展示了所有可用于函数参数以及返回的类型 + +|Void| +|Bool| +|Char| +|UnsignedChar| +|Short| +|UnsignedShort| +|Int| +|UnsignedInt| +|Long| +|UnsignedLong| +|LongLong| +|UnsignedLongLong| +|Float| +|Double| +|Pointer| + +
\ No newline at end of file diff --git a/docs/apis/NativeAPI/NativePatch.zh.md b/docs/apis/NativeAPI/NativePatch.zh.md new file mode 100644 index 00000000..e3b72439 --- /dev/null +++ b/docs/apis/NativeAPI/NativePatch.zh.md @@ -0,0 +1,51 @@ +## NativePatch补丁工具 + +此类工具用于对指定地址进行补丁操作,通常用于对汇编的修改,请确保有相关知识储备 + +### PatternSearch搜索 + +在全局范围内搜索指定Bytes并获得第一个结果地址 + +`NativePatch.search(pattern)` + +- 参数: + - String: `pattern` + 描述匹配模式的字符串 +- 返回值:结果地址 +- 返回值类型:`NativePointer` + +
+ +### Patch应用补丁 + +对指定位置进行Patch操作 + +`NativePatch.patch(pointer, expect, target)` + +- 参数: + - NativePointer: `pointer` + 目标地址 + - String: `expect` + 原始字节 + - String: `target` + 目标字节 +- 返回值:成功结果 +- 返回值类型:`Bool` + +
+ +### Dump展示内存 + +以十六进制字符串展示目标地址的指定长度内存 + +`NativePatch.dump(pointer, size)` + +- 参数: + - NativePointer: `pointer` + 目标地址 + - int64: `size` + 长度 +- 返回值:内存内容 +- 返回值类型:`String` + +
\ No newline at end of file diff --git a/docs/apis/NativeAPI/NativePointer.zh.md b/docs/apis/NativeAPI/NativePointer.zh.md new file mode 100644 index 00000000..3f8f4be9 --- /dev/null +++ b/docs/apis/NativeAPI/NativePointer.zh.md @@ -0,0 +1,121 @@ +## NativePointer原生指针 + +此API旨在帮助开发者操作原生指针 + +> 由于x64调用约定,任何对象(size>8)均以引用方式传递,欲要了解更多相关细节,请参考[msdoc: x64 calling convention](https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention) + +### 内存申请 + +此函数帮助申请一块指定大小内存 + +`static NativePointer.malloc(size)` + +- 参数: + - int64: `size` + 欲申请的内存的大小 +- 返回值:指向新内存的指针 +- 返回值类型:`NativePointer` + +
+ +### 销毁内存 + +销毁一个指定内存块 + +`static NativePointer.free(block)` + +- 参数: + - NativePointer: `block` + 需要销毁的内存块 + +
+ +### 指针偏移 + +获取相对某个指针偏移后的地址 + +`NativePointer.offset(offset)` + +- 参数: + - int32: `offset` + +- 返回值:偏移后指针 +- 返回值类型:`NativePointer` + +
+ +### 获得符号地址 + +获得一个MCAPI符号地址,等同于CPP中`dlsym` + +`NativePointer.fromSymbol(symbol)` + +- 参数: + - String: `symbol` + 需要查询的符号 +- 返回值:查询结果,若查询失败则返回空指针 +- 返回值类型:`NativePointer` + +
+ +### 获得地址实例 + +获得一个指定地址的指针实例 + +`NativePointer.fromAddress(address)` + +- 参数: + - String/int64: `address` + 地址,以16进制字符串或数字表示 +- 返回值:对应地址的指针实例 +- 返回值类型:`NativePointer` + +
+ +### 获得指针地址 + +获取原始指针地址 + +`NativePointer.asRawAddress` + +- 返回值:以数字形式表示的指针所指地址 +- 返回值类型:`int64` + +
+ +### 获得指针地址描述 + +获取原始指针地址(16进制字符串) + +`NativePointer.asHexAddress` + +- 返回值:以十六进制形式表示的指针所指地址 +- 返回值类型:`String` + +
+ +### 读写指针内存 + +以下虚拟属性为帮助访问指针内容设立,可用type如下表所示 + +`NativePointer.type` + +|访问名|大小|特殊说明| +|:--|:--:|:--| +|byte|1|此属性读写通过十六进制字符串完成| +|int8|1|| +|uint8|1|| +|int16|2|| +|uint16|2|| +|int32|3|| +|uint32|4|| +|long|4|| +|ulong|4|| +|int64|8|| +|uint64|8|| +|float|4|| +|double|8|| +|string|32|此属性表示std::string*| +|bool|1|| + +
\ No newline at end of file diff --git a/docs/apis/NativeAPI/Summary.zh.md b/docs/apis/NativeAPI/Summary.zh.md new file mode 100644 index 00000000..9d2ef551 --- /dev/null +++ b/docs/apis/NativeAPI/Summary.zh.md @@ -0,0 +1,7 @@ +# 脚本层原生接口(FFI) + +通过在脚本层提供FFI(Foreign Function Interface)相关接口,有助于简化小型修复插件的开发过程,并通过脚本引擎获得较为稳定的ABI,便于在多个版本之间共享插件 + +> 此类API只适用于对非性能敏感的工作流程,对调用者拥有对原生语言较为透彻及准确的理解,否则极容易带来意外的情况。 +> 若需要高性能底层接口,请使用原生语言。 +> 由于FFI接口规范仍然在设计当中,接口等相关信息可能在没有通知的情况下随时改变。 diff --git a/docs/apis/NbtAPI/NBT.md b/docs/apis/NbtAPI/NBT.md new file mode 100644 index 00000000..9313bdd9 --- /dev/null +++ b/docs/apis/NbtAPI/NBT.md @@ -0,0 +1,69 @@ +# LLSE - NBT Documentation + +> **NBT** (**N**amed **B**inary **T**ags) format is a storage format used in Minecraft to store data into files. +> The NBT format stores data in a tree structure with many *tags*. All tags have an independent ID and name. +> +> --- Minecraft Wiki + +This provides scripts with the ability to manipulate the **NBT** data type. **NBT** interface support greatly improves the scalability of the game. + +In the game, a node called **NBT tag** is used to identify an item of NBT data. A variety of data types such as ordinary data, List, Compound, etc. can be stored in NBT tags. + +In LiteLoader ScriptEngine, each NBT data type has its corresponding data type, and we collectively call them "NBT objects". +The comparison of the LLSE type with the NBT data type is as follows: + +| NBT Data Type | Corresponding NBT Object Type | Type Description Wiki) | +| ----------- | ----------------- | ----------------------------- | +| `End` | `NbtEnd` | Used to mark the end of a tag. | +| `Byte` | `NbtByte` | Signed byte or boolean (8 bits) | +| `Short` | `NbtShort` | Signed Short (16-bit) | +| `Int` | `NbtInt` | Signed Integer (32-bit) | +| `Long` | `NbtLong` | Signed Long (64-bit) | +| `Float` | `NbtFloat` | Single precision floating point number | +| `Double` | `NbtDouble` | Double precision floating point number | +| `ByteArray` | `NbtByteBuffer` | Byte Array | +| `String` | `NbtString` | UTF-8 string | +| `List` | `NbtList` | NBT List (similar to array) | +| `Compound` | `NbtCompound` | NBT Tags (Similar to a list of Key-Value pairs)| + +Each data type may have a slightly different usage interface. They are introduced separately below: + +
+ +## 🎈 NBT Object Generic Interface + +Each NBT object contains some executable member functions (member methods). +For any kind of NBT object, there are the following general interfaces. named `nbt`. An example of an NBT object of: + +#### Get the Data Type Stored by the NBT Object + +`nbt.getType()` + +- Return value: The data type stored by this NBT object. +- Return value type: `Enum` + +Possible return values are: `NBT.End` `NBT.Byte` `NBT.Short` `NBT.Int` `NBT.Long` +`NBT.Float` `NBT.Double` `NBT.ByteArray` `NBT.String` +`NBT.List` `NBT.Compound` + +
+ +#### Convert NBT Object to JSON String + +`nbt.toString([space])` + +- Parameter: + - space : `Integer` + (Optional parameter) If you want to format the output string, pass this parameter. + Represents the number of spaces per indent, so the resulting string is more human-readable. + This parameter defaults to `-1`, i.e. the output string is not formatted. +- Return value: The JSON form of the NBT object. +- Return value type: `String` + +Hint: If this NBT object stores the `List` or `Compoundtype`, they will expand recursively to `Array` or `Object`. +If this NBT object stores the `ByteArray` Type, the output byte string will be base64 encoded before output. + +> The string output by the above function conforms to the JSON standard format, but cannot be deserialized. +> If there is a need for deserialization, please use the **SNBT** interface provided by the NBT tag class. + +
\ No newline at end of file diff --git a/docs/apis/NbtAPI/NBT.zh.md b/docs/apis/NbtAPI/NBT.zh.md new file mode 100644 index 00000000..60a93a2e --- /dev/null +++ b/docs/apis/NbtAPI/NBT.zh.md @@ -0,0 +1,69 @@ +# 脚本引擎 - NBT 文档 + +> **NBT(二进制命名标签**,**N**amed **B**inary **T**ags**)** 格式为Minecraft中用于向文件中存储数据的一种存储格式。 +> NBT格式以树形结构并配以许多*标签* 的形式存储数据。所有的标签都有一个独立的ID和名称。 +> +> --- Minecraft Wiki + +这里为脚本提供了操作 **NBT** 数据类型的能力。 **NBT** 接口的支持,极大的提高了游戏的可扩展性 + +游戏中,使用被称为 **NBT标签 **的节点来标识一项NBT数据。NBT标签中可以储存普通数据、List、Compound 等多种数据类型。 + +在LiteLoader ScriptEngine中,每种NBT数据类型都有其对应的数据类型,我们统称他们为「NBT对象」。 +脚本引擎类型与NBT数据类型的对照如下: + +| NBT数据类型 | 对应的NBT对象类型 | 类型说明(来自MC Wiki) | +| ----------- | ----------------- | ----------------------------- | +| `End` | `NbtEnd` | 用于标记标签的结尾 | +| `Byte` | `NbtByte` | 有符号字节 或 布尔值(8位) | +| `Short` | `NbtShort` | 有符号短整型(16位) | +| `Int` | `NbtInt` | 有符号整形(32位) | +| `Long` | `NbtLong` | 有符号长整型(64位) | +| `Float` | `NbtFloat` | 单精度浮点数 | +| `Double` | `NbtDouble` | 双精度浮点数 | +| `ByteArray` | `NbtByteBuffer` | 字节数组 | +| `String` | `NbtString` | UTF-8 字符串 | +| `List` | `NbtList` | NBT 列表(类似于 数组) | +| `Compound` | `NbtCompound` | NBT 标签(类似于 键值对列表) | + +每种数据类型可能有略微不同的使用接口。下面对他们作分别介绍 + +
+ +## 🎈 NBT 对象通用接口 + +每一个 NBT 对象都包含一些可以执行的成员函数(成员方法) +对于任何种类的NBT对象,都有下面这些通用的接口。以名为`nbt`的某个NBT对象为例: + +#### 获取NBT对象储存的数据类型 + +`nbt.getType()` + +- 返回值:此NBT对象储存的数据类型 +- 返回值类型:`Enum` + +可能的返回值有:`NBT.End` `NBT.Byte` `NBT.Short` `NBT.Int` `NBT.Long` +`NBT.Float` `NBT.Double` `NBT.ByteArray` `NBT.String` +`NBT.List` `NBT.Compound` + +
+ +#### 将NBT对象转换为JSON字符串 + +`nbt.toString([space])` + +- 参数 + - space : `Integer` + (可选参数)如果要格式化输出的字符串,则传入此参数 + 代表每个缩进的空格数量,这样生成的字符串更适合人阅读 + 此参数默认为-1,即不对输出字符串进行格式化 +- 返回值:对应的JSON字符串 +- 返回值类型:`String` + +提示:如果这个NBT对象储存的是`List`或者`Compound`类型,将递归展开为`Array`或`Object` +如果这个NBT对象储存的是`ByteArray`类型,输出的字节串将先进行base64编码后再输出 + +> 上述函数输出的字符串符合JSON标准格式,但是无法进行反序列化。 +> 如果有反序列化的需求,请使用 NBT标签类 提供的的 **SNBT** 接口 + +
\ No newline at end of file diff --git a/docs/apis/NbtAPI/NBTCompound.md b/docs/apis/NbtAPI/NBTCompound.md new file mode 100644 index 00000000..e975461d --- /dev/null +++ b/docs/apis/NbtAPI/NBTCompound.md @@ -0,0 +1,237 @@ +## 📒 NbtCompound - Tag Type + +A `NbtCompound` represents a complete tag, which stores a series of key-value pairs, similar to a data structure such as an object/table. +pass `NbtCompound` Only the interface of the object can perform some operations unique to the NBT tag. + +### Get an NBT Tag Object + +#### Parse From an Existing NBT Object + +See [NbtList - List Type](/LLSEPluginDevelopment/NbtAPI/NBTList.md) and [NbtCompound - Tag Type](/LLSEPluginDevelopment/NbtAPI/NBTCompound.md) documentation. + +
+ +#### Create a New NBT Tag Object + +[JavaScript] `new NbtCompound([data])` +[Lua] `NbtCompound([data])` + +- Parameter: + - data: Object (Optional parameter) + Pass in an object consisting of NBT objects. Objects are allowed to contain other array/object structures, but the contents must be NBT objects. +- Return value: The generated NBT Object +- Return value type: `NbtList` + - If the creation fails, an exception will be thrown. + +[JavaScript] +```js +var nbt = new NbtCompound({ + "name1": new NbtInt(3), + "name2": new NbtString("test"), + "name3": new NbtList([ + new NbtFloat(4.0), + new NbtFloat(6.0) + ]), + "name4": new NbtLong(66666) + }); +``` +[Lua] +```lua +local nbt = NbtCompound({ + "name1" = NbtInt(3), + "name2" = NbtString("test"), + "name3" = NbtList({ + NbtFloat(4.0), + NbtFloat(6.0) + }), + "name4" = NbtLong(66666) + }); +``` + + + +#### Generate NBT Tag Object From SNBT String + +`NBT.parseSNBT(snbt)` + +- Parameter: + - snbt : `String` + The SNBT string you want to parse. +- Return value: The generated NBT object. +- Return value type: `NbtCompound` + - If the return value is `Null` it means the parsing failed. + +> The SNBT string must contain a complete Compound. + +
+ +#### Generate NBT Tag Objects From Binary NBT Data + +`NBT.parseBinaryNBT(nbt)` + +- Parameter: + - nbt : `ByteBuffer` + The binary NBT data you want to parse. +- Return value: The generated NBT object. +- Return value type: `NbtCompound` + - If the return value is `Null` it means the parsing failed. + +> A complete Compound must be included in the binary NBT data + +
For an object `comp` of type `NbtCompound`, there are the following interfaces: + +#### Get All Keys + +`comp.getKeys()` + +- Return value: All keys in Compound. +- Return value type: `Array` + +
+ +#### Get the Data Type of the Value Corresponding to the Key + +`comp.getTypeOf(key)` + +- Parameter: + - key: `String` + The name of the key to query. +- Return value: The data type of the corresponding value. +- Return value type: `Enum` + - If the NBT to read does not exist, it will return `Null`. + +Possible return values ​​are: `NBT.End` `NBT.Byte` `NBT.Short` `NBT.Int` `NBT.Long` +`NBT.Float` `NBT.Double` `NBT.ByteArray` `NBT.String` +`NBT.List` `NBT.Compound` + +
+ +#### Set the NBT Object Corresponding to the Key + +`comp.setTag(key,tag)` + +- Parameters: + - key: `String` + The name of the key to operate on. + - tag: `NBT Object` + NBT object to be written (it carries specific NBT data). + The write data type must be the same as the data type stored in the value corresponding to the key, and the key name may not exist. +- Return value: Whether the write was successful or not. +- Return value type: `Boolean` + +
+ +#### Read the NBT Object Corresponding to the Key + +`comp.getTag(key)` + +- Parameter: + - key: `String` + The name of the key to operate on. +- Return value: NBT object corresponding to the key. +- Return value type: `NBT Object` + - If the NBT to read does not exist, it will return `Null`. + +
+ +#### Delete the NBT Object Corresponding to the Key + +`comp.removeTag(key)` + +- Parameter: + - key: `String` + The name of the key to operate on. The key must already exist. +- Return value: The processed NBT object (for other operations in the chain). +- Return value type: `NbtCompound` + +
+ +## Some Convenience Functions to Assist in the Manipulation of NBT Objects + +Obviously, purely using NBT objects can be cumbersome and syntactically complex when modifying some of the NBT values. +Therefore, some convenient functions for simplifying object operations are also provided here. By directly operating the data at the specified location and avoiding transit through the NBT object, the amount of code can be reduced to a certain extent. + +#### Set the Specific Data of the Value Corresponding to the Key + +`comp.setEnd(key)` +`comp.setByte(key,data)` +`comp.setShort(key,data)` +`comp.setInt(key,data)` +`comp.setLong(key,data)` +`comp.setFloat(key,data)` +`comp.setDouble(key,data)` +`comp.setByteArray(key,data)` +`comp.setString(key,data)` + +- Parameters: + - key: `String` + The name of the key to operate on. + - data: `Above type` + The data to write. + The write data type must be the same as the data type stored in the value corresponding to the key, and the key name may not exist. +- Return value: The NBT object that has been written to. (For chaining to perform other operations) +- Return value type: `NbtCompound` + +
+ +#### Read the Specific Data of the Value Corresponding to the Key + +`comp.getData(key)` + +- Parameter: + - key: `String` + The name of the key to operate on. +- Return value: The specific data of the value corresponding to the key. +- Return value type: `Any type`, whichever is the type of the stored data. + - If the target location stores the `List` type NBT, will return a `NbtList` object; if the target location stores a `Compound` type NBT, will return a `NbtCompound` object. + - If the NBT to read does not exist, it will return `Null`. + +
+ +#### Convert NBT Tag Object to Object + +`comp.toObject()` + +- Return value: The object/table form of an NBT Tag object. +- Return value type: `Object` + +Convert the content of Compound to LLSE object, convert all data items to LLSE data type and store them in the corresponding key of the object, which is convenient for reading and processing. +If an item of Compound stores a `List` or `Compound` type NBT, it will recursively expand at the corresponding position as `Array` or `Object`. + +
+ +#### Serialize NBT Tag Object to SNBT +`nbt.toSNBT([space])` + +- Parameter: + - space : `Integer` + (Optional parameter) If you want to format the output string, pass this parameter. + Represents the number of spaces per indent, so the resulting string is more human-readable. + This parameter defaults to `-1`, i.e. the output string is not formatted. +- Return value: The converted SNBT string. +- Return value type: `String` + +> In addition to the normal binary NBT, another type of NBT that players are more familiar with is plain text, usually used in [commands](https://minecraft.wiki/w/Commands). This format is often referred to as **SNBT** (**Binary Named Tag,**, **S**tringified **NBT**) +> +> --- Minecraft Wiki + +
+ +#### Serialize NBT Tag Object to Binary NBT + +`comp.toBinaryNBT()` + +- Return value: The corresponding binary NBT data. +- Return value type: `ByteBuffer` +> Only complete top-level Compound tags can be converted to binary NBT. + +
+ +#### Destroy This NBT Tag Object +`comp.destroy()` + +- Return value: Whether the cleanup was successful. +- Return value type: `Boolean` + +Note that only the root Compound tag can be destroyed, and please use this function with caution, improper use will cause the server to crash. +Proper destruction can help with memory footprint issues. After destruction, please never use this NBT object and all its sub-objects again. \ No newline at end of file diff --git a/docs/apis/NbtAPI/NBTCompound.zh.md b/docs/apis/NbtAPI/NBTCompound.zh.md new file mode 100644 index 00000000..082e8231 --- /dev/null +++ b/docs/apis/NbtAPI/NBTCompound.zh.md @@ -0,0 +1,237 @@ +## 📒 NbtCompound - 标签类型 + +一个`NbtCompound `代表一个完整的标签,里面储存了一系列键值对,类似于对象 / 表这样的数据结构。 +通过`NbtCompound`对象的接口,才可以进行 NBT 标签所独有的一些操作。 + +### 获取一个 NBT 标签对象 + +#### 从现有的 NBT 对象中解析获取 + +详见 [NbtList - 列表类型](LLSEPluginDevelopment/NbtAPI/NBTList.md) 和 [NbtCompound - 标签类型](LLSEPluginDevelopment/NbtAPI/NBTCompound.md) 文档 + +
+ +#### 创建新的 NBT 标签对象 + +[JavaScript] `new NbtCompound([data])` +[Lua] `NbtCompound([data])` + +- 参数: + - data: Object(可选参数) + 传入一个NBT对象构成的对象。对象中允许包含其他数组 / 对象结构,但内容必须都为NBT对象 +- 返回值:生成的NBT对象 +- 返回值类型:`NbtList` + - 如果创建失败,将抛出异常 + +[JavaScript] +```js +var nbt = new NbtCompound({ + "name1": new NbtInt(3), + "name2": new NbtString("test"), + "name3": new NbtList([ + new NbtFloat(4.0), + new NbtFloat(6.0) + ]), + "name4": new NbtLong(66666) + }); +``` +[Lua] +```lua +local nbt = NbtCompound({ + "name1" = NbtInt(3), + "name2" = NbtString("test"), + "name3" = NbtList({ + NbtFloat(4.0), + NbtFloat(6.0) + }), + "name4" = NbtLong(66666) + }); +``` + + + +#### 从 SNBT 字符串生成 NBT 标签对象 + +`NBT.parseSNBT(snbt)` + +- 参数: + - snbt : `String` + 你要解析的SNBT字符串 +- 返回值:生成的NBT对象 +- 返回值类型:`NbtCompound` + - 如返回值为 `Null` 则表示解析失败 + +> SNBT字符串中必须包含一个完整的Compound + +
+ +#### 从二进制 NBT 数据生成 NBT 标签对象 + +`NBT.parseBinaryNBT(nbt)` + +- 参数: + - nbt : `ByteBuffer` + 你要解析的二进制 NBT 数据 +- 返回值:生成的NBT对象 +- 返回值类型:`NbtCompound` + - 如返回值为 `Null` 则表示解析失败 + +> 二进制 NBT 数据中必须包含一个完整的Compound + +
对于某个一个`NbtCompound`类型的对象`comp`,有如下这些接口 + +#### 获取所有的键 + +`comp.getKeys()` + +- 返回值:Compound 中所有的键 +- 返回值类型:`Array` + +
+ +#### 获取键对应的值的数据类型 + +`comp.getTypeOf(key)` + +- 参数: + - key: `String` + 要查询的键名 +- 返回值:对应的值的数据类型 +- 返回值类型:`Enum` + - 如果要读取的NBT不存在,将返回`Null` + +可能的返回值有:`NBT.End` `NBT.Byte` `NBT.Short` `NBT.Int` `NBT.Long` +`NBT.Float` `NBT.Double` `NBT.ByteArray` `NBT.String` +`NBT.List` `NBT.Compound` + +
+ +#### 设置键对应的 NBT 对象 + +`comp.setTag(key,tag)` + +- 参数: + - key: `String` + 要操作的键名 + - tag: `NBT对象` + 要写入的 NBT 对象(它承载着具体的NBT数据) + 写入数据类型必须和键对应的值储存的数据类型一致,键名可以不存在 +- 返回值:是否成功写入 +- 返回值类型:`Boolean` + +
+ +#### 读取键对应的 NBT 对象 + +`comp.getTag(key)` + +- 参数: + - key: `String` + 要操作的键名 +- 返回值:键对应的NBT对象 +- 返回值类型: `NBT对象` + - 如果要读取的NBT不存在,将返回`Null` + +
+ +#### 删除键对应的 NBT 对象 + +`comp.removeTag(key)` + +- 参数: + - key: `String` + 要操作的键名。键名必须已经存在 +- 返回值:处理完毕的NBT对象(便于连锁进行其他操作) +- 返回值类型:`NbtCompound` + +
+ +## 一些协助 NBT 对象操作的方便函数 + +很明显,在修改 NBT 的某些值的时候,纯粹使用 NBT 对象会显得麻烦而语法复杂。 +因此,这里还提供了一些简化对象操作的方便函数,通过直接操作指定位置的数据,而避免通过 NBT 对象中转,可以一定程度上降低代码量 + +#### 设置键对应的值的具体数据 + +`comp.setEnd(key)` +`comp.setByte(key,data)` +`comp.setShort(key,data)` +`comp.setInt(key,data)` +`comp.setLong(key,data)` +`comp.setFloat(key,data)` +`comp.setDouble(key,data)` +`comp.setByteArray(key,data)` +`comp.setString(key,data)` + +- 参数: + - key: `String` + 要操作的键名 + - data: `上述类型` + 要写入的具体数据 + 写入数据类型必须和键对应的值储存的数据类型一致,键名可以不存在 +- 返回值:写入完毕的NBT对象(便于连锁进行其他操作) +- 返回值类型:`NbtCompound` + +
+ +#### 读取键对应的值的具体数据 + +`comp.getData(key)` + +- 参数: + - key: `String` + 要操作的键名 +- 返回值:键对应的值的具体数据 +- 返回值类型:`任意类型`,以储存的数据类型为准 + - 如果目标位置储存的是`List`类型 NBT,将返回一个`NbtList`对象;如果目标位置储存的是`Compound`类型 NBT,将返回一个`NbtCompound`对象 + - 如果要读取的NBT不存在,将返回`Null` + +
+ +#### 将 NBT 标签对象 转换为Object + +`comp.toObject()` + +- 返回值:对应的对象 / 表 +- 返回值类型:`Object` + +将Compound的内容转换为脚本引擎对象,把数据项都转换为脚本引擎数据类型储存于对象的对应key中,方便读取和处理 +如果Compound某一项储存的是`List`或者`Compound`类型的 NBT,将在对应位置递归展开为`Array`或`Object` + +
+ +#### 将 NBT 标签对象 序列化为SNBT +`nbt.toSNBT([space])` + +- 参数 + - space : `Integer` + (可选参数)如果要格式化输出的字符串,则传入此参数 + 代表每个缩进的空格数量,这样生成的字符串更适合人阅读 + 此参数默认为-1,即不对输出字符串进行格式化 +- 返回值:对应的SNBT字符串 +- 返回值类型:`String` + +> 除了普通的二进制NBT之外,另一种玩家更熟悉的NBT是纯文本形式的,通常在[命令](https://minecraft.fandom.com/zh/wiki/命令)里使用。这种格式常被称为**SNBT**(**字符串化的二进制命名标签**,**S**tringified **NBT**) +> +> --- Minecraft Wiki + +
+ +#### 将 NBT 标签对象 序列化为二进制NBT + +`comp.toBinaryNBT()` + +- 返回值:对应的二进制NBT数据 +- 返回值类型:`ByteBuffer` +> 只有完整的顶层Compound标签可以被转换为二进制NBT + +
+ +#### 销毁此 NBT 标签对象 +`comp.destroy()` + +- 返回值:是否成功清理 +- 返回值类型:`Boolean` + +注意,只有根Compound标签可以被销毁,而且,请谨慎使用此函数,不当的使用将会造成服务器崩溃 +合适的销毁有助于解决内存占用问题。在销毁完后,请千万不要再使用此NBT对象和他的所有子对象 \ No newline at end of file diff --git a/docs/apis/NbtAPI/NBTList.md b/docs/apis/NbtAPI/NBTList.md new file mode 100644 index 00000000..111ba6b2 --- /dev/null +++ b/docs/apis/NbtAPI/NBTList.md @@ -0,0 +1,161 @@ +## 📚 NbtList - List type + +A `NbtList` represents a list that stores a list of NBT objects, similar to a data structure like a list/array. +The interface of the object can perform some operations unique to the NBT list. + +### Get an NBT List Object + +#### Parse From an Existing NBT Object + +See [NbtList - List Type](/LLSEPluginDevelopment/NbtAPI/NBTList.md) and [NbtCompound - Tag Type](/LLSEPluginDevelopment/NbtAPI/NBTCompound.md) documentation. + +
+ +#### Create a New NBT List Object + +[JavaScript] `new NbtList([data])` +[Lua] `NbtList([data])` + +- Parameter: + - data: Array (optional parameter) + Pass in an array of NBT objects. Arrays are allowed to contain other array/object structures, but the contents must all be NBT objects +- Return value: The generated NBT object. +- Return value type: `NbtList` + - If the creation fails, an exception will be thrown. + +
+ +For a certain `NbtList` type of object `list`, there are the following interfaces. + +#### Get List Length + +`list.getSize()` + +- Return value: The length of the list. +- Return value type: `Integer` + +
+ +#### Get the Data Type of an Element Stored in a List at the Index Position Given + +`list.getTypeOf(index)` + +- Parameter: + - index : `Integer` + The index of the element to query. +- Return value: The data type of the NBT stored at this element. +- Return value type: `Enum` + - If the NBT being read does not exist, it will return `Null` + +Possible return values are: `NBT.End` `NBT.Byte` `NBT.Short` `NBT.Int` `NBT.Long` +`NBT.Float` `NBT.Double` `NBT.ByteArray` `NBT.String` +`NBT.List` `NBT.Compound` + +
+ +#### Set a NBT Object in a List at the Index Position Given + +`list.setTag(index,tag)` + +- Parameters: + - index : `Integer` + The index of the NBT you want to operate on. + - tag: `NBT object` + NBT object to write to. + The data type of the write object must be the same as the data type stored in the list position, and the index cannot exceed the number of items in the list. +- Return value: The NBT list that has been written (for other operations in the chain). +- Return value type: `NbtList` + +
+ +#### Read NBT Object in a List at the Index Position Given + +`list.getTag(index)` + +- Parameter: + - index : `Integer` + The index of the NBT you want to operate on. +- Return value: The NBT Object at the index position. +- Return value type: `NBT object` + - If the NBT being read does not exist, it will return `Null` + +
+ +#### Append an NBT Object to the End of the List + +`list.addTag(tag)` + +- Parameter: + - tag: `NBT object` + The NBT object being added to the list. +- Return value: The NBT list with the NBT object added (for chaining operations). +- Return value type: `NbtList` + +
+ +#### Delete an NBT Object at the Given Index Position + +`list.removeTag(index)` + +- Parameter: + - index : `Integer` + The position of the NBT object to be deleted. + The index cannot exceed the number of NBT objects in the list. +- Return value: Processed NBT list (easy for chaining to perform other operations). +- Return value type: `NbtList` + +
+ +## Some Convenience Functions to Assist in the Manipulation of NBT Objects + +Obviously, purely using NBT objects can be cumbersome and syntactically complex when modifying some of the NBT values. +Therefore, some convenient functions for simplifying object operations are also provided here. By directly operating the data at the specified location and avoiding transit through the NBT object, the amount of code can be reduced to a certain extent. + +#### Set Data at a Specific Position + +`list.setEnd(index)` +`list.setByte(index,data)` +`list.setShort(index,data)` +`list.setInt(index,data)` +`list.setLong(index,data)` +`list.setFloat(index,data)` +`list.setDouble(index,data)` +`list.setByteBuffer(index,data)` +`list.setString(index,data)` + +- Parameter: + - index : `Integer` + The index of the NBT you want to operate on. + - data: `Number` / `Float` / `Double` / `ByteBuffer` / `String` + The specific data being written. + The write data type must be the same as the data type stored in the subscript position, and the index cannot be greater than the number of NBT objects in the list. +- Return value: NBT list that has been written (for other operations in the chain). +- Return value type: `NbtList` + +
+ +#### Read the Specific Data of a Subscript Position + +`list.getData(index)` + +- Parameter: + - index : `Integer` + The index of the NBT you want to operate on. +- Return value: The data stored in the specified location in the list. +- Return value type: `Number` / `Float` / `Double` / `ByteBuffer` / `String`, whatever is the data type of the data stored by the object. + - If the target location stores the `List` type NBT, it will return a `NbtList` object; if the target location stores a `Compound` type NBT, it will return a `NbtCompound` object. + - If the NBT being read does not exist, it will return `Null` + +
+ +#### Convert List Type to Array + +`list.toArray()` + +- Return value: The array form of the list. +- Return value type: `Array` + +Convert the contents of List to LLSE array/list, convert all data items to LLSE data type and store them in the corresponding subscript of the array/list for easy reading and processing. +If an item in the List stores a `List` or `Compound` type which will recursively expand at the corresponding position as `Array` or `Object`. + +
\ No newline at end of file diff --git a/docs/apis/NbtAPI/NBTList.zh.md b/docs/apis/NbtAPI/NBTList.zh.md new file mode 100644 index 00000000..f9549305 --- /dev/null +++ b/docs/apis/NbtAPI/NBTList.zh.md @@ -0,0 +1,161 @@ +## 📚 NbtList - 列表类型 + +一个`NbtList`代表一个列表,里面储存了一列 NBT 对象,类似于列表 / 数组这样的数据结构。 +通过`NbtList`对象的接口,才可以进行 NBT 列表所独有的一些操作。 + +### 获取一个 NBT 列表对象 + +#### 从现有的NBT对象中解析获取 + +详见 [NbtList - 列表类型](LLSEPluginDevelopment/NbtAPI/NBTList.md) 和 [NbtCompound - 标签类型](LLSEPluginDevelopment/NbtAPI/NBTCompound.md) 文档 + +
+ +#### 创建新的NBT列表对象 + +[JavaScript] `new NbtList([data])` +[Lua] `NbtList([data])` + +- 参数: + - data: Array(可选参数) + 传入一个NBT对象构成的数组。数组中允许包含其他数组 / 对象结构,但内容必须都为NBT对象 +- 返回值:生成的NBT对象 +- 返回值类型:`NbtList` + - 如果创建失败,将抛出异常 + +
+ +对于某个一个`NbtList`类型的对象`list`,有如下这些接口 + +#### 获取列表长度 + +`list.getSize()` + +- 返回值:此列表的长度 +- 返回值类型:`Integer` + +
+ +#### 获取某个下标位置储存的数据类型 + +`list.getTypeOf(index)` + +- 参数: + - index : `Integer` + 要查询的目标下标 +- 返回值:此下标处储存的NBT的数据类型 +- 返回值类型:`Enum` + - 如果要读取的NBT不存在,将返回`Null` + +可能的返回值有:`NBT.End` `NBT.Byte` `NBT.Short` `NBT.Int` `NBT.Long` +`NBT.Float` `NBT.Double` `NBT.ByteArray` `NBT.String` +`NBT.List` `NBT.Compound` + +
+ +#### 设置某个下标位置的NBT对象 + +`list.setTag(index,tag)` + +- 参数: + - index : `Integer` + 要操作的目标下标 + - tag: `NBT对象` + 要写入的 NBT 对象 + 写入对象的数据类型必须和下标位置储存的数据类型一致,且下标不能超出有效下标的最大值 +- 返回值:写入完毕的NBT列表(便于连锁进行其他操作) +- 返回值类型:`NbtList` + +
+ +#### 读取某个下标位置的NBT对象 + +`list.getTag(index)` + +- 参数: + - index : `Integer` + 要操作的目标下标 +- 返回值:下标位置的NBT对象 +- 返回值类型:`NBT对象` + - 如果要读取的NBT不存在,将返回`Null` + +
+ +#### 往列表末尾追加一个NBT对象 + +`list.addTag(tag)` + +- 参数: + - tag: `NBT对象` + 要追加的 NBT 对象 +- 返回值:追加完毕的NBT列表(便于连锁进行其他操作) +- 返回值类型:`NbtList` + +
+ +#### 删除某个下标位置的NBT对象 + +`list.removeTag(index)` + +- 参数: + - index : `Integer` + 要删除的目标下标 + 下标不能超出有效下标的最大值 +- 返回值:处理完毕的NBT列表(便于连锁进行其他操作) +- 返回值类型:`NbtList` + +
+ +## 一些协助 NBT 对象操作的方便函数 + +很明显,在修改NBT的某些值的时候,纯粹使用NBT对象会显得麻烦而语法复杂。 +因此,这里还提供了一些简化对象操作的方便函数,通过直接操作指定位置的数据,而避免通过NBT对象中转,可以一定程度上降低代码量 + +#### 设置某个下标位置的具体数据 + +`list.setEnd(index)` +`list.setByte(index,data)` +`list.setShort(index,data)` +`list.setInt(index,data)` +`list.setLong(index,data)` +`list.setFloat(index,data)` +`list.setDouble(index,data)` +`list.setByteBuffer(index,data)` +`list.setString(index,data)` + +- 参数: + - index : `Integer` + 要操作的目标下标 + - data: `Number` / `Float` / `Double` / `ByteBuffer` / `String` + 要写入的具体数据 + 写入数据类型必须和下标位置储存的数据类型一致,且下标不能超出有效下标的最大值 +- 返回值:写入完毕的NBT列表(便于连锁进行其他操作) +- 返回值类型:`NbtList` + +
+ +#### 读取某个下标位置的具体数据 + +`list.getData(index)` + +- 参数: + - index : `Integer` + 要操作的目标下标 +- 返回值:指定位置储存的具体数据 +- 返回值类型:`Number` / `Float` / `Double` / `ByteBuffer` / `String`,以对象储存的数据类型为准 + - 如果目标位置储存的是`List`类型 NBT,将返回一个`NbtList`对象;如果目标位置储存的是`Compound`类型 NBT,将返回一个`NbtCompound`对象 + - 如果要读取的NBT不存在,将返回`Null` + +
+ +#### 将List类型转换为Array + +`list.toArray()` + +- 返回值:对应的数组 / 列表 +- 返回值类型:`Array` + +将List的内容转换为脚本引擎数组 / 列表,把数据项都转换为脚本引擎数据类型储存于数组 / 列表的对应下标中,方便读取和处理 +如果List某一项储存的是`List`或者`Compound`类型的 NBT,将在对应位置递归展开为`Array`或`Object` + +
\ No newline at end of file diff --git a/docs/apis/NbtAPI/NBTValue.md b/docs/apis/NbtAPI/NBTValue.md new file mode 100644 index 00000000..5ce034f9 --- /dev/null +++ b/docs/apis/NbtAPI/NBTValue.md @@ -0,0 +1,67 @@ +## 📋 NBT - Normal Data Type + +We refer to other NBT objects other than `NbtList` and `NbtCompound` types collectively as **normal data** types. These objects only store simple data and contain no other complex structures inside. + +### Get an NBT Normal Data Object + +#### Parse From an Existing NBT Object + +See the [NbtList - List Type](/LLSEPluginDevelopment/NbtAPI/NBTList.md) and [NbtCompound - Tag Type](/LLSEPluginDevelopment/NbtAPI/NBTCompound.md) documentation. + +
+ +#### Create a New NBT Data Object + +[JavaScript] +`new NbtEnd()` +`new NbtByte([data])` +`new NbtShort([data])` +`new NbtInt([data])` +`new NbtLong([data])` +`new NbtFloat([data])` +`new NbtDouble([data])` +`new NbtByteArray([data])` +`new NbtString([data])` +[Lua] +`NbtEnd()` +`NbtByte([data])` +`NbtShort([data])` +`NbtInt([data])` +`NbtLong([data])` +`NbtFloat([data])` +`NbtDouble([data])` +`NbtByteArray([data])` +`NbtString([data])` + +- Parameters: + - data: `Number` / `Float` / `Double` / `ByteBuffer` / `String` (Optional parameter) + Set the initial data according to the type of object you want to create. The incoming data type needs to be able to initialize the corresponding type of data. +- Return value: The generated NBT object. +- Return value type: `NbtEnd` / `NbtByte` / `NbtShort` / `NbtInt` / `NbtLong` / `NbtFloat` / `NbtDouble` / `NbtByteBuffer` / `NbtString` , depending on the type of the data. + - If the creation fails, an exception will be thrown. + +
+ +For an NBT object that stores common data types `value`, with the following member functions. + +#### Set Object Data + +`value.set(data)` + +- Parameter: + - data : `Number` / `Float` / `Double` / `ByteBuffer` / `String` + According to the data type of this NBT object, write the data of the corresponding type. + For an `NbtFloat` object, write data with a `Float` type. +- Return value: Whether the write was successful or not. +- Return value type: `Boolean` + +
+ +#### Read Object Data. + +`value.get()` + +- Return value: The data stored in the object. +- Return value type: ``Number` / `Float` / `Double` / `ByteBuffer` / `String`, depending on the type of the data stored. + +
\ No newline at end of file diff --git a/docs/apis/NbtAPI/NBTValue.zh.md b/docs/apis/NbtAPI/NBTValue.zh.md new file mode 100644 index 00000000..ce7701cf --- /dev/null +++ b/docs/apis/NbtAPI/NBTValue.zh.md @@ -0,0 +1,68 @@ +## 📋 NBT - 普通数据类型 + +我们把除了 `NbtList` 和 `NbtCompound` 类型以外的其他NBT对象统称为 **普通数据** 类型。这些对象只储存了简单的数据,内部不含有其他复杂结构。 + +### 获取一个 NBT 普通数据对象 + +#### 从现有的NBT对象中解析获取 + +详见 [NbtList - 列表类型](LLSEPluginDevelopment/NbtAPI/NBTList.md) 和 [NbtCompound - 标签类型](LLSEPluginDevelopment/NbtAPI/NBTCompound.md) 文档 + +
+ +#### 创建新的NBT数据对象 + +[JavaScript] +`new NbtEnd()` +`new NbtByte([data])` +`new NbtShort([data])` +`new NbtInt([data])` +`new NbtLong([data])` +`new NbtFloat([data])` +`new NbtDouble([data])` +`new NbtByteArray([data])` +`new NbtString([data])` +[Lua] +`NbtEnd()` +`NbtByte([data])` +`NbtShort([data])` +`NbtInt([data])` +`NbtLong([data])` +`NbtFloat([data])` +`NbtDouble([data])` +`NbtByteArray([data])` +`NbtString([data])` + +- 参数: + - data: `Number` / `Float` / `Double` / `ByteBuffer` / `String`(可选参数) + 根据你要创建的对象类型设置初始数据,传入的数据类型需要能够初始化对应类型的数据 + 可以不传入此参数 +- 返回值:生成的NBT对象 +- 返回值类型:`NbtEnd` / `NbtByte` / `NbtShort` / `NbtInt` / `NbtLong` / `NbtFloat` / `NbtDouble` / `NbtByteBuffer` / `NbtString` ,取决于你选择的数据类型 + - 如果创建失败,将抛出异常 + +
+ +对于一个储存普通数据类型的NBT对象 `value`,有如下成员函数 + +#### 设置对象的数据 + +`value.set(data)` + +- 参数: + - data : `Number` / `Float` / `Double` / `ByteBuffer` / `String` + 根据这个NBT对象的数据类型,写入对应类型的数据 + 如对于一个`Float`类型的 NBT 对象,你需要传入一个`Float`类型的值 +- 返回值:是否成功写入 +- 返回值类型:`Boolean` + +
+ +#### 读取对象的数据 + +`value.get()` + +- 返回值:对象中储存的数据 +- 返回值类型:``Number` / `Float` / `Double` / `ByteBuffer` / `String`,以储存的实际数据类型为准 + +
\ No newline at end of file diff --git a/docs/apis/README.md b/docs/apis/README.md new file mode 100644 index 00000000..8bb3cd63 --- /dev/null +++ b/docs/apis/README.md @@ -0,0 +1,109 @@ +# Overview of LLSE Plugin Development + +## ⛳ Start + +`LiteLoader ScriptEngine` hereinafter referred to as **LLSE** is an official server for Bedrock Edition `Bedrock Dedicated Server` hereinafter referred to as **BDS** plugin framework, providing powerful cross-language script plug-in support and stable development API support. + +> Welcome to LLSE's plug-in development! + +From here, you will gradually become familiar with the basic elements and processes of LLSE plug-in development. + +Before engaging with development, you need to have a systematic understanding of LLSE. The documentation here, first of all, will help you establish a general knowledge framework. +Familiarize yourself with them first, this will be a very important part of your learning development process. + +
+ +## 💊 Data Types + +As we all know, the type system is usually a more critical part of a design framework. +So, first, you need to be familiar with several data types that you will use frequently when working with API documentation. +The nouns of these data types appear frequently in the development documentation, so be sure to be familiar with them first. + +### Generic Data Type Conventions + +Although scripting languages ​​are usually weakly typed, there is no need to pay attention to specific data types, but since LLSE supports a variety of different scripting languages, in order to facilitate the docking of the API, some general data types and the mapping relationship to the corresponding scripting language types are defined below. + +| Engine Data Type | JS Data Type | Lua Data Type | Data Type Description | +| --------------- | ------------------ | ------------ | ---------------------- | +| `Null` | `null` `undefined` | `nil` | Empty, undefined, does not exist, etc. | +| `Integer` | `Number` | `number` | Integer | +| `Float` | `Number` | `number` | Float (Decimal, Real) | +| `String` | `String` | `string` | String | +| `Boolean` | `Boolean` | `boolean` | Boolean | +| `Function` | `Function` | `function` | Function (Method) | +| `Array` | `Array` | `table` | Array (List) | +| `Object` | `Object` | `table` | Objects (Maps, Dictionaries, Tables) | +| `ByteBuffer` | `ArrayBuffer` | `table` | Byte Array | + +In addition to the above standard types, there are also some engine-defined object types. + +- `IntPos` - Integer coordinate object (see the base game interface for details) +- `FloatPos` - Floating point coordinate object (see the base game interface for details) +- `Player` - Player object (see Player for details) +- `Entity` - Entity objects (see Entity for details) +- `Block` - Block objects (see Blocks for details) +- `BlockEntity` - Block entity object (see Block entity for details) +- `Item` - Inventory item object (see Items for details) +- `Device` - Player equipment information object (see player for details) +- `Container` - container object (see container for details) +- `Objective` - Scored item object (see Scoreboard for details) +- `NBT` - NBT Tag object (see NBT for details) +- `SimpleForm` - Normal form objects (see Form Builder for details) +- `CustomForm` - Custom form objects (see Form Builder for details) +- `Conf` - Configuration file object (see configuration file for details) +- `DB` - Database objects (see Database for details) +- `File` - File object (see file reading and writing for details) +- `WSClient` - WebSocket client object (see Network for details) +- `Enum` - Enumeration type, usually stored in some type, providing some limited range of options. + +
+ +## 📌 API Documentation Description Conventions + +As we all know, a good help document is naturally inseparable from a unified and concise format and a clear appearance. +Therefore, in order to unify and standardize the format of the document, it is necessary to uniformly specify the description convention of LLSE's help document. + +> For all the API documentation you see next, there are writing rules like this: + +Regarding the description of function parameter types in the documentation: +Function parameters will be described in the format parameter name: parameter type +For example: cmd : String represents a string type variable cmd +If Array<...> appears in the parameter type, it means an array/list containing the variables within <> + +1. About the description of **function parameter types** in the documentation: + The function parameters will follow **Paameter Name : Parameter Type** Format description example: cmd : `String` means a **String** variable of type **cmd** + The parameter type `Array<...>`, represents an array/list containing the variables within <>. + +2. About the description of **optional parameters** in the documentation: + If `optional parameters` appears in the parameter descripton, it means that you have the option to not pass this parameter. + When you do not pass this parameter, the engine will use the default value given in the description. + For example: `pl.tell(msg[,type])`, where `type` is an optional parameter. + +
+ +After you are familiar with the above infrastructure, you can start to read the documentation for each other specific content step by step. +If you come across something you forgot, you can look it up more. + +
+ +## 📜 Plugin Development Tips + +Here, there are some suggestions when developing plugins, I hope they can help you + +- **Don't reinvent** the wheel + When possible, try to use libraries that have been written by others for specific functions, rather than writing each function yourself. In this way, it is conducive to the integration and development of the ecology. +- Think about the **user** + When designing the interface and configuration, it is best to take the user's feelings into account. The content of external interaction such as UI and commands should be as clear and clear as possible, in line with normal usage habits. +- From multiple perspectives, **innovation** occurs + Everyone is encouraged to learn from the excellent plugins already available in JE, and everyone is welcome to make their own innovations. + +## 📡 Debug Plugins + +You can type these commands to enter the corresponding debug mode: + +* `jsdebug`: JavaScript debug mode +* `luadebug`: Lua debug mode + +In debug mode, all texts you type will be parsed as scripts and be executed in real time, as the console of developer tools of browsers do. If any error occurs, you will see an error report. + +You can type `jsdebug` / `luadebug` and enter to exit the debug mode. \ No newline at end of file diff --git a/docs/apis/README.zh.md b/docs/apis/README.zh.md new file mode 100644 index 00000000..119af48b --- /dev/null +++ b/docs/apis/README.zh.md @@ -0,0 +1,108 @@ +# ⛳ 脚本引擎 - 插件开发概述 + +## 🔔 放在前面 + +`LiteLoader ScriptEngine`(以下简称**LLSE**/**脚本引擎**)是一个基岩版官方服务端 `Bedrock Dedicated Server`(以下简称**BDS**)的插件框架,提供强大的跨语言脚本插件支持能力和稳定的开发API支持。 + +> 欢迎参与到脚本引擎的插件开发中来! + +从这里开始,你将逐步熟悉脚本插件开发的基本要素和流程。 + +在接触开发之前,你需要对脚本引擎有一个成体系的认识。这里的文档,首先将帮助你建立一个大概的知识框架。 +首先熟悉他们,这将是你学习开发的过程中非常重要的一环。 + +
+ +## 💊 数据类型 + +众所周知,类型系统通常都是一个设计框架中比较关键的部分。 +因此,首先,你需要熟悉几种在使用 API 文档的过程中会频繁用到的数据类型。 +这些数据类型的名词会频繁出现在开发文档当中,请务必首先对他们足够熟悉。 + +### 通用数据类型约定 + +虽然脚本语言通常是弱类型的,不需要关注具体的数据类型,但由于脚本引擎支持多种不同的脚本语言,为了方便对接API,下面定义一些通用的数据类型,以及到对应脚本语言类型的映射关系。 + +| 引擎数据类型 | JavaScript 数据类型 | Lua 数据类型 | 数据类型说明 | +| --------------- | ------------------ | ------------ | ---------------------- | +| `Null` | `null`/`undefined` | `nil` | 空,未定义,不存在等等 | +| `Integer` | `Number` | `number` | 整数 | +| `Float` | `Number` | `number` | 浮点数(小数,实数) | +| `String` | `String` | `string` | 字符串 | +| `Boolean` | `Boolean` | `boolean` | 布尔型 | +| `Function` | `Function` | `function` | 函数(方法) | +| `Array` | `Array` | `table` | 数组(列表) | +| `Object` | `Object` | `table` | 对象(映射,字典,表) | +| `ByteBuffer` | `ArrayBuffer` | `table` | 字节数组 | + +除了上述了标准类型之外,还存在一些引擎自定义的对象类型。 + +- `IntPos` - 整数 坐标对象(详见 基础游戏接口) +- `FloatPos` - 浮点数 坐标对象(详见 基础游戏接口) +- `Player` - 玩家对象(详见 玩家)- 在脚本引擎内实际注册的类名:`LLSE_Player` +- `Entity` - 实体对象(详见 实体)- 在脚本引擎内实际注册的类名:`LLSE_Entity` +- `Block` - 方块对象(详见 方块)- 在脚本引擎内实际注册的类名:`LLSE_Block` +- `BlockEntity` - 方块实体对象(详见 方块实体)- 在脚本引擎内实际注册的类名:`LLSE_BlockEntity` +- `Item` - 物品栏物品对象(详见 物品)- 在脚本引擎内实际注册的类名:`LLSE_Item` +- `Device` - 玩家设备信息对象(详见 玩家)- 在脚本引擎内实际注册的类名:`LLSE_Device` +- `Container` - 容器对象(详见 容器)- 在脚本引擎内实际注册的类名:`LLSE_Container` +- `Objective` - 计分项对象(详见 计分板)- 在脚本引擎内实际注册的类名:`LLSE_Objective` +- `NBT` - NBT Tag对象(详见 NBT) +- `SimpleForm` - 普通表单对象(详见 表单构建器)- 在脚本引擎内实际注册的类名:`LLSE_SimpleForm` +- `CustomForm` - 自定义表单对象(详见 表单构建器)- 在脚本引擎内实际注册的类名:`LLSE_CustomForm` +- `Conf` - 配置文件对象(详见 配置文件) +- `DB` - 数据库对象(详见 数据库) +- `File` - 文件对象(详见 文件读写) +- `WSClient` - WebSocket 客户端对象(详见 网络) +- `Enum` - 枚举类型,通常储存于某些类型中,提供一些限定范围的可选项 + +
+ +## 📌 API文档描述约定 + +众所周知,一个好的帮助文档自然离不开统一简洁的格式和一目了然的外观。 +因此,为了文档的格式统一和规范,接下来,需要统一规定一下脚本引擎的帮助文档描述约定。 + +> 对于接下来你看到的所有API文档,都有这样的写作规则: + +1. 关于文档中对 **函数参数类型** 的描述: + 函数参数将按照 **参数名 : 参数类型** 格式描述 + 例如: cmd : `String` 表示一个**字符串**类型的变量cmd + 如果参数类型出现`Array<...>`表示一个以<>内的变量为内容的数组 / 列表 + + + +2. 关于文档中对 **可选参数** 的描述: + 如果在参数描述处出现 `可选参数` 则代表你可以不传入这个参数。 + 当你不传入这个参数的时候,引擎将使用描述中给出的默认值。 + 在API接口参数中,可选参数会被[ ]框起来。 + 形如:`pl.tell(msg[,type])`,这里的`type`就属于可选参数 + +
+ +在熟悉上面这些基础设施之后,你可以开始逐步阅读其他各特定内容的文档了。 +如果碰到遗忘了的东西,可以多翻回来看看。 + +
+ +## 📜 插件开发小贴士 + +这里,有一些在开发插件的时候的建议,希望可以帮到你 + +- **不要重复**造轮子 + 在条件允许的情况下,尽量使用他人已经编写好的特定功能的库,而不是每个功能都自己编写一遍。这样,有利于生态的整合和发展。 +- 为**用户**思考 + 在设计界面和配置的时候,最好考虑到用户的感受。UI和命令等对外交互的内容尽量做到清晰和一目了然,符合常规的使用习惯。 +- 多角度思考**创新** + 鼓励大家向其他平台已有的优秀插件学习,也欢迎大家作出自己的创新。 + +## 📡 调试插件 + +你可以输入这些命令来进入相应的调试模式: + +* `jsdebug`: JavaScript调试模式 +* `luadebug`: Lua调试模式 + +在调试模式下,你输入的所有文本将被解析为脚本并实时执行,就像浏览器的开发工具的控制台那样。如果发生任何错误,你会看到一个错误报告。 + +你可以输入`jsdebug`/`luadebug`并回车以退出调试模式。 \ No newline at end of file diff --git a/docs/apis/ScriptAPI/Ll.md b/docs/apis/ScriptAPI/Ll.md new file mode 100644 index 00000000..69f999a9 --- /dev/null +++ b/docs/apis/ScriptAPI/Ll.md @@ -0,0 +1,203 @@ +## 💡 Plugin loading related API + +Some interfaces related to loader operations are provided here. + +### Properties + +| Property | Type | Description | +| ------------------------ | --------- | ---------------------------------------------------------- | +| `ll.language` | `String` | The language LiteLoader used.(such as `zh`, `en`, `ru_RU`) | +| `ll.major` | `Integer` | Major Version Number (ex: the **2** in **2**.7.1) | +| `ll.minor` | `Integer` | Minor Version Number (ex: the **7** in 2.**7**.1) | +| `ll.revision` | `Integer` | Revision Number: (ex: the **1** in 2.7.**1**) | +| `ll.status` | `Integer` | Status (`0` is Dev, `1` is Beta, `2` is Release) | +| `ll.scriptEngineVersion` | `String` | LiteLoaderBDS Script Engine Version | +| `ll.isWine` | `Boolean` | Whether the LiteLoaderBDS started from Wine | +| `ll.isDebugMode` | `Boolean` | Whether the LiteLoaderBDS in debug mode | +| `ll.isBeta` | `Boolean` | Whether the current version is a beta version | +| `ll.isDev` | `Boolean` | Whether the current version is a dev version | +| `ll.isRelease` | `Boolean` | Whether the current version is a release version | + +### Get LiteLoader loader version string + +`ll.versionString()` + +- Return value: loader version +- Return value type: `String` + +
+ +### Check LiteLoader loader version + +`ll.requireVersion(major[,minor,revision])` + +- Parameter: + - major: `Integer` + Check if the major version number of the currently installed LL is >= this value. + - minor: `Integer` (optional parameter) + Check if the minor version number of the currently installed LL is >= this value. + - revision: `Integer` (optional parameter) + Check if the revision number of the currently installed LL is >= this value. +- Return value: Test result +- Return value type: `Boolean` + +If the detection finds that the currently installed version of LLSE is lower than the value passed in, it will return `false`. +You can choose to judge based on the results and report an error to remind users to upgrade their LiteLoaderBDS version. + +
+ +### Get information about Plugin + +`ll.getPluginInfo(name)` + +- Parameter: + - name: `String` + Plugin name +- Return value: Plugin Object +- Return value type: `Plugin` + - For a returned plugin object, there are the following members: + + | Property | Description | Type | + | ----------------- | ----------------------- | -------------------------------- | + | plugin.name | Plugin name | `String` | + | plugin.desc | Plugin description | `String` | + | plugin.version | Plugin version (array) | `Array` | + | plugin.versionStr | Plugin version (string) | `String` | + | plugin.filePath | Path to plugin | `String` | + | plugin.others | Other information | `Object` | + + +
+ +### List all loaded plugins + +`ll.listPlugins()` + +- Return value: A list containing the names of all loaded plugin +- Return value type: `Array` + +
+ +### List all loaded plugins with information + +`ll.getAllPluginInfo()` + +- Return value: A list containing the plugin objects of all loaded plugin +- Return value type: `Array` + +
+ +### Remote Function Call + +In order to allow the pre-plug-ins developed by developers to provide interfaces and services for other plug-ins, the remote function call function is provided here, so that one LLSE plug-in can call the existing functions in another plug-in. + +#### Export Function + +In order to allow the pre-plug-ins developed by developers to provide interfaces and services for other plug-ins, the remote function call function is provided here, so that an LL or LLSE plug-in can call the existing functions in another plug-in. + +`ll.exports(func,namespace,name)` + +- Parameter: + - func : `Function` + Function to be exported + - namespace : `String` + The namespace name of the function, which is only convenient for distinguishing the API exported by different plugins. + - name : `String` + The export name of the function. Other plugins call this function based on the export name. +- Return value: Whether the export was successful. +- Return value type: `Boolean` + +Note: If the namespace and name of the exported function are exactly the same as another already exported function, the export will fail. Please select the namespace and export name appropriately when exporting. + +
+ +#### Import Function + +After you have learned that there is a plug-in exporting function, in order to use the function exported by him, you first need to import this function into your own scripting system. +LLSE provides the interface import to import functions already exported by other plugins. + +`ll.imports(namespace,name)` + +- Parameter: + - namespace : `String` + The namespace name used by the function that is being imported. + - name : `String` + The name of the function that is being imported. +- Return value: The imported function +- Return value type: `Function` + +The return value of `ll.import` is a function. When you call this function, the cross-plugin call process will be done automatically in the background. The parameters of the calling function will be wrapped and passed to the remote function, and the return value of this function is the return value returned by the remote function after it has been executed. + +
+ +#### Example of Remote Calling Function + +For example, there is a plug-in that exports a function using the namespace AAA, and the name of the exported function is Welcome +You can execute `welcome = ll.import("AAA", "Welcome"); ` to import this function. After the import is complete, you can execute directly below: + +`welcome("hello",2,true);` + +The parameters of the function will be automatically forwarded to the corresponding target function for execution, and the return value of the corresponding target function will be returned after execution. The whole process is automatically completed. + +Notice! When calling a function, you need to ensure that the number and types of parameters you pass in and the parameters accepted by the target function are correct and in one-to-one correspondence. Otherwise, an error will occur. + +
+ +### Determine if a remote function has been exported + +`ll.hasExported(namespace,name)` + +- Parameter: + - namespace : `String` + Namespace name used by the function + - name : `String` + Export name used by the function +- Return value:Whether the function has been exported +- Return value type: `Boolean` + +
+ +### Set Plugin Dependencies + +Sometimes, you need to make sure that certain plugins are loaded before your own plugins to use the frontend services provided by them. We call these frontend plugins **library dependencies**. + +When using the import function mentioned above, you need to pay attention: the premise of being able to import a function is that the pre-plugin to be called has been loaded by LLSE. +Therefore, you may need to use the following function to set the dependent library, so that the pre-plugins you need are loaded first and the import is successful. + +LLSE provides the following interface to preload the dependent libraries required by the plugin, download the dependent library files you need from local files, or even from remote HTTP(s) addresses. + +`ll.require(path[,remotePath])` + +- Parameter: + - path : `String` + Library dependency filename (Example: `addplugin.js`) + - remotePath : `String` + (Optional parameter) The path to find and load dependent libraries, see below for instructions. +- Return value: Whether the dependent library is loaded successfully +- Return value type: `Boolean` + +For execution, use `ll.require`, then LLSE will perform the following series of operations: + +- Search the list of loaded plugins. If the dependent library has been loaded, it will return success directly. +- Search **plugins** and **plugins/lib** directories, if the corresponding dependent library file is found, load it and return the loading result. +- If the corresponding dependent library file is not found after the search is completed, and the remotePath parameter is not passed in, it will return directly to failure. +- Use the HTTP(s) protocol remotePath to request the download address corresponding to the remotePath parameter, and download the dependent library files to the `plugins/lib` directory. If the download fails, return failure. +- Load the successfully downloaded dependent library file and return the loading result. + +
+ +Authors of dependent libraries can host relevant code on stable large websites such as GitHub or Gitee, and provide external links to other developers for remote download. + +
+ +### Execute a String as a Script + +`ll.eval(str)` + +- Parameter: + - str : `String` + String to execute as a Script +- Return value: Execution result +- Return value type: `Any Type` + +Different from the above mentioned `ll.require`, the script code executed here is directly executed in the engine corresponding to the current plugin, similar to the eval mechanism of each language. \ No newline at end of file diff --git a/docs/apis/ScriptAPI/Ll.zh.md b/docs/apis/ScriptAPI/Ll.zh.md new file mode 100644 index 00000000..dbdad41f --- /dev/null +++ b/docs/apis/ScriptAPI/Ll.zh.md @@ -0,0 +1,221 @@ +## 💡 插件加载相关 API + +这里提供了一些与加载器操作相关的接口。 + +### Properties + +| 属性 | 类型 | 描述 | +| ------------------------ | --------- | ------------------------------------------------------- | +| `ll.language` | `String` | LiteLoaderBDS使用的语言。(例如`zh_Hans`、`en`和`ru_RU`) | +| `ll.major` | `Integer` | 主版本号(如 **2**.1.0 里的 **2**) | +| `ll.minor` | `Integer` | 次版本号(如 2.**1**.0 里的 **1**) | +| `ll.revision` | `Integer` | 修订版本号(如 2.1.**0** 里的 **0**) | +| `ll.status` | `Integer` | 版本状态 (`0`为Dev, `1`为Beta, `2`为Release) | +| `ll.scriptEngineVersion` | `String` | LiteLoaderBDS Script Engine版本 | +| `ll.isWine` | `Boolean` | 是否处于Wine环境下 | +| `ll.isDebugMode` | `Boolean` | 是否处于debug模式 | +| `ll.isBeta` | `Boolean` | 当前版本是否为测试版 | +| `ll.isDev` | `Boolean` | 当前版本是否为开发版 | +| `ll.isRelease` | `Boolean` | 当前版本是否为发布版本 | +
+ +### 获取 LiteLoaderBDS 版本字符串 + +`ll.versionString()` + +- 返回值:加载器版本 +- 返回值类型: `String` + +
+ +### 检查 LiteLoaderBDS 版本 + +`ll.requireVersion(major[,minor,revision])` + +- 参数: + - major: `Integer` + 检查当前已安装LiteLoaderBDS的主版本号是否 >= 此值 + - minor: `Integer`(可选参数) + 检查当前已安装LiteLoaderBDS的次版本号是否 >= 此值 + - revision: `Integer`(可选参数) + 检查当前已安装LiteLoaderBDS的修订版本号是否 >= 此值 +- 返回值:检查结果 +- 返回值类型: `Boolean` + +如果检测发现当前安装的脚本引擎版本低于传入的数值,将返回`false`。 +你可以选择根据结果判断并报错,提醒用户升级自己的LiteLoaderBDS版本 + +
+ +### 获取有关插件的信息 + +`ll.getPluginInfo(name)` + +- 参数: + - name: `String` + 插件名称 +- 返回值: 插件对象 +- 返回值类型: `Plugin` + + - 对于返回的某个插件对象 plugin,有如下这些属性: + + | 属性 | 描述 | 类型 | + | ----------------- | -------------------- | -------------------------------- | + | plugin.name | 插件名称 | `String` | + | plugin.desc | 插件描述 | `String` | + | plugin.version | 插件版本(数组形式) | `Array` | + | plugin.versionStr | 插件版本 | `String` | + | plugin.filePath | 插件路径 | `String` | + | plugin.others | 其他信息 | `Object` | + +
+ +### 列出所有已加载的插件 + +`ll.listPlugins()` + +- 返回值:已加载的所有的插件名字列表 +- 返回值类型: `Array` + +
+ +### 列出所有加载的插件信息 + +`ll.getAllPluginInfo()` + +- 返回值: 包含所有已加载插件的插件对象的列表 +- 返回值类型: `Array` + +
+ +### 远程函数调用 + +#### 导出函数 + +为了可以让开发者开发的前置插件能够为其他插件提供接口和服务,这里提供了远程函数调用功能,让一个 原生 或 脚本 插件可以调用另一个插件中已有的函数。 + +`ll.exports(func,namespace,name)` + +- 参数: + - func : `Function` + 要导出的函数 + - namespace : `String` + 函数的命名空间名,只是方便用于区分不同插件导出的API + - name : `String` + 函数的导出名称。其他插件根据导出名称来调用这个函数 +- 返回值:是否成功导出 +- 返回值类型: `Boolean` + +注意:如果导出的函数的命名空间和名字与另一个已经导出的函数完全相同,将会导出失败。选定命名空间和导出名称时请适当选择。 + +
+ +#### 导入函数 + +当你已经得知有插件导出函数之后,为了可以使用他导出的函数,首先需要将这个函数导入到你自己的脚本系统中 +脚本引擎提供了接口 import 来导入其他插件已经导出的函数。 + +`ll.imports(namespace,name)` + +- 参数: + - namespace : `String` + 要导入的函数使用的命名空间名称 + - name : `String` + 要导入的函数使用的导出名称 +- 返回值:导入的函数 +- 返回值类型: `Function` + +`ll.import` 的返回值是一个函数。当你调用这个函数时,跨插件调用的流程将在后台自动完成。调用函数的参数将被包装并传递给远程函数,此函数的返回值即是远程函数执行完毕之后返回的返回值。 + +
+ +#### 远程调用参数类型对照,其中Type可以为其他受支持的类型 + +| C++层类型 | 脚本引擎类型 | .NET引擎类型 | 内部类型(备注) | +| --------------------------------------------- | ------------- | --------------------------------------- | -------------------------------------- | +| `std::nullptr_t` | `Null` | `null` / `Nothing` / `nullptr` | `std::nullptr_t` | +| `bool` | `Boolean` | `Boolean` | `bool` | +| `__int64`, `double`... | `Number` | `Int64`, `Double`... | `RemoteCall::NumberType` | +| `std::string` | `String` | `String` | `std::string` | +| `std::vector` | `Array` | `List` | `std::vector` | +| `std::unordered_map` | `Object` | `Dictionary` | `std::unordered_map` | +| `Actor*` | `Entity` | `MC.Actor` | `Actor*` | +| `Player*` | `Player` | `MC.Player` | `Player*` | +| `ItemStack*`, `std::unique_ptr` | `Item` | `RemoteCall.ItemType` | `RemoteCall::ItemType` | +| `Block*`, `BlockInstance` | `Block` | `RemoteCall.BlockType` | `RemoteCall::BlockType` | +| `BlockActor*` | `BlockActor` | `MC.BlockActor` | `BlockActor*` | +| `Container*` | `Container` | `MC.Container` | `Container*` | +| `Vec3`,`std::pair` | `FloatPos` | `MC.Vec3`,`RemoteCall.WorldPosType` | `RemoteCall::WorldPosType` | +| `BlockPos`,`std::pair` | `IntPos` | `MC.BlockPos`,`RemoteCall.BlockPosType` | `RemoteCall::BlockPosType` | +| `CompoundTag*`,`std::unique_ptr` | `NBTCompound` | `RemoteCall.NbtType` | `RemoteCall::NbtType` | + +#### 远程调用函数举例说明 + +比如,有一个插件导出了某个函数,函数导出使用的命名空间为 AAA,导出函数名称为 Welcome +当你使用 `welcome = ll.import("AAA","welcome"); ` 完成导入之后,你就可以直接在下面执行: + +`welcome("hello",2,true);` + +函数的参数将被自动转发到对应的目标函数执行,执行完毕之后将返回回应的目标函数的返回值,整个过程都是自动完成的。 + +注意!在调用函数的时候,需要保证你传入的参数和目标函数接受的参数数量和类型都是正确且一一对应的。否则,将会发生错误。 + +
+ +### 判断远程函数是否已导出 +`ll.hasExported(namespace,name)` + +- 参数: + - namespace : `String` + 函数使用的命名空间名称 + - name : `String` + 函数使用的导出名称 +- 返回值:函数是否已导出 +- 返回值类型: `Boolean` + +
+ +### 设置插件依赖库 + +有的时候,你需要确保某些插件在你自己的插件之前加载,以使用他们提供的前置服务,我们称这些前置插件为**依赖库**。 + +在使用上述提到的导入函数时,你需要注意:能够导入一个函数的前提是要被调用的前置插件已经被脚本引擎加载。 +因此,你可能需要用下面的函数来设置依赖库,让你需要的前置插件被优先加载,保证导入成功 + +脚本引擎提供了下面的接口来提前加载插件所需要的依赖库,从本地文件,甚至可以从远程HTTP(s)地址下载你所需的依赖库文件 + +`ll.require(path[,remotePath])` + +- 参数: + - path : `String` + 依赖库文件名(如`addplugin.js`) + - remotePath : `String` + (可选参数)查找并装载依赖库的路径,说明见下 +- 返回值:是否加载依赖库成功 +- 返回值类型: `Boolean` + +在执行`ll.require`后,脚本引擎将进行如下一系列操作 + +- 搜索已加载插件列表。如果依赖库已经被加载,则直接返回成功。 +- 搜索 **plugins** 和 **plugins/lib** 目录,如果发现对应的依赖库文件,则加载,并返回加载结果 +- 如果搜索完毕之后未发现对应的依赖库文件,且 remotePath 参数也未传入,则直接返回失败 +- 使用 HTTP(s) 协议请求 remotePath 参数对应的下载地址,并下载依赖库文件到 **plugins/lib** 目录。如果下载失败,则返回失败 +- 加载下载成功的依赖库文件,并返回加载结果 + +
+ +依赖库作者可以将相关代码托管在GitHub或Gitee等稳定的大型网站上,并将外链提供给其他开发者以供远程下载使用。 + +
+ +### 将字符串作为脚本代码执行 + +`ll.eval(str)` + +- 参数: + - str : `String` + 要作为脚本代码执行的字符串 +- 返回值:执行结果 +- 返回值类型: `任意类型` + +不同于上面提到的的`ll.require`,此处执行的脚本代码是在当前插件对应的引擎中直接执行的,类似于各语言的 eval 机制 \ No newline at end of file diff --git a/docs/apis/ScriptAPI/Logger.md b/docs/apis/ScriptAPI/Logger.md new file mode 100644 index 00000000..3a9bb990 --- /dev/null +++ b/docs/apis/ScriptAPI/Logger.md @@ -0,0 +1,154 @@ +# LLSE - Script Assist Interface Documentation + +> A large number of **helper functions** are provided here, including log functions, loader function interfaces, and more. + +They make it easier and more natural for you to develop scripts and avoid a lot of unnecessary details. + +## 📅 Generic logging API + +In the past, it was a very troublesome thing to output logs in a certain format to a specified location. +Today, LLSE provides you with a convenient generic logging interface. + +### Concept: About log output levels + +In order to rank the priority and importance of logs, we introduce the concept of **log output level**. +The higher the log output level, the more detailed the content of the log, but the larger the amount of logs output at the same time. +See the table below for details: + +| Log Output Level | Log Severity | Log Description | +| ------------ | ------------ | ------------------------------------------- | +| 0 | Slient | No log output. | +| 1 | Fatal | Only critical error messages. | +| 2 | Error | Only error and critical error messages. | +| 3 | Warn | Output arnings, errors, critical errors. | +| 4 | Info | Output everythng except debug info. | +| 5 | Debug | Output everything. | + +With the **Log output level** setting, you can easily filter out some unnecessary information in the production environment. + +The default value of the log output level is `4`, that is, all kinds of logs other than debug information will be output. +With some APIs given below, you can adjust the log output level to your own desired value. + +
+ +### Set Output Configuration + +Before using the general log interface, you need to modify some configuration settings of the log output according to your needs. + +You can freely choose to send the log to the console, file or even a player by modifying the settings. +These settings can exist at the same time, for example, you can set to send to the console and file at the same time. +If you don't change any settings, by **default** the log will only be output to the console. + +#### Set whether the log is output to the console + +`logger.setConsole(isOpen[,logLevel])` + +- Parameter: + - isOpen : `Boolean` + Set whether the log is output to the console + The switch is on by default. + - logLevel : `Integer` + (optional parameter) the log output level of the console, the default is `4` +- Return value: none + +
+ +#### Set whether the log is output to a file + +`logger.setFile(filepath[,logLevel])` + +- Parameter: + - filepath : `String` + Set the file path where logs are output. + If you pass in an empty string or `Null`, then output to a file is closed. + The switch is off by default. + - logLevel : `Integer` + (optional parameter) the minimum log output level of the file, the default is `4` +- Return value: none + +If you want to output to a file, we recommend that you output the log uniformly to `BDS_Root_Directory/logs/` folder for easy organization and inspection. + +
+ +#### Set whether the log is output to a certain player + +`logger.setPlayer(player[,logLevel])` + +- Parameter: + - player : `Player` + Set the target player object for sending logging output. + If it returns `Null`, output to the player is closed. + The switch is off by default + - logLevel : `Integer` + (optional parameter) The player's minimum log output level, defaults to `4` +- Return value: none + +This is a function designed to facilitate in-game debugging. The log output to the player will be treated as a chat message and displayed on the target player's screen. + +
+ + ### Output Log Function + +After the setup is complete, you can use the function here to output the log. + +`logger.log(data1,data2,...)` -> Output normal text +`logger.debug(data1,data2,...)` -> Output debugging information +`logger.info(data1,data2,...)` -> Output prompt information +`logger.warn(data1,data2,...)` -> Output warning message +`logger.error(data1,data2,...)` -> Output error messages +`logger.fatal(data1,data2,...)` -> Output critical error message + +- Parameter: + - Variable or data to be output + Can be of any type, and the number of parameters can be any number. +- Return value: none + +Among them, **ordinary text** will be output as it is when output, while other output interfaces will append the **current time and log type.** +For example: you call `logger.error("Fail to transport the player")` +The result of the log output is: + +```log +[2021-05-21 19:41:03 Error] Fail to transport the player +``` + +
+ +### Other Settings + +In addition, there are other settings to change the format of the output log + +#### Set custom log message headers + +`logger.setTitle(title)` + +- Parameter: + - title : `String` + Set custom headers +- Return value: none + +"Header" is the text at the beginning of the log output entry, which is used to visually distinguish the output source of the log. +By default, message headers are empty by default, i.e. output without headers. + +For example: set a custom header as `logger.setTitle("LiteLoader")` +Then the following log output will become like: + +```log +20:05:26 ERROR [LiteLoader] Fail to transport the player +``` + +If you want to turn off the header after setting it, do `logger.setTitle("")` + +
+ +#### Unified modification log output level + +`logger.setLogLevel(level)` + +- Parameter: + - level : `Integer` + Log output level +- Return value: none + +Unified reset of log output levels for various output directions + +
\ No newline at end of file diff --git a/docs/apis/ScriptAPI/Logger.zh.md b/docs/apis/ScriptAPI/Logger.zh.md new file mode 100644 index 00000000..1a0a8c0c --- /dev/null +++ b/docs/apis/ScriptAPI/Logger.zh.md @@ -0,0 +1,154 @@ +# 脚本引擎 - 脚本辅助接口文档 + +> 这里提供了大量的 **辅助功能** ,包括日志功能、加载器功能接口等等。 + +他们让你开发脚本变得更加容易而自然,避免了很多无谓的细节问题的纠缠。 + +## 📅 通用日志 API + +以往,按某种格式输出日志到指定位置是一件非常麻烦的事情。 +如今,脚本引擎为你提供了方便的通用日志接口。 + +### 概念:关于日志输出等级 + +为了给日志的优先程度和重要性进行分级,我们引入了 **日志输出等级** 的概念。 +日志输出等级越高,日志的内容越详细,但同时输出的日志量也越大 +详见下表: + +| 日志输出等级 | 对应等级名称 | 实际输出日志内容 | +| ------------ | ------------ | ------------------------------------------- | +| 0 | Slient | 不输出任何日志 | +| 1 | Fatal | 仅输出 严重错误信息 | +| 2 | Error | 输出 严重错误、错误信息 | +| 3 | Warn | 输出 严重错误、错误、警告信息 | +| 4 | Info | 输出 严重错误、错误、警告、提示信息 | +| 5 | Debug | 输出 严重错误、错误、警告、提示 和 调试信息 | + +通过 **日志输出等级** 设置,你可以很方便地过滤掉某些在生产环境中没必要输出的信息。 + +日志输出等级的默认值为`4`,也就是说,除了调试信息以外其他种类的日志都将被输出。 +通过下面给出的一些 API ,你可以将日志输出等级调整为你自己想要的值。 + +
+ +### 设置输出配置 + +在使用通用日志接口之前,你需要先按你的需求修改一下日志输出的某些配置设置 + +你可以通过修改设置,自由选择将日志发向控制台、文件甚至某个玩家 +这些设置是可以同时存在的,比如说,你可以设置同时发送到控制台和文件 +如果你不修改任何设置,**默认情况** 下,日志仅会输出到控制台。 + +#### 设置日志是否输出到控制台 + +`logger.setConsole(isOpen[,logLevel])` + +- 参数: + - isOpen : `Boolean` + 设置日志是否输出到控制台 + 开关默认是打开状态。 + - logLevel : `Integer` + (可选参数)控制台的日志输出等级,默认为`4` +- 返回值:无 + +
+ +#### 设置日志是否输出到文件 + +`logger.setFile(filepath[,logLevel])` + +- 参数: + - filepath : `String` + 设置日志输出到的文件路径 + 如果传入空字符串或者`Null`,则代表关闭到文件的输出。 + 开关默认是关闭状态 + - logLevel : `Integer` + (可选参数)文件的最小日志输出等级,默认为`4` +- 返回值:无 + +如果要输出到文件,我们提倡您将日志统一输出到`BDS根目录/logs/`文件夹下,以方便整理和检查。 + +
+ +#### 设置日志是否输出到某个玩家 + +`logger.setPlayer(player[,logLevel])` + +- 参数: + - player : `Player` + 设置日志输出到的目标玩家对象 + 如果传入`Null`,则代表关闭到玩家的输出。 + 开关默认是关闭状态 + - logLevel : `Integer` + (可选参数)玩家的最小日志输出等级,默认为`4` +- 返回值:无 + +这是为了方便游戏内调试而设计的功能,输出到玩家的日志会被当作聊天消息,显示在目标玩家的屏幕上 + +
+ + ### 输出日志函数 + +在设置完毕之后,你就可以用这里的函数输出日志了 + +`logger.log(data1,data2,...)` -> 输出普通文本 +`logger.debug(data1,data2,...)` -> 输出调试信息 +`logger.info(data1,data2,...)` -> 输出提示信息 +`logger.warn(data1,data2,...)` -> 输出警告信息 +`logger.error(data1,data2,...)` -> 输出错误信息 +`logger.fatal(data1,data2,...)` -> 输出严重错误信息 + +- 参数: + - 待输出的变量或者数据 + 可以是任意类型,参数数量可以是任意个 +- 返回值:无 + +其中,**普通文本**在输出的时候会按照原样输出,而其他的各个输出接口都会在日志内容前面附加上**当前时间和日志类型** +例如:你调用`logger.error("Fail to transport the player")` +日志输出的结果是 + +```log +[2021-05-21 19:41:03 Error] Fail to transport the player +``` + +
+ +### 其他的一些设置项 + +除此之外,还有其他的一些设置项,用来改变输出日志的格式 + +#### 设置自定义日志消息标头 + +`logger.setTitle(title)` + +- 参数: + - title : `String` + 设置的自定义标头 +- 返回值:无 + +「标头」为日志输出条目开头的文字,用来直观地区分日志的输出源。 +默认情况下,消息标头默认为空,即输出时没有标头。 + +例如:设置自定义标头为`logger.setTitle("LiteLoader")` +则在接下来的日志输出将变为形如: + +```log +20:05:26 ERROR [LiteLoader] Fail to transport the player +``` + +如果在设置之后想要关闭标头,请执行`logger.setTitle("")` + +
+ +#### 统一修改日志输出等级 + +`logger.setLogLevel(level)` + +- 参数: + - level : `Integer` + 日志输出等级 +- 返回值:无 + +统一重设各种输出方向的日志输出等级 + +
\ No newline at end of file diff --git a/docs/apis/ScriptAPI/ScriptHelp.md b/docs/apis/ScriptAPI/ScriptHelp.md new file mode 100644 index 00000000..414f3100 --- /dev/null +++ b/docs/apis/ScriptAPI/ScriptHelp.md @@ -0,0 +1,167 @@ +# LLSE - Generic Scripting Interface Documentation + +> Here are some commonly used **auxiliary functions** , such as plugin registration, output information and asynchronous interfaces, etc. + +They make it easier and more natural for you to develop scripts and avoid a lot of unnecessary details. + +## 🎯 Plugin Registration API + +Before you start writing code for your plugin, you first need to provide the loader with some plugin-related information. + +`ll.registerPlugin(name, introduction, version, otherInformation)` + +- Parameters: + + - name : `String` + Plugin Name + + - introduction : `String` + A short description of the plugin. + + - version : `Array` + Plugin version information. + + For `VersionStatus`, the following enumeration can be used + | Enum | Description | + | --------- | ---------------------------------- | + | `Release` | Official release version (default) | + | `Beta` | Test version | + | `Dev` | Development Version | + + - other : `Object` + Other additional information you are willing to provide (such as license, open source address, etc.) + +Among them, version version information is an array of version number numbers, such as `[2,0,1]` indicates that the version number is 2.0.1 +If you do not pass in valid version information, the version number of the plugin will be set to the default value `1.0.0` + +For plugin additional information, you can pass in any information you need to inform the user in the same format as `Object` key-value pair. The specific data of the key-value pair needs to be `String` format. + +
+ +## 💼 Script Assist API + +The following APIs add necessary auxiliary interfaces to scripts. + +### Output Information To The Console + +`log(data1,data2,...)` + +- Parameter:., + - Variable or data to be output + Can be of any type, and the number of parameters can be any number. +- Return value: none + +
+ +### Output Color Text + +This is an upgraded version of the above function; it supports color output. + +`colorLog(color,data1,data2,...)` + +- Parameter: + - color : `String` + The color output by this line (code example and effect are as follows) + - data... : + Variable or data to be output + Can be of any type, and the number of parameters can be any number. +- Return value: none + +#### Show results: + +![ColorLogExample](../../../assets/ColorLog.png) + +
+ +### Asynchronous Output + +This function returns immediately after the output request is sent, avoiding the blocking time caused by synchronous reading and writing. +The bottom layer has lock protection, different `fastLog` There will be no string phenomenon between. + +`fastLog(data1,data2,...)` + +- Parameter: + - data... : + Variable or data to be output + Can be of any type, and the number of parameters can be any number +- Return value: none + +
+ +### Delay the execution of a function for a period of time + +`setTimeout(func,msec)` + +- Parameter: + + - func : `Function` + The function to be executed. + + - msec : `Integer` + Delay execution time (milliseconds) +- Return value: this task id. +- Return value type: `Integer` + - If it returns `Null`, the task failed. + +
+ +### Delay the execution of a code segment for a period of time (eval) + +`setTimeout(code,msec)` + +- Parameter: + + - code : `String` + The code segment to be executed. + + - msec : `Integer` + Delay execution time (milliseconds) +- Return value: this task id +- Return value type: `Integer` + - If it returns `Null`, the task creation failed. + +
+ +### Set period execution function + +`setInterval(func,msec)` + +- Parameter: + - func : `Function` + The function to be executed + + - msec : `Integer` + Execution interval period (ms) +- Return value: this task id +- Return value type: `Integer` + +
+ +### Set period execution code segment (eval) + +`setInterval(code,msec)` + +- Parameter: + - code : `String` + The code to be executed. + + - msec : `Integer` + Execution interval period (ms) +- Return value: this task id +- Return value type: `Integer` + - If it returns `Null`, the task creation failed. + +
+ +### Cancel Delay/Period Execution Item + +`clearInterval(taskid)` + +- Parameter: + - timerid : `Integer` + The task ID returned by the first few functions +- Return value: whether the cancellation was successful. +- Return value type: `Boolean` + - If it returns `Null`, the cancellation of the task failed. + +
\ No newline at end of file diff --git a/docs/apis/ScriptAPI/ScriptHelp.zh.md b/docs/apis/ScriptAPI/ScriptHelp.zh.md new file mode 100644 index 00000000..d5645978 --- /dev/null +++ b/docs/apis/ScriptAPI/ScriptHelp.zh.md @@ -0,0 +1,168 @@ +# 脚本引擎 - 通用脚本接口文档 + +> 这里提供了一些常用的 **辅助功能** ,如插件注册、输出信息和异步接口等 + +他们让你开发脚本变得更加容易而自然,避免了很多无谓的细节问题的纠缠。 + +## 🎯 插件注册 API + +在开始为你的插件编写代码之前,你首先需要向加载器提供一些插件相关的信息 + +`ll.registerPlugin(name, introduction, version, otherInformation)` + +- 参数: + + - name : `String` + 插件名字 + + - introduction : `String` + 对插件的简短介绍 + + - version : `Array` + 插件的版本信息 + + 对于 `VersionStatus`,可以使用以下枚举 + + | Enum | Description | + | ----------------- | ---------------------- | + | `Version.Release` | 正式发布版本(默认值) | + | `Version.Beta` | 测试版本 | + | `Version.Dev` | 开发版本 | + + - other : `Object` + 其他你愿意提供的的附加信息(如许可证、开源地址等) + +其中,version 版本信息为版本号数字构成的数组,如`[2,0,1]`表示版本号为2.0.1 +如果你没有传入有效的版本信息,插件的版本号将被设置为默认值`1.0.0` + +对于插件附加信息,你可以传入任意你需要告知用户的信息,格式同样为`Object`键值对。键值对的具体数据需要为`String`格式 + +
+ +## 💼 脚本辅助 API + +下面这些API为脚本增加了必要的辅助接口 + +### 输出信息到控制台 + +`log(data1,data2,...)` + +- 参数: + - 待输出的变量或者数据 + 可以是任意类型,参数数量可以是任意个 +- 返回值:无 + +
+ +### 输出带颜色文本 + +这是楼上那位的升级版,没错,它支持彩色输出 + +`colorLog(color,data1,data2,...)` + +- 参数: + - color : `String` + 此行输出的颜色(代码示例和效果如下图) + - data... : + 待输出的变量或者数据 + 可以是任意类型,参数数量可以是任意个 +- 返回值:无 + +#### 效果展示: + +![ColorLogExample](../../../assets/ColorLog.png) + +
+ +### 异步输出 + +此函数将输出请求发出后即刻返回,避免同步读写造成的阻塞时间 +底层有锁保护,不同的`fastLog`之间不会出现串字符现象 + +`fastLog(data1,data2,...)` + +- 参数: + - data... : + 待输出的变量或者数据 + 可以是任意类型,参数数量可以是任意个 +- 返回值:无 + +
+ +### 推迟一段时间执行函数 + +`setTimeout(func,msec)` + +- 参数: + + - func : `Function` + 待执行的函数 + + - msec : `Integer` + 推迟执行的时间(毫秒) +- 返回值:此任务ID +- 返回值类型:`Integer` + - 如果返回`Null`,则代表创建任务失败 + +
+ +### 推迟一段时间执行代码段(eval) + +`setTimeout(code,msec)` + +- 参数: + + - code : `String` + 待执行的代码段 + + - msec : `Integer` + 推迟执行的时间(毫秒) +- 返回值:此任务ID +- 返回值类型:`Integer` + - 如果返回`Null`,则代表创建任务失败 + +
+ +### 设置周期执行函数 + +`setInterval(func,msec)` + +- 参数: + - func : `Function` + 待执行的函数 + + - msec : `Integer` + 执行间隔周期(毫秒) +- 返回值:此任务ID +- 返回值类型: `Integer` + +
+ +### 设置周期执行代码段(eval) + +`setInterval(code,msec)` + +- 参数: + - code : `String` + 待执行的代码段 + + - msec : `Integer` + 执行间隔周期(毫秒) +- 返回值:此任务ID +- 返回值类型: `Integer` + - 如果返回`Null`,则代表创建任务失败 + +
+ +### 取消延时 / 周期执行项 + +`clearInterval(taskid)` + +- 参数: + - timerid : `Integer` + 由前几个函数返回的任务ID +- 返回值:是否取消成功 +- 返回值类型: `Boolean` + - 如果返回`Null`,则代表取消任务失败 + +
diff --git a/docs/apis/ScriptAPI/i18n.md b/docs/apis/ScriptAPI/i18n.md new file mode 100644 index 00000000..7818ea47 --- /dev/null +++ b/docs/apis/ScriptAPI/i18n.md @@ -0,0 +1,154 @@ +## 🛫 Internationalization API + +As our community gets bigger and bigger, language becomes a barrier for users and players from different countries to communicate. To change this, we made `I18nAPI` and encourage plugin creators use it. + +## Load translation data + +`i18n.load(path, defaultLocaleName, defaultLangData)` + + +- Params: + - path: `String` + The file[^1]/directory[^2] where the translation data is located + - defaultLocaleName: `String` + default locale name, in the form of `zh_CN` or `en` (this parameter will be used if the target language is not provided for the translation of `i18n.tr` or `i18n.get`) + If an empty string is passed in, the default follows the system language + - defaultLangData: `Object` + This parameter will be used to complete or create translation files in the form of + ```js + { + localeName: { + "src": "translation" + }, + en_CN: { + "a.b.c.d.114514": "1919810", + "src": "source" + } + } + ``` +- Throw: + - Invalid parameter + +[^1]: the file must be in JSON format and the content of the file should be similar to + ```json + { + "localeName": { + "src": "translation" + }, + "zh_CN": { + "a.b.c.d.114514": "1919810", + "src": "源" + } + } + ``` + +[^2]: Please add the path separator (`/` or `\\\`) at the end of the path. + The contents of the directory should be similar to. + ``` + ┌ LOCALE_name.json + [Dir] ┼ en.json + └ zh_CN.json + ``` + Each file inside should be similar to: + ```json + { + "a.c.b.d": "translation", + "use": { + "nested": { + "src": "translation" + }, + "114514": { + "1919810": "heng heng aaaaaaaaaaaaaaaaaaaaaaaaa", + "a": "此处的ID为use.nested.114514.a", + "b": "The ID of this will be use.nested.114514.b" + } + } + } + ``` + +
+ +## Get the translation of the text in the specified language + +`i18n.get(key[,localeName])` + +- Params: + - key: `String` + Text or ID + - localeName: `String`(Optional) + Target language, default is the `defaultLocaleName` passed in when `i18n.load`. +- Return value: `String` translation (if no translation is found after multiple fallbacks, then `key` is returned) +- Throw: + - Invalid parameter + +
+ +## Translate and format the text using the specified language + +`i18n.trl(localeName, key, ...) ` + +- Parameters: + - localeName: `String` + Target language + - key: `String` + Text or ID + - ... : `Any` + Format arguments +- Return value: `String` translated and formatted text +- Note: Formatting should follow [syntax](https://fmt.dev/latest/syntax.html) +- Throw: + - Invalid parameter + +
+ +## Translate and format the text using the default language + +`i18n.tr(key, ...) ` + +- Parameters: + - key: `String` + Text or ID + - ... : `Any` + Format arguments +- Return value: `String` translated and formatted text +- Note: Formatting should follow [syntax](https://fmt.dev/latest/syntax.html) +- Throw: + - Invalid parameter + +
+ +## Full sample + +```js +i18n.load("plugins/feature-llse-i18n-test/language.json", "" /* "zh_CN" */, { + "zh_CN": { + "{1}, {0}, named_arg(float.2): {named_arg:.2f}": "测试: {1}, {0}, named_arg(float.2): {named_arg:.2f}", + "{} {} {a} {b}": "测试2: {} {} {a} {b}", + "welcome": "Hi, {}! Welcome to the server!" + }, + "en": { + "welcome": "Hi, {}! Welcome to the SERVER!" + } +}); + +LLSE_Player.prototype._sendText = LLSE_PLayer.prototype.sendText; +LLSE_Player.prototype.sendText = function() { + let args = Array.from(arguments); + let text = args.shift(); + pl._sendText(i18n.trl(this.langCode, text, . . args)); +} + +logger.info(tr("{1}, {0}, named_arg(float.2): {named_arg:.2f}", "string0", 1, { + named_arg: 114.51419 // Named arguments should be object +})); +// Out: test: 1, string0, named_arg(float.2): 114.51 + +logger.info(tr("{} {} {a} {b}", "arg0", "arg1", { + a: "114514", + b: "1919810" +})); + +mc.listen("onJoin", (pl) => { + pl.sendText("welcome", pl.realName); +}); +``` \ No newline at end of file diff --git a/docs/apis/ScriptAPI/i18n.zh.md b/docs/apis/ScriptAPI/i18n.zh.md new file mode 100644 index 00000000..098c600b --- /dev/null +++ b/docs/apis/ScriptAPI/i18n.zh.md @@ -0,0 +1,155 @@ +## 🛫 国际化 API + +随着我们的社区越来越大,语言成为了各个国家的用户和玩家之间交流的障碍。为了解决这个问题,我们提供了`I18nAPI`并鼓励插件创作者使用国际化接口。 + + +## 加载翻译数据 + +`i18n.load(path, defaultLocaleName, defaultLangData)` + + +- 参数: + - path: `String` + 翻译数据所在的文件[^1]/目录[^2] + - defaultLocaleName: `String` + 默认的语言名称,形如`zh_CN`或`en`(如果没有提供目标语言给`i18n.tr`或`i18n.get`的翻译,这个参数将被使用) + 若传入空字符串,则默认跟随系统语言 + - defaultLangData: `Object` + 该参数将用于补全或创建翻译文件,形如 + ```js + { + localeName: { + "src": "translation" + }, + zh_CN: { + "a.b.c.d.114514": "1919810", + "src": "源" + } + } + ``` +- 抛出: + - 参数无效 + +[^1]: 文件必须为JSON格式,且文件内容应类似: + ```json + { + "localeName": { + "src": "translation" + }, + "zh_CN": { + "a.b.c.d.114514": "1919810", + "src": "源" + } + } + ``` + +[^2]: 请在路径的末尾加上路径分隔符(`/`或`\\`)。 + 目录内容应类似: + ``` + ┌ LOCALE_name.json + [Dir] ┼ en.json + └ zh_CN.json + ``` + 其中的每个文件内容都应类似: + ```json + { + "a.c.b.d": "translation", + "use": { + "nested": { + "src": "translation" + }, + "114514": { + "1919810": "heng heng aaaaaaaaaaaaaaaaaaaaaaaaa", + "a": "此处的ID为use.nested.114514.a", + "b": "The ID of this will be use.nested.114514.b" + } + } + } + ``` + +
+ +## 获取文本的指定语言翻译 + +`i18n.get(key[,localeName])` + +- 参数: + - key: `String` + 文本或ID + - localeName: `String`(可选) + 目标语言,默认为`i18n.load`时传入的`defaultLocaleName` +- 返回值: `String` 翻译内容(若经过多次回落仍未找到翻译,则返回`key`) +- 抛出: + - 参数无效 + +
+ +## 使用指定语言翻译文本并格式化 + +`i18n.trl(localeName, key, ...)` + +- 参数: + - localeName: `String` + 目标语言 + - key: `String` + 文本或ID + - ...: `Any` + 格式化参数 +- 返回值: `String` 翻译并格式化后的文本 +- 注意: 格式化应遵循[语法](https://fmt.dev/latest/syntax.html) +- 抛出: + - 参数无效 + +
+ +## 使用默认语言翻译文本并格式化 + +`i18n.tr(key, ...)` + +- 参数: + - key: `String` + 文本或ID + - ...: `Any` + 格式化参数 +- 返回值: `String` 翻译并格式化后的文本 +- 注意: 格式化应遵循[语法](https://fmt.dev/latest/syntax.html) +- 抛出: + - 参数无效 + +
+ +## 完整样例 + +```js +i18n.load("plugins/feature-llse-i18n-test/language.json", "" /* "zh_CN" */, { + "zh_CN": { + "{1}, {0}, named_arg(float.2): {named_arg:.2f}": "测试: {1}, {0}, named_arg(float.2): {named_arg:.2f}", + "{} {} {a} {b}": "测试2: {} {} {a} {b}", + "welcome": "Hi, {}! 欢迎来到服务器!" + }, + "en": { + "welcome": "Hi, {}! Welcome to the SERVER!" + } +}); + +LLSE_Player.prototype._sendText = LLSE_PLayer.prototype.sendText; +LLSE_Player.prototype.sendText = function() { + let args = Array.from(arguments); + let text = args.shift(); + pl._sendText(i18n.trl(this.langCode, text, ...args)); +} + +logger.info(tr("{1}, {0}, named_arg(float.2): {named_arg:.2f}", "string0", 1, { + named_arg: 114.51419 // Named arguments should be object +})); +// Out: 测试: 1, string0, named_arg(float.2): 114.51 + +logger.info(tr("{} {} {a} {b}", "arg0", "arg1", { + a: "114514", + b: "1919810" +})); + +mc.listen("onJoin", (pl) => { + pl.sendText("welcome", pl.realName); +}); +``` \ No newline at end of file diff --git a/docs/apis/SystemAPI/File.md b/docs/apis/SystemAPI/File.md new file mode 100644 index 00000000..55fa20fa --- /dev/null +++ b/docs/apis/SystemAPI/File.md @@ -0,0 +1,385 @@ +# LLSE - System Functional Interface Documentation + +> This provides an interface for connecting to **underlying system functions**, including operating the file system, accessing the network, etc. + +For plugin development, the realization of interoperability with the underlying interface of the system is an important extension, which greatly enhances the flexibility of plug-in development. + +## 📝 Simple File Read and Write API + +The following APIs provide a simple interface for reading and writing files, which is convenient for occasional reading and writing of files. +LLSE uses the file class `File` to encapsulate file-related operations. +If you need to manipulate files frequently, use the file classes below to improve performance. + +> Note: All text-related operations use UTF-8 encoding. + +### Read in All the Contents of the File + +`File.readFrom(path)` + +- Parameter: + - path : `String` + The path of the target file, the relative path is based on the BDS root directory. +- Return value: All data in the file +- Return value type: `String` + - If the return value is `Null`, the read failed. + +
+ +### Write Content to the Specified File + +`File.writeTo(path,text)` + +- Parameter: + - path : `String` + The path of the target file, the relative path is based on the BDS root directory. + + - text : `String` + What will be written to the file. + +- Return value: Whether the write is successful or not. + +- Return value type: `Boolean` + +> Note: If the file does not exist, it will be created automatically. If it exists, it will be **emptied** before writing. + +
+ +### Append a Line to the Specified File + +`File.writeLine(path,text)` + +- Parameter: + - path : `String` + The path of the target file, the relative path is based on the BDS root directory. + + - text : `String` + What will be written to the file. +- Return value: Whether the write is successful or not. +- Return value type: `Boolean` + +
+ +## 📋 File Object API + +In LLSE, "file objects" are used to manipulate and read and write to a particular file. + +### Create a New File Object + +[JavaScript] `new File(path,mode[,isBinary])` +[Lua] `File(path,mode[,isBinary])` + +- Parameter: + - path : `String` + The path of the file you want to open + - mode : `Enum` + File open mode + - isBinary : `Boolean` + (optional parameter) whether to open the file in binary mode, the default is `false` + In normal mode, during file reading and writing, newlines will be converted according to the local format. If you open the file in binary mode, indicating that the file is not in normal text format, these automatic conversions will not occur. +- Return value: The open file object. +- Return value type: `File` + - If the open fails, an exception will be thrown + +The file opening mode has the following options: + +| Open Mode | Meaning | +| ----------------- | ------------------------------------------------------ | +| `file.ReadMode` | Open file for reading | +| `file.WriteMode` | Open and overwrite file, or create new file for writing| +| `file.AppendMode` | Open and write at the end of the file | + +When using `ReadMode` and `WriteMode`, you can use `seekTo` to manually move the file pointer position. + +> If the file with the given path exists, the existing file will be opened directly; if the file does not exist, a new file will be created automatically. If some directories in the opened path do not exist, the interface will automatically create directories. + +After opening the file, you can use the interface of the file object described below to read and write the file. + +
+ + +### File Object - Properties + +Every file object contains some fixed object properties. for a specific file object `fi`, has the following properties + +| Attributes | Meaning | Data Types | +| --------------- | ------------------ | --------- | +| fi.path | Current File Path | `String` | +| fi.absolutePath | Absolute current file path | `String` | +| fi.size | Current file size | `Integer` | + +These object properties are read-only and cannot be modified. + +
+ +### File Object - Function + +Each file object contains some member functions (member methods) that can be executed. for a specific file object `fi`, you can perform some operations on this file through the following functions + +#### Synchronous Read and Write + +When using the synchronous read/write interface, you need to pay attention. If the file is too large or the read and write content is too large, the consumption time is too long, which may cause the game to freeze. +If there is not much content to read and write, use the synchronous interface to have a better development experience. +If there is a lot of content, you can use the following asynchronous read and write interface. + +##### Read Text/Binary Data From File + +`fi.readSync(cnt)` + +- Parameter: + - cnt : `Number` + Number of characters/bytes to read +- Return value: read string content/binary data +- Return value type: `String` / `ByteBuffer` + - If the return value is `Null`, the read failed. + +Start reading from the current file pointer. Returns if the file was opened in binary mode `ByteBuffer`, otherwise return `String`. + +
+ +##### Read a Line of Text From a File + +`fi.readLineSync()` + +- Return value: Read String Content +- Return value type: `String` + - If the return value is `Null`, the read failed. + +> Note that the newline at the end of the string should be handled by itself + +
+ +##### Read Everything From File + +`fi.readAllSync()` + +- Return value: Read string content/binary data +- Return value type: `String` / `ByteBuffer` + - If the return value is `Null`, the read failed. + +Reading starts at the current file pointer and continues until the end of the file. +Returns if the file was opened in binary mode `ByteBuffer`, otherwise return `String`. + +
+ +##### Write Text/Binary Data to File + +`fi.writeSync(str)` + +- Parameter: + - str : `String` / `ByteBuffer` + The data that will be written +- Return value: Whether the write succeeded or not. +- Return value type: `Boolean` + +If the file is opened in binary mode, the passed arguments will be written as binary bytes, otherwise they will be written as normal text. + +
+ +##### Write a Line of Text to a File + +`fi.writeLineSync(str)` + +- Parameter: + - str : `String` + The `String` that will be written +- Return value: Whether the write succeeded or not. +- Return value type: `Boolean` + +When this function executes, it will automatically add a newline at the end of the string. + +
+ +#### Asynchronous Read and Write + +When the amount of data is large and it takes a long time, it is recommended to use the asynchronous read/write interface to reduce the impact on the server. + +##### Read Text/Binary Data From File (Async) + +`fi.read(cnt,callback)` + +- Parameter: + - cnt : `Number` + Number of characters/bytes to read + - callback : `Function` + Callback function to get the result +- Return value: Whether the request was successfully sent. +- Return value type: `Boolean` + +Note: The prototype of the callback function of the parameter callback: `function(result)` + +- result : `String` / `ByteBuffer` + read text/binary data + If result is `Null` it means that the read failed + +Start reading from the current file pointer. Returns if the file was opened in binary mode `ByteBuffer`, otherwise return `String`. + +
+ +##### Read a Line of Text From a File (Async) + +`fi.readLine(callback)` + +- Parameter: + - callback : `Function` + Callback function to get the result. +- Return value: Whether the request was successfully sent. +- Return value type: `Boolean` + +Note: The prototype of the callback function of the parameter callback: `function(result)` + +- result : `String` + The text that was read from the file. + +> Note that the newline at the end of the string should be handled by itself. + +
+ +##### Read Everything From File (Async) + +`fi.readAll(callback)` + +- Parameter: + - callback : `Function` + Callback function to get the result. +- Return value: Whether the request was successfully sent. +- Return value type: `Boolean` + +Note: The prototype of the callback function of the parameter callback: `function(result)` + +- result : `String` / `ByteBuffer` + Text/Binary data read from the file. + If result is `Null` it means that the read failed. + +Reading starts at the current file pointer and continues until the end of the file. +Returns if the file was opened in binary mode `ByteBuffer`, otherwise return `String`. + +
+ +##### Write Text/Binary Data to File (Async) + +`fi.write(str[,callback])` + +- Parameter: + - str : `String` / `ByteBuffer` + The data that will be written. + - callback : `Function` + (optional parameter) Callback function to get the result. +- Return value: Whether the request was successfully sent. +- Return value type: `Boolean` + +If the file is opened in binary mode, pass in a `ByteBuffer`, otherwise you need to pass in `String`. + +Note: The prototype of the callback function of the parameter callback: `function(result)` + +- result : `Boolean` + Whether the write is successful. + +
+ +##### Write a Line of Text to a File (Async) + +`fi.writeLine(str[,callback])` + +- Parameter: + - str : `String` + The data that will be written + - callback : `Function` + (optional parameter) Callback function to get the result. +- Return value: Whether the request was successfully sent. +- Return value type: `Boolean` + +Note: The prototype of the callback function of the parameter callback: `function(result)` + +- result : `Boolean` + Whether the write is successful. + +> When this function executes, it will automatically add a newline at the end of the string. + +
+ +#### Other Common Interfaces + +In addition to the above-mentioned read and write interfaces, other general interfaces for manipulating file objects are also provided here. + +##### Move the File Pointer + +`fi.seekTo(pos,isRelative)` + +- Parameter: + - pos : `Number` + The position to move the file pointer to. + - isRelative : `Boolean` + Whether it is moving relative to the current file pointer position. +- Return value: Whether the move was successful. +- Return value type: `Boolean` + +If isRelative is `true`pos means moving relative to the current position, a positive number means moving backward, and a negative number means moving forward. +If isRelative is `false`, pos means move relative to the beginning of the file, which is `0` or a positive number. If `-1`, which means move to the end of the file. + +
+ +##### Set File Size + +`fi.setSize(size)` + +- Parameter: + - size : `Number` + The size the file will be set to. +- Return value: Whether the setting was successful. +- Return value type: `Boolean` + +The new size can be set larger than the current size of the file. +If the new size set is smaller than the current size of the file, the original file will be truncated. + +
+ +##### Close File + +`fi.close()` + +- Return value: Whether closing the file was successful. +- Return value type: `Boolean` + +Once the file is closed, it cannot be used until it is opened again. + +
+ +##### Whether the File Pointer Is at the End of the File + +`fi.isEOF()` + +- Return value: Whether the file pointer is at the end of the file. +- Return value type: `Boolean` + +
+ +##### Flush File Buffer + +`fi.flush()` + +- Return value: Whether the refresh was successful. +- Return value type: `Boolean` + +
+ +##### Get Error Code + +`fi.errorCode()` + +- Return value: the error code generated by the last IO operation. +- Return value type: `Integer` + +If you encounter a failure in the use of the above interface, you can get the last error code from here. + +
+ +##### Clear Error Status + +`fi.clear()` + +- Return value: whether the error was cleared successfully +- Return value type: `Boolean` + +If a failure is encountered in the use of the above interface, after obtaining the error code, use this function to clear the error state to continue to use the file object normally. + +
\ No newline at end of file diff --git a/docs/apis/SystemAPI/File.zh.md b/docs/apis/SystemAPI/File.zh.md new file mode 100644 index 00000000..a8364011 --- /dev/null +++ b/docs/apis/SystemAPI/File.zh.md @@ -0,0 +1,385 @@ +# 脚本引擎 - 系统功能接口文档 + +> 这里提供了对接 **底层系统功能** 的接口,包括操作文件系统、访问网络等 + +对插件开发来说,实现与系统底层接口的互通是重要的扩展,大大增强了插件开发的灵活性。 + +## 📝 简单文件读写 API + +下面这些API提供了简单读写文件的接口,为偶尔读取和写入文件提供方便。 +脚本引擎使用文件类 **File** 来封装文件相关操作 +如果需要频繁地操作文件,请使用下方的文件类,以提高性能 + +> 注:所有文本相关的操作均使用UTF-8编码。 + +### 读入文件的所有内容 + +`File.readFrom(path)` + +- 参数: + - path : `String` + 目标文件的路径,相对路径以BDS根目录为基准 +- 返回值:文件的所有数据 +- 返回值类型:`String` + - 如返回值为 `Null` 则表示读取失败 + +
+ +### 向指定文件写入内容 + +`File.writeTo(path,text)` + +- 参数: + - path : `String` + 目标文件的路径,相对路径以BDS根目录为基准 + + - text : `String` + 要写入的内容 + +- 返回值:是否写入成功 + +- 返回值类型:`Boolean` + +> 注:若文件不存在会自动创建,若存在则会先将其**清空**再写入 + +
+ +### 向指定文件追加一行 + +`File.writeLine(path,text)` + +- 参数: + - path : `String` + 目标文件的路径,相对路径以BDS根目录为基准 + + - text : `String` + 要写入的内容 +- 返回值:是否写入成功 +- 返回值类型:`Boolean` + +
+ +## 📋 文件对象 API + +在脚本引擎中,使用「文件对象」来操作和读写某一个特定的文件。 + +### 创建一个新的文件对象 + +[JavaScript] `new File(path,mode[,isBinary])` +[Lua] `File(path,mode[,isBinary])` + +- 参数: + - path : `String` + 想要打开的文件路径 + - mode : `Enum` + 文件的打开模式 + - isBinary : `Boolean` + (可选参数)是否以二进制模式打开文件,默认为`false` + 普通模式下,文件读写过程中,换行符将会被按本地格式转换。如果你使用二进制模式打开文件,表明此文件并非普通的文本格式,这些自动转换将不会发生。 +- 返回值:打开的文件对象 +- 返回值类型:`File` + - 如果打开失败,将抛出异常 + +文件的打开模式有如下可选项: + +| 打开模式 | 表示的含义 | +| ----------------- | ------------------------------------------------------ | +| `file.ReadMode` | 准备读取文件内容 | +| `file.WriteMode` | 准备写入文件。如果文件已存在,会被清空 | +| `file.AppendMode` | 准备写入文件。之后写入的任何内容都将会被追加到文件最后 | + +当使用`ReadMode`和`WriteMode`时,可以使用`seekTo`手动移动文件指针位置 + +> 如果给出路径的文件存在,会直接打开那个已存在的文件;如果文件不存在,会自动创建新的文件。如果打开的路径中有部分目录不存在,接口将会自动创建目录。 + +在打开文件之后,就可以使用下述文件对象的接口来读写文件。 + +
+ + +### 文件对象 - 属性 + +每一个文件对象都包含一些固定的对象属性。对于某个特定的文件对象`fi`,有以下这些属性 + +| 属性 | 含义 | 类型 | +| --------------- | ------------------ | --------- | +| fi.path | 当前文件路径 | `String` | +| fi.absolutePath | 当前文件的绝对路径 | `String` | +| fi.size | 当前文件大小 | `Integer` | + +这些对象属性都是只读的,无法被修改 + +
+ +### 文件对象 - 函数 + +每一个文件对象都包含一些可以执行的成员函数(成员方法)。对于某个特定的文件对象`fi`,可以通过以下这些函数对这个文件进行一些操作 + +#### 同步读写 + +使用同步读写接口时需要注意,如果文件过大或者读写内容过多,消耗时间过长,可能造成游戏卡顿 +如果读写内容不多,使用同步接口有更好的开发体验 +如果内容较多,可以使用后面的异步读写接口 + +##### 从文件读取文本 / 二进制数据 + +`fi.readSync(cnt)` + +- 参数: + - cnt : `Number` + 要读取的字符数 / 字节数 +- 返回值:读取的字符串内容 / 二进制数据 +- 返回值类型:`String` / `ByteBuffer` + - 如返回值为 `Null` 则表示读取失败 + +从当前文件指针处开始读取。如果文件以二进制模式打开,则返回`ByteBuffer`,否则返回`String` + +
+ +##### 从文件读取一行文本 + +`fi.readLineSync()` + +- 返回值:读取的字符串内容 +- 返回值类型:`String` + - 如返回值为 `Null` 则表示读取失败 + +> 注意,字符串尾部的换行符要自行处理 + +
+ +##### 从文件读取所有内容 + +`fi.readAllSync()` + +- 返回值:读取的字符串内容 / 二进制数据 +- 返回值类型:`String` / `ByteBuffer` + - 如返回值为 `Null` 则表示读取失败 + +从当前文件指针处开始读取,一直读取到文件末尾为止。 +如果文件以二进制模式打开,则返回`ByteBuffer`,否则返回`String` + +
+ +##### 写入文本 / 二进制数据到文件 + +`fi.writeSync(str)` + +- 参数: + - str : `String` / `ByteBuffer` + 要写入的内容 +- 返回值:是否成功写入 +- 返回值类型:`Boolean` + +如果文件以二进制模式打开,传入的参数将被按照二进制字节写入,否则将按照普通文本写入 + +
+ +##### 写入一行文本到文件 + +`fi.writeLineSync(str)` + +- 参数: + - str : `String` + 要写入的内容 +- 返回值:是否成功写入 +- 返回值类型:`Boolean` + +此函数执行时,将在字符串尾自动添加换行符 + +
+ +#### 异步读写 + +在数据量较大,耗费时间较长时,建议使用异步读写接口,以减少对服务器的影响。 + +##### 从文件读取文本 / 二进制数据(异步) + +`fi.read(cnt,callback)` + +- 参数: + - cnt : `Number` + 要读取的字符数 / 字节数 + - callback : `Function` + 获取结果的回调函数 +- 返回值:是否成功发送请求 +- 返回值类型:`Boolean` + +注:参数callback的回调函数原型:`function(result)` + +- result : `String` / `ByteBuffer` + 读取到的文本 / 二进制数据 + 如 result 为 `Null` 则表示读取失败 + +从当前文件指针处开始读取。如果文件以二进制模式打开,则返回`ByteBuffer`,否则返回`String` + +
+ +##### 从文件读取一行文本(异步) + +`fi.readLine(callback)` + +- 参数: + - callback : `Function` + 获取结果的回调函数 +- 返回值:是否成功发送请求 +- 返回值类型:`Boolean` + +注:参数callback的回调函数原型:`function(result)` + +- result : `String` + 读取到的文本 + +> 注意,字符串尾部的换行符要自行处理 + +
+ +##### 从文件读取所有内容(异步) + +`fi.readAll(callback)` + +- 参数: + - callback : `Function` + 获取结果的回调函数 +- 返回值:是否成功发送请求 +- 返回值类型:`Boolean` + +注:参数callback的回调函数原型:`function(result)` + +- result : `String` / `ByteBuffer` + 读取到的文本 / 二进制数据 + 如 result 为 `Null` 则表示读取失败 + +从当前文件指针处开始读取,一直读取到文件末尾为止。 +如果文件以二进制模式打开,则返回`ByteBuffer`,否则返回`String` + +
+ +##### 写入文本 / 二进制数据到文件(异步) + +`fi.write(str[,callback])` + +- 参数: + - str : `String` / `ByteBuffer` + 要写入的内容 + - callback : `Function` + (可选参数)获取结果的回调函数 +- 返回值:是否成功发送请求 +- 返回值类型:`Boolean` + +如果文件以二进制模式打开,请传入一个`ByteBuffer`,否则需要传入`String` + +注:参数callback的回调函数原型:`function(result)` + +- result : `Boolean` + 是否写入成功 + +
+ +##### 写入一行文本到文件(异步) + +`fi.writeLine(str[,callback])` + +- 参数: + - str : `String` + 要写入的内容 + - callback : `Function` + (可选参数)获取结果的回调函数 +- 返回值:是否成功发送请求 +- 返回值类型:`Boolean` + +注:参数callback的回调函数原型:`function(result)` + +- result : `Boolean` + 是否写入成功 + +> 此函数执行时,将在字符串尾自动添加换行符 + +
+ +#### 其他通用接口 + +除了上述的读写接口之外,这里还提供了其他操作文件对象的通用接口 + +##### 移动文件指针 + +`fi.seekTo(pos,isRelative)` + +- 参数: + - pos : `Number` + 文件指针要移动到的位置 + - isRelative : `Boolean` + 是否是相对当前文件指针位置移动 +- 返回值:是否移动成功 +- 返回值类型:`Boolean` + +如果isRelative为`true`,pos表示相对当前位置移动,正数为向后移动,负数为向前移动 +如果isRelative为`false`,pos表示相对文件开头移动,为`0`或正数。如果为`-1`,表示移动到文件末尾 + +
+ +##### 设定文件大小 + +`fi.setSize(size)` + +- 参数: + - size : `Number` + 要设定的目标大小 +- 返回值:是否设定成功 +- 返回值类型:`Boolean` + +设定的新大小可以大于文件的当前大小。 +如果设定的新大小小于文件的当前大小,原文件将被截断。 + +
+ +##### 关闭文件 + +`fi.close()` + +- 返回值:是否成功关闭 +- 返回值类型:`Boolean` + +文件关闭后,严禁再次使用 + +
+ +##### 文件指针是否位于文件尾 + +`fi.isEOF()` + +- 返回值:文件指针是否处于文件尾 +- 返回值类型:`Boolean` + +
+ +##### 刷新文件缓冲区 + +`fi.flush()` + +- 返回值:是否成功刷新 +- 返回值类型:`Boolean` + +
+ +##### 获取错误码 + +`fi.errorCode()` + +- 返回值:上一次IO操作产生的错误码 +- 返回值类型:`Integer` + +如果在上述接口使用中遇到了失败,可以从这里获取上一个错误码 + +
+ +##### 清除错误状态 + +`fi.clear()` + +- 返回值:是否成功清除 +- 返回值类型:`Boolean` + +如果在上述接口使用中遇到了失败,在获取错误码完成之后,使用此函数清除错误状态,以继续正常使用文件对象 + +
\ No newline at end of file diff --git a/docs/apis/SystemAPI/FileSystem.md b/docs/apis/SystemAPI/FileSystem.md new file mode 100644 index 00000000..27324298 --- /dev/null +++ b/docs/apis/SystemAPI/FileSystem.md @@ -0,0 +1,130 @@ +## 📂 Directory and File API + +The following APIs provide interfaces for manipulating files, directories, etc. to interact with the file system. + +> Note: The relative paths of all incoming functions are based on the BDS root directory + +### Create Folder + +`File.createDir(dir)` +`File.mkdir(dir)` + +- Parameter: + - dir : `String` + The path to the destination folder. + Multiple folders can be created directly, no need to create one at a time. +- Return value: Whether the folder or folders were created successfully. +- Return value type: `Boolean` + +
+ +### Delete File/Folder + +`File.delete(path)` + +- Parameter: + - path : `String` + Path to target file/folder +- Return value: Whether the deletion was successful. +- Return value type: `Boolean` + +
+ +### Check if a File/Folder Exists + +`File.exists(path)` + +- Parameter: + - path : `String` + Path to target file/folder. +- Return value: Whether the target exists. +- Return value type: `Boolean` + +
+ +### Copy Files/Folders to Specified Location + +`File.copy(from,to)` + +- Parameters: + - from : `String` + Path to source file/folder. + + - to : `String` + The location of the target file/folder. +- Return value: Whether the copy is successful. +- Return value type: `Boolean` + +
+ +### Move File/Folder to Specified Location + +`File.move(from,to)` + +- Parameters: + - from : `String` + Path to source file/folder. + + - to : `String` + The location of the target file/folder. +- Return value: Whether the copy is successful. +- Return value type: `Boolean` + +
+ +### Rename specified file/folder + +`File.rename(from,to)` + +- Parameters: + - from : `String` + Current name of file/folder. + + - to : `String` + New name of the file/folder. +- Return value: Whether the rename is successful. +- Return value type: `Boolean` + +
+ +### Get the Size of the Specified File + +`File.getFileSize(path)` + +- Parameter: + - path : `String` + The file path to be manipulated. + +- Return value: the size of the file (bytes). +- Return value type: `Integer` + +If the path location passed in is a folder, returns `-1`. + +
+ +### Determine if the Specified Path Is a Folder + +`File.checkIsDir(path)` + +- Parameter: + - path : `String` + Determined path. +- Return value: Whether the target path is a folder. +- Return value type: `Boolean` + +If the target path does not exist, it will also return `false` + +
+ +### List All Files/Folders Under the Specified Folder + +`File.getFilesList(dir)` + +- Parameter: + - dir: `String` + Folder path. + +- Return value: Array of file names, folder names. +- Return value type: `Array` + +
\ No newline at end of file diff --git a/docs/apis/SystemAPI/FileSystem.zh.md b/docs/apis/SystemAPI/FileSystem.zh.md new file mode 100644 index 00000000..04de0d31 --- /dev/null +++ b/docs/apis/SystemAPI/FileSystem.zh.md @@ -0,0 +1,130 @@ +## 📂 目录与文件 API + +下面这些API提供了操作文件、目录等与文件系统互动的接口 + +> 注:所有传入函数的相对路径都以BDS根目录为基准。 + +### 创建文件夹 + +`File.createDir(dir)` +`File.mkdir(dir)` + +- 参数: + - dir : `String` + 目标文件夹的路径 + 可以直接创建多层,不需要逐层创建 +- 返回值:是否成功创建 +- 返回值类型:`Boolean` + +
+ +### 删除文件 / 文件夹 + +`File.delete(path)` + +- 参数: + - path : `String` + 目标文件 / 文件夹的路径 +- 返回值:是否成功删除 +- 返回值类型:`Boolean` + +
+ +### 判断文件 / 文件夹是否存在 + +`File.exists(path)` + +- 参数: + - path : `String` + 目标文件 / 文件夹的路径 +- 返回值:目标是否存在 +- 返回值类型:`Boolean` + +
+ +### 复制文件 / 文件夹到指定位置 + +`File.copy(from,to)` + +- 参数: + - from : `String` + 源文件 / 文件夹的路径 + + - to : `String` + 目标文件 / 文件夹的位置 +- 返回值:是否复制成功 +- 返回值类型:`Boolean` + +
+ +### 移动文件 / 文件夹到指定位置 + +`File.move(from,to)` + +- 参数: + - from : `String` + 源文件 / 文件夹的路径 + + - to : `String` + 目标文件 / 文件夹的位置 +- 返回值:是否复制成功 +- 返回值类型:`Boolean` + +
+ +### 重命名指定文件 / 文件夹 + +`File.rename(from,to)` + +- 参数: + - from : `String` + 文件 / 文件夹的旧名字 + + - to : `String` + 新名字 +- 返回值:是否复制成功 +- 返回值类型:`Boolean` + +
+ +### 获取指定文件的大小 + +`File.getFileSize(path)` + +- 参数: + - path : `String` + 所操作的文件路径 + +- 返回值:文件的大小(字节) +- 返回值类型:`Integer` + +如果传入的路径位置是一个文件夹,则返回`-1` + +
+ +### 判断指定路径是否是文件夹 + +`File.checkIsDir(path)` + +- 参数: + - path : `String` + 所判断的路径 +- 返回值:目标路径是否是文件夹 +- 返回值类型:`Boolean` + +如果目标路径不存在,同样将返回`false` + +
+ +### 列出指定文件夹下的所有文件 / 文件夹 + +`File.getFilesList(dir)` + +- 参数: + - dir: `String` + 文件夹路径 + +- 返回值:文件名、文件夹名数组 +- 返回值类型:`Array` + +
\ No newline at end of file diff --git a/docs/apis/SystemAPI/Network.md b/docs/apis/SystemAPI/Network.md new file mode 100644 index 00000000..a4cbf796 --- /dev/null +++ b/docs/apis/SystemAPI/Network.md @@ -0,0 +1,221 @@ +## 🌏 Web Interface API + +The following APIs provide the basic network interface for scripts. +If there are more complex needs, the network library of the respective language platform can be used to complete the task. + +### Send an Asynchronous HTTP(s) Get Request + +`network.httpGet(url,callback)` + +- Parameters: + - url : `String` + The target address of the request (including the parameters attached to the Get request). + - callback : `Function` + The callback function to execute when the request returns, to return the HTTP(s) response result. +- Return value: Whether the request was successfully sent. +- Return value type: `Boolean` + +Note: The prototype of the callback function of the parameter callback: `function(status,result)` + +- status : `Integer` + The returned HTTP(s) response code, such as 200 means the request was successful. +- result : `String` + The returned data. + +If the request fails, the status value will be `-1`. + +
+ +### Send an Asynchronous HTTP(s) Post Request + +`network.httpPost(url,data,type,callback)` + +- Parameters: + - url : `String` + The destination address of the request. + - data : `String` + The data being sent. + - type : `String` + The Post data type sent, in the form of `text/plain` `application/x-www-form-urlencoded`. + - callback : `Function` + The callback function to execute when the request returns, to return the HTTP(s) response result. +- Return value: Whether the request was successfully sent. +- Return value type: `Boolean` + +Note: The prototype of the callback function of the parameter callback: `function(status,result)` + +- status : `Integer` + The returned HTTP(s) response code, such as 200 means the request was successful. +- result : `String` + The returned data. + +If the request fails, the status value will be `-1`. + +
+ +## 🔌 WebSocket Client Object API + +In LLSE, use "WebSocket objects" to manipulate the connection and work of a WebSocket client. + +### Create a New WebSocket Client Object + +[JavaScript] `new WSClient()` +[Lua] `WSClient()` + +- Return value: A new WebSocket client object. +- Return value type: `WSClient` + +
+ +### WebSocket Client Object - Properties + +Every WS client object contains some fixed object properties. for a specific file object `wsc`, has the following properties: + +| Attributes | Meaning | Data Type | +| ---------- | -------------- | ------ | +| wsc.status | Current Connection Status | `Enum` | + +These object properties are read-only and cannot be modified. + +Among them, the wsc.status enumeration has the following situations: + +`wsc.Open` - In normal connection. +`wsc.Closing` - Disconnecting. +`wsc.Closed` - Not connected. + +
+ +### WebSocket Client Object - Function + +Every WS client object contains some member functions (member methods) that can be executed. for a specific file object `wsc`, you can perform some operations on this client through the following functions. + +#### Create a Connection + +`wsc.connect(target)` + +- Parameter: + - target : `String` + The destination address to connect to, in the form of `ws://hostname[:port][/path/path][?query=value]` +- Return value: Whether the connection is successful. +- Return value type: `Boolean` + +
+ +#### Create a Connection Asynchronously + +`wsc.connectAsync(target,callback)` + +- Parameters: + - target : `String` + The destination address to connect to, in the form of `ws://hostname[:port][/path/path][?query=value]` + - callback : `Function` + A callback function to execute when the connection succeeds or fails. +- Return value: Whether the connection attempt was started successfully or not. +- Return value type: `Boolean` + +Note: The prototype of the callback function of the parameter callback: `function(success)` + +- success : `Boolean` + Whether the WebSocket connection is successful + +
+ +#### Send Text/Binary Messages + +`wsc.send(msg)` + +- Parameter: + - msg : `String` / `ByteBuffer` + Text/Binary data to send. +- Return value: Whether it was sent successfully. +- Return value type: `Boolean` + +If the parameter type passed in is `String`, will be sent as text, if it is `ByteBuffer` will be sent as binary data. + +
+ +#### Listen for WebSocket Events + +In the process of WS working, when a message is received or an error occurs, the relevant information needs to be processed. Here is the interface for listening to events. + +`wsc.listen(event,callback)` + +- Parameters: + + - event : `String` + The name of the event to listen for (see the list of listening events below). + + - callback : `Functon` + Registered listener function (see below for function-related parameters) + When the specified event occurs, LLSE will call the listener function you gave and pass in the corresponding parameters. +- Return value: Whether the event was successfully monitored. +- Return value type: `Boolean` + +
+ +#### List of Listening Events + +##### `"onTextReceived"` - Listen for string messages. + +- Listener function prototype + `function(msg)` +- Parameter: + - msg : `String` + Received string message. + +##### `"onBinaryReceived"` - Listen for binary messages. + +- Listener function prototype + `function(data)` +- Parameter: + - data : `ByteBuffer` + Received binary message. + +##### `"onError"` - Listen for errors. + +- Listener function prototype + `function(msg)` +- Parameter: + - msg : `String` + Error message. + +##### `"onLostConnection"` - Listen for lost connections. + +- Listener function prototype + `function(code)` +- Parameter: + - code : `Integer` + Error code. + +
+ +#### Close the Connection + +`wsc.close()` + +- Return value: Whether the connection was successfully closed. +- Return value type: `Boolean` + +Do not continue to use this client object while it is closed! + +
+ +#### Force Disconnect + +`wsc.shutdown()` + +- Return value: Whether the connection was successfully disconnected. +- Return value type: `Boolean` + +Do not continue to use this client object while it is disconnected! + +
+ +#### Get Error Code + +`wsc.errorCode()` + +- Return value: The error code generated by the last error. +- Return value type: `Integer` + +If you encounter a failure in the use of the above interface, you can get the last error code from here. \ No newline at end of file diff --git a/docs/apis/SystemAPI/Network.zh.md b/docs/apis/SystemAPI/Network.zh.md new file mode 100644 index 00000000..640e6779 --- /dev/null +++ b/docs/apis/SystemAPI/Network.zh.md @@ -0,0 +1,570 @@ +## 🌏 网络接口 API + +下面这些API为脚本提供了基本的网络接口。 +如果有更复杂的需求,可以使用各自语言平台的网络库来完成任务 + +## 目录 +- 🔌 [WebSocket 客户端对象 API](#🔌-websocket-客户端对象-api) +- 📡 [Http 服务端对象 API](#📡-http-服务端对象-api) + - [Http 请求对象 API](#http-请求对象-api) + - [Http 响应对象 API](#http-响应对象-api) + +### 发送一个异步HTTP(s) Get请求 + +`network.httpGet(url[,header],callback)` + +- 参数: + - url : `String` + 请求的目标地址(包括 Get 请求附带的参数) + - header : `Object` + 请求头(包括 Get 请求Request header) + - callback : `Function` + 当请求返回时执行的回调函数,用于回传HTTP(s)响应结果。 +- 返回值:是否成功发送请求 +- 返回值类型:`Boolean` + +注:参数callback的回调函数原型:`function(status,result)` + +- status : `Integer` + 返回的HTTP(s)响应码,如200代表请求成功 +- result : `String` + 返回的具体数据 + +如果请求执行失败,status值将为 -1 + +
+ +### 发送一个异步HTTP(s) Post请求 + +`network.httpPost(url[,header],data,type,callback)` + +- 参数: + - url : `String` + 请求的目标地址 + - header : `Object` + 请求头(包括 Post 请求Request header) + - data : `String` + 发送的数据 + - type : `String` + 发送的 Post 数据类型,形如 `text/plain` `application/x-www-form-urlencoded` 等 + - callback : `Function` + 当请求返回时执行的回调函数,用于回传HTTP(s)响应结果。 +- 返回值:是否成功发送请求 +- 返回值类型:`Boolean` + +注:参数callback的回调函数原型:`function(status,result)` + +- status : `Integer` + 返回的HTTP(s)响应码,如200代表请求成功 +- result : `String` + 返回的具体数据 + +如果请求执行失败,status值将为 -1 + +
+ +## 🔌 WebSocket 客户端对象 API + +在脚本引擎中,使用「WebSocket 对象」来操作某个 WebSocket 客户端的连接和工作 + +### 创建一个新的WebSocket 客户端对象 + +[JavaScript] `new WSClient()` +[Lua] `WSClient()` + +- 返回值:一个新的 websocket 客户端对象 +- 返回值类型:`WSClient` + +
+ +### WebSocket 客户端对象 - 属性 + +每一个WS客户端对象都包含一些固定的对象属性。对于某个特定的文件对象`wsc`,有以下这些属性 + +| 属性 | 含义 | 类型 | +| ---------- | -------------- | ------ | +| wsc.status | 当前的连接状态 | `Enum` | + +这些对象属性都是只读的,无法被修改 + +其中,wsc.status 枚举有如下几种情况: + +`wsc.Open` - 处于正常连接中 +`wsc.Closing` - 正在断开连接 +`wsc.Closed` - 未连接 + +
+ +### WebSocket 客户端对象 - 函数 + +每一个WS客户端对象都包含一些可以执行的成员函数(成员方法)。对于某个特定的文件对象`wsc`,可以通过以下这些函数对这个客户端进行一些操作 + +#### 创建连接 + +`wsc.connect(target)` + +- 参数: + - target : `String` + 要连接的目标地址,形如`ws://hostname[:port][/path/path][?query=value]` +- 返回值:是否成功连接 +- 返回值类型:`Boolean` + +
+ +#### 异步创建连接 + +`wsc.connectAsync(target,callback)` + +- 参数: + - target : `String` + 要连接的目标地址,形如`ws://hostname[:port][/path/path][?query=value]` + - callback : `Function` + 当连接成功或者失败时执行的回调函数。 +- 返回值:是否成功开始尝试连接 +- 返回值类型:`Boolean` + +注:参数callback的回调函数原型:`function(success)` + +- success : `Boolean` + WebSocket 连接是否成功 + +
+ +#### 发送文本 / 二进制消息 + +`wsc.send(msg)` + +- 参数: + - msg : `String` / `ByteBuffer` + 要发送的文本 / 二进制数据 +- 返回值:是否成功发送 +- 返回值类型:`Boolean` + +如果传入的参数类型是`String`,会按照文本发送,如果是`ByteBuffer`将按照二进制数据发送 + +
+ +#### 监听WebSocket事件 + +在WS工作的过程中,当收到消息或发生错误时,需要对相关信息进行处理。这里给出了监听事件的接口 + +`wsc.listen(event,callback)` + +- 参数: + + - event : `String` + 要监听的事件名(见下方监听事件列表) + + - callback : `Functon` + 注册的监听函数(函数相关参数见下) + 当指定的事件发生时,脚本引擎会调用你给出的监听函数,并传入相应的参数 +- 返回值:是否成功监听事件 +- 返回值类型:`Boolean` + +
+ +#### 监听事件列表 + +##### `"onTextReceived"` - 收到文本消息 + +- 监听函数原型 + `function(msg)` +- 参数: + - msg : `String` + 收到的文本消息 + +##### `"onBinaryReceived"` - 收到二进制消息 + +- 监听函数原型 + `function(data)` +- 参数: + - data : `ByteBuffer` + 收到的二进制消息 + +##### `"onError"` - 发生错误 + +- 监听函数原型 + `function(msg)` +- 参数: + - msg : `String` + 错误的提示信息 + +##### `"onLostConnection"` - 连接丢失 + +- 监听函数原型 + `function(code)` +- 参数: + - code : `Integer` + 错误码 + +
+ +#### 关闭连接 + +`wsc.close()` + +- 返回值:是否成功关闭连接 +- 返回值类型:`Boolean` + +在处于关闭状态时,请勿继续使用此客户端对象! + +
+ +#### 强制断开连接 + +`wsc.shutdown()` + +- 返回值:是否成功断开连接 +- 返回值类型:`Boolean` + +在处于关闭状态时,请勿继续使用此客户端对象! + +
+ +#### 获取错误码 + +`wsc.errorCode()` + +- 返回值:上一次错误产生的错误码 +- 返回值类型:`Integer` + +如果在上述接口使用中遇到了失败,可以从这里获取上一个错误码 + +## 📡 Http 服务端对象 API + +脚本引擎提供了简易的Http服务端服务,可以用于Webhook等**数据传输量较小**的Web服务。 +如果您想搭建网站,更推荐使用老牌Web服务软件如Apache, Nginx等。 + +### 创建一个新的服务器对象 + +[JavaScript] `new HttpServer()` +[Lua] `HttpServer()` + +- 返回值:新的服务器对象 +- 返回值类型:`HttpServer` + +
+ +### 监听 Get 请求 + +`svr.onGet(path, callback)` + +- 参数: + - path : `String` + 请求目录,以`/`开头,可以包含正则表达式。如: `/test/(.+)` + - callback : `Function<(HttpRequest, HttpResponse)>` + 回调函数,在收到符合path的GET请求回调 +- 返回值:处理完毕的服务器对象(便于连锁进行其他操作) +- 返回值类型:`HttpServer` + +
+ +### 监听 Put 请求 + +`svr.onPut(path, callback)` + +- 参数: + - path : `String` + 请求目录,以`/`开头,可以包含正则表达式。如: `/test/(.+)` + - callback : `Function<(HttpRequest, HttpResponse)>` + 回调函数,在收到符合path的PUT请求回调 +- 返回值:处理完毕的服务器对象(便于连锁进行其他操作) +- 返回值类型:`HttpServer` + +
+ +### 监听 Post 请求 + +`svr.onPost(path, callback)` + +- 参数: + - path : `String` + 请求目录,以`/`开头,可以包含正则表达式。如: `/test/(.+)` + - callback : `Function<(HttpRequest, HttpResponse)>` + 回调函数,在收到符合path的POST请求回调 +- 返回值:处理完毕的服务器对象(便于连锁进行其他操作) +- 返回值类型:`HttpServer` + +
+ +### 监听 Patch 请求 + +`svr.onPatch(path, callback)` + +- 参数: + - path : `String` + 请求目录,以`/`开头,可以包含正则表达式。如: `/test/(.+)` + - callback : `Function<(HttpRequest, HttpResponse)>` + 回调函数,在收到符合path的PATCH请求回调 +- 返回值:处理完毕的服务器对象(便于连锁进行其他操作) +- 返回值类型:`HttpServer` + +
+ +### 监听 Delete 请求 + +`svr.onDelete(path, callback)` + +- 参数: + - path : `String` + 请求目录,以`/`开头,可以包含正则表达式。如: `/test/(.+)` + - callback : `Function<(HttpRequest, HttpResponse)>` + 回调函数,在收到符合path的DELETE请求回调 +- 返回值:处理完毕的服务器对象(便于连锁进行其他操作) +- 返回值类型:`HttpServer` + +
+ +### 监听 Options 请求 + +`svr.onOptions(path, callback)` + +- 参数: + - path : `String` + 请求目录,以`/`开头,可以包含正则表达式。如: `/test/(.+)` + - callback : `Function<(HttpRequest, HttpResponse)>` + 回调函数,在收到符合path的OPTIONS请求回调 +- 返回值:处理完毕的服务器对象(便于连锁进行其他操作) +- 返回值类型:`HttpServer` + +
+ +### 监听请求 - 说明 + +请注意,请求监听是有优先级的。 +如果有多个路径同时满足正则表达式,则选择先定义的路径。 +例如: +```js +svr.onGet('/test/123', (req, res) => { + res.write('test'); +}).onGet('/test/(.+)', (req, res) => { + res.write('get /test/'); +}).onGet('/test/foo', (req, res) => { + res.write("bar"); +}); +// 请求 /test/123 时,第一个回调函数将被调用; 而请求 /test/foo 时,第二个回调函数将被调用(尽管第三个回调函数的路径更匹配) +``` + +### 监听 PreRouting 预路由事件 + +`svr.onPreRouting(callback)` + +- 参数: + - callback : `Function` + 回调函数,在收到请求时调用。在回调函数中可以修改响应,如果返回`false`,则不会继续路由至对应路径的回调函数(但仍然会触发PostRouting事件)。 +- 返回值:处理完毕的服务器对象(便于连锁进行其他操作) +- 返回值类型:`HttpServer` + +
+ +### 监听 PostRouting 后路由事件 + +`svr.onPostRouting(callback)` + +- 参数: + - callback : `Function<(HttpRequest, HttpResponse)>` + 回调函数,在对应目录的回调函数(或PreRouting事件)执行完毕后调用,在回调函数中可以修改响应 +- 返回值:处理完毕的服务器对象(便于连锁进行其他操作) +- 返回值类型:`HttpServer` + +
+ +### 监听 Error 错误事件 + +`svr.onError(callback)` + +- 参数: + - callback : `Function<(HttpRequest, HttpResponse)>` + 回调函数,在错误(状态码 >= 400)时调用 +- 返回值:处理完毕的服务器对象(便于连锁进行其他操作) +- 返回值类型:`HttpServer` + +
+ +### 监听 Exception 异常事件 + +`svr.onException(callback)` + +- 参数: + - callback : `Function<(HttpRequest, HttpResponse, String)>` + 回调函数,在handler中有抛出异常时调用,参数3为异常信息 +- 返回值:处理完毕的服务器对象(便于连锁进行其他操作) +- 返回值类型:`HttpServer` + +
+ +### 监听端口并开启服务器 + +`svr.listen(addr, port)` +`svr.startAt(addr, port)` + +- 参数: + - addr : `String` + 监听地址,可以是IP地址或域名 + - port : `Number` + 监听端口 +- 返回值:处理完毕的服务器对象(便于连锁进行其他操作) +- 返回值类型:`HttpServer` + +
+ +### 停止服务器 + +`svr.stop()` + +- 返回值:无 + +
+ +### 获取服务器是否正在运行 + +`svr.isRunning()` + +- 返回值:服务器正在运行与否 +- 返回值类型:`Boolean` + +
+ +## Http 请求对象 API + +### Http请求对象 - 属性 +| 属性 | 含义 | 类型 | 例 | +|------------------|-------------------|----------|-----------------------------| +| `req.method` | 请求方法 | `String` | `'GET'` | +| `req.path` | 请求路径 | `String` | `'/233'` | +| `req.query` | 请求查询参数 | `Object` | `{a: 'b', c: ['d', 'e']}` | +| `req.params` | 请求查询参数(同上) | `Object` | `{a: 'b', c: ['d', 'e']}` | +| `req.headers` | 请求头 | `Object` | `{a: ['b'], c: ['d', 'e']}` | +| `req.body` | 请求内容 | `String` | `'awa'` | +| `req.remoteAddr` | 请求源地址 | `String` | `'114.51.41.91'` | +| `req.remotePort` | 请求源端口 | `Number` | `11451` | +| `req.version` | 请求版本 | `String` | `'HTTP/1.1'` | +| `req.matches` | 请求路径正则匹配结果 | `Array` | `['/test11', '11']` | + +这些对象属性都是只读的,无法被修改,并且只能在请求回调函数中使用(理论上复制到外部也可以,但不推荐)。 + +***注意:*** +1. **`req.matches[0]` 为原始文本,其后面的元素才是匹配结果** +2. **`req.header["Name"]` 为数组而不是字符串** + +***扩展例子:*** +1. `?k=v1&k=v2&k1=v1` => `{k: ['v1', 'v2'], k1: 'v1'}` +2. `/test/(.+)/(.+)` => `/test/ll/233` => `['/test/ll/233', 'll', '233']` + +
+ +### 获取指定请求头的值 + +`req.getHeader(name)` + +- 参数: + - name : `String` + 请求头名称 +- 返回值:请求头的值数组(如果没有该请求头,则返回`[]`空数组) +- 返回值类型:`Array` + +
+ +## Http 响应对象 API + +### Http响应对象 - 属性 +| 属性 | 含义 | 类型 | 例 | +|------------------|-------------------|----------|-----------------------------| +| `res.status` | 响应状态码 | `Number` | `200` | +| `res.headers` | 响应头 | `Object` | `{a: ['b'], c: ['d', 'e']}` | +| `res.body` | 响应内容 | `String` | `'awa'` | +| `res.version` | 响应版本 | `String` | `'HTTP/1.1'` | +| `res.reason` | 错误原因 | `String` | `'OK'` | + +这些属性可以修改且应当被修改,但只有在回调函数中修改才有效 + +
+ +### 获取指定响应头的值 + +`req.getHeader(name)` + +- 参数: + - name : `String` + 响应头名称 +- 返回值:响应头的值数组(如果没有该响应头,则返回`[]`空数组) +- 返回值类型:`Array` + +
+ +### 设置指定响应头的值 + +`req.setHeader(name, value)` + +- 参数: + - name : `String` + 响应头名称 + - value : `Any` + 响应头值 +- 返回值:处理完毕的响应对象 +- 返回值类型:`HttpResponse` + +
+ +### 写入响应内容 + +`res.write(content1, content2, ...)` + +- 参数: + - content : `Any` + 响应内容 +- 返回值:处理完毕的响应对象 +- 返回值类型:`HttpResponse` +- 注:本函数在目前相当于`res.body += content1 + content2 + ...` + +
+ +## Http API 样例 + +```js +let server = new HttpServer(); +server.onGet("/hello(.+)", (req, resp) => { + logger.info("http_server_test: run: onGet: Received a request from ", req.remoteAddr, + ':', req.remotePort, " for ", req.path); + resp.write("") + .write("

It works!

") + .write("
") + .write("

Request Headers: ", JSON.stringify(req.headers, null, 4), "

") + .write("

Request Body: ", req.body, "

") + .write("

Your Address: ", req.remoteAddr, ':', req.remotePort, "

") + .write("

HTTP Version: ", req.version, "

") + .write("

Method: ", req.method, "

") + .write("

Path: ", req.path, "

") + .write("

Parsed Query: ", JSON.stringify(req.query, null, 4), "

") + .write("

Path Regex Matches: ", JSON.stringify(req.matches), "

") + .write("") + resp.status = 200; + resp.reason = "OK"; + resp.setHeader("Content-Type", "text/html"); +}).onGet("/404", (req, resp) => { + resp.status = 404; + resp.reason = "Not Found"; + resp.write("Not Found"); +}).onGet("/test-redirect", (req, resp) => { + // https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Redirections + resp.status = 301; + resp.reason = "Moved Permanently"; + resp.setHeader("Location", "https://github.com"); +}).onGet("/(.+)", (req, resp) => { + resp.write("Hello World! ", req.matches); +}).onPreRouting((req, resp) => { + logger.info("http_server_test: run: onPreRouting: resp.body.length: ", resp.body.length); + if (req.path == "/test-prerouting") { + resp.body = "Hello World!"; + resp.status = 200; + resp.reason = "OK"; + return false; + } +}).onPostRouting((req, resp) => { + logger.info("http_server_test: run: onPostRouting: resp.body.length: ", resp.body.length); +}).onError((req, resp) => { + resp.write("\nonError called"); +}).listen(this.listen_address, this.listen_port); +logger.info("http_server_test: run: Server listening on " + this.listen_address + ":" + this.listen_port); +``` +请查看 [UnitTest](https://github.com/LiteLDev/LiteLoaderBDSv2/tree/main/Test/UnitTest.js) diff --git a/docs/apis/SystemAPI/SystemCall.md b/docs/apis/SystemAPI/SystemCall.md new file mode 100644 index 00000000..a6e870cc --- /dev/null +++ b/docs/apis/SystemAPI/SystemCall.md @@ -0,0 +1,56 @@ +## 📡 System Call API + +The following APIs provide interfaces to perform some system calls: + +### Invoke the Shell to Execute the Specified System Command + +`system.cmd(cmd,callback[,timeLimit])` + +- Parameters: + - cmd : `String` + The executed system command. + - callback : `Function` + The callback function used to return data after the system process ends. + - timeLimit : `Integer` + (Optional parameter) The maximum time for the command to run, in milliseconds. + The default is `-1`, i.e. unlimited runtime +- Return value: Whether the command was successfully started. +- Return value type: `Boolean` + +Note: The prototype of the callback function of the parameter callback: `function(exitcode,output)` + +- exitcode : `Integer` + The process exit code. +- output : `String` + The contents of standard output and standard error. + +Notice! What is executed here is not the command of the MC command system. +This function works asynchronously. It will not wait for the system to execute the command before returning, but the engine will automatically call the given callback function to return the result. + +
+ +### Run the Specified Location Program + +`system.newProcess(process,callback[,timeLimit])` + +- Parameters: + - process : `String` + The path of the program to run (with command line arguments). + - callback : `Function` + The callback function used to return data after the program process ends. + - timeLimit : `Integer` + (Optional parameter) The maximum time limit for the program process to run, in milliseconds. + The default is `-1`, i.e. unlimited runtime. +- Return value: Whether the process was successfully started. +- Return value type: `Boolean` + +Note: The prototype of the callback function of the parameter callback: `function(exitcode,output)` + +- exitcode : `Integer` + Process exit code. +- output : `String` + The contents of the program's standard output and standard error output. + +This function works asynchronously. It will not wait for the system to execute the command before returning, but the engine will automatically call the given callback function to return the result. + +
\ No newline at end of file diff --git a/docs/apis/SystemAPI/SystemCall.zh.md b/docs/apis/SystemAPI/SystemCall.zh.md new file mode 100644 index 00000000..4e4e04b8 --- /dev/null +++ b/docs/apis/SystemAPI/SystemCall.zh.md @@ -0,0 +1,56 @@ +## 📡 系统调用 API + +下面这些API提供了执行一些系统调用的接口 + +### 调用shell执行指定系统命令 + +`system.cmd(cmd,callback[,timeLimit])` + +- 参数: + - cmd : `String` + 执行的系统命令 + - callback : `Function` + shell进程结束之后返回数据使用的回调函数 + - timeLimit : `Integer` + (可选参数)命令运行的最长时限,单位为毫秒 + 默认为`-1`,即不限制运行时间 +- 返回值:是否成功启动命令 +- 返回值类型:`Boolean` + +注:参数callback的回调函数原型:`function(exitcode,output)` + +- exitcode : `Integer` + shell退出码 +- output : `String` + 标准输出和标准错误输出的内容 + +注意!这里执行的不是MC命令系统的命令 +此函数异步工作,不会等待系统执行完命令后再返回,而是由引擎自动调用给出的回调函数来返回结果 + +
+ +### 运行指定位置程序 + +`system.newProcess(process,callback[,timeLimit])` + +- 参数: + - process : `String` + 运行的程序路径(与命令行参数) + - callback : `Function` + 程序进程结束之后返回数据使用的回调函数 + - timeLimit : `Integer` + (可选参数)程序进程运行的最长时限,单位为毫秒 + 默认为`-1`,即不限制运行时间 +- 返回值:是否成功启动进程 +- 返回值类型:`Boolean` + +注:参数callback的回调函数原型:`function(exitcode,output)` + +- exitcode : `Integer` + 程序进程退出码 +- output : `String` + 程序标准输出和标准错误输出的内容 + +此函数异步工作,不会等待系统执行完命令后再返回,而是由引擎自动调用给出的回调函数来返回结果 + +
\ No newline at end of file diff --git a/docs/apis/SystemAPI/SystemInfo.md b/docs/apis/SystemAPI/SystemInfo.md new file mode 100644 index 00000000..ef83aa27 --- /dev/null +++ b/docs/apis/SystemAPI/SystemInfo.md @@ -0,0 +1,44 @@ +## 📜 Get System Information API + +The following APIs provide interfaces to obtain necessary system information: + +### Get Current Time String + +`system.getTimeStr()` + +- Return value: The current time string, using the local time zone and 24-hour clock. + For example: `2021-04-03 19:15:01` +- Return value type: `String` + +
+ +### Get the Current Time Object + +`system.getTimeObj()` + +- Return value: The current time object `Object`) + +- Return value type: `Object` + + - For the returned time object tm, there are the following members: + + | Field | Meaning | Data Type | + | ----- | -------------------- | --------- | + | tm.Y | Year value (4 digits)| `Integer` | + | tm.M | Month value | `Integer` | + | tm.D | Day value | `Integer` | + | tm.h | Hour value (24-hour clock)|`Integer` | + | tm.m | Minute value | `Integer` | + | tm.s | Seconds value | `Integer` | + | tm.ms | Millisecond value | `Integer` | + +
+ +### Randomly Generate a Guid String + +`system.randomGuid()` + +- Return value: A randomly generated unique identifier GUID. +- Return value type: `String` + +
\ No newline at end of file diff --git a/docs/apis/SystemAPI/SystemInfo.zh.md b/docs/apis/SystemAPI/SystemInfo.zh.md new file mode 100644 index 00000000..fa248781 --- /dev/null +++ b/docs/apis/SystemAPI/SystemInfo.zh.md @@ -0,0 +1,44 @@ +## 📜 获取系统信息 API + +下面这些API提供了获取必要的系统信息的接口 + +### 获取当前时间字符串 + +`system.getTimeStr()` + +- 返回值:当前的时间字符串,使用当地时区和24小时制。 + 形如`2021-04-03 19:15:01` +- 返回值类型:`String` + +
+ +### 获取当前的时间对象 + +`system.getTimeObj()` + +- 返回值:当前的时间对象(`Object`) + +- 返回值类型: `Object` + + - 对于返回的某个时间对象 tm,有如下这些成员: + + | 成员 | 含义 | 类型 | + | ----- | -------------------- | --------- | + | tm.Y | 年份数值(4位) | `Integer` | + | tm.M | 月份数值 | `Integer` | + | tm.D | 天数数值 | `Integer` | + | tm.h | 小时数值(24小时制) | `Integer` | + | tm.m | 分钟数值 | `Integer` | + | tm.s | 秒数值 | `Integer` | + | tm.ms | 毫秒数值 | `Integer` | + +
+ +### 随机生成一个 GUID 字符串 + +`system.randomGuid()` + +- 返回值:一个随机生成的唯一标识符GUID +- 返回值类型: `String` + +
\ No newline at end of file diff --git a/docs/faq.md b/docs/faq.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/img/logo.png b/docs/img/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..7761c0dd2a8ca14bf28a020f780a99c92f961ab3 GIT binary patch literal 7093 zcmV;m8%pGfP)mGmEL+I({0Eo~ zJ0v8J+1M<`5{wuL&wW%^cU9%%oInxhoUF{Otm^LDkE*(KwCdKa%*sb)+hk58`imfZo2#SKsKv?kCaU774hkYO0o3K{9&xU)~4> z<63Umsd&*w14z#1d(Z83fse}^r0v6v4Wg%FR@S%k==ru{=pyRP6i&h2Q3NDQH7 zoU0tBZEd8mSe)VD_y|doAWjk_Ch6>$m-FlR_!!euAj?OcgIWz(vbHYEV^~!*-q=zi ze`giDtoiNp!LP~Z7K^!haCBUK<8Qula&&Y&TJ%OBk4{$LyYId$@BI-RMG>m1!q0#H zb9v{_ZOKO&Ca06?AHMg)7t_;el;wH-ueiBeLmN1z(I_YlM~ElX=kmq263GD z5gbG7?u7^n6svAcZoPQs+i@wqk57K@EImu;`Lwt2OM_s`4Bz_xCCw%-*N zvsw^Z-%H;YJ~`g98}QnEZZ)6d;P}B3=hoevj(FrDJ5t32QnqAB%hr4pCI9bJ`gKZs~C11zq)?Ge#)a7%5+89y5JMaG1AkO8{ z$;$oAXFjtL2Y>R(C#dUs5Jowi{0mfNi8yYrZ}{ZuyYGGfHOL_xX*)bL0*H;^)M)on}}3jK|#Tn8Ns}6Rl%_+^7!}=bzLIXZEJREKAGRU z0KHMo-SEk=-Y!skZ9doGT)P(MvVw!19kRjUJHZCiN+c3ugXi5$%=oFwWg{b!Klf$ z_+*vk4{mGUmpVRxQ9sb394O{cLY$|`FO-U&^}SpkF%OQ8@y);es$Aq@HYvg9KKD6+ zN_{VyKeN)FJ$u%S=C)iOClB+f4ZPu`&^+OA1b4}9$EPu}g^0M)u_w^yIMGYWPnV(5p(ZxJFG z-EWe^P=s-EhJ$e~IaHl>hRKH8#mT(9C<>Hixk5KuTZs*Jd@{DiC+~oQ$?+;{Zdzsa zM+E&un77WC_?|Z&CnM>@Bu6J^-n&*p;J4)_a58(?hlhs)PL@KN0>)aL96iL@`4q{h zM=IS>ee$+(a6_sM3n@@EA}DRO>D}T?sOuz6(qAa0o_5xNP|ZsmKRCuWzV+8QI(mS` zyvrwF7bo-05!MfF&->(KK}S)JUDFg?w8_|qloa_Vsm}+MSSwES2pm_o(&Ce zr6Q13I6plbXqD!iwO6MaRZ+uK=EiX{D=&=Tpv<-;Nh-^jPd=L-;=y5iAl+Sk@?O>^ z@sCqh+^#Ik^MUow=B48lu^u7TIijdovGLcz$zeI$;Gy+l*?eANHZP&0?hJCB`sAzd z$$Q2oIdA%EeCnIVC+jQy{=HE!iIT4Nuh+~mSfoq>Gjq91xj1-6Be`TTJ_00uV8BZJ0L^##d0YlZYZfJ zjz@`&DDrS?so=6yILI@cPA9S{UqDjSe8bcR*){m&pio}Vul{=8FE3*@iY3dk)>?(p zIF?|{$rh& z@|WekKf(h}1|^uDo=WD*QZC=`dguE^bBL0aY*er;E2{3)7xQ&eM#GRotrQ-QfQKVO zZW2$)xvA|SOOTlg=daFCR2&X6{vHV-O^ZpbQI+*;;pFxRW(BU}o7eHlxkR=Uj!zB| zMHZuM)LMIaK6&@2Xaz*#Y1^SJ{!V?db%Ph2{6VHhJRjlI&XAM|ib}N{D=VJ+qKt45 zC74$gk|dJR66ujl14TKLQ4>X}f0b9_lP|KtVcj}D8J^Rg&kD?DC9LfgxL=x2-UA{3 zlQx%eEZZUmHSk4M{;%&flmF~yZRKh8{pF5_MD3Rst(wti8`_MNXA+^57NuFAov9U% z9G{H40b?lTCpfJ=mZYYaQ@`!QKFS`#Bm+{loOFvoLDwy4gO5A6HUM$L*c+}QSc+!pT8Wyw4AWsvF zGj_0SM^U_dVJaD=p}4GT2Hi{$_~ia_$0x^Yaq?wsFmJ~m_OO$ci(|*fXGd*?j2Mqm zmLbn;eR119_KQ}eICaM$CrTdV2^(kBRVC`6 z!djw<_H`3(N^Y<+BTeCxi6~juu6P}v-1egRM(DFiVg1?J*&xi~{W46NOeXTq&RAQD zqGXuF2c4{m&GI#Ssj_^0tCP<~v1oCM)>hzgzv$>g5S|iTq(LTBRV!80c#>!4FaPBC z9vB%S(^-k1{L6=!)C;7M2H6ajDp+kp^yy_`s<&&UX9gqKrgs^~NH}e? zj*~3oyz6H?g@aN-=EPHfHOIlhF~0rnuMG0Zq07%_Kl@o3ZG8pv@p;)VfBDP7>cr7F z!>h>z-}$@u1P8Yh0^ofIBD^TelG`nJ4(_~YcC4-4e!pn%#jaH{4fKm94NDH|9gjvh zIml5Iv9qk6T^nZ+v;|%*7I;B5;tG=2#N-A4Np_-Alqboj;Xs|kXlI+xrW3VX-wv7; zsB5*BPYwzWQLMg#LjgID;MLL>uFNQ#5nNYu`A+}B@VR7p{@k~H9K3uxF-2P;=dA=Z zy24tdPXYa;StYlwmifA_EQ+#18Am7<-3uIBi?Xbt^B7pvpqQ1DBGM@|$Hv^lwm4I3 ztU}U2<2_sO-JuX=+2}xy9LbEGh*H^F@bw;z^0j<&+qMtItNC-V!QuaH$@2_(QHTwm zR@KS~4u@fLOhjukI(Eg$A~z;m?FRx*jrZ4sh|B~tC^WDgEmzeYmRt#50? zg)qbHjFK(*n02FUHzjE4y63!gBMz3s<-3oWcc;40zmsJw+fJ`Cil<5y$IKm|W-V&I zv}~Szz7{QAqvqWgv^dUzRU}}@dDH8XBzPvFO3q=K8KUGRXT(kG6gAG+KEUK1^P=5@ z<6O|f`Z0ypNFrHh$wgX+YK9TM-{OPAzPX->NAIRB+uJw)CGt3#n%Us;xcFx7f~)MM z{oUPzNirj9Bszk!v?!{YjEua>qg&ksC#u3=lxiHXL)8jD@(;|j1T&Muc!fst=Yk+D zhi)ZlO|3i#Q@sTpsK)j@;r>4!WjGw?&@w-`0Waplx|nI4K!PWI8yhMXdHXtM8{R!` zKF+Zy3r`|AvSmO9lkQqrVCxDV;&VlKCe<*>!z{Lpd)cvK=g0b-VN((g;~3MKLkJ7T zxkQa^Ow1TB=i>Oq_R3Ph8eOdv0f2QJcx+^oS2PXFj>L zS@5EZXU~ubue{19vlq=?a#>c0Yb{spg5> zHi_dv^|Gk(wt=42eq^@1*>F?M+ZU+^H~8d7!ci%XiO@1WO{7TcBu*G7Gft{{>2(Sa3n%3ZpVdtLJgellSd40h1B*|t0_ zD~!_!^TNo(uS~?p;==G0iIgT;WfhGLXm+Es6z@!1BtVvoQ;=ckmP#I#B?qyJav`Q5 zi3xE`zQOoXw8zeeoVigJE2S$&ZX1aZjMrB#Tr78DgPYP%p#L}(3aghkMtS(Lr0tfu zk;`qB|6IljRpBaih%dRgQW=jOXewLQ2scFkQ9~&@3fYxphgrf!mBPKaeVly9PL}o; zq)7zzbFq?0mLzOPu9d&y4y{_P?Z(*L4n9aPSeG%ccwt6T&S*`x<8>4*zH)<;#o)TJ z1{eHrP|6_zapu%Ohlx9sJNKf=J0YDO6Re%6lGGe+T|CKXaihf^$Hq#!nY02jr zKiV}c_wC?%u%oS7&{OM*$PZzxRdb(A+wlQBvTr- zX7Avp)N_S2$&uwLN?k3}*%dI#5)_?OR^`b4h??i?Yo#8l0Zm@eKXT}deE?=<1@Gul zI0UtB!XV7!a^7`Ocb%xq^10W&O>SGk!+b7W_%F3c57Nj=EiI2;T6TF|)P%z<#_7C} z%e$zS56H3&pF6h%It^Edi>@4nAk!iTkY50++Pu=}y?BOg>XUoZzo510bo$`M%U8+d z?6kAdW%=CeCW+lL4t9Jlb@*JTA}R~@Bu(sB{_OWpn9nVGfq+q>h3b3%gAehlDv_re zrRDBorLRJesr+SS>UT;N&8!*|XA(wo*E$6oCUq5U#EC0s+|Q1@LVa>juo7ZJ90D38 z>Axu*|8{@Bm*sO6u6F)?x&0}6h|g{Dw#TC!CkLYyx{vu>4l|z37I*=Rv{oqLGC4>l z0~edhS*OePn@bC!^@VQI+K&&kT{341` z6iWpwPa7_(8lxn}s48Le95JQPlsL!Lf3*e#C%VbI-T}{sZS@k;WqBTL=yh`;pL<=o z(Gg6c?_}pE826Yfo>sYFo!fYEOju$C0Xug2+$JlEs}r>6aU~KQEswDRKfH6bbzJ##O<CErbBq@u6HGkCeRlF`12NB_NG8 zbnLiWaj7CDsqP^G$3?qvxb7U#2~ys!C_j3K(?{cjb^Wfn_H1Zjo6o)O`Cn4OmpKSE zFQ*2ML@|xW@dr+Gi?d4`)_I1k`7eg=Na(>gRdIP!5q|CI zA)bs_;iKh!NgAU(#q;wy{`>h0ocj~8ttsAzy-c3Q{}Iw?c0Y%4NYsCA)3v|c2qqsO zR4daANqsIwPdMve;y1FmM8cq^)|k)EF{KQ%vfO$g2a;*|gqzSVykboV!aE0r%*u%6 zWm?CQ<9x5=i{-U&FwfW-<5onAd07!j&T;|N9BoRVtr7o!URKi0hU;^wrAW>+;=JWW zZN+M{E1V{gb4dN5m1GDVJzS;I$j80+w~hB_BLR zv%6K)Ov-1N&I&}9Ft1F*>N88k+`?pDSOa@1#+8E|wX4vFE8JR>x7^CvYEJQ9)=4Z+ zAELFB9pl`e0(dHnLF89f>&4lXv$p`5Ra>`@JmWS<>v~Gw%e57ZfJ|v9dr_dxry$pdisQl& z*9>vJpK%rSMOkAWR~)3&T&(ytp?vUd|Vo?MFSsA6pP;1+d4+OMCD$t zD}ykJM{gP>e5n`nvL-{O=?ZTo@mx#O&bo}HHptcIMjhaiXAx#Lb<=cUHx2nJS`{Kv zYw~^r(XtCUR{Je6CnkEz$fA|+#0AV+)ybnwTjKB|$B88*?Fe|PHIAZ8S{3nx&CO6; zh|5*qhx%NQnmC85mcSM(+-Gv|48Nv6*SAhkulF#hds#{hL_Y)QF&j#9weMm93+8CY z+I;m(fAsLJk-~X>z6?EcGBEdBo-Oc$4}OYiRbtGY;uN>>^#E2V_EwbP%?llVIIx%YBi1%u3|py)9_gUK=~jZ;L%qOKQ+Y=lKM!+DhAyy>^>;F6K@ z3x#o_F*n@)KKF?qE@T;lTOP&ADl@j~p3mKuw45xqxe1f(&Kx(7#%pE5b*4-A*=U#T zXd@oA4(lrIssWXMz?_q)m7R7kcO@M!T4Gr?^qW%~J=iwM$J4sRwV0&$b2PEX?E6Z! zg{fk7?>ya^bQCN#xT;2^YE)9ptP%QWXj-Oy+E!6PRJ#w{Iza~v>#=Xc8Mj2(BHwKL zw(4>2WhujSp?}U0mvWBML|(O8j#+B)xgk8ceBcEd1uCTi%AIa<_%#u|9IDR^N)8P>@8$MHrFr(h zp!kU^3=3YemeiOCH4YNZ#J;Ny^0_!XCgs@(L@(#2e#cmS4sp=5SFm!~?mQJ-P@jA8 zNWLg!d9yRY73+gts?vtMXl|e?e#&rV!>!Ajj1KoSl8Qr3Gb_bjK?(&Zr9L-F zekBjTXy?7(%g)G(f*pxOpqMKSA|y%bo>>%?&e_tg@*tK5oswVa>T`|tM8dt6cS&L; zP2W|kg@%=Oz7anpil-OyJ(Rg}fvG~CZcObhYl|*afkwQSol-E7tE5(H$?`~d)Q}*j zoHC=(LWs*itsS0@?;WO{lQ^WIvezuVn62?VFnPMpIXMK~>WGfDkBYgM-I7=-{U~^W zuIaTOoGn&9WP7ke`2iE;iT-tbZo4hveZ*?J5(D-lsL