├── .clang-format ├── .clang-tidy ├── .clangd ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ └── feature_request.yml ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── build.yml │ ├── build_docs.yml │ └── release.yml ├── CHANGELOG.md ├── COPYING ├── README.md ├── README.zh.md ├── docs ├── apis │ ├── DataAPI │ │ ├── ConfigFile.md │ │ ├── ConfigFile.zh.md │ │ ├── DataBase.md │ │ ├── DataBase.zh.md │ │ ├── Economy.md │ │ ├── Economy.zh.md │ │ ├── OtherData.md │ │ ├── OtherData.zh.md │ │ ├── PlayerData.md │ │ └── PlayerData.zh.md │ ├── EventAPI │ │ ├── BlockEvents.md │ │ ├── BlockEvents.zh.md │ │ ├── EconomicEvents.md │ │ ├── EconomicEvents.zh.md │ │ ├── EntityEvents.md │ │ ├── EntityEvents.zh.md │ │ ├── Listen.md │ │ ├── Listen.zh.md │ │ ├── OtherEvents.md │ │ ├── OtherEvents.zh.md │ │ ├── PlayerEvents.md │ │ └── PlayerEvents.zh.md │ ├── GameAPI │ │ ├── Basic.md │ │ ├── Basic.zh.md │ │ ├── Block.md │ │ ├── Block.zh.md │ │ ├── BlockEntity.md │ │ ├── BlockEntity.zh.md │ │ ├── Command.md │ │ ├── Command.zh.md │ │ ├── Container.md │ │ ├── Container.zh.md │ │ ├── Device.md │ │ ├── Device.zh.md │ │ ├── Entity.md │ │ ├── Entity.zh.md │ │ ├── GameUtils.md │ │ ├── GameUtils.zh.md │ │ ├── Item.md │ │ ├── Item.zh.md │ │ ├── Packet.md │ │ ├── Packet.zh.md │ │ ├── Particle.md │ │ ├── Particle.zh.md │ │ ├── Player.md │ │ ├── Player.zh.md │ │ ├── ScoreBoard.md │ │ ├── ScoreBoard.zh.md │ │ ├── Server.md │ │ └── Server.zh.md │ ├── GuiAPI │ │ ├── Form.md │ │ ├── Form.zh.md │ │ ├── FormBuilder.md │ │ └── FormBuilder.zh.md │ ├── LanguageSupport.md │ ├── LanguageSupport.zh.md │ ├── NbtAPI │ │ ├── NBT.md │ │ ├── NBT.zh.md │ │ ├── NBTCompound.md │ │ ├── NBTCompound.zh.md │ │ ├── NBTList.md │ │ ├── NBTList.zh.md │ │ ├── NBTValue.md │ │ └── NBTValue.zh.md │ ├── README.md │ ├── README.zh.md │ ├── ScriptAPI │ │ ├── Ll.md │ │ ├── Ll.zh.md │ │ ├── Logger.md │ │ ├── Logger.zh.md │ │ ├── ScriptHelp.md │ │ ├── ScriptHelp.zh.md │ │ ├── i18n.md │ │ └── i18n.zh.md │ └── SystemAPI │ │ ├── File.md │ │ ├── File.zh.md │ │ ├── FileSystem.md │ │ ├── FileSystem.zh.md │ │ ├── Network.md │ │ ├── Network.zh.md │ │ ├── SystemCall.md │ │ ├── SystemCall.zh.md │ │ ├── SystemInfo.md │ │ └── SystemInfo.zh.md ├── faq.md ├── faq.zh.md ├── img │ ├── ColorLog.png │ └── logo.png ├── index.md ├── index.zh.md └── tutorials │ ├── create_your_first_plugin.md │ └── create_your_first_plugin.zh.md ├── manifest.json ├── mkdocs.yml ├── requirements.txt ├── scripts ├── download_crowdin_files.py └── validate_release.py ├── src ├── baselib │ ├── BaseLib.js │ ├── BaseLib.lua │ └── BaseLib.py ├── lang │ ├── de.json │ ├── en.json │ ├── fr.json │ ├── id.json │ ├── it.json │ ├── ja.json │ ├── ko.json │ ├── pt_BR.json │ ├── ru.json │ ├── th.json │ ├── tr.json │ ├── vi.json │ ├── zh_CN.json │ └── zh_TW.json ├── legacy │ ├── api │ │ ├── APIHelp.cpp │ │ ├── APIHelp.h │ │ ├── BaseAPI.cpp │ │ ├── BaseAPI.h │ │ ├── BlockAPI.cpp │ │ ├── BlockAPI.h │ │ ├── BlockEntityAPI.cpp │ │ ├── BlockEntityAPI.h │ │ ├── CommandAPI.cpp │ │ ├── CommandAPI.h │ │ ├── CommandCompatibleAPI.cpp │ │ ├── CommandCompatibleAPI.h │ │ ├── CommandOriginAPI.cpp │ │ ├── CommandOriginAPI.h │ │ ├── CommandOutputAPI.cpp │ │ ├── CommandOutputAPI.h │ │ ├── ContainerAPI.cpp │ │ ├── ContainerAPI.h │ │ ├── DataAPI.cpp │ │ ├── DataAPI.h │ │ ├── DatabaseAPI.cpp │ │ ├── DatabaseAPI.h │ │ ├── DeviceAPI.cpp │ │ ├── DeviceAPI.h │ │ ├── EntityAPI.cpp │ │ ├── EntityAPI.h │ │ ├── EventAPI.cpp │ │ ├── EventAPI.h │ │ ├── FileSystemAPI.cpp │ │ ├── FileSystemAPI.h │ │ ├── GameUtilsAPI.cpp │ │ ├── GameUtilsAPI.h │ │ ├── GuiAPI.cpp │ │ ├── GuiAPI.h │ │ ├── InternationalAPI.cpp │ │ ├── InternationalAPI.h │ │ ├── ItemAPI.cpp │ │ ├── ItemAPI.h │ │ ├── LlAPI.cpp │ │ ├── LlAPI.h │ │ ├── LoggerAPI.cpp │ │ ├── LoggerAPI.h │ │ ├── McAPI.cpp │ │ ├── McAPI.h │ │ ├── NbtAPI.cpp │ │ ├── NbtAPI.h │ │ ├── NetworkAPI.cpp │ │ ├── NetworkAPI.h │ │ ├── PacketAPI.cpp │ │ ├── PacketAPI.h │ │ ├── ParticleAPI.cpp │ │ ├── ParticleAPI.h │ │ ├── PlayerAPI.cpp │ │ ├── PlayerAPI.h │ │ ├── RemoteCallAPI.cpp │ │ ├── ScoreboardAPI.cpp │ │ ├── ScoreboardAPI.h │ │ ├── ScriptAPI.cpp │ │ ├── ScriptAPI.h │ │ ├── ServerAPI.cpp │ │ ├── ServerAPI.h │ │ ├── SimulatedPlayerAPI.cpp │ │ ├── StructureAPI.cpp │ │ ├── SystemAPI.cpp │ │ └── SystemAPI.h │ ├── engine │ │ ├── EngineManager.cpp │ │ ├── EngineManager.h │ │ ├── EngineOwnData.h │ │ ├── GlobalShareData.cpp │ │ ├── GlobalShareData.h │ │ ├── LocalShareData.cpp │ │ ├── LocalShareData.h │ │ ├── MessageSystem.cpp │ │ ├── MessageSystem.h │ │ ├── OperationCount.cpp │ │ ├── OperationCount.h │ │ ├── RemoteCall.cpp │ │ ├── RemoteCall.h │ │ ├── TimeTaskSystem.cpp │ │ └── TimeTaskSystem.h │ ├── legacyapi │ │ ├── db │ │ │ ├── Any.cpp │ │ │ ├── Any.h │ │ │ ├── ConnParams.cpp │ │ │ ├── ConnParams.h │ │ │ ├── Pointer.h │ │ │ ├── Row.cpp │ │ │ ├── Row.h │ │ │ ├── RowSet.cpp │ │ │ ├── RowSet.h │ │ │ ├── Session.cpp │ │ │ ├── Session.h │ │ │ ├── Stmt.cpp │ │ │ ├── Stmt.h │ │ │ ├── Types.h │ │ │ └── impl │ │ │ │ ├── mysql │ │ │ │ ├── Session.cpp │ │ │ │ ├── Session.h │ │ │ │ ├── Stmt.cpp │ │ │ │ └── Stmt.h │ │ │ │ └── sqlite │ │ │ │ ├── Session.cpp │ │ │ │ ├── Session.h │ │ │ │ ├── Stmt.cpp │ │ │ │ └── Stmt.h │ │ └── utils │ │ │ ├── FileHelper.cpp │ │ │ ├── FileHelper.h │ │ │ ├── StringReader.cpp │ │ │ └── StringReader.h │ ├── main │ │ ├── BindAPIs.cpp │ │ ├── BuiltinCommands.cpp │ │ ├── BuiltinCommands.h │ │ ├── EconomicSystem.h │ │ ├── EconomySystem.cpp │ │ ├── Global.cpp │ │ ├── Global.h │ │ ├── NodeJsHelper.cpp │ │ ├── NodeJsHelper.h │ │ ├── PythonHelper.cpp │ │ ├── PythonHelper.h │ │ ├── SafeGuardRecord.cpp │ │ └── SafeGuardRecord.h │ └── utils │ │ ├── IniHelper.cpp │ │ ├── IniHelper.h │ │ ├── JsonHelper.h │ │ ├── UsingScriptX.h │ │ ├── Utils.cpp │ │ └── Utils.h ├── lse │ ├── Config.h │ ├── Entry.cpp │ ├── Entry.h │ ├── MemoryOperators.cpp │ ├── Plugin.cpp │ ├── Plugin.h │ ├── PluginManager.cpp │ ├── PluginManager.h │ ├── PluginMigration.cpp │ ├── PluginMigration.h │ ├── api │ │ ├── DirectFormatter.cpp │ │ ├── DirectFormatter.h │ │ ├── MoreGlobal.cpp │ │ ├── MoreGlobal.h │ │ ├── NetworkPacket.h │ │ ├── PlayerSink.cpp │ │ ├── PlayerSink.h │ │ └── helper │ │ │ ├── AttributeHelper.cpp │ │ │ ├── AttributeHelper.h │ │ │ ├── BlockHelper.cpp │ │ │ ├── BlockHelper.h │ │ │ ├── CustomFormWrapper.cpp │ │ │ ├── CustomFormWrapper.h │ │ │ ├── ItemHelper.cpp │ │ │ ├── ItemHelper.h │ │ │ ├── ItemStackSerializerHelpers.h │ │ │ ├── PlayerHelper.cpp │ │ │ ├── PlayerHelper.h │ │ │ ├── ScoreboardHelper.cpp │ │ │ ├── ScoreboardHelper.h │ │ │ ├── SimulatedPlayerHelper.cpp │ │ │ └── SimulatedPlayerHelper.h │ └── events │ │ ├── BlockEvents.cpp │ │ ├── BlockEvents.h │ │ ├── EntityEvents.cpp │ │ ├── EntityEvents.h │ │ ├── OtherEvents.cpp │ │ ├── OtherEvents.h │ │ ├── PlayerEvents.cpp │ │ └── PlayerEvents.h └── tests │ └── LSETests │ ├── EventTests.js │ ├── PlayerTests.js │ ├── ScriptTests.js │ ├── main.js │ └── manifest.json ├── tooth.json └── xmake.lua /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | AccessModifierOffset: -4 3 | AlignAfterOpenBracket: BlockIndent 4 | AlignArrayOfStructures: Left 5 | AlignConsecutiveDeclarations: 6 | Enabled: true 7 | AcrossEmptyLines: false 8 | AcrossComments: false 9 | AlignConsecutiveAssignments: 10 | Enabled: true 11 | AcrossEmptyLines: false 12 | AcrossComments: false 13 | AlignCompound: true 14 | PadOperators: true 15 | AlignConsecutiveMacros: 16 | Enabled: true 17 | AcrossEmptyLines: false 18 | AcrossComments: false 19 | AllowAllParametersOfDeclarationOnNextLine: false 20 | AllowAllArgumentsOnNextLine: false 21 | AlignOperands: AlignAfterOperator 22 | AlignConsecutiveBitFields: 23 | Enabled: true 24 | AcrossEmptyLines: false 25 | AcrossComments: false 26 | AllowShortLambdasOnASingleLine: All 27 | AllowShortBlocksOnASingleLine: Empty 28 | AllowShortIfStatementsOnASingleLine: AllIfsAndElse 29 | AllowShortLoopsOnASingleLine: true 30 | AlwaysBreakAfterDefinitionReturnType: None 31 | AlwaysBreakTemplateDeclarations: 'Yes' 32 | BinPackArguments: false 33 | BinPackParameters: false 34 | BreakBeforeBraces: Custom 35 | BreakBeforeBinaryOperators: NonAssignment 36 | ColumnLimit: 120 37 | CommentPragmas: '^ IWYU pragma:' 38 | ConstructorInitializerIndentWidth: 0 39 | IndentWidth: 4 40 | Language: Cpp 41 | MaxEmptyLinesToKeep: 1 42 | PackConstructorInitializers: CurrentLine 43 | PointerAlignment: Left 44 | TabWidth: 4 45 | UseTab: Never 46 | SortIncludes: CaseSensitive 47 | IncludeBlocks: Regroup 48 | -------------------------------------------------------------------------------- /.clangd: -------------------------------------------------------------------------------- 1 | Diagnostics: 2 | Suppress: 3 | - "-Wmicrosoft-enum-forward-reference" 4 | - "-Wc++11-narrowing" 5 | - "-Wc++2b-extensions" 6 | - "-Wmicrosoft-cast" 7 | CompileFlags: 8 | Add: 9 | - "-ferror-limit=0" 10 | - '-D__FUNCTION__="dummy"' 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Create a report to help us improve 3 | title: "[Bug]: " 4 | labels: ["bug"] 5 | body: 6 | - type: textarea 7 | attributes: 8 | label: Describe the bug 9 | description: A clear and concise description of what the bug is. 10 | validations: 11 | required: true 12 | 13 | - type: textarea 14 | attributes: 15 | label: To Reproduce 16 | description: Steps to reproduce the behavior. 17 | validations: 18 | required: true 19 | 20 | - type: textarea 21 | attributes: 22 | label: Expected behavior 23 | description: A clear and concise description of what you expected to happen. 24 | validations: 25 | required: true 26 | 27 | - type: textarea 28 | attributes: 29 | label: Screenshots 30 | description: If applicable, add screenshots to help explain your problem. 31 | 32 | - type: input 33 | attributes: 34 | label: Platform 35 | description: The platform you are using. (e.g. Windows 10) 36 | 37 | - type: input 38 | attributes: 39 | label: BDS Version 40 | description: The version of BDS you are using. (e.g. 1.20.32.1) 41 | 42 | - type: input 43 | attributes: 44 | label: LeviLamina Version 45 | description: The version of LeviLamina you are using. (e.g. 1.0.0) 46 | 47 | - type: input 48 | attributes: 49 | label: LegacyScriptEngine Version 50 | description: The version of LegacyScriptEngine you are using. (e.g. 1.0.0) 51 | 52 | - type: textarea 53 | attributes: 54 | label: Additional context 55 | description: Add any other context about the problem here. 56 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Suggest an idea for this project 3 | title: "[Feature]: " 4 | labels: ["enhancement"] 5 | body: 6 | - type: textarea 7 | attributes: 8 | label: Is your feature request related to a problem? Please describe. 9 | description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 10 | validations: 11 | required: true 12 | 13 | - type: textarea 14 | attributes: 15 | label: Describe the solution you'd like 16 | description: A clear and concise description of what you want to happen. 17 | validations: 18 | required: true 19 | 20 | - type: textarea 21 | attributes: 22 | label: Describe alternatives you've considered 23 | description: A clear and concise description of any alternative solutions or features you've considered. 24 | 25 | - type: textarea 26 | attributes: 27 | label: Additional context 28 | description: Add any other context or screenshots about the feature request here. 29 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## What does this PR do? 2 | 3 | 4 | 5 | ## Which issues does this PR resolve? 6 | 7 | 8 | 9 | ## Checklist before merging 10 | 11 | Thank you for your contribution to the repository. 12 | Before submitting this PR, please make sure: 13 | 14 | - [ ] Your code builds clean without any errors or warnings 15 | - [ ] Your code follows [LeviLamina C++ Style Guide](https://github.com/LiteLDev/LeviLamina/wiki/CPP-Style-Guide) 16 | - [ ] You have tested all functions 17 | - [ ] You have not used code without license 18 | - [ ] You have added statement for third-party code 19 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: 3 | paths: 4 | - .github/workflows/build.yml 5 | - src/** 6 | - xmake.lua 7 | push: 8 | paths: 9 | - .github/workflows/build.yml 10 | - src/** 11 | - xmake.lua 12 | workflow_dispatch: 13 | 14 | jobs: 15 | build: 16 | runs-on: windows-latest 17 | strategy: 18 | matrix: 19 | backend: 20 | - nodejs 21 | - lua 22 | - python 23 | - quickjs 24 | steps: 25 | - uses: actions/checkout@v4 26 | 27 | - uses: xmake-io/github-action-setup-xmake@v1 28 | 29 | - uses: actions/cache@v4 30 | with: 31 | path: | 32 | ~/AppData/Local/.xmake 33 | key: xmake-${{ hashFiles('xmake.lua') }} 34 | restore-keys: | 35 | xmake- 36 | 37 | - run: | 38 | xmake repo -u 39 | 40 | - run: | 41 | xmake f -a x64 -m release -p windows -v -y --backend=${{ matrix.backend }} 42 | 43 | - run: | 44 | xmake -y 45 | 46 | - uses: actions/upload-artifact@v4 47 | with: 48 | name: legacy-script-engine-${{ matrix.backend }}-windows-x64-${{ github.sha }} 49 | path: | 50 | bin/ 51 | -------------------------------------------------------------------------------- /.github/workflows/build_docs.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | paths: 4 | - .github/workflows/build_docs.yml 5 | - docs/** 6 | - mkdocs.yml 7 | workflow_dispatch: 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | 15 | - run: | 16 | pip install -r requirements.txt 17 | 18 | - run: | 19 | mkdocs build 20 | 21 | - uses: actions/upload-pages-artifact@v3 22 | with: 23 | path: site/ 24 | 25 | deploy: 26 | if: github.ref == 'refs/heads/develop' && github.event_name == 'push' 27 | needs: 28 | - build 29 | permissions: 30 | id-token: write 31 | pages: write 32 | runs-on: ubuntu-latest 33 | steps: 34 | - uses: actions/deploy-pages@v4 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LegacyScriptEngine 2 | 3 | English | [简体中文](README.zh.md) 4 | A plugin engine for running LLSE plugins on LeviLamina 5 | 6 | ## Installation 7 | 8 | ### Attention 9 | 10 | Before installing the Python engine, you need to 11 | install [Python 3.12.8](https://www.python.org/downloads/release/python-3128/) first. 12 | To install a specific engine, you can use the following command: 13 | ```shell 14 | lip install github.com/LiteLDev/LegacyScriptEngine#lua 15 | lip install github.com/LiteLDev/LegacyScriptEngine#quickjs 16 | lip install github.com/LiteLDev/LegacyScriptEngine#nodejs 17 | lip install github.com/LiteLDev/LegacyScriptEngine#python 18 | ``` 19 | For version older than 0.10.0, you can use the following command: 20 | ```shell 21 | lip install gitea.litebds.com/LiteLDev/legacy-script-engine-lua@version 22 | lip install gitea.litebds.com/LiteLDev/legacy-script-engine-quickjs@version 23 | lip install gitea.litebds.com/LiteLDev/legacy-script-engine-nodejs@version 24 | lip install gitea.litebds.com/LiteLDev/legacy-script-engine-python@version 25 | ``` 26 | Version numbers can be found in [releases](https://github.com/LiteLDev/LegacyScriptEngine/releases). 27 | 28 | ## Usage 29 | 30 | To access plugin development API hints and scaffolding toolkits, visit the [LegacyScriptEngine_API](https://github.com/LiteLDev/LegacyScriptEngine_API) repository. 31 | 32 | 1. Put LLSE plugins directly in `plugins/` 33 | 2. Run the server, then the plugins will be migrated to LeviLamina plugin manifest automatically 34 | 3. To load them, you need to restart the server 35 | 36 | For more information, please refer to [the documentation](https://lse.levimc.org) 37 | 38 | ## Contributing 39 | 40 | If you have any questions, please open an issue to discuss it 41 | Help us improve translation [here](https://crowdin.com/project/legacyscriptengine) 42 | PRs are welcome 43 | 44 | ## License 45 | 46 | GPL-3.0-or-later © LiteLDev 47 | -------------------------------------------------------------------------------- /README.zh.md: -------------------------------------------------------------------------------- 1 | # LegacyScriptEngine 2 | 3 | [English](README.md) | 简体中文 4 | 一个用于在 LeviLamina 上运行 LLSE 插件的插件引擎 5 | 6 | ## 安装 7 | 8 | ### 注意 9 | 10 | 在安装Python引擎之前,你需要先安装[Python 3.12.8](https://www.python.org/downloads/release/python-3128/) 11 | 要安装特定的引擎,您可以使用以下命令: 12 | ```shell 13 | lip install github.com/LiteLDev/LegacyScriptEngine#lua 14 | lip install github.com/LiteLDev/LegacyScriptEngine#quickjs 15 | lip install github.com/LiteLDev/LegacyScriptEngine#nodejs 16 | lip install github.com/LiteLDev/LegacyScriptEngine#python 17 | ``` 18 | 对于0.10.0之前的版本,可以使用以下命令: 19 | ```shell 20 | lip install gitea.litebds.com/LiteLDev/legacy-script-engine-lua@版本 21 | lip install gitea.litebds.com/LiteLDev/legacy-script-engine-quickjs@版本 22 | lip install gitea.litebds.com/LiteLDev/legacy-script-engine-nodejs@版本 23 | lip install gitea.litebds.com/LiteLDev/legacy-script-engine-python@版本 24 | ``` 25 | 可以在[releases](https://github.com/LiteLDev/LegacyScriptEngine/releases)中找到版本号。 26 | 27 | ## 使用 28 | 29 | 如需获取插件开发 API 提示库和脚手架工具,请访问 [LegacyScriptEngine_API](https://github.com/LiteLDev/LegacyScriptEngine_API) 仓库 30 | 31 | 1. 直接将 LLSE 插件放在 `plugins/` 中 32 | 2. 运行服务器,然后插件将自动迁移到 LeviLamina 插件清单中 33 | 3. 重启服务器后,插件就会被加载 34 | 35 | 更多信息请参见[文档](https://lse.levimc.org) 36 | 37 | ## 贡献 38 | 39 | 如果您有任何问题,请开启一个 issue 来讨论 40 | [在这里](https://crowdin.com/project/legacyscriptengine)帮助我们完善翻译 41 | 欢迎 PR 42 | 43 | ## 许可 44 | 45 | GPL-3.0-only © LiteLDev 46 | -------------------------------------------------------------------------------- /docs/apis/DataAPI/Economy.zh.md: -------------------------------------------------------------------------------- 1 | # 💰 经济系统 API 2 | 3 | 在很多服务器中,经济系统是非常关键的一环。 4 | 为了解决传统使用计分板经济系统的种种问题,脚本引擎提供了对接LLMoney经济系统的接口,可以与其他各系列插件数据互通。 5 | 6 | LLMoney除了拥有传统经济系统的能力之外,还有查询金额变动历史、操作离线玩家经济等额外能力。 7 | LeviLamina在安装时附带了LLMoney插件,因此无需额外安装,就可以直接使用此接口。 8 | 9 | ### 设置玩家的存款金额 10 | 11 | `Player.setMoney(value)` 12 | 13 | `money.set(xuid,value)` 14 | 15 | - 参数: 16 | - xuid : `String` 17 | 要操作的玩家的XUID标识符 18 | - value : `Integer` 19 | 要设置的金额 20 | - 返回值:是否设置成功 21 | - 返回值类型:`Boolean` 22 | 23 | 24 | 25 | ### 获取玩家的存款金额 26 | 27 | `Player.getMoney()` 28 | 29 | `money.get(xuid)` 30 | 31 | - 参数: 32 | - xuid : `String` 33 | 要读取的玩家的XUID标识符 34 | - 返回值:玩家的资金数值 35 | - 返回值类型:`Integer` 36 | 37 | 38 | 39 | ### 增加玩家的存款 40 | 41 | `Player.addMoney(value)` 42 | 43 | `money.add(xuid,value)` 44 | 45 | - 参数: 46 | - xuid : `String` 47 | 要操作的玩家的XUID标识符 48 | - value : `Integer` 49 | 要增加的金额 50 | - 返回值:是否设置成功 51 | - 返回值类型:`Boolean` 52 | 53 | 54 | 55 | ### 减少玩家的存款 56 | 57 | `Player.reduceMoney(value)` 58 | 59 | `money.reduce(xuid,value)` 60 | 61 | - 参数: 62 | - xuid : `String` 63 | 要操作的玩家的XUID标识符 64 | - value : `Integer` 65 | 要减小的金额 66 | - 返回值:是否设置成功 67 | - 返回值类型:`Boolean` 68 | 69 | 70 | 71 | ### 进行一笔转账 72 | 73 | `Player.transMoney(target,money[,note])` 74 | 75 | `money.trans(xuid1,xuid2,money[,note])` 76 | 77 | - 参数: 78 | - xuid1 : `String` 79 | 付款的玩家的XUID标识符 80 | 81 | - xuid2 : `String` 82 | 收款的玩家的XUID标识符 83 | 84 | 如果你使用 `Player.transMoney`,target可以是玩家对象 85 | 86 | - money : `Integer` 87 | 要支付的金额 88 | 89 | - note : `String` 90 | (可选参数)给这笔转账附加一些文字说明 91 | 92 | - 返回值:是否转账成功 93 | 94 | - 返回值类型:`Boolean` 95 | 96 | 97 | 98 | ### 查询历史账单 99 | 100 | `Player.getHistory(time)` 101 | 102 | `money.getHistory(xuid,time)` 103 | 104 | - 参数: 105 | - xuid : `String` 106 | 要操作的玩家的XUID标识符 107 | - time : `Integer` 108 | 查询从现在开始往前time秒的记录 109 | - 返回值:查询结果对象的数组 110 | - 返回值类型:`Array` 111 | 112 | 其中,结果为一系列记录对象组成的数组。对于每个记录对象`record`,有如下的键和对应的值: 113 | 114 | | 键 | 值的意义 | 数据类型 | 115 | | -------------- | -------------------------- | --------- | 116 | | `record.from` | 此项交易的发起者玩家XUID | `String` | 117 | | `record.to` | 此项交易的接收者玩家XUID | `String` | 118 | | `record.money` | 此项交易的金额 | `Integer` | 119 | | `record.time` | 此项交易发生时的时间字符串 | `String` | 120 | | `record.note` | 此交易的附加说明信息 | `String` | 121 | 122 | 时间字符串的格式为:YYYY-mm-dd hh:mm:ss 123 | 124 | 125 | 126 | ### 删除账单历史记录 127 | 128 | `money.clearHistory(time)` 129 | 130 | - 参数: 131 | - time : `Integer` 132 | 删除从现在开始往前time秒的记录 133 | - 返回值:是否删除成功 134 | - 返回值类型:`Boolean` 135 | 136 | 137 | -------------------------------------------------------------------------------- /docs/apis/DataAPI/OtherData.md: -------------------------------------------------------------------------------- 1 | # 🧰 Other Data Processing APIs 2 | 3 | Provides some other common data processing interfaces. You can use and expand by yourself. 4 | 5 | Note that data is an empty class and the functions are all static functions. 6 | 7 | ### Convert Variable to JSON String 8 | 9 | `data.toJson(var[,space])` 10 | 11 | - Parameters: 12 | - var : `Any type` 13 | Variable to convert to JSON string. The allowed data types for conversion are: 14 | `Integer` `Float` `String` `Boolean` `Array` `Object ` 15 | The above elements can only be nested inside an `Array` or `Object`. 16 | - space : `Integer` 17 | (Optional parameter) If you want to format the output string, pass this parameter. 18 | Represents the number of spaces in each indent, so that the output JSON string is more human-readable. 19 | This parameter defaults to 0, that is, the output string is not formatted 20 | - Return value: Converted JSON string. 21 | - Return value type: `String` 22 | - If the return value is `Null`, it means that the conversion failed. 23 | 24 | 25 | 26 | ### JSON String Parsed as Variable 27 | 28 | `data.parseJson(json)` 29 | 30 | - Parameters: 31 | - json : `String` 32 | JSON string to convert to variable. 33 | - Return value: The converted variable. 34 | - Return value type: `Any type`, depending on the data type contained in JSON. 35 | - If the return value is `Null`, it means that the conversion failed . 36 | 37 | 38 | 39 | ### MD5 Calculation 40 | 41 | `data.toMD5(str)` 42 | 43 | - Parameters: 44 | - str : `String` / `ByteBuffer` 45 | String/byte array from which to calculate MD5. 46 | - Return value: MD5 digest string of original data. 47 | - Return value type: `String` 48 | 49 | 50 | 51 | ### SHA1 Calculation 52 | 53 | `data.toSHA1(str)` 54 | 55 | - Parameters: 56 | - str : `String` / `ByteBuffer` 57 | String/byte array to calculate SHA1. 58 | - Return value: SHA1 digest string of original data. 59 | - Return value type: `String` 60 | 61 | 62 | 63 | ### Data to Base64 64 | 65 | `data.toBase64(str)` 66 | 67 | - Parameter: 68 | - str : `String` / `ByteBuffer` 69 | String/byte array to convert to Base64. 70 | - Return value: Base64 result. 71 | - Return value type: `String` 72 | 73 | 74 | 75 | ### Base64 decode to data 76 | 77 | `data.fromBase64(base64, isBinary)` 78 | 79 | - Parameters: 80 | - base64 : `String` 81 | The base64 string to decode. 82 | - isBinary : `Boolean` 83 | Returns whether the data type is binary data, the default is false. 84 | - Return value: Decoded data. 85 | - Return value type: `String` or `ByteBuffer` 86 | 87 | 88 | -------------------------------------------------------------------------------- /docs/apis/DataAPI/OtherData.zh.md: -------------------------------------------------------------------------------- 1 | # 🧰 其他数据处理 API 2 | 3 | 提供一些其他的常用数据处理接口。你可以自行使用并拓展。 4 | 5 | 注意data是一个空类,函数都是静态函数。 6 | 7 | ### 变量转换为JSON字符串 8 | 9 | `data.toJson(var[,space])` 10 | 11 | - 参数: 12 | - var : `指定类型` 13 | 要转换为JSON字符串的变量。允许进行转换的数据类型有: 14 | `Integer` `Float` `String` `Boolean` `Array` `Object ` 15 | 其中,`Array` 和 `Object` 内部仅能嵌套上面出现的这些元素 16 | - space : `Integer` 17 | (可选参数)如果要格式化输出的字符串,则传入此参数 18 | 代表每个缩进的空格数量,这样输出的JSON串更适合人阅读 19 | 此参数默认为0,即不对输出字符串进行格式化 20 | - 返回值:转换成的JSON字符串 21 | - 返回值类型:`String` 22 | - 如果返回值为`Null`,则表示转换失败 23 | 24 | 25 | 26 | ### JSON字符串解析为变量 27 | 28 | `data.parseJson(json)` 29 | 30 | - 参数: 31 | - json : `String` 32 | 要转换为变量的JSON字符串 33 | - 返回值:转换成的变量 34 | - 返回值类型:`任意类型`,以JSON具体包含的数据类型为准 35 | - 如返回值为 `Null` 则表示转换失败 36 | 37 | 38 | 39 | ### MD5计算 40 | 41 | `data.toMD5(str)` 42 | 43 | - 参数: 44 | - str : `String` / `ByteBuffer` 45 | 要计算MD5的字符串 / 字节数组 46 | - 返回值:原数据的MD5摘要字符串 47 | - 返回值类型:`String` 48 | 49 | 50 | 51 | ### SHA1计算 52 | 53 | `data.toSHA1(str)` 54 | 55 | - 参数: 56 | - str : `String` / `ByteBuffer` 57 | 要计算SHA1的字符串 / 字节数组 58 | - 返回值:原数据的SHA1摘要字符串 59 | - 返回值类型:`String` 60 | 61 | 62 | 63 | ### 数据转Base64 64 | 65 | `data.toBase64(str)` 66 | 67 | - 参数: 68 | - str : `String` / `ByteBuffer` 69 | 要转化为Base64的字符串 / 字节数组 70 | - 返回值:Base64结果 71 | - 返回值类型:`String` 72 | 73 | 74 | 75 | ### Base64解码为数据 76 | 77 | `data.fromBase64(base64, isBinary)` 78 | 79 | - 参数: 80 | - base64 : `String` 81 | 要解码的base64字符串 82 | - isBinary : `Boolean` 83 | 返回数据类型是否为二进制数据,默认为 false 84 | - 返回值:解码后的数据 85 | - 返回值类型:`String` 或 `ByteBuffer` 86 | 87 | 88 | -------------------------------------------------------------------------------- /docs/apis/DataAPI/PlayerData.zh.md: -------------------------------------------------------------------------------- 1 | # 🏃‍♂️ 玩家绑定数据 2 | 3 | 在实际开发中,经常有需要将某些数据和服务器中的某个玩家相关联,并在插件的工作周期中不断维护这些数据的需求。 4 | 5 | 为此,脚本引擎设计了玩家绑定数据接口。绑定数据接口使用键 - 值对的形式储存数据。 6 | 在你将数据绑定到某个玩家上以后,即使在玩家对象超出作用域被销毁,甚至当此玩家退出游戏时,玩家绑定数据将仍然存在。当你再次获得这个玩家的玩家对象的时候,仍然可以读取到之前储存的绑定数据。 7 | 只有当服务端关闭的时候,所有的数据才会被统一销毁。 8 | 9 | 由此,脚本引擎给予开发者在插件的整个生命周期中跟踪某个特定玩家相关数据的能力。 10 | 11 | 对于某个特定的玩家对象`pl`,有如下这些接口: 12 | 13 | #### 储存玩家绑定数据 14 | 15 | `pl.setExtraData(name,data)` 16 | 17 | - 参数: 18 | - name : `String` 19 | 要储存到绑定数据的名字 20 | - data : `任意类型` 21 | 你要储存的绑定数据,可以是`Null` 22 | 23 | - 返回值:是否成功储存 24 | - 返回值类型:`Boolean` 25 | 26 | #### 获取玩家绑定数据 27 | 28 | `pl.getExtraData(name)` 29 | 30 | - 参数: 31 | - name : `String` 32 | 要读取的绑定数据的名字 33 | - 返回值:储存的绑定数据 34 | - 返回值类型:`任意类型`,取决于储存的数据类型 35 | - 如返回值为 `Null` 则表示未获取到指定的绑定数据,或者数据为空 36 | 37 | #### 删除玩家绑定数据 38 | 39 | `pl.delExtraData(name)` 40 | 41 | - 参数: 42 | - name : `String` 43 | 要删除的绑定数据的名字 44 | - 返回值:是否删除成功 45 | - 返回值类型:`Boolean` 46 | 47 | ## 👨‍💻 XUID 数据库 48 | 49 | XUID数据库让你可以即使在玩家离线的时候,也可以查询玩家名字与XUID的对应关系。 50 | 当一个玩家第一次进服的时候,他的名字和XUID就会被自动记录在内置 XUID 数据库中。使用下面的函数来进行相关查询 51 | 52 | #### 根据玩家名查询XUID 53 | 54 | `data.name2xuid(name)` 55 | 56 | - 参数: 57 | - name : `String` 58 | 要查询的玩家名 59 | - 返回值:玩家的XUID 60 | - 返回值类型:`String` 61 | - 如果返回值为`Null`,则代表查询失败 62 | 63 | #### 根据XUID查询玩家名 64 | 65 | `data.xuid2name(xuid)` 66 | 67 | - 参数: 68 | - xuid: `String` 69 | 要查询的玩家XUID 70 | - 返回值:玩家名 71 | - 返回值类型:`String` 72 | - 如果返回值为`Null`,则代表查询失败 73 | 74 | #### 根据玩家名查询UUID 75 | 76 | `data.name2uuid(name)` 77 | 78 | - 参数: 79 | - name : `String` 80 | 要查询的玩家名 81 | - 返回值:玩家的UUID 82 | - 返回值类型:`String` 83 | - 如果返回值为`Null`,则代表查询失败 84 | 85 | #### 根据XUID查询玩家UUID 86 | 87 | `data.xuid2uuid(xuid)` 88 | 89 | - 参数: 90 | - xuid: `String` 91 | 要查询的玩家XUID 92 | - 返回值:玩家的UUID 93 | - 返回值类型:`String` 94 | - 如果返回值为`Null`,则代表查询失败 95 | 96 | #### 获取所有的玩家信息 97 | 98 | `data.getAllPlayerInfo()` 99 | 100 | - 返回值: 所有的玩家信息 101 | - 返回值类型: `Array` 102 | - 每个对象都含有以下属性: 103 | - `name`: 玩家名 104 | - `xuid`: 玩家XUID 105 | - `uuid`: 玩家UUID 106 | 107 | 提示:XUID数据库中储存的玩家名为玩家对象对应的`realName`字段 108 | 109 | !!! warning 110 | 以下API均为0.8.13新API,使用以下API将导致插件无法兼容旧版 111 | #### 根据XUID查询玩家信息 112 | 113 | `data.fromXuid(xuid)` 114 | 115 | - 参数: 116 | - xuid: `String` 117 | 要查询玩家的XUID 118 | - 返回值: 玩家信息条目,例如 `{xuid:1145141919810,name:yjsp,uuid:2a30fa4a-3a63-3370-88a8-144a941101e2}` 119 | - 返回值类型: `Object` 120 | - 如果返回值为`Null`,则代表查询失败 121 | 122 | #### 根据UUID查询玩家信息 123 | 124 | `data.fromUuid(uuid)` 125 | 126 | - 参数: 127 | - uuid: `String` 128 | 要查询玩家的UUID 129 | - 返回值: 玩家信息条目,例如 `{xuid:1145141919810,name:yjsp,uuid:2a30fa4a-3a63-3370-88a8-144a941101e2}` 130 | - 返回值类型: `Object` 131 | - 如果返回值为`Null`,则代表查询失败 132 | 133 | #### 根据名字查询玩家信息 134 | 135 | `data.fromName(name)` 136 | 137 | - 参数: 138 | - name: `String` 139 | 要查询玩家的名字 140 | - 返回值: 玩家信息条目,例如 `{xuid:1145141919810,name:yjsp,uuid:2a30fa4a-3a63-3370-88a8-144a941101e2}` 141 | - 返回值类型: `Object` 142 | - 如果返回值为`Null`,则代表查询失败 143 | -------------------------------------------------------------------------------- /docs/apis/EventAPI/EconomicEvents.zh.md: -------------------------------------------------------------------------------- 1 | # 💰 经济系统事件 2 | 3 | 此处为脚本引擎内置经济系统相关的经济变动事件 4 | 5 | #### `"beforeMoneyAdd"` - 玩家金额增加前事件 6 | 7 | - 监听函数原型 8 | `function(xuid,money)` 9 | - 参数: 10 | - xuid : `String` 11 | 金额变动的玩家的XUID 12 | - money : `Integer` 13 | 增加的金额 14 | - 拦截事件:函数返回`false` 15 | 16 | 17 | 18 | #### `"onMoneyAdd"` - 玩家金额增加事件 19 | 20 | - 监听函数原型 21 | `function(xuid,money)` 22 | - 参数: 23 | - xuid : `String` 24 | 金额变动的玩家的XUID 25 | - money : `Integer` 26 | 增加的金额 27 | 28 | 29 | 30 | #### `"beforeMoneyReduce"` - 玩家金额减少前事件 31 | 32 | - 监听函数原型 33 | `function(xuid,money)` 34 | - 参数: 35 | - xuid : `String` 36 | 金额变动的玩家的XUID 37 | - money : `Integer` 38 | 减少的金额 39 | - 拦截事件:函数返回`false` 40 | 41 | 42 | 43 | #### `"onMoneyReduce"` - 玩家金额减少事件 44 | 45 | - 监听函数原型 46 | `function(xuid,money)` 47 | - 参数: 48 | - xuid : `String` 49 | 金额变动的玩家的XUID 50 | - money : `Integer` 51 | 减少的金额 52 | 53 | 54 | 55 | #### `"beforeMoneyTrans"` - 玩家转账前事件 56 | 57 | - 监听函数原型 58 | `function(from,to,money)` 59 | - 参数: 60 | - from : `String` 61 | 发起转账的玩家的XUID 62 | - to : `String` 63 | 接受转账的玩家的XUID 64 | - money : `Integer` 65 | 转账的金额 66 | - 拦截事件:函数返回`false` 67 | 68 | 69 | 70 | #### `"onMoneyTrans"` - 玩家转账事件 71 | 72 | - 监听函数原型 73 | `function(from,to,money)` 74 | - 参数: 75 | - from : `String` 76 | 发起转账的玩家的XUID 77 | - to : `String` 78 | 接受转账的玩家的XUID 79 | - money : `Integer` 80 | 转账的金额 81 | 82 | **注意: 当 `onMoneyReduce` 或 `onMoneyAdd` 被触发时,该事件也会被触发** 83 | 84 | 85 | #### `"beforeMoneySet"` - 设置玩家金额前事件 86 | 87 | - 监听函数原型 88 | `function(xuid,money)` 89 | - 参数: 90 | - xuid : `String` 91 | 金额变动的玩家的XUID 92 | - money : `Integer` 93 | 被设置的金额 94 | - 拦截事件:函数返回`false` 95 | 96 | 97 | 98 | #### `"onMoneySet"` - 直接设置玩家金额事件 99 | 100 | - 监听函数原型 101 | `function(xuid,money)` 102 | - 参数: 103 | - xuid : `String` 104 | 金额变动的玩家的XUID 105 | - money : `Integer` 106 | 被设置的金额 107 | 108 | 109 | -------------------------------------------------------------------------------- /docs/apis/EventAPI/Listen.md: -------------------------------------------------------------------------------- 1 | # LLSE - Event Listening Documentation 2 | 3 | > The event system allows plugins to **respond** to certain game events, allowing you to execute code when certain events occur. 4 | 5 | The following APIs provide the ability to listen to **game events** and respond to them. 6 | 7 | ## 🔔 Monitor API 8 | 9 | Register the specified listener function. 10 | 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. 11 | 12 | ### Add a Listener 13 | 14 | `mc.listen(event,callback)` 15 | 16 | - Parameters: 17 | - event : `String` 18 | The name of the event to listen for (see the list of listening events below). 19 | - callback : `Function` 20 | Registered listener function (see below for function-related parameters). 21 | When the specified event occurs, BDS will call the listener function you give and pass in the corresponding parameters. 22 | - Return value: Whether the event was successfully monitored. 23 | - Return value type: `Boolean` 24 | 25 | 26 | 27 | ### Intercept Event 28 | 29 | 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. 30 | For example: intercepting a chat event will cause everyone to not see the chat message 31 | 32 | However, intercepting events is only valid for BDS. 33 | 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. 34 | 35 | 36 | 37 | ### Avoid Mistakes 38 | 39 | Sometimes, calling a specific API inside some event listeners will cause an infinite loop to collapse. Please avoid these situations. 40 | 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. 41 | 42 | ## 📜 Listen Event List 43 | 44 | There is a list of the various events in sidebar that LLSE supports listening for. 45 | 46 | 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. 47 | At the same time, the member functions of these objects can also be called. 48 | 49 | > Notice! Some of the callback parameters passed in may sometimes be Null, which requires a good judgment check when writing code. 50 | -------------------------------------------------------------------------------- /docs/apis/EventAPI/Listen.zh.md: -------------------------------------------------------------------------------- 1 | # 脚本引擎 - 事件监听文档 2 | 3 | > 事件系统让插件可以 **响应** 特定的游戏事件,让你可以在特定事件发生时执行代码 4 | 5 | 下面这些API,提供了监听**游戏事件**并做出响应的相关能力。 6 | 7 | ## 🔔 监听 API 8 | 9 | 注册指定的监听函数。 10 | 当游戏中的某种事件发生时,你设置的对应的监听函数将被引擎调用,这时候你可以对相关事件进行处理。 11 | 12 | ### 注册监听器 13 | 14 | `mc.listen(event,callback)` 15 | 16 | - 参数: 17 | 18 | - event : `String` 19 | 要监听的事件名(见下方监听事件列表) 20 | 21 | - callback : `Function` 22 | 注册的监听函数(函数相关参数见下) 23 | 当指定的事件发生时,BDS会调用你给出的监听函数,并传入相应的参数 24 | - 返回值:是否成功监听事件 25 | - 返回值类型:`Boolean` 26 | 27 | 28 | 29 | ### 拦截事件 30 | 31 | 在脚本引擎的事件监听系统中,一般你可以通过返回`false`来拦截某个可以被拦截的事件。拦截事件意味着在脚本拦截之后BDS将不再处理这个事件,就像他从没发生过一样。 32 | 举例:拦截某条聊天事件,会造成所有人都看不到这条聊天消息 33 | 34 | 不过,拦截事件仅对BDS有效。 35 | 也就是说,拦截事件并不影响其他有对应监听的脚本引擎脚本处理这个事件,只是BDS无法再接收到它。 36 | 37 | 38 | 39 | ### 避开误区 40 | 41 | 有些时候,在某些事件监听内部调用特定的API会造成死循环崩服,请务必避免这些情况的发生 42 | 举例:在`onConsoleCmd`事件监听中调用`mc.runcmd(Ex)`系列函数执行后台指令,将导致死循环 43 | 44 | ## 📜 监听事件列表 45 | 46 | 侧边栏中给出了脚本引擎支持监听的各种事件的列表。 47 | 48 | 提示:你可以根据监听得到的游戏对象来获取他们的相关信息,比如说方块的坐标、实体的名字等等。 49 | 同时,这些对象的成员函数也都可以被调用。 50 | 51 | > 注意!传入的回调参数中,有些有时候可能为 Null,这需要在编写代码的时候做好判断检查 52 | 53 | -------------------------------------------------------------------------------- /docs/apis/EventAPI/OtherEvents.md: -------------------------------------------------------------------------------- 1 | # 🔊 Other Events 2 | 3 | #### `"onScoreChanged"` - Player Scoreboard Change Event 4 | 5 | - Listener function prototype 6 | `function(player,num,name,disName)` 7 | - Parameters: 8 | - player : `Player` 9 | The player whose scoreboard values have changed. 10 | - num: `Integer` 11 | The changed scoreboard value. 12 | - name : `String` 13 | The name of the scoreboard scoring item. 14 | - disName : `String` 15 | The display name of the scoreboard item. 16 | - Intercept event: cannot be intercepted. 17 | 18 | 19 | 20 | #### `"onTick"` - Tick Event 21 | 22 | - Listener function prototype 23 | `function()` 24 | - Parameters: 25 | - None 26 | - Intercept events: function returns `false` 27 | 28 | 29 | 30 | #### `"onServerStarted"` - Server Start Event 31 | 32 | - Listener function prototype 33 | `function()` 34 | - Parameters: 35 | - None 36 | - Intercept event: cannot be intercepted. 37 | 38 | 39 | 40 | #### `"onConsoleCmd"` - Server Command Event 41 | 42 | - Listener function prototype 43 | `function(cmd)` 44 | - Parameters: 45 | - cmd : `String` 46 | The console command being executed. 47 | 48 | - Intercept events: function returns `false` 49 | -------------------------------------------------------------------------------- /docs/apis/EventAPI/OtherEvents.zh.md: -------------------------------------------------------------------------------- 1 | # 🔊 其他事件 2 | 3 | #### `"onScoreChanged"` - 玩家计分板数值改变 4 | 5 | - 监听函数原型 6 | `function(player,num,name,disName)` 7 | - 参数: 8 | - player : `Player` 9 | 计分板数值改变的玩家 10 | - num: `Integer` 11 | 改变后的计分板数值 12 | - name : `String` 13 | 计分板计分项名称 14 | - disName : `String` 15 | 计分板计分项的显示名称 16 | - 拦截事件:不可以拦截 17 | 18 | 19 | 20 | #### `"onTick"` - 每个游戏刻触发 21 | 22 | - 监听函数原型 23 | `function()` 24 | - 参数: 25 | - 无 26 | - 拦截事件:函数返回`false` 27 | 28 | 29 | 30 | #### `"onServerStarted"` - 服务器启动完毕 31 | 32 | - 监听函数原型 33 | `function()` 34 | - 参数: 35 | - 无 36 | - 拦截事件:不可以拦截 37 | 38 | 39 | 40 | #### `"onConsoleCmd"` - 服务端执行后台命令 41 | 42 | - 监听函数原型 43 | `function(cmd)` 44 | - 参数: 45 | - cmd : `String` 46 | 执行的后台命令 47 | 48 | - 拦截事件:函数返回`false` 49 | -------------------------------------------------------------------------------- /docs/apis/GameAPI/BlockEntity.md: -------------------------------------------------------------------------------- 1 | # 📮 Block Entity Object API 2 | 3 | In LLSE, "block entity objects" are used to manipulate and obtain additional data associated with a particular block. 4 | Note: **Block Entity Object** is not a **Entity**! There is no special relationship between them. 5 | 6 | ### Get a Block Entity Object 7 | 8 | #### Obtained From Blocks 9 | 10 | 11 | For an existing block object `bl`, there are: 12 | 13 | `bl.getBlockEntity()` 14 | 15 | - Return type: The block's block entity object. 16 | - Return value type: `BlockEntity` 17 | - 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. 18 | 19 | > Note: Do not save a block entity object. 20 | > 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. 21 | 22 | 23 | 24 | 25 | ### Block Entity Object - Properties 26 | 27 | Each block entity object contains some fixed object properties. For a particular block entity object `be`, there are the following properties: 28 | 29 | | Attributes | Meaning | Data Type | 30 | | ---------- | -------------------------------------------------- | --------- | 31 | | be.name | The block entity name (example: `container.chest`) | `String` | 32 | | be.pos | The coordinates where the block entity is located. | `IntPos` | 33 | | be.type | The Type ID of the block entity object. | `Integer` | 34 | 35 | These object properties are read-only and cannot be modified. 36 | 37 | 38 | 39 | ### Block Entity Object - Function 40 | 41 | 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: 42 | 43 | #### Get the Block Entity's NBT Object 44 | 45 | `be.getNbt()` 46 | 47 | - Return type: NBT object of the block entity. 48 | - Return value type: `NbtCompound` 49 | 50 | 51 | 52 | #### Write to the Block Entity's NBT object 53 | 54 | `be.setNbt(nbt)` 55 | 56 | - Parameters: 57 | - nbt : `NbtCompound` 58 | NBT objects. 59 | - Return type: Whether the write was successful or not. 60 | - Return value type: `Boolean` 61 | 62 | For more usage of NBT objects, please refer to [NBT Interface Documentation](../NbtAPI/NBT.md) 63 | 64 | 65 | 66 | #### Get the Block Entity's Block Object 67 | 68 | `be.getBlock()` 69 | 70 | - Return type: The block entity's block object. 71 | - Return value type: `Block` 72 | 73 | 74 | -------------------------------------------------------------------------------- /docs/apis/GameAPI/BlockEntity.zh.md: -------------------------------------------------------------------------------- 1 | # 📮 方块实体对象 API 2 | 3 | 在脚本引擎中,使用「方块实体对象」来操作和获取与特定方块关联的附加数据。 4 | 注意:**方块实体对象** 不是一种 **实体**!他们之间并没有特别的关系 5 | 6 | ### 获取一个方块实体对象 7 | 8 | #### 通过方块获取 9 | 10 | 11 | 对于已存在的方块对象`bl`,有 12 | 13 | `bl.getBlockEntity()` 14 | 15 | - 返回值:此方块对象对应的方块实体对象 16 | - 返回值类型:`BlockEntity` 17 | - 如返回值为 `Null` 则表示获取方块实体对象失败,或者此方块**没有**对应的实体对象 18 | 19 | > 注意:不要**长期保存**一个方块实体对象 20 | > 当方块对象对应的方块被销毁时,对应的方块实体对象将同时释放。因此,如果有长期操作某个方块实体的需要,请通过上述途径获取实时的方块实体对象 21 | 22 | 23 | 24 | 25 | ### 方块实体对象 - 属性 26 | 27 | 每一个方块实体对象都包含一些固定的对象属性。对于某个特定的方块实体对象`be`,有以下这些属性 28 | 29 | | 属性 | 含义 | 类型 | 30 | | ------- | -------------------------------------------------- | --------- | 31 | | be.name | The block entity name (example: `container.chest`) | `String` | 32 | | be.pos | 方块实体对应方块所在的坐标 | `IntPos` | 33 | | be.type | 方块实体对象的类型ID | `Integer` | 34 | 35 | 这些对象属性都是只读的,无法被修改 36 | 37 | 38 | 39 | ### 方块实体对象 - 函数 40 | 41 | 每一个方块实体对象都包含一些可以执行的成员函数(成员方法)。对于某个特定的方块实体对象`be`,可以通过以下这些函数对这个方块实体进行一些操作 42 | 43 | #### 获取方块实体对应的NBT对象 44 | 45 | `be.getNbt()` 46 | 47 | - 返回值:方块实体的NBT对象 48 | - 返回值类型:`NbtCompound` 49 | 50 | 51 | 52 | #### 写入方块实体对应的NBT对象 53 | 54 | `be.setNbt(nbt)` 55 | 56 | - 参数: 57 | - nbt : `NbtCompound` 58 | NBT对象 59 | - 返回值:是否成功写入 60 | - 返回值类型:`Boolean` 61 | 62 | 关于NBT对象的更多使用,请参考 [NBT接口文档](../NbtAPI/NBT.zh.md) 63 | 64 | 65 | 66 | #### 获取方块实体对应的方块对象 67 | 68 | `be.getBlock()` 69 | 70 | - 返回值:方块实体对应的方块对象 71 | - 返回值类型:`Block` 72 | 73 | 74 | -------------------------------------------------------------------------------- /docs/apis/GameAPI/Container.zh.md: -------------------------------------------------------------------------------- 1 | # 👜 容器对象 API 2 | 3 | 在脚本引擎中,使用「容器对象」来操作拥有格子、可以储存和放置物品的容器的相关信息。 4 | 此处的 **容器** 是一种宽泛的概念,除了箱子、桶这些传统的容器之外,如玩家物品栏、羊驼携带的箱子等这些也统统可以作为「容器」处理,获取并使用容器对应的API 5 | 6 | ### 获取一个容器对象 7 | 8 | #### 从事件或API获取 9 | 10 | 通过注册**事件监听**函数,或者调用某些**返回容器对象**的函数,来获取到BDS给出的容器对象 11 | 详见 [事件监听文档 - EventAPI](../EventAPI/Listen.zh.md) 12 | 13 | #### 通过实体获取 14 | 15 | 通过玩家对象的各个成员函数,来获取一个玩家物品栏、盔甲栏、末影箱对应的**容器对象** 16 | 详见 [玩家对象 API](./Player.zh.md) 17 | 18 | #### 通过方块获取 19 | 20 | 对于可以容纳物品的方块,通过方块对象的成员函数,来他所对应的对应的**容器对象** 21 | 详见 [方块对象 API](./Block.zh.md) 22 | 23 | > 注意:不要**长期保存**一个容器对象 24 | > 当容器对象对应的实体 / 方块被销毁时,对应的容器对象将同时释放。因此,如果有长期操作某个容器的需要,请通过上述途径获取实时的容器对象 25 | 26 | 27 | 28 | ### 容器信息对象 - 属性 29 | 30 | 每一个容器信息对象都包含一些固定的对象属性。对于某个特定的容器对象`ct`,有以下这些属性 31 | 32 | | 属性 | 含义 | 类型 | 33 | | ------- | ------------------ | --------- | 34 | | ct.size | 容器拥有的格子总数 | `Integer` | 35 | | ct.type | 容器的类型名 | `String` | 36 | 37 | 38 | 39 | ### 容器对象 - 函数 40 | 41 | 每一个容器对象都包含一些可以执行的成员函数(成员方法)。对于某个特定的容器对象`ct`,可以通过以下这些函数对这个容器进行一些操作 42 | 43 | > 注意!在修改完玩家物品栏对应的物品之后,不要忘记使用玩家对象的成员函数`pl.refreshItems`,刷新客户端显示的玩家物品栏 44 | 45 | #### 放入物品对象到容器中 46 | 47 | `ct.addItem(item[, amount])` 48 | 49 | - 参数: 50 | - item : `Item` 51 | 待增加的物品对象 52 | 53 | - amount: `Integer` 54 | 55 | (可选)欲添加物品数量,若提供此参数,item对象本身的count属性将被忽略。 56 | - 返回值:是否成功增加 57 | - 返回值类型:`Boolean` 58 | 59 | 60 | 61 | #### 放入物品对象到容器的第一个空格子 62 | 63 | `ct.addItemToFirstEmptySlot(item)` 64 | 65 | - 参数: 66 | - item : `Item` 67 | 待增加的物品对象 68 | - 返回值:是否成功增加 69 | - 返回值类型:`Boolean` 70 | 71 | 和上述函数不同,此函数将不会堆叠至容器内现有的物品堆中 72 | 73 | 74 | 75 | #### 检查容器中是否(有空间)可以放入此物品 76 | 77 | `ct.hasRoomFor(item)` 78 | 79 | - 参数: 80 | - item : `Item` 81 | 待放入的物品对象 82 | - 返回值:是否可以放入 83 | - 返回值类型:`Boolean` 84 | 85 | 86 | 87 | #### 减少容器中的某个物品对象 88 | 89 | `ct.removeItem(index,count)` 90 | 91 | - 参数: 92 | - index : `Integer` 93 | 减少的物品对象所在的格子序号 94 | - count : `Integer` 95 | 减少的数量。如果大于等于此格子物品堆叠的数量,则物品堆将被整个清除 96 | - 返回值:是否成功减少 97 | - 返回值类型:`Boolean` 98 | 99 | 100 | 101 | #### 获取容器某个格子的物品对象 102 | 103 | `ct.getItem(index)` 104 | 105 | - 参数: 106 | - index : `Integer` 107 | 待获取的格子序号 108 | - 返回值:格子位置的物品对象 109 | - 返回值类型:`Item` 110 | 111 | 此处获取的物品对象为引用。也就是说,修改此处返回的物品对象,或使用其API,就相当于直接操作容器中对应的物品 112 | 113 | 114 | 115 | #### 设置容器某个格子的物品对象 116 | 117 | `ct.setItem(index,item)` 118 | 119 | - 参数: 120 | - index : `Integer` 121 | 待设置的格子序号 122 | - item : `Item` 123 | 待设置的物品对象 124 | - 返回值:是否设置成功 125 | - 返回值类型:`Boolean` 126 | 127 | 128 | 129 | #### 获取容器所有格子的物品对象列表 130 | 131 | `ct.getAllItems()` 132 | 133 | - 返回值:容器中所有的物品对象 134 | - 返回值类型:`Array` 135 | 136 | 此处获取的物品对象均为引用。也就是说,修改此处返回的物品对象,或使用其API,就相当于直接操作容器中对应的物品 137 | 138 | 139 | 140 | #### 清空容器 141 | 142 | `ct.removeAllItems()` 143 | 144 | - 返回值:是否成功清空 145 | - 返回值类型:`Boolean` 146 | 147 | 148 | 149 | #### 判断容器是否为空 150 | 151 | `ct.isEmpty()` 152 | 153 | - 返回值:当前容器是否为空 154 | - 返回值类型:`Boolean` 155 | -------------------------------------------------------------------------------- /docs/apis/GameAPI/Device.zh.md: -------------------------------------------------------------------------------- 1 | # 📱 设备信息对象 API 2 | 3 | 在脚本引擎中,使用「设备信息对象」来操作和获取某一个玩家使用的游戏设备的相关信息。 4 | 5 | ### 获取一个设备信息对象 6 | 7 | #### 通过玩家获取 8 | 9 | 通过玩家对象的`.getDevice`成员函数,来获取一个玩家对应的**设备信息对象** 10 | 详见 [玩家对象 API](./Player.zh.md) 11 | 12 | > 注意:不要**长期保存**一个设备信息对象 13 | > 当设备对应的玩家退出游戏时,对应的对象将同时释放。因此,如果有长期操作某个对象的需要,请通过上述途径获取实时的设备信息对象 14 | 15 | 16 | 17 | 18 | ### 设备信息对象 - 属性 19 | 20 | 每一个设备信息对象都包含一些固定的对象属性。对于某个特定的实体对象`dv`,有以下这些属性 21 | 22 | | 属性 | 含义 | 类型 | 23 | | ----------------- | ---------------------------- | --------- | 24 | | dv.ip | 玩家设备的IP地址 | `String` | 25 | | dv.avgPing | 玩家的平均网络延迟时间(ms) | `Integer` | 26 | | dv.avgPacketLoss | 玩家的平均网络丢包率(%) | `Float` | 27 | | dv.lastPing | 玩家的网络延迟时间(ms) | `Integer` | 28 | | dv.lastPacketLoss | 玩家的网络丢包率(%) | `Float` | 29 | | dv.os | 玩家设备的操作系统类型 | `String` | 30 | | dv.inputMode | 玩家的操作模式 | `Integer` | 31 | | dv.serverAddress | 玩家连接的地址 | `String` | 32 | | dv.clientId | 玩家客户端的识别码ID | `String` | 33 | 34 | 这些对象属性都是只读的,无法被修改 35 | 36 | 其中,操作系统类型属性返回一个字符串,记录了玩家设备的操作系统。可能返回的值如下表 37 | 38 | | dv.os返回字符串 | 玩家设备的操作系统 | 39 | | --------------- | ------------------------- | 40 | | `Android` | 手机谷歌Android | 41 | | `iOS` | 手机苹果iOS/平板iPadOS | 42 | | `OSX` | 电脑苹果macOS | 43 | | `Amazon` | 平板/电视亚马逊FireOS | 44 | | `GearVR` | 头显三星GearVR | 45 | | `Hololens` | 头显微软HoloLens | 46 | | `Windows10` | 电脑微软Windows | 47 | | `Win32` | 电脑微软Win32(教育版?) | 48 | | `TVOS` | 机顶盒苹果tvOS | 49 | | `PlayStation` | 主机索尼PlayStation | 50 | | `Nintendo` | 掌机任天堂Switch | 51 | | `Xbox` | 主机微软Xbox | 52 | | `WindowsPhone` | 手机微软Windows Mobile | 53 | | `Unknown` | 未知系统 | 54 | 55 | | Input mode ENUM | 备注 | 56 | | ---------------------------- | ---------- | 57 | | `InputMode.Mouse` | 鼠标 | 58 | | `InputMode.Touch` | 触屏 | 59 | | `InputMode.GamePad` | 手柄 | 60 | | `InputMode.MotionController` | 运动控制器 | 61 | -------------------------------------------------------------------------------- /docs/apis/GameAPI/GameUtils.zh.md: -------------------------------------------------------------------------------- 1 | # 🎮 游戏实用工具 API 2 | 3 | 下面这些API提供了某些帮助游戏内容开发的实用工具接口,让开发效率可以得到一定的提高。 4 | 5 | ### 格式化代码实用工具 6 | 7 | MC通过 **格式化代码** 符号在游戏内提供颜色文字、样式修改等格式控制能力。格式化代码分为颜色代码与格式代码两种,分别提供颜色控制和样式控制两种能力。 8 | 9 | 此处的接口为了帮助开发者快速上手MC格式化代码,而不需要频繁查表才能使用 10 | 注意:此处接口仅有在传递到BDS中并显示时才会产生效果 11 | 12 | #### 颜色代码表 13 | 14 | | 颜色代码符号 | 表示的颜色意义 | 游戏内对应的字符串 | 15 | | ---------------------- | ----------------------- | ------------------ | 16 | | `Format.Black` | 接下来的文字为 黑色 | §0 | 17 | | `Format.DarkBlue` | 接下来的文字为 深蓝色 | §1 | 18 | | `Format.DarkGreen` | 接下来的文字为 深绿色 | §2 | 19 | | `Format.DarkAqua ` | 接下来的文字为 湖蓝色 | §3 | 20 | | `Format.DarkRed` | 接下来的文字为 深红色 | §4 | 21 | | `Format.DarkPurple` | 接下来的文字为 紫色 | §5 | 22 | | `Format.Gold` | 接下来的文字为 金色 | §6 | 23 | | `Format.Gray` | 接下来的文字为 灰色 | §7 | 24 | | `Format.DarkGray` | 接下来的文字为 深灰色 | §8 | 25 | | `Format.Blue` | 接下来的文字为 蓝色 | §9 | 26 | | `Format.Green` | 接下来的文字为 浅绿色 | §a | 27 | | `Format.Aqua` | 接下来的文字为 天蓝色 | §b | 28 | | `Format.Red` | 接下来的文字为 浅红色 | §c | 29 | | `Format.LightPurple` | 接下来的文字为 浅紫色 | §d | 30 | | `Format.Yellow` | 接下来的文字为 浅黄色 | §e | 31 | | `Format.White` | 接下来的文字为 白色 | §f | 32 | | `Format.MinecoinGold ` | 接下来的文字为 硬币金色 | §g | 33 | 34 | 35 | 36 | #### 格式代码表 37 | 38 | | 格式代码符号 | 表示的格式意义 | 游戏内对应的字符串 | 39 | | ---------------------- | ------------------------------- | ------------------ | 40 | | `Format.Bold` | 接下来的文字 **加粗** | §l | 41 | | `Format.Italics` | 接下来的文字 *斜体* | §o | 42 | | `Format.Underline` | 接下来的文字 下划线 | §n | 43 | | `Format.StrikeThrough` | 接下来的文字 ~~删除线~~ | §m | 44 | | `Format.Random` | 接下来的文字 随机闪烁的乱码字符 | §k | 45 | | `Format.Clear` | 接下来的文字 清除所有格式 | §r | 46 | 47 | 48 | 49 | 上述代码使用的方法为连接字符串,类似于: 50 | 51 | [JavaScript] 52 | ```js 53 | mc.broadcast(Format.Red + Format.Bold + "Red & Bold " + Format.DarkGreen + Format.Underline + "DarkGreen & Underline" + Format.Clear + "Clear"); 54 | ``` 55 | [Lua] 56 | ```lua 57 | mc.broadcast(Format.Red .. Format.Bold .. "Red & Bold " .. Format.DarkGreen .. Format.Underline .. "DarkGreen & Underline" .. Format.Clear .. "Clear") 58 | ``` 59 | -------------------------------------------------------------------------------- /docs/apis/GameAPI/Server.md: -------------------------------------------------------------------------------- 1 | # 💻 Server Settings API 2 | 3 | The following APIs provide interfaces for customizing some server settings: 4 | 5 | ### Get the Version Number of the BDS Server 6 | 7 | `mc.getBDSVersion()` 8 | 9 | - Return value: The server version number string, formatted like this: `v1.17.10` 10 | - Return value type: `String` 11 | 12 | 13 | 14 | ### Get BDS Server Protocol Version 15 | 16 | `mc.getServerProtocolVersion()` 17 | 18 | - Return value: Server protocol version 19 | - Return value type: `Number` 20 | 21 | 22 | 23 | ### Set Server Motd String 24 | 25 | `mc.setMotd(motd)` 26 | 27 | - Parameters: 28 | - motd : `String` 29 | The desired Motd string. 30 | - Return value: Whether the setting was successful. 31 | - Return value type: `Boolean` 32 | 33 | 34 | 35 | ### Set the Maximum Number of Players on the Server 36 | 37 | `mc.setMaxPlayers(num)` 38 | 39 | - Parameters: 40 | - num : `Number` 41 | The maximum number of players. 42 | - Return value: Whether the setting was successful. 43 | - Return value type: `Boolean` 44 | 45 | 46 | 47 | ### Get Sever time 48 | 49 | `mc.getTime(TimeID)` 50 | 51 | - Parameters: 52 | - TimeID : `Integer` 53 | Specifies the time to get. Must be 0, 1 or 2. (0 represents daytime, 1 represents gametime, 2 represents day) 54 | - Return value: Current time 55 | - Return value type: `Integer` 56 | 57 | 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. 58 | 59 | 60 | 61 | ### Set Sever time 62 | 63 | `mc.setTime(tick)` 64 | 65 | - Parameters: 66 | - tick : `Integer` 67 | The time you want to set 68 | - Return value: Whether the setting was successful. 69 | - Return value type: `Boolean` 70 | 71 | 72 | 73 | ### Get Sever Weather 74 | 75 | `mc.getWeather()` 76 | 77 | - Return value: Current weather (0 represents Clear, 1 represents Rain, 2 represents Thunder) 78 | - Return value type: `Integer` 79 | 80 | 81 | 82 | ### Set Sever Weather 83 | 84 | `mc.setWeather(WeatherID)` 85 | 86 | - Parameters: 87 | - WeatherID : `Integer` 88 | The weather you want to set (0 represents Clear, 1 represents Rain, 2 represents Thunder) 89 | - Return value: Whether the setting was successful. 90 | - Return value type: `Boolean` 91 | 92 | 93 | -------------------------------------------------------------------------------- /docs/apis/GameAPI/Server.zh.md: -------------------------------------------------------------------------------- 1 | # 💻 服务端设置 API 2 | 3 | 下面这些API提供了自定义某些服务器设置的接口 4 | 5 | ### 获取服务器版本号 6 | 7 | `mc.getBDSVersion()` 8 | 9 | - 返回值:服务端版本号字符串,格式形如`v1.17.10` 10 | - 返回值类型:`String` 11 | 12 | 13 | 14 | ### 获取服务器协议版本 15 | 16 | `mc.getServerProtocolVersion()` 17 | 18 | - 返回值:服务端协议版本 19 | - 返回值类型:`Number` 20 | 21 | 22 | 23 | ### 设置服务器MOTD字符串 24 | 25 | `mc.setMotd(motd)` 26 | 27 | - 参数: 28 | - motd : `String` 29 | 目标MOTD字符串 30 | - 返回值:是否设置成功 31 | - 返回值类型:`Boolean` 32 | 33 | 34 | 35 | ### 设置服务器最大玩家数 36 | 37 | `mc.setMaxPlayers(num)` 38 | 39 | - 参数: 40 | - num : `Number` 41 | 最大玩家数 42 | - 返回值:是否设置成功 43 | - 返回值类型:`Boolean` 44 | 45 | 46 | 47 | ### 获取服务器游戏时间 48 | 49 | `mc.getTime(TimeID)` 50 | 51 | - 参数: 52 | - TimeID : `Integer` 53 | 想要查询的时间 (0 代表daytime,1 代表gametime,2 代表day) 54 | - 返回值:获取到的时间 55 | - 返回值类型:`Integer` 56 | 57 | 其中,daytime 代表自当天日出后流逝的游戏刻数,gametime 代表世界总共流逝的游戏刻数,day 代表已流逝的游戏天数。 58 | 59 | 60 | 61 | ### 设置服务器游戏时间 62 | 63 | `mc.setTime(tick)` 64 | 65 | - 参数: 66 | - tick : `Integer` 67 | 想要设置的时间 68 | - 返回值:是否设置成功 69 | - 返回值类型:`Boolean` 70 | 71 | 72 | 73 | ### 获取服务器天气 74 | 75 | `mc.getWeather()` 76 | 77 | - 返回值:当前天气 (0 代表晴天,1 代表雨天,2 代表雷暴) 78 | - 返回值类型:`Integer` 79 | 80 | 81 | 82 | ### 设置服务器天气 83 | 84 | `mc.setWeather(WeatherID)` 85 | 86 | - 参数: 87 | - WeatherID : `Integer` 88 | 想要设置的天气 (0 代表晴天,1 代表雨天,2 代表雷暴) 89 | - 返回值:是否设置成功 90 | - 返回值类型:`Boolean` 91 | 92 | 93 | -------------------------------------------------------------------------------- /docs/apis/NbtAPI/NBT.zh.md: -------------------------------------------------------------------------------- 1 | # 脚本引擎 - NBT 文档 2 | 3 | > **NBT(二进制命名标签**,**N**amed **B**inary **T**ags**)** 格式为Minecraft中用于向文件中存储数据的一种存储格式。 4 | > NBT格式以树形结构并配以许多*标签* 的形式存储数据。所有的标签都有一个独立的ID和名称。 5 | > 6 | > --- Minecraft Wiki 7 | 8 | 这里为脚本提供了操作 **NBT** 数据类型的能力。 **NBT** 接口的支持,极大的提高了游戏的可扩展性 9 | 10 | 游戏中,使用被称为 **NBT标签 **的节点来标识一项NBT数据。NBT标签中可以储存普通数据、List、Compound 等多种数据类型。 11 | 12 | 在LegacyScriptEngine中,每种NBT数据类型都有其对应的数据类型,我们统称他们为「NBT对象」。 13 | 脚本引擎类型与NBT数据类型的对照如下: 14 | 15 | | NBT数据类型 | 对应的NBT对象类型 | 类型说明(来自MC Wiki) | 16 | | ----------- | ----------------- | ----------------------------- | 17 | | `Byte` | `NbtByte` | 有符号字节 或 布尔值(8位) | 18 | | `Short` | `NbtShort` | 有符号短整型(16位) | 19 | | `Int` | `NbtInt` | 有符号整形(32位) | 20 | | `Long` | `NbtLong` | 有符号长整型(64位) | 21 | | `Float` | `NbtFloat` | 单精度浮点数 | 22 | | `Double` | `NbtDouble` | 双精度浮点数 | 23 | | `ByteArray` | `NbtByteBuffer` | 字节数组 | 24 | | `String` | `NbtString` | UTF-8 字符串 | 25 | | `List` | `NbtList` | NBT 列表(类似于 数组) | 26 | | `Compound` | `NbtCompound` | NBT 标签(类似于 键值对列表) | 27 | 28 | 每种数据类型可能有略微不同的使用接口。下面对他们作分别介绍 29 | 30 | 31 | 32 | ## 🎈 NBT 对象通用接口 33 | 34 | 每一个 NBT 对象都包含一些可以执行的成员函数(成员方法) 35 | 对于任何种类的NBT对象,都有下面这些通用的接口。以名为`nbt`的某个NBT对象为例: 36 | 37 | #### 获取NBT对象储存的数据类型 38 | 39 | `nbt.getType()` 40 | 41 | - 返回值:此NBT对象储存的数据类型 42 | - 返回值类型:`Enum` 43 | 44 | 可能的返回值有:`NBT.End` `NBT.Byte` `NBT.Short` `NBT.Int` `NBT.Long` 45 | `NBT.Float` `NBT.Double` `NBT.ByteArray` `NBT.String` 46 | `NBT.List` `NBT.Compound` 47 | 48 | 49 | 50 | #### 将NBT对象转换为JSON字符串 51 | 52 | `nbt.toString([space])` 53 | 54 | - 参数 55 | - space : `Integer` 56 | (可选参数)如果要格式化输出的字符串,则传入此参数 57 | 代表每个缩进的空格数量,这样生成的字符串更适合人阅读 58 | 此参数默认为-1,即不对输出字符串进行格式化 59 | - 返回值:对应的JSON字符串 60 | - 返回值类型:`String` 61 | 62 | 提示:如果这个NBT对象储存的是`List`或者`Compound`类型,将递归展开为`Array`或`Object` 63 | 如果这个NBT对象储存的是`ByteArray`类型,输出的字节串将先进行base64编码后再输出 64 | 65 | > 上述函数输出的字符串符合JSON标准格式,但是无法进行反序列化。 66 | > 如果有反序列化的需求,请使用 NBT标签类 提供的的 **SNBT** 接口 67 | 68 | 69 | -------------------------------------------------------------------------------- /docs/apis/NbtAPI/NBTValue.md: -------------------------------------------------------------------------------- 1 | # 📋 NBT - Normal Data Type 2 | 3 | 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. 4 | 5 | ### Get an NBT Normal Data Object 6 | 7 | #### Parse From an Existing NBT Object 8 | 9 | See the [NbtList - List Type](./NBTList.md) and [NbtCompound - Tag Type](./NBTCompound.md) documentation. 10 | 11 | 12 | 13 | #### Create a New NBT Data Object 14 | 15 | [JavaScript] 16 | `new NbtByte([data])` 17 | `new NbtShort([data])` 18 | `new NbtInt([data])` 19 | `new NbtLong([data])` 20 | `new NbtFloat([data])` 21 | `new NbtDouble([data])` 22 | `new NbtByteArray([data])` 23 | `new NbtString([data])` 24 | [Lua] 25 | `NbtByte([data])` 26 | `NbtShort([data])` 27 | `NbtInt([data])` 28 | `NbtLong([data])` 29 | `NbtFloat([data])` 30 | `NbtDouble([data])` 31 | `NbtByteArray([data])` 32 | `NbtString([data])` 33 | 34 | - Parameters: 35 | - data: `Number` / `Float` / `Double` / `ByteBuffer` / `String` (Optional parameter) 36 | 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. 37 | - Return value: The generated NBT object. 38 | - Return value type:`NbtByte` / `NbtShort` / `NbtInt` / `NbtLong` / `NbtFloat` / `NbtDouble` / `NbtByteBuffer` / `NbtString` , depending on the type of the data. 39 | - If the creation fails, an exception will be thrown. 40 | 41 | 42 | 43 | For an NBT object that stores common data types `value`, with the following member functions. 44 | 45 | #### Set Object Data 46 | 47 | `value.set(data)` 48 | 49 | - Parameter: 50 | - data : `Number` / `Float` / `Double` / `ByteBuffer` / `String` 51 | According to the data type of this NBT object, write the data of the corresponding type. 52 | For an `NbtFloat` object, write data with a `Float` type. 53 | - Return value: Whether the write was successful or not. 54 | - Return value type: `Boolean` 55 | 56 | 57 | 58 | #### Read Object Data. 59 | 60 | `value.get()` 61 | 62 | - Return value: The data stored in the object. 63 | - Return value type: ``Number` / `Float` / `Double` / `ByteBuffer` / `String`, depending on the type of the data stored. 64 | 65 | 66 | -------------------------------------------------------------------------------- /docs/apis/NbtAPI/NBTValue.zh.md: -------------------------------------------------------------------------------- 1 | # 📋 NBT - 普通数据类型 2 | 3 | 我们把除了 `NbtList` 和 `NbtCompound` 类型以外的其他NBT对象统称为 **普通数据** 类型。这些对象只储存了简单的数据,内部不含有其他复杂结构。 4 | 5 | ### 获取一个 NBT 普通数据对象 6 | 7 | #### 从现有的NBT对象中解析获取 8 | 9 | 详见 [NbtList - 列表类型](./NBTList.zh.md) 和 [NbtCompound - 标签类型](./NBTCompound.zh.md) 文档 10 | 11 | 12 | 13 | #### 创建新的NBT数据对象 14 | 15 | [JavaScript] 16 | `new NbtByte([data])` 17 | `new NbtShort([data])` 18 | `new NbtInt([data])` 19 | `new NbtLong([data])` 20 | `new NbtFloat([data])` 21 | `new NbtDouble([data])` 22 | `new NbtByteArray([data])` 23 | `new NbtString([data])` 24 | [Lua] 25 | `NbtByte([data])` 26 | `NbtShort([data])` 27 | `NbtInt([data])` 28 | `NbtLong([data])` 29 | `NbtFloat([data])` 30 | `NbtDouble([data])` 31 | `NbtByteArray([data])` 32 | `NbtString([data])` 33 | 34 | - 参数: 35 | - data: `Number` / `Float` / `Double` / `ByteBuffer` / `String`(可选参数) 36 | 根据你要创建的对象类型设置初始数据,传入的数据类型需要能够初始化对应类型的数据 37 | 可以不传入此参数 38 | - 返回值:生成的NBT对象 39 | - 返回值类型:`NbtByte` / `NbtShort` / `NbtInt` / `NbtLong` / `NbtFloat` / `NbtDouble` / `NbtByteBuffer` / `NbtString` ,取决于你选择的数据类型 40 | - 如果创建失败,将抛出异常 41 | 42 | 43 | 44 | 对于一个储存普通数据类型的NBT对象 `value`,有如下成员函数 45 | 46 | #### 设置对象的数据 47 | 48 | `value.set(data)` 49 | 50 | - 参数: 51 | - data : `Number` / `Float` / `Double` / `ByteBuffer` / `String` 52 | 根据这个NBT对象的数据类型,写入对应类型的数据 53 | 如对于一个`Float`类型的 NBT 对象,你需要传入一个`Float`类型的值 54 | - 返回值:是否成功写入 55 | - 返回值类型:`Boolean` 56 | 57 | 58 | 59 | #### 读取对象的数据 60 | 61 | `value.get()` 62 | 63 | - 返回值:对象中储存的数据 64 | - 返回值类型:``Number` / `Float` / `Double` / `ByteBuffer` / `String`,以储存的实际数据类型为准 65 | 66 | 67 | -------------------------------------------------------------------------------- /docs/apis/ScriptAPI/ScriptHelp.zh.md: -------------------------------------------------------------------------------- 1 | # 脚本引擎 - 通用脚本接口文档 2 | 3 | > 这里提供了一些常用的 **辅助功能** ,如插件注册、输出信息和异步接口等 4 | 5 | 他们让你开发脚本变得更加容易而自然,避免了很多无谓的细节问题的纠缠。 6 | 7 | ## 💼 脚本辅助 API 8 | 9 | 下面这些API为脚本增加了必要的辅助接口 10 | 11 | ### 输出信息到控制台 12 | 13 | `log(data1,data2,...)` 14 | 15 | - 参数: 16 | - 待输出的变量或者数据 17 | 可以是任意类型,参数数量可以是任意个 18 | - 返回值:无 19 | 20 | ### 输出带颜色文本 21 | 22 | 这是楼上那位的升级版,没错,它支持彩色输出 23 | 24 | `colorLog(color,data1,data2,...)` 25 | 26 | - 参数: 27 | - color : `String` 28 | 此行输出的颜色(代码示例和效果如下图) 29 | - data... : 30 | 待输出的变量或者数据 31 | 可以是任意类型,参数数量可以是任意个 32 | - 返回值:无 33 | 34 | #### 效果展示: 35 | 36 | ![ColorLogExample](/img/ColorLog.png) 37 | 38 | ### 异步输出 39 | 40 | 此函数将输出请求发出后即刻返回,避免同步读写造成的阻塞时间 41 | 底层有锁保护,不同的`fastLog`之间不会出现串字符现象 42 | 43 | `fastLog(data1,data2,...)` 44 | 45 | - 参数: 46 | - data... : 47 | 待输出的变量或者数据 48 | 可以是任意类型,参数数量可以是任意个 49 | - 返回值:无 50 | 51 | ### 推迟一段时间执行函数 52 | 53 | `setTimeout(func,msec)` 54 | 55 | - 参数: 56 | 57 | - func : `Function` 58 | 待执行的函数 59 | 60 | - msec : `Integer` 61 | 推迟执行的时间(毫秒) 62 | - 返回值:此任务ID 63 | - 返回值类型:`Integer` 64 | - 如果返回`Null`,则代表创建任务失败 65 | 66 | ### 推迟一段时间执行代码段(eval) 67 | 68 | `setTimeout(code,msec)` 69 | 70 | - 参数: 71 | 72 | - code : `String` 73 | 待执行的代码段 74 | 75 | - msec : `Integer` 76 | 推迟执行的时间(毫秒) 77 | - 返回值:此任务ID 78 | - 返回值类型:`Integer` 79 | - 如果返回`Null`,则代表创建任务失败 80 | 81 | ### 设置周期执行函数 82 | 83 | `setInterval(func,msec)` 84 | 85 | - 参数: 86 | - func : `Function` 87 | 待执行的函数 88 | 89 | - msec : `Integer` 90 | 执行间隔周期(毫秒) 91 | - 返回值:此任务ID 92 | - 返回值类型: `Integer` 93 | 94 | ### 设置周期执行代码段(eval) 95 | 96 | `setInterval(code,msec)` 97 | 98 | - 参数: 99 | - code : `String` 100 | 待执行的代码段 101 | 102 | - msec : `Integer` 103 | 执行间隔周期(毫秒) 104 | - 返回值:此任务ID 105 | - 返回值类型: `Integer` 106 | - 如果返回`Null`,则代表创建任务失败 107 | 108 | ### 取消延时 / 周期执行项 109 | 110 | `clearInterval(taskid)` 111 | 112 | - 参数: 113 | - timerid : `Integer` 114 | 由前几个函数返回的任务ID 115 | - 返回值:是否取消成功 116 | - 返回值类型: `Boolean` 117 | - 如果返回`Null`,则代表取消任务失败 118 | 119 | 120 | -------------------------------------------------------------------------------- /docs/apis/SystemAPI/FileSystem.zh.md: -------------------------------------------------------------------------------- 1 | # 📂 目录与文件 API 2 | 3 | 下面这些API提供了操作文件、目录等与文件系统互动的接口 4 | 5 | > 注:所有传入函数的相对路径都以BDS根目录为基准。 6 | 7 | ### 创建文件夹 8 | 9 | `File.createDir(dir)` 10 | `File.mkdir(dir)` 11 | 12 | - 参数: 13 | - dir : `String` 14 | 目标文件夹的路径 15 | 可以直接创建多层,不需要逐层创建 16 | - 返回值:是否成功创建 17 | - 返回值类型:`Boolean` 18 | 19 | 20 | 21 | ### 删除文件 / 文件夹 22 | 23 | `File.delete(path)` 24 | 25 | - 参数: 26 | - path : `String` 27 | 目标文件 / 文件夹的路径 28 | - 返回值:是否成功删除 29 | - 返回值类型:`Boolean` 30 | 31 | 32 | 33 | ### 判断文件 / 文件夹是否存在 34 | 35 | `File.exists(path)` 36 | 37 | - 参数: 38 | - path : `String` 39 | 目标文件 / 文件夹的路径 40 | - 返回值:目标是否存在 41 | - 返回值类型:`Boolean` 42 | 43 | 44 | 45 | ### 复制文件 / 文件夹到指定位置 46 | 47 | `File.copy(from,to)` 48 | 49 | - 参数: 50 | - from : `String` 51 | 源文件 / 文件夹的路径 52 | 53 | - to : `String` 54 | 目标文件 / 文件夹的位置 55 | - 返回值:是否复制成功 56 | - 返回值类型:`Boolean` 57 | 58 | 59 | 60 | ### 移动文件 / 文件夹到指定位置 61 | 62 | `File.move(from,to)` 63 | 64 | - 参数: 65 | - from : `String` 66 | 源文件 / 文件夹的路径 67 | 68 | - to : `String` 69 | 目标文件 / 文件夹的位置 70 | - 返回值:是否复制成功 71 | - 返回值类型:`Boolean` 72 | 73 | 74 | 75 | ### 重命名指定文件 / 文件夹 76 | 77 | `File.rename(from,to)` 78 | 79 | - 参数: 80 | - from : `String` 81 | 文件 / 文件夹的旧名字 82 | 83 | - to : `String` 84 | 新名字 85 | - 返回值:是否复制成功 86 | - 返回值类型:`Boolean` 87 | 88 | 89 | 90 | ### 获取指定文件的大小 91 | 92 | `File.getFileSize(path)` 93 | 94 | - 参数: 95 | - path : `String` 96 | 所操作的文件路径 97 | 98 | - 返回值:文件的大小(字节) 99 | - 返回值类型:`Integer` 100 | 101 | 如果传入的路径位置是一个文件夹,则返回`-1` 102 | 103 | 104 | 105 | ### 判断指定路径是否是文件夹 106 | 107 | `File.checkIsDir(path)` 108 | 109 | - 参数: 110 | - path : `String` 111 | 所判断的路径 112 | - 返回值:目标路径是否是文件夹 113 | - 返回值类型:`Boolean` 114 | 115 | 如果目标路径不存在,同样将返回`false` 116 | 117 | 118 | 119 | ### 列出指定文件夹下的所有文件 / 文件夹 120 | 121 | `File.getFilesList(dir)` 122 | 123 | - 参数: 124 | - dir: `String` 125 | 文件夹路径 126 | 127 | - 返回值:文件名、文件夹名数组 128 | - 返回值类型:`Array` 129 | 130 | 131 | -------------------------------------------------------------------------------- /docs/apis/SystemAPI/SystemCall.md: -------------------------------------------------------------------------------- 1 | # 📡 System Call API 2 | 3 | The following APIs provide interfaces to perform some system calls: 4 | 5 | ### Invoke the Shell to Execute the Specified System Command 6 | 7 | `system.cmd(cmd,callback[,timeLimit])` 8 | 9 | - Parameters: 10 | - cmd : `String` 11 | The executed system command. 12 | - callback : `Function` 13 | The callback function used to return data after the system process ends. 14 | - timeLimit : `Integer` 15 | (Optional parameter) The maximum time for the command to run, in milliseconds. 16 | The default is `-1`, i.e. unlimited runtime 17 | - Return value: Whether the command was successfully started. 18 | - Return value type: `Boolean` 19 | 20 | Note: The prototype of the callback function of the parameter callback: `function(exitcode,output)` 21 | 22 | - exitcode : `Integer` 23 | The process exit code. 24 | - output : `String` 25 | The contents of standard output and standard error. 26 | 27 | Notice! What is executed here is not the command of the MC command system. 28 | 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. 29 | 30 | 31 | 32 | ### Run the Specified Location Program 33 | 34 | `system.newProcess(process,callback[,timeLimit])` 35 | 36 | - Parameters: 37 | - process : `String` 38 | The path of the program to run (with command line arguments). 39 | - callback : `Function` 40 | The callback function used to return data after the program process ends. 41 | - timeLimit : `Integer` 42 | (Optional parameter) The maximum time limit for the program process to run, in milliseconds. 43 | The default is `-1`, i.e. unlimited runtime. 44 | - Return value: Whether the process was successfully started. 45 | - Return value type: `Boolean` 46 | 47 | Note: The prototype of the callback function of the parameter callback: `function(exitcode,output)` 48 | 49 | - exitcode : `Integer` 50 | Process exit code. 51 | - output : `String` 52 | The contents of the program's standard output and standard error output. 53 | 54 | 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. 55 | 56 | 57 | -------------------------------------------------------------------------------- /docs/apis/SystemAPI/SystemCall.zh.md: -------------------------------------------------------------------------------- 1 | # 📡 系统调用 API 2 | 3 | 下面这些API提供了执行一些系统调用的接口 4 | 5 | ### 调用shell执行指定系统命令 6 | 7 | `system.cmd(cmd,callback[,timeLimit])` 8 | 9 | - 参数: 10 | - cmd : `String` 11 | 执行的系统命令 12 | - callback : `Function` 13 | shell进程结束之后返回数据使用的回调函数 14 | - timeLimit : `Integer` 15 | (可选参数)命令运行的最长时限,单位为毫秒 16 | 默认为`-1`,即不限制运行时间 17 | - 返回值:是否成功启动命令 18 | - 返回值类型:`Boolean` 19 | 20 | 注:参数callback的回调函数原型:`function(exitcode,output)` 21 | 22 | - exitcode : `Integer` 23 | shell退出码 24 | - output : `String` 25 | 标准输出和标准错误输出的内容 26 | 27 | 注意!这里执行的不是MC命令系统的命令 28 | 此函数异步工作,不会等待系统执行完命令后再返回,而是由引擎自动调用给出的回调函数来返回结果 29 | 30 | 31 | 32 | ### 运行指定位置程序 33 | 34 | `system.newProcess(process,callback[,timeLimit])` 35 | 36 | - 参数: 37 | - process : `String` 38 | 运行的程序路径(与命令行参数) 39 | - callback : `Function` 40 | 程序进程结束之后返回数据使用的回调函数 41 | - timeLimit : `Integer` 42 | (可选参数)程序进程运行的最长时限,单位为毫秒 43 | 默认为`-1`,即不限制运行时间 44 | - 返回值:是否成功启动进程 45 | - 返回值类型:`Boolean` 46 | 47 | 注:参数callback的回调函数原型:`function(exitcode,output)` 48 | 49 | - exitcode : `Integer` 50 | 程序进程退出码 51 | - output : `String` 52 | 程序标准输出和标准错误输出的内容 53 | 54 | 此函数异步工作,不会等待系统执行完命令后再返回,而是由引擎自动调用给出的回调函数来返回结果 55 | 56 | 57 | -------------------------------------------------------------------------------- /docs/apis/SystemAPI/SystemInfo.md: -------------------------------------------------------------------------------- 1 | # 📜 Get System Information API 2 | 3 | The following APIs provide interfaces to obtain necessary system information: 4 | 5 | ### Get Current Time String 6 | 7 | `system.getTimeStr()` 8 | 9 | - Return value: The current time string, using the local time zone and 24-hour clock. 10 | For example: `2021-04-03 19:15:01` 11 | - Return value type: `String` 12 | 13 | 14 | 15 | ### Get the Current Time Object 16 | 17 | `system.getTimeObj()` 18 | 19 | - Return value: The current time object `Object`) 20 | 21 | - Return value type: `Object` 22 | 23 | - For the returned time object tm, there are the following members: 24 | 25 | | Field | Meaning | Data Type | 26 | | ----- | -------------------------- | --------- | 27 | | tm.Y | Year value (4 digits) | `Integer` | 28 | | tm.M | Month value | `Integer` | 29 | | tm.D | Day value | `Integer` | 30 | | tm.h | Hour value (24-hour clock) | `Integer` | 31 | | tm.m | Minute value | `Integer` | 32 | | tm.s | Seconds value | `Integer` | 33 | | tm.ms | Millisecond value | `Integer` | 34 | 35 | 36 | 37 | ### Randomly Generate a Guid String 38 | 39 | `system.randomGuid()` 40 | 41 | - Return value: A randomly generated unique identifier GUID. 42 | - Return value type: `String` 43 | 44 | 45 | -------------------------------------------------------------------------------- /docs/apis/SystemAPI/SystemInfo.zh.md: -------------------------------------------------------------------------------- 1 | # 📜 获取系统信息 API 2 | 3 | 下面这些API提供了获取必要的系统信息的接口 4 | 5 | ### 获取当前时间字符串 6 | 7 | `system.getTimeStr()` 8 | 9 | - 返回值:当前的时间字符串,使用当地时区和24小时制。 10 | 形如`2021-04-03 19:15:01` 11 | - 返回值类型:`String` 12 | 13 | 14 | 15 | ### 获取当前的时间对象 16 | 17 | `system.getTimeObj()` 18 | 19 | - 返回值:当前的时间对象(`Object`) 20 | 21 | - 返回值类型: `Object` 22 | 23 | - 对于返回的某个时间对象 tm,有如下这些成员: 24 | 25 | | 成员 | 含义 | 类型 | 26 | | ----- | -------------------- | --------- | 27 | | tm.Y | 年份数值(4位) | `Integer` | 28 | | tm.M | 月份数值 | `Integer` | 29 | | tm.D | 天数数值 | `Integer` | 30 | | tm.h | 小时数值(24小时制) | `Integer` | 31 | | tm.m | 分钟数值 | `Integer` | 32 | | tm.s | 秒数值 | `Integer` | 33 | | tm.ms | 毫秒数值 | `Integer` | 34 | 35 | 36 | 37 | ### 随机生成一个 GUID 字符串 38 | 39 | `system.randomGuid()` 40 | 41 | - 返回值:一个随机生成的唯一标识符GUID 42 | - 返回值类型: `String` 43 | 44 | 45 | -------------------------------------------------------------------------------- /docs/faq.md: -------------------------------------------------------------------------------- 1 | # FAQ 2 | 3 | ## What is the purpose of this project? 4 | 5 | The purpose of this project is to run LLSE plugins on LeviLamina. 6 | 7 | ## Does this project support all LLSE plugins? 8 | 9 | Almost all LLSE plugins are supported, but some plugins may not work properly due to the differences in event triggering timing and other reasons. 10 | 11 | ## How long will this project be maintained? 12 | 13 | This project will be maintained as long as we maintainers have the ability and time to maintain it. 14 | -------------------------------------------------------------------------------- /docs/faq.zh.md: -------------------------------------------------------------------------------- 1 | # 常见问题 2 | 3 | ## 这个项目的目的是什么? 4 | 5 | 该项目的目的是在 LeviLamina 上运行 LLSE 插件。 6 | 7 | ## 这个项目支持所有 LLSE 插件吗? 8 | 9 | 几乎支持所有LLSE插件,但由于事件触发时机的差异等原因,部分插件可能无法正常工作。 10 | 11 | ## 这个项目会维持多久? 12 | 13 | 只要我们维护者有能力、有时间维护这个项目就会一直维护下去。 14 | -------------------------------------------------------------------------------- /docs/img/ColorLog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiteLDev/LegacyScriptEngine/099037869381a6b3cf8bff3197637cb3f9ad7824/docs/img/ColorLog.png -------------------------------------------------------------------------------- /docs/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiteLDev/LegacyScriptEngine/099037869381a6b3cf8bff3197637cb3f9ad7824/docs/img/logo.png -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # LegacyScriptEngine 2 | 3 | English | [简体中文](README.zh.md) 4 | A plugin engine for running LLSE plugins on LeviLamina 5 | 6 | ## Installation 7 | 8 | ### Attention 9 | 10 | Before installing the Python engine, you need to 11 | install [Python 3.12.8](https://www.python.org/downloads/release/python-3128/) first. 12 | To install a specific engine, you can use the following command: 13 | ```shell 14 | lip install github.com/LiteLDev/LegacyScriptEngine#lua 15 | lip install github.com/LiteLDev/LegacyScriptEngine#quickjs 16 | lip install github.com/LiteLDev/LegacyScriptEngine#nodejs 17 | lip install github.com/LiteLDev/LegacyScriptEngine#python 18 | ``` 19 | For version older than 0.10.0, you can use the following command: 20 | ```shell 21 | lip install gitea.litebds.com/LiteLDev/legacy-script-engine-lua@version 22 | lip install gitea.litebds.com/LiteLDev/legacy-script-engine-quickjs@version 23 | lip install gitea.litebds.com/LiteLDev/legacy-script-engine-nodejs@version 24 | lip install gitea.litebds.com/LiteLDev/legacy-script-engine-python@version 25 | ``` 26 | Version numbers can be found in [releases](https://github.com/LiteLDev/LegacyScriptEngine/releases). 27 | 28 | ## Usage 29 | 30 | To access plugin development API hints and scaffolding toolkits, visit the [LegacyScriptEngine_API](https://github.com/LiteLDev/LegacyScriptEngine_API) repository. 31 | 32 | 1. Put LLSE plugins directly in `plugins/` 33 | 2. Run the server, then the plugins will be migrated to LeviLamina plugin manifest automatically 34 | 3. To load them, you need to restart the server 35 | 36 | ## Contributing 37 | 38 | If you have any questions, please open an issue to discuss it 39 | Help us improve translation [here](https://crowdin.com/project/legacyscriptengine) 40 | PRs are welcome 41 | 42 | ## License 43 | 44 | GPL-3.0-or-later © LiteLDev 45 | -------------------------------------------------------------------------------- /docs/index.zh.md: -------------------------------------------------------------------------------- 1 | # LegacyScriptEngine 2 | 3 | [English](README.md) | 简体中文 4 | 一个用于在 LeviLamina 上运行 LLSE 插件的插件引擎 5 | 6 | ## 安装 7 | 8 | ### 注意 9 | 10 | 在安装Python引擎之前,你需要先安装[Python 3.12.8](https://www.python.org/downloads/release/python-3128/) 11 | 要安装特定的引擎,您可以使用以下命令: 12 | ```shell 13 | lip install github.com/LiteLDev/LegacyScriptEngine#lua 14 | lip install github.com/LiteLDev/LegacyScriptEngine#quickjs 15 | lip install github.com/LiteLDev/LegacyScriptEngine#nodejs 16 | lip install github.com/LiteLDev/LegacyScriptEngine#python 17 | ``` 18 | 对于0.10.0之前的版本,可以使用以下命令: 19 | ```shell 20 | lip install gitea.litebds.com/LiteLDev/legacy-script-engine-lua@版本 21 | lip install gitea.litebds.com/LiteLDev/legacy-script-engine-quickjs@版本 22 | lip install gitea.litebds.com/LiteLDev/legacy-script-engine-nodejs@版本 23 | lip install gitea.litebds.com/LiteLDev/legacy-script-engine-python@版本 24 | ``` 25 | 可以在[releases](https://github.com/LiteLDev/LegacyScriptEngine/releases)中找到版本号。 26 | 27 | ## 使用 28 | 29 | 如需获取插件开发 API 提示库和脚手架工具,请访问 [LegacyScriptEngine_API](https://github.com/LiteLDev/LegacyScriptEngine_API) 仓库 30 | 31 | 1. 直接将 LLSE 插件放在 `plugins/` 中 32 | 2. 运行服务器,然后插件将自动迁移到 LeviLamina 插件清单中 33 | 3. 重启服务器后,插件就会被加载 34 | 35 | ## 贡献 36 | 37 | 如果您有任何问题,请开启一个 issue 来讨论 38 | [在这里](https://crowdin.com/project/legacyscriptengine)帮助我们完善翻译 39 | 欢迎 PR 40 | 41 | ## 许可 42 | 43 | GPL-3.0-only © LiteLDev 44 | -------------------------------------------------------------------------------- /docs/tutorials/create_your_first_plugin.zh.md: -------------------------------------------------------------------------------- 1 | # 创造你的首个脚本插件 2 | 3 | > 4 | 本指南旨在展示创建你的第一个插件的非常简单和直接的过程--以及在考虑做什么和如何做时的一些最佳做法。建议有使用JavaScript的经验,但不是必须的。JavaScript是一种对初学者非常友好的语言,所以不要被淹没了! 5 | 6 | ## 先决条件 7 | 8 | 在开发你的第一个插件之前,我们需要设置你的开发环境。你用来编程的软件由你自己选择,但建议使用可信和可靠的软件。 9 | 10 | - [Atom](https://atom.io/) 是轻量级的编辑器,在本教程中很好用。 11 | - [VSCode](https://code.visualstudio.com/) 也是一个广泛使用的编辑器,具有很多强大的功能。 12 | 13 | 你还需要建立一个干净的LeviLamina安装,关于如何安装LeviLamina的细节可以在[这里](https://lamina.levimc.org/zh/install/) 14 | 找到。这个服务器将被用来测试你的插件。 15 | 16 | 有了你的开发环境,并完成了服务器的安装,你就可以开始了! 17 | 18 | ## 我现在该做什么? 19 | 20 | 开发一个脚本插件,首先要创建你的插件文件。这个文件应该命名为 "LLMyPlugin.js",将 "MyPlugin" 21 | 替换为你想要的插件名称。它应该被放在你的服务器安装的插件文件夹中。有些开发环境会允许你创建一个新文件并选择一个位置,而其他开发环境则允许你在点击 " 22 | 另存为" 后才选择。 23 | 24 | 这可能会使一些开发者感到困惑,因为`ll`应该是未定义的。然而,这个文件将被LeviLamina ScriptX引擎所利用。`ll` 25 | 将在脚本运行时自动包含。这与你看到的任何其他没有定义的变量/类的引用是一样的。 26 | 27 | 现在我们已经创建了我们的.js文件,并注册了插件,我们要做的就是创建一个事件监听器。我们通过使用`mc`来实现。 28 | 29 | ```js 30 | mc.listen("onJoin", (player) => log(`${player.name}已经加入服务器。`)); 31 | ``` 32 | 33 | > 参考资料: [事件监听文档](../apis/EventAPI/Listen.zh.md) 34 | 35 | 为了测试你的插件,只需启动服务器,服务器应该能够识别你的插件并成功加载它。LeviLamina控制台将记录您创建的任何日志,以及您的插件或API失败时的任何错误。开发时的迭代很重要。经常测试,每一步都要确保当问题出现时,你清楚地知道你改变了什么,并能想出解决方案来解决它。 36 | 37 | 你可以引用`mc`类,以及其他特殊的类和构造函数。`mc`类是你的插件的面包和黄油,将允许你做很多很酷的事情。游戏内容接口有所有的方法和属性供你使用。 38 | > 参考:[游戏元素接口文档](../apis/GameAPI/Basic.zh.md) 39 | 40 | 例如,我们可以使用玩家对象并直接对其采取行动,以发送信息/操纵玩家。 41 | 42 | ```js 43 | mc.listen("onJoin", (player) => { 44 | log(`${player.name}已经加入服务器。`)。 45 | player.sendToast('欢迎!', '感谢您游玩本服!'); 46 | }); 47 | ``` 48 | 49 | 我们可以引用玩家对象的属性,并使用它来执行其他动作。 50 | 51 | ```js 52 | mc.listen("onJoin", (player) => { 53 | log(`${player.name}已经加入服务器。`)。 54 | player.sendToast('欢迎!', '感谢您游玩本服!'); 55 | let loginReward = mc.newItem('minecraft:diamond', 1); 56 | mc.spawnItem(loginReward, player.pos)。 57 | }); 58 | ``` 59 | 60 | 这给我们带来了最后的考虑。在制作插件时,尽量想一些简单的、自我封闭的东西。每个开发者都想建立一个具有大量功能的大型插件,但这样的项目很容易被放弃,因为它们从未真正完成。做一系列有特定目的的小插件。为这些插件添加功能,以实现配置和定制。找到你希望游戏拥有的功能或事物,并使用LeviLamina中的方法来实现它们。使用LeviLamina的API确实有无限可能。 61 | 62 | 如果您在开发过程中遇到任何问题,可以通过加入[LeviLamina](https://github.com/LiteLDev/LeviLamina) 63 | 的相关交流群、在LegacyScriptEngine的Github仓库上开立一个问题,来回答您的问题、意见或担忧。 64 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "${modName}", 3 | "entry": "${modFile}", 4 | "version": "${modVersion}", 5 | "type": "native", 6 | "description": "A plugin engine for running LLSE plugins on LeviLamina", 7 | "author": "LiteLDev", 8 | "dependencies": [ 9 | { 10 | "name": "LegacyMoney" 11 | }, 12 | { 13 | "name": "LegacyParticleAPI" 14 | }, 15 | { 16 | "name": "LegacyRemoteCall" 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Babel==2.12.1 2 | certifi==2023.7.22 3 | charset-normalizer==3.2.0 4 | click==8.1.7 5 | colorama==0.4.6 6 | ghp-import==2.1.0 7 | idna==3.4 8 | Jinja2==3.1.2 9 | Markdown==3.4.4 10 | MarkupSafe==2.1.3 11 | mergedeep==1.3.4 12 | mkdocs==1.5.2 13 | mkdocs-material==9.3.1 14 | mkdocs-material-extensions==1.1.1 15 | mkdocs-static-i18n==1.0.3 16 | packaging==23.1 17 | paginate==0.5.6 18 | pathspec==0.11.2 19 | platformdirs==3.10.0 20 | Pygments==2.16.1 21 | pymdown-extensions==10.3 22 | python-dateutil==2.8.2 23 | PyYAML==6.0.1 24 | pyyaml_env_tag==0.1 25 | regex==2023.8.8 26 | requests==2.31.0 27 | six==1.16.0 28 | urllib3==2.0.4 29 | watchdog==3.0.0 30 | -------------------------------------------------------------------------------- /scripts/download_crowdin_files.py: -------------------------------------------------------------------------------- 1 | import os 2 | from shutil import copy 3 | import sys 4 | from crowdin_api import CrowdinClient 5 | import requests 6 | from zipfile import ZipFile 7 | 8 | PROJECT_ID = "648706" 9 | OUTPUT_DIR = "./src/lang/" 10 | 11 | 12 | class Client(CrowdinClient): 13 | TOKEN = sys.argv[1] 14 | 15 | 16 | def request(url): 17 | resp = requests.get(url) 18 | if resp.status_code == 200: 19 | return resp.content 20 | else: 21 | print("ERROR: " + str(resp.status_code) + " " + resp.reason) 22 | return None 23 | 24 | 25 | os.makedirs(OUTPUT_DIR, exist_ok=True) 26 | client = Client() 27 | # download source file 28 | files = client.source_files.list_files(PROJECT_ID) 29 | file_id = files["data"][0]["data"]["id"] 30 | download_info = client.source_files.download_file(file_id, PROJECT_ID) 31 | url = download_info["data"]["url"] 32 | with open(OUTPUT_DIR + "en.json", "wb") as file: 33 | file.write(request(url)) 34 | print("Download source finished.") 35 | 36 | build = client.translations.build_project_translation({}, PROJECT_ID)["data"] 37 | status = "" 38 | while status != "finished": 39 | info = client.translations.check_project_build_status(build["id"], PROJECT_ID) 40 | status = info["data"]["status"] 41 | if status != "finished": 42 | print("Build progress: {}%".format(info["data"]["progress"])) 43 | download_info = client.translations.download_project_translations( 44 | build["id"], PROJECT_ID 45 | ) 46 | url = download_info["data"]["url"] 47 | with open("temp.zip", "wb") as file: 48 | file.write(request(url)) 49 | print("Zip file downloaded!") 50 | 51 | zip = ZipFile("temp.zip") 52 | os.makedirs("./temp", exist_ok=True) 53 | zip.extractall("./temp") 54 | for f in os.listdir("./temp"): 55 | if os.path.isdir("./temp/" + f): 56 | f1 = f 57 | if f.find("-") != -1: 58 | f1 = f.replace("-", "_") 59 | copy("./temp/" + f + "/locale.json", OUTPUT_DIR + f1 + ".json") 60 | if os.path.exists("./temp/" + f + "/cpp-docs-locale.txt"): 61 | os.remove("./temp/" + f + "/cpp-docs-locale.txt") 62 | 63 | os.remove("./temp/" + f + "/locale.json") 64 | os.removedirs("./temp/" + f) 65 | 66 | zip.close() 67 | os.remove("temp.zip") 68 | print("Finished!") 69 | -------------------------------------------------------------------------------- /scripts/validate_release.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import re 3 | import subprocess 4 | from typing import TypedDict 5 | 6 | 7 | class Args(TypedDict): 8 | tag: str 9 | 10 | 11 | def main(): 12 | args = get_args() 13 | 14 | version = args["tag"].lstrip("v") 15 | 16 | validate_changelog(version) 17 | validate_tooth_json(version) 18 | 19 | 20 | def get_args() -> Args: 21 | parser = argparse.ArgumentParser() 22 | parser.add_argument("--tag", required=True) 23 | 24 | args = parser.parse_args() 25 | 26 | return { 27 | "tag": args.tag, 28 | } 29 | 30 | 31 | def validate_changelog(version: str): 32 | try: 33 | subprocess.run( 34 | f"npx changelog --format markdownlint", 35 | shell=True, 36 | check=True, 37 | ) 38 | except subprocess.CalledProcessError as e: 39 | print("Have you installed it by `npm i -g keep-a-changelog`?") 40 | raise e 41 | 42 | with open("CHANGELOG.md", "r", encoding="utf-8") as f: 43 | content = f.read() 44 | 45 | if not re.search(r"## \[{}\]".format(version), content): 46 | raise Exception("CHANGELOG.md lacks version {}".format(version)) 47 | 48 | 49 | def validate_tooth_json(version: str): 50 | with open("tooth.json", "r", encoding="utf-8") as f: 51 | content = f.read() 52 | 53 | if not re.search(r"\"version\": \"{}\"".format(version), content): 54 | raise Exception("tooth.json has wrong version") 55 | 56 | 57 | if __name__ == "__main__": 58 | main() 59 | -------------------------------------------------------------------------------- /src/baselib/BaseLib.lua: -------------------------------------------------------------------------------- 1 | -- --------------------- 2 | -- For require 3 | -- --------------------- 4 | package.path = ll.pluginsRoot:match("^(.-)/?$") .. "/lib/?.lua;" .. package.path 5 | 6 | 7 | -- --------------------- 8 | -- For Compatibility 9 | -- --------------------- 10 | file = File 11 | lxl = ll; 12 | -- DirectionAngle.valueOf = DirectionAngle.toFacing 13 | LXL_Block = LLSE_Block 14 | LXL_BlockEntity = LLSE_BlockEntity 15 | LXL_Container = LLSE_Container 16 | LXL_Device = LLSE_Device 17 | LXL_Entity = LLSE_Entity 18 | LXL_SimpleForm = LLSE_SimpleForm 19 | LXL_CustomForm = LLSE_CustomForm 20 | LXL_Item = LLSE_Item 21 | LXL_Player = LLSE_Player 22 | LXL_Objective = LLSE_Objective 23 | ll.export = ll.exports 24 | ll.import = ll.imports 25 | -------------------------------------------------------------------------------- /src/baselib/BaseLib.py: -------------------------------------------------------------------------------- 1 | def _llse_python_base_lib_handle(event): 2 | def wrapper(func): 3 | __builtins__.mc.listen(event, func) 4 | return func 5 | 6 | return wrapper 7 | 8 | 9 | def _llse_python_base_lib_command_handle(self, func=None): 10 | def wrapper(func): 11 | self.setCallback(func) 12 | return func 13 | 14 | if func: 15 | return wrapper(func) 16 | return wrapper 17 | 18 | 19 | setattr(__builtins__, "handle", _llse_python_base_lib_handle) 20 | setattr(__builtins__.LLSE_Command, "handle", _llse_python_base_lib_command_handle) 21 | -------------------------------------------------------------------------------- /src/lang/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "Failed to enable: {0}": "Fehler beim Aktivieren: {0}", 3 | "Failed to load: {0}": "Fehler beim Laden: {0}", 4 | "Cannot save default configurations to {0}": "Standardkonfigurationen können nicht in {0} gespeichert werden", 5 | "Failed to read BaseLib at {0}": "Fehler beim Lesen von BaseLib auf {0}", 6 | "Failed to register plugin manager": "Fehler beim Registrieren des Plugin-Managers", 7 | "Failed to load plugin code": "Fehler beim Laden des Plugin-Codes", 8 | "Failed to read plugin entry at {0}": "Fehler beim Lesen des Plugin-Eintrags auf {0}", 9 | "Failed to load plugin {0}: {1}\\n{2}": "Fehler beim Laden des Plugins {0}: {1}\\n{2}", 10 | "Failed to unload plugin {0}: {1}": "Entladen des Plugins {0}fehlgeschlagen: {1}", 11 | "Migrating legacy plugin at {0}": "Altes Plugin auf {0} migrieren", 12 | "Failed to migrate legacy plugin at {0}: {1} already exists": "Fehler beim Migrieren des älteren Plugins auf {0}: {1} existiert bereits", 13 | "Failed to create directory {0}": "Verzeichnis {0} konnte nicht erstellt werden", 14 | "Migrating legacy plugins": { 15 | "": { 16 | "": { 17 | "": "Alte Plugins werden migriert..." 18 | } 19 | } 20 | }, 21 | "Legacy plugins have been migrated, please restart the server to load them!": "Alte Plugins wurden migriert, bitte starte den Server neu, um sie zu laden!", 22 | "Overworld": "Overworld", 23 | "Nether": "Nederland", 24 | "End": "Ende", 25 | "Other dimension": "Sonstige Dimension", 26 | "JSON parse error": "JSON-Parse-Fehler", 27 | "Npm finished successfully": { 28 | "": "Npm erfolgreich abgeschlossen." 29 | }, 30 | "Executing \"npm install\" for plugin {name}": { 31 | "": { 32 | "": { 33 | "": "Führe \"npm install\" für Plugin {name} aus ..." 34 | } 35 | } 36 | }, 37 | "Error occurred": { 38 | " Exit code: {code}": "Fehler aufgetreten. Exit-Code: {code}" 39 | }, 40 | "Executing \"pip install\" for plugin {name}": { 41 | "": { 42 | "": { 43 | "": "Führe \"pip install\" für Plugin {name} aus ..." 44 | } 45 | } 46 | }, 47 | "Pip finished successfully": { 48 | "": "Pip erfolgreich abgeschlossen." 49 | }, 50 | "Runtime command {} already exists, changes will not beapplied except for setOverload!": "Laufzeitbefehl {} existiert bereits, Änderungen werden außer setOverload nicht angewendet!", 51 | "Failed to initialize file mapping": "Fehler beim Initialisieren der Dateizuordnung", 52 | "Failed to initialize map file": "Fehler beim Initialisieren der Kartendatei", 53 | "Command {} failed to execute, is the plugin unloaded?": "Befehl {} konnte nicht ausgeführt werden, wird das Plugin entladen?", 54 | "Could not find {} in registered commands": { 55 | "": "Konnte {} in registrierten Befehlen nicht finden." 56 | }, 57 | "Event {} not found!": "Event {} nicht gefunden!" 58 | } 59 | -------------------------------------------------------------------------------- /src/lang/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "Failed to enable: {0}": "Failed to enable: {0}", 3 | "Failed to load: {0}": "Failed to load: {0}", 4 | "Cannot save default configurations to {0}": "Cannot save default configurations to {0}", 5 | "Failed to read BaseLib at {0}": "Failed to read BaseLib at {0}", 6 | "Failed to register plugin manager": "Failed to register plugin manager", 7 | "Failed to load plugin code": "Failed to load plugin code", 8 | "Failed to read plugin entry at {0}": "Failed to read plugin entry at {0}", 9 | "Failed to load plugin {0}: {1}\\n{2}": "Failed to load plugin {0}: {1}\\n{2}", 10 | "Failed to unload plugin {0}: {1}": "Failed to unload plugin {0}: {1}", 11 | "Migrating legacy plugin at {0}": "Migrating legacy plugin at {0}", 12 | "Failed to migrate legacy plugin at {0}: {1} already exists": "Failed to migrate legacy plugin at {0}: {1} already exists", 13 | "Failed to create directory {0}": "Failed to create directory {0}", 14 | "Migrating legacy plugins": { 15 | "": { 16 | "": { 17 | "": "Migrating legacy plugins..." 18 | } 19 | } 20 | }, 21 | "Legacy plugins have been migrated, please restart the server to load them!": "Legacy plugins have been migrated, please restart the server to load them!", 22 | "Overworld": "Overworld", 23 | "Nether": "Nether", 24 | "End": "End", 25 | "Other dimension": "Other dimension", 26 | "JSON parse error": "JSON parse error", 27 | "Npm finished successfully": { 28 | "": "Npm finished successfully." 29 | }, 30 | "Executing \"npm install\" for plugin {name}": { 31 | "": { 32 | "": { 33 | "": "Executing \"npm install\" for plugin {name}..." 34 | } 35 | } 36 | }, 37 | "Error occurred": { 38 | " Exit code: {code}": "Error occurred. Exit code: {code}" 39 | }, 40 | "Executing \"pip install\" for plugin {name}": { 41 | "": { 42 | "": { 43 | "": "Executing \"pip install\" for plugin {name}..." 44 | } 45 | } 46 | }, 47 | "Pip finished successfully": { 48 | "": "Pip finished successfully." 49 | }, 50 | "Runtime command {} already exists, changes will not beapplied except for setOverload!": "Runtime command {} already exists, changes will not beapplied except for setOverload!", 51 | "Failed to initialize file mapping": "Failed to initialize file mapping", 52 | "Failed to initialize map file": "Failed to initialize map file", 53 | "Command {} failed to execute, is the plugin unloaded?": "Command {} failed to execute, is the plugin unloaded?", 54 | "Could not find {} in registered commands": { 55 | "": "Could not find {} in registered commands." 56 | }, 57 | "Event {} not found!": "Event {} not found!" 58 | } 59 | -------------------------------------------------------------------------------- /src/lang/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Failed to enable: {0}": "Échec de l'activation : {0}", 3 | "Failed to load: {0}": "Impossible de charger : {0}", 4 | "Cannot save default configurations to {0}": "Impossible d'enregistrer les configurations par défaut dans {0}", 5 | "Failed to read BaseLib at {0}": "Impossible de lire la BaseLib à {0}", 6 | "Failed to register plugin manager": "Impossible d'enregistrer le gestionnaire de plugin", 7 | "Failed to load plugin code": "Impossible de charger le code du plugin", 8 | "Failed to read plugin entry at {0}": "Impossible de lire l'entrée du plugin à {0}", 9 | "Failed to load plugin {0}: {1}\\n{2}": "Impossible de charger le plugin {0}: {1}\\n{2}", 10 | "Failed to unload plugin {0}: {1}": "Impossible de décharger le plugin {0}: {1}", 11 | "Migrating legacy plugin at {0}": "Migration du plugin existant à {0}", 12 | "Failed to migrate legacy plugin at {0}: {1} already exists": "Impossible de migrer le plugin existant à {0}: {1} existe déjà", 13 | "Failed to create directory {0}": "Impossible de créer le répertoire {0}", 14 | "Migrating legacy plugins": { 15 | "": { 16 | "": { 17 | "": "Migration des plugins existants..." 18 | } 19 | } 20 | }, 21 | "Legacy plugins have been migrated, please restart the server to load them!": "Les plugins hérités ont été migrés, veuillez redémarrer le serveur pour les charger !", 22 | "Overworld": "Surface", 23 | "Nether": "Le Nether", 24 | "End": "L'Ender", 25 | "Other dimension": "Autre dimension", 26 | "JSON parse error": "Erreur JSON parse", 27 | "Npm finished successfully": { 28 | "": "NPM fini avec succès." 29 | }, 30 | "Executing \"npm install\" for plugin {name}": { 31 | "": { 32 | "": { 33 | "": "Exécution de \"npm install\" pour le plugin {name}..." 34 | } 35 | } 36 | }, 37 | "Error occurred": { 38 | " Exit code: {code}": "Une erreur est survenue. Code de sortie : {code}" 39 | }, 40 | "Executing \"pip install\" for plugin {name}": { 41 | "": { 42 | "": { 43 | "": "Exécution de \"pip install\" pour le plugin {name}..." 44 | } 45 | } 46 | }, 47 | "Pip finished successfully": { 48 | "": "Pip terminé avec succès." 49 | }, 50 | "Runtime command {} already exists, changes will not beapplied except for setOverload!": "La commande d'exécution {} existe déjà, les modifications ne seront pas appliquées sauf pour setOverload !", 51 | "Failed to initialize file mapping": "Impossible d'initialiser le mappage du fichier", 52 | "Failed to initialize map file": "Impossible d'initialiser le fichier de carte", 53 | "Command {} failed to execute, is the plugin unloaded?": "La commande {} n'a pas réussi à s'exécuter, le plugin est-il déchargé ?", 54 | "Could not find {} in registered commands": { 55 | "": "Impossible de trouver {} dans les commandes enregistrées." 56 | }, 57 | "Event {} not found!": "Événement {} introuvable !" 58 | } 59 | -------------------------------------------------------------------------------- /src/lang/id.json: -------------------------------------------------------------------------------- 1 | { 2 | "Failed to enable: {0}": "Failed to enable: {0}", 3 | "Failed to load: {0}": "Failed to load: {0}", 4 | "Cannot save default configurations to {0}": "Cannot save default configurations to {0}", 5 | "Failed to read BaseLib at {0}": "Failed to read BaseLib at {0}", 6 | "Failed to register plugin manager": "Failed to register plugin manager", 7 | "Failed to load plugin code": "Failed to load plugin code", 8 | "Failed to read plugin entry at {0}": "Failed to read plugin entry at {0}", 9 | "Failed to load plugin {0}: {1}\\n{2}": "Failed to load plugin {0}: {1}\\n{2}", 10 | "Failed to unload plugin {0}: {1}": "Failed to unload plugin {0}: {1}", 11 | "Migrating legacy plugin at {0}": "Migrating legacy plugin at {0}", 12 | "Failed to migrate legacy plugin at {0}: {1} already exists": "Failed to migrate legacy plugin at {0}: {1} already exists", 13 | "Failed to create directory {0}": "Failed to create directory {0}", 14 | "Migrating legacy plugins": { 15 | "": { 16 | "": { 17 | "": "Migrating legacy plugins..." 18 | } 19 | } 20 | }, 21 | "Legacy plugins have been migrated, please restart the server to load them!": "Legacy plugins have been migrated, please restart the server to load them!", 22 | "Overworld": "Dunia Awal", 23 | "Nether": "Dunia Neraka", 24 | "End": "Dunia Akhir", 25 | "Other dimension": "Dimensi Lain", 26 | "JSON parse error": "Kesalahan Parsing API", 27 | "Npm finished successfully": { 28 | "": "Npm selesai dengan sukses." 29 | }, 30 | "Executing \"npm install\" for plugin {name}": { 31 | "": { 32 | "": { 33 | "": "Menjalankan \"npm install\" untuk plugin {name}..." 34 | } 35 | } 36 | }, 37 | "Error occurred": { 38 | " Exit code: {code}": "Sepertinya ada kesalahan. Kode Exit: {code}" 39 | }, 40 | "Executing \"pip install\" for plugin {name}": { 41 | "": { 42 | "": { 43 | "": "Menjalankan perintah \"pip install\" untuk plugin {name}..." 44 | } 45 | } 46 | }, 47 | "Pip finished successfully": { 48 | "": "Pip selesai secara sukses." 49 | }, 50 | "Runtime command {} already exists, changes will not beapplied except for setOverload!": "Runtime command {} already exists, changes will not beapplied except for setOverload!", 51 | "Failed to initialize file mapping": "Failed to initialize file mapping", 52 | "Failed to initialize map file": "Failed to initialize map file", 53 | "Command {} failed to execute, is the plugin unloaded?": "Command {} failed to execute, is the plugin unloaded?", 54 | "Could not find {} in registered commands": { 55 | "": "Could not find {} in registered commands." 56 | }, 57 | "Event {} not found!": "Event {} not found!" 58 | } 59 | -------------------------------------------------------------------------------- /src/lang/it.json: -------------------------------------------------------------------------------- 1 | { 2 | "Failed to enable: {0}": "Attivazione non riuscita: {0}", 3 | "Failed to load: {0}": "Caricamento non riuscito: {0}", 4 | "Cannot save default configurations to {0}": "Impossibile salvare le configurazioni predefinite in {0}", 5 | "Failed to read BaseLib at {0}": "Lettura di BaseLib su {0} non riuscita", 6 | "Failed to register plugin manager": "Registrazione del gestore plugin non riuscita", 7 | "Failed to load plugin code": "Impossibile caricare il codice del plugin", 8 | "Failed to read plugin entry at {0}": "Lettura della voce del plugin in {0} non riuscita", 9 | "Failed to load plugin {0}: {1}\\n{2}": "Caricamento del plugin {0}non riuscito: {1}\\n{2}", 10 | "Failed to unload plugin {0}: {1}": "Scaricamento del plugin {0}non riuscito: {1}", 11 | "Migrating legacy plugin at {0}": "Migrazione plugin legacy in {0}", 12 | "Failed to migrate legacy plugin at {0}: {1} already exists": "Migrazione del plugin legacy in {0}non riuscita: {1} esiste già", 13 | "Failed to create directory {0}": "Creazione della directory {0} non riuscita", 14 | "Migrating legacy plugins": { 15 | "": { 16 | "": { 17 | "": "Migrazione plugin legacy..." 18 | } 19 | } 20 | }, 21 | "Legacy plugins have been migrated, please restart the server to load them!": "I plugin legacy sono stati migrati, si prega di riavviare il server per caricarli!", 22 | "Overworld": "Overworld", 23 | "Nether": "Nether", 24 | "End": "Fine", 25 | "Other dimension": "Dimensione sconosciuta", 26 | "JSON parse error": "Errore di analisi JSON", 27 | "Npm finished successfully": { 28 | "": "Esecuzione di \"npm install\" completata con successo." 29 | }, 30 | "Executing \"npm install\" for plugin {name}": { 31 | "": { 32 | "": { 33 | "": "Esecuzione di \"npm install\" per il plugin {name}..." 34 | } 35 | } 36 | }, 37 | "Error occurred": { 38 | " Exit code: {code}": "Si è verificato un errore. Codice di uscita: {code}" 39 | }, 40 | "Executing \"pip install\" for plugin {name}": { 41 | "": { 42 | "": { 43 | "": "Esecuzione di \"pip install\" per il plugin {name}..." 44 | } 45 | } 46 | }, 47 | "Pip finished successfully": { 48 | "": "Pip finito con successo." 49 | }, 50 | "Runtime command {} already exists, changes will not beapplied except for setOverload!": "Il comando Runtime {} esiste già, le modifiche non saranno applicate tranne per setOverload!", 51 | "Failed to initialize file mapping": "Impossibile inizializzare la mappatura dei file", 52 | "Failed to initialize map file": "Impossibile inizializzare il file mappa", 53 | "Command {} failed to execute, is the plugin unloaded?": "L'esecuzione del comando {} non è riuscita, il plugin è stato scaricato?", 54 | "Could not find {} in registered commands": { 55 | "": "Impossibile trovare {} nei comandi registrati." 56 | }, 57 | "Event {} not found!": "Evento {} non trovato!" 58 | } 59 | -------------------------------------------------------------------------------- /src/lang/ja.json: -------------------------------------------------------------------------------- 1 | { 2 | "Failed to enable: {0}": "有効化に失敗しました: {0}", 3 | "Failed to load: {0}": "読み込みに失敗しました: {0}", 4 | "Cannot save default configurations to {0}": "デフォルト設定を {0}に保存できません", 5 | "Failed to read BaseLib at {0}": "{0} の BaseLib の読み込みに失敗しました", 6 | "Failed to register plugin manager": "プラグインマネージャーの登録に失敗しました", 7 | "Failed to load plugin code": "プラグインコードの読み込みに失敗しました", 8 | "Failed to read plugin entry at {0}": "{0} のプラグインエントリの読み取りに失敗しました", 9 | "Failed to load plugin {0}: {1}\\n{2}": "プラグイン {0}の読み込みに失敗しました: {1}\\n{2}", 10 | "Failed to unload plugin {0}: {1}": "プラグイン {0}のアンロードに失敗しました: {1}", 11 | "Migrating legacy plugin at {0}": "{0}でレガシープラグインを移行中", 12 | "Failed to migrate legacy plugin at {0}: {1} already exists": "{0}でレガシープラグインを移行できませんでした: {1} は既に存在します", 13 | "Failed to create directory {0}": "{0}ディレクトリの作成に失敗しました", 14 | "Migrating legacy plugins": { 15 | "": { 16 | "": { 17 | "": "レガシープラグインを移行中..." 18 | } 19 | } 20 | }, 21 | "Legacy plugins have been migrated, please restart the server to load them!": "以前のプラグインは移行されました。サーバーを再起動してロードしてください!", 22 | "Overworld": "オーバーワールド", 23 | "Nether": "ネザー", 24 | "End": "エンド", 25 | "Other dimension": "その他のサイズ", 26 | "JSON parse error": "JSONの構文エラー", 27 | "Npm finished successfully": { 28 | "": "Npmは正常に終了しました。" 29 | }, 30 | "Executing \"npm install\" for plugin {name}": { 31 | "": { 32 | "": { 33 | "": "プラグイン {name} の \"npm install\" を実行しています..." 34 | } 35 | } 36 | }, 37 | "Error occurred": { 38 | " Exit code: {code}": "エラーが発生しました。終了コード: {code}" 39 | }, 40 | "Executing \"pip install\" for plugin {name}": { 41 | "": { 42 | "": { 43 | "": "プラグイン {name} の \"pip install\" を実行中 ..." 44 | } 45 | } 46 | }, 47 | "Pip finished successfully": { 48 | "": "ピップは正常に終了しました。" 49 | }, 50 | "Runtime command {} already exists, changes will not beapplied except for setOverload!": "ランタイムコマンド {} が既に存在します。変更は setOverload 以外は適用されません。", 51 | "Failed to initialize file mapping": "ファイルマッピングの初期化に失敗しました", 52 | "Failed to initialize map file": "マップファイルの初期化に失敗しました", 53 | "Command {} failed to execute, is the plugin unloaded?": "コマンド {} の実行に失敗しました。プラグインがアンロードされていますか?", 54 | "Could not find {} in registered commands": { 55 | "": "登録されたコマンドで {} が見つかりませんでした。" 56 | }, 57 | "Event {} not found!": "イベント {} が見つかりません!" 58 | } 59 | -------------------------------------------------------------------------------- /src/lang/ko.json: -------------------------------------------------------------------------------- 1 | { 2 | "Failed to enable: {0}": "Failed to enable: {0}", 3 | "Failed to load: {0}": "Failed to load: {0}", 4 | "Cannot save default configurations to {0}": "Cannot save default configurations to {0}", 5 | "Failed to read BaseLib at {0}": "Failed to read BaseLib at {0}", 6 | "Failed to register plugin manager": "Failed to register plugin manager", 7 | "Failed to load plugin code": "Failed to load plugin code", 8 | "Failed to read plugin entry at {0}": "Failed to read plugin entry at {0}", 9 | "Failed to load plugin {0}: {1}\\n{2}": "Failed to load plugin {0}: {1}\\n{2}", 10 | "Failed to unload plugin {0}: {1}": "Failed to unload plugin {0}: {1}", 11 | "Migrating legacy plugin at {0}": "Migrating legacy plugin at {0}", 12 | "Failed to migrate legacy plugin at {0}: {1} already exists": "Failed to migrate legacy plugin at {0}: {1} already exists", 13 | "Failed to create directory {0}": "Failed to create directory {0}", 14 | "Migrating legacy plugins": { 15 | "": { 16 | "": { 17 | "": "Migrating legacy plugins..." 18 | } 19 | } 20 | }, 21 | "Legacy plugins have been migrated, please restart the server to load them!": "Legacy plugins have been migrated, please restart the server to load them!", 22 | "Overworld": "오버월드", 23 | "Nether": "네더", 24 | "End": "엔더", 25 | "Other dimension": "다른 월드", 26 | "JSON parse error": "JSON 파싱 오류", 27 | "Npm finished successfully": { 28 | "": "Npm이 성공적으로 설치됐습니다." 29 | }, 30 | "Executing \"npm install\" for plugin {name}": { 31 | "": { 32 | "": { 33 | "": "플러그인 {name} 에 대하여 \"npm install\" 명령어를 실행합니다." 34 | } 35 | } 36 | }, 37 | "Error occurred": { 38 | " Exit code: {code}": "에러가 발생했습니다. 종료 코드: {code}" 39 | }, 40 | "Executing \"pip install\" for plugin {name}": { 41 | "": { 42 | "": { 43 | "": "{name} 플러그인에 대하여 pip install 명령어를 실행중입니다" 44 | } 45 | } 46 | }, 47 | "Pip finished successfully": { 48 | "": "pip가 성공적으로 실행됐습니다" 49 | }, 50 | "Runtime command {} already exists, changes will not beapplied except for setOverload!": "Runtime command {} already exists, changes will not beapplied except for setOverload!", 51 | "Failed to initialize file mapping": "Failed to initialize file mapping", 52 | "Failed to initialize map file": "Failed to initialize map file", 53 | "Command {} failed to execute, is the plugin unloaded?": "Command {} failed to execute, is the plugin unloaded?", 54 | "Could not find {} in registered commands": { 55 | "": "Could not find {} in registered commands." 56 | }, 57 | "Event {} not found!": "Event {} not found!" 58 | } 59 | -------------------------------------------------------------------------------- /src/lang/pt_BR.json: -------------------------------------------------------------------------------- 1 | { 2 | "Failed to enable: {0}": "Falha ao ativar: {0}", 3 | "Failed to load: {0}": "Falha ao carregar: {0}", 4 | "Cannot save default configurations to {0}": "Não é possível salvar as configurações padrão para {0}", 5 | "Failed to read BaseLib at {0}": "Falha ao ler BaseLib em {0}", 6 | "Failed to register plugin manager": "Falha ao registrar o gerenciador de plugins", 7 | "Failed to load plugin code": "Falha ao carregar o código do plugin", 8 | "Failed to read plugin entry at {0}": "Falha ao ler entrada do plugin em {0}", 9 | "Failed to load plugin {0}: {1}\\n{2}": "Falha ao carregar plugin {0}: {1}\\n{2}", 10 | "Failed to unload plugin {0}: {1}": "Falha ao descarregar plugin {0}: {1}", 11 | "Migrating legacy plugin at {0}": "Migrando plugin legado em {0}", 12 | "Failed to migrate legacy plugin at {0}: {1} already exists": "Falha ao migrar o plugin legado para {0}: {1} já existe", 13 | "Failed to create directory {0}": "Falha ao criar diretório {0}", 14 | "Migrating legacy plugins": { 15 | "": { 16 | "": { 17 | "": "Migrando plugins legados..." 18 | } 19 | } 20 | }, 21 | "Legacy plugins have been migrated, please restart the server to load them!": "Plugins Legacy foram migrados, por favor reinicie o servidor para carregá-los!", 22 | "Overworld": "Extrema", 23 | "Nether": "Nether", 24 | "End": "Término", 25 | "Other dimension": "Outra dimensão", 26 | "JSON parse error": "Erro de análise JSON", 27 | "Npm finished successfully": { 28 | "": "Npm concluído com sucesso." 29 | }, 30 | "Executing \"npm install\" for plugin {name}": { 31 | "": { 32 | "": { 33 | "": "Executando \"npm install\" para o plugin {name}..." 34 | } 35 | } 36 | }, 37 | "Error occurred": { 38 | " Exit code: {code}": "Ocorreu um erro. Sair do código: {code}" 39 | }, 40 | "Executing \"pip install\" for plugin {name}": { 41 | "": { 42 | "": { 43 | "": "Executando \"pip install\" para o plugin {name}..." 44 | } 45 | } 46 | }, 47 | "Pip finished successfully": { 48 | "": "Pip concluído com sucesso." 49 | }, 50 | "Runtime command {} already exists, changes will not beapplied except for setOverload!": "Comando de execução {} já existe, as alterações não serão aplicadas exceto para setOverload!", 51 | "Failed to initialize file mapping": "Falha ao inicializar o mapeamento de arquivos", 52 | "Failed to initialize map file": "Falha ao inicializar arquivo de mapa", 53 | "Command {} failed to execute, is the plugin unloaded?": "Comando {} falha ao executar, o plugin está descarregado?", 54 | "Could not find {} in registered commands": { 55 | "": "Não foi possível encontrar {} nos comandos registrados." 56 | }, 57 | "Event {} not found!": "Evento {} não encontrado!" 58 | } 59 | -------------------------------------------------------------------------------- /src/lang/ru.json: -------------------------------------------------------------------------------- 1 | { 2 | "Failed to enable: {0}": "Не удалось включить: {0}", 3 | "Failed to load: {0}": "Не удалось загрузить: {0}", 4 | "Cannot save default configurations to {0}": "Не удается сохранить конфигурации по умолчанию в {0}", 5 | "Failed to read BaseLib at {0}": "Не удалось прочитать BaseLib на {0}", 6 | "Failed to register plugin manager": "Не удалось зарегистрировать менеджер плагинов", 7 | "Failed to load plugin code": "Не удалось загрузить код плагина", 8 | "Failed to read plugin entry at {0}": "Не удалось прочитать запись плагина на {0}", 9 | "Failed to load plugin {0}: {1}\\n{2}": "Не удалось загрузить плагин {0}: {1}\\n{2}", 10 | "Failed to unload plugin {0}: {1}": "Не удалось выгрузить плагин {0}: {1}", 11 | "Migrating legacy plugin at {0}": "Миграция старого плагина на {0}", 12 | "Failed to migrate legacy plugin at {0}: {1} already exists": "Не удалось перенести устаревший плагин на {0}: {1} уже существует", 13 | "Failed to create directory {0}": "Не удалось создать каталог {0}", 14 | "Migrating legacy plugins": { 15 | "": { 16 | "": { 17 | "": "Миграция старых плагинов..." 18 | } 19 | } 20 | }, 21 | "Legacy plugins have been migrated, please restart the server to load them!": "Устаревшие плагины были перенесены, пожалуйста, перезапустите сервер, чтобы загрузить их!", 22 | "Overworld": "Верхний мир", 23 | "Nether": "Нижний мир", 24 | "End": "Край", 25 | "Other dimension": "Другое измерение", 26 | "JSON parse error": "Ошибка при чтении JSON файла", 27 | "Npm finished successfully": { 28 | "": "NPM успешно завершил свою работу." 29 | }, 30 | "Executing \"npm install\" for plugin {name}": { 31 | "": { 32 | "": { 33 | "": "Запускаю команду \"npm install\" для плагина {name}..." 34 | } 35 | } 36 | }, 37 | "Error occurred": { 38 | " Exit code: {code}": "Произошла ошибка. Код завершения: {code}" 39 | }, 40 | "Executing \"pip install\" for plugin {name}": { 41 | "": { 42 | "": { 43 | "": "Выполняю \"pip install\" для плагина {name}..." 44 | } 45 | } 46 | }, 47 | "Pip finished successfully": { 48 | "": "Pip успешно выполнено." 49 | }, 50 | "Runtime command {} already exists, changes will not beapplied except for setOverload!": "Команда Runtime {} уже существует, изменения не будут работать, кроме setOverload!", 51 | "Failed to initialize file mapping": "Не удалось инициализировать сопоставление файлов", 52 | "Failed to initialize map file": "Не удалось инициализировать файл карты", 53 | "Command {} failed to execute, is the plugin unloaded?": "Не удалось выполнить команду {}, не загружен ли плагин?", 54 | "Could not find {} in registered commands": { 55 | "": "Не удалось найти {} в зарегистрированных командах." 56 | }, 57 | "Event {} not found!": "Событие {} не найдено!" 58 | } 59 | -------------------------------------------------------------------------------- /src/lang/th.json: -------------------------------------------------------------------------------- 1 | { 2 | "Failed to enable: {0}": "Failed to enable: {0}", 3 | "Failed to load: {0}": "Failed to load: {0}", 4 | "Cannot save default configurations to {0}": "Cannot save default configurations to {0}", 5 | "Failed to read BaseLib at {0}": "Failed to read BaseLib at {0}", 6 | "Failed to register plugin manager": "Failed to register plugin manager", 7 | "Failed to load plugin code": "Failed to load plugin code", 8 | "Failed to read plugin entry at {0}": "Failed to read plugin entry at {0}", 9 | "Failed to load plugin {0}: {1}\\n{2}": "Failed to load plugin {0}: {1}\\n{2}", 10 | "Failed to unload plugin {0}: {1}": "Failed to unload plugin {0}: {1}", 11 | "Migrating legacy plugin at {0}": "Migrating legacy plugin at {0}", 12 | "Failed to migrate legacy plugin at {0}: {1} already exists": "Failed to migrate legacy plugin at {0}: {1} already exists", 13 | "Failed to create directory {0}": "Failed to create directory {0}", 14 | "Migrating legacy plugins": { 15 | "": { 16 | "": { 17 | "": "Migrating legacy plugins..." 18 | } 19 | } 20 | }, 21 | "Legacy plugins have been migrated, please restart the server to load them!": "Legacy plugins have been migrated, please restart the server to load them!", 22 | "Overworld": "โลกปกติ", 23 | "Nether": "เนเธอร์", 24 | "End": "ดิเอนด์", 25 | "Other dimension": "มิติอื่นๆ", 26 | "JSON parse error": "ข้อผิดพลาดในการแยกวิเคราะห์ Json", 27 | "Npm finished successfully": { 28 | "": "Npm เสร็จเรียบร้อยแล้ว" 29 | }, 30 | "Executing \"npm install\" for plugin {name}": { 31 | "": { 32 | "": { 33 | "": "ดำเนินการ \"npm install\" สำหรับปลั๊กอิน {name}..." 34 | } 35 | } 36 | }, 37 | "Error occurred": { 38 | " Exit code: {code}": "เกิดข้อผิดพลาด โค้ด: {code}" 39 | }, 40 | "Executing \"pip install\" for plugin {name}": { 41 | "": { 42 | "": { 43 | "": "Executing \"pip install\" for plugin {name}..." 44 | } 45 | } 46 | }, 47 | "Pip finished successfully": { 48 | "": "Pip finished successfully." 49 | }, 50 | "Runtime command {} already exists, changes will not beapplied except for setOverload!": "Runtime command {} already exists, changes will not beapplied except for setOverload!", 51 | "Failed to initialize file mapping": "Failed to initialize file mapping", 52 | "Failed to initialize map file": "Failed to initialize map file", 53 | "Command {} failed to execute, is the plugin unloaded?": "Command {} failed to execute, is the plugin unloaded?", 54 | "Could not find {} in registered commands": { 55 | "": "Could not find {} in registered commands." 56 | }, 57 | "Event {} not found!": "Event {} not found!" 58 | } 59 | -------------------------------------------------------------------------------- /src/lang/tr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Failed to enable: {0}": "Failed to enable: {0}", 3 | "Failed to load: {0}": "Failed to load: {0}", 4 | "Cannot save default configurations to {0}": "Cannot save default configurations to {0}", 5 | "Failed to read BaseLib at {0}": "Failed to read BaseLib at {0}", 6 | "Failed to register plugin manager": "Failed to register plugin manager", 7 | "Failed to load plugin code": "Failed to load plugin code", 8 | "Failed to read plugin entry at {0}": "Failed to read plugin entry at {0}", 9 | "Failed to load plugin {0}: {1}\\n{2}": "Failed to load plugin {0}: {1}\\n{2}", 10 | "Failed to unload plugin {0}: {1}": "Failed to unload plugin {0}: {1}", 11 | "Migrating legacy plugin at {0}": "Migrating legacy plugin at {0}", 12 | "Failed to migrate legacy plugin at {0}: {1} already exists": "Failed to migrate legacy plugin at {0}: {1} already exists", 13 | "Failed to create directory {0}": "Failed to create directory {0}", 14 | "Migrating legacy plugins": { 15 | "": { 16 | "": { 17 | "": "Migrating legacy plugins..." 18 | } 19 | } 20 | }, 21 | "Legacy plugins have been migrated, please restart the server to load them!": "Legacy plugins have been migrated, please restart the server to load them!", 22 | "Overworld": "Overworld", 23 | "Nether": "Nether", 24 | "End": "End", 25 | "Other dimension": "Diğer boyut", 26 | "JSON parse error": "JSON ayrıştırma hatası", 27 | "Npm finished successfully": { 28 | "": "Npm başarıyla tamamlandı." 29 | }, 30 | "Executing \"npm install\" for plugin {name}": { 31 | "": { 32 | "": { 33 | "": "Eklenti {name} için \"npm install\" çalıştırılıyor..." 34 | } 35 | } 36 | }, 37 | "Error occurred": { 38 | " Exit code: {code}": "Hata oluştu. Çıkış kodu: {code}" 39 | }, 40 | "Executing \"pip install\" for plugin {name}": { 41 | "": { 42 | "": { 43 | "": "Eklenti, {name} için \"pip install\" çalıştırılıyor..." 44 | } 45 | } 46 | }, 47 | "Pip finished successfully": { 48 | "": "Pip başarıyla tamamlandı." 49 | }, 50 | "Runtime command {} already exists, changes will not beapplied except for setOverload!": "Runtime command {} already exists, changes will not beapplied except for setOverload!", 51 | "Failed to initialize file mapping": "Failed to initialize file mapping", 52 | "Failed to initialize map file": "Failed to initialize map file", 53 | "Command {} failed to execute, is the plugin unloaded?": "Command {} failed to execute, is the plugin unloaded?", 54 | "Could not find {} in registered commands": { 55 | "": "Could not find {} in registered commands." 56 | }, 57 | "Event {} not found!": "Event {} not found!" 58 | } 59 | -------------------------------------------------------------------------------- /src/lang/vi.json: -------------------------------------------------------------------------------- 1 | { 2 | "Failed to enable: {0}": "Failed to enable: {0}", 3 | "Failed to load: {0}": "Failed to load: {0}", 4 | "Cannot save default configurations to {0}": "Cannot save default configurations to {0}", 5 | "Failed to read BaseLib at {0}": "Failed to read BaseLib at {0}", 6 | "Failed to register plugin manager": "Failed to register plugin manager", 7 | "Failed to load plugin code": "Failed to load plugin code", 8 | "Failed to read plugin entry at {0}": "Failed to read plugin entry at {0}", 9 | "Failed to load plugin {0}: {1}\\n{2}": "Failed to load plugin {0}: {1}\\n{2}", 10 | "Failed to unload plugin {0}: {1}": "Failed to unload plugin {0}: {1}", 11 | "Migrating legacy plugin at {0}": "Migrating legacy plugin at {0}", 12 | "Failed to migrate legacy plugin at {0}: {1} already exists": "Failed to migrate legacy plugin at {0}: {1} already exists", 13 | "Failed to create directory {0}": "Failed to create directory {0}", 14 | "Migrating legacy plugins": { 15 | "": { 16 | "": { 17 | "": "Migrating legacy plugins..." 18 | } 19 | } 20 | }, 21 | "Legacy plugins have been migrated, please restart the server to load them!": "Legacy plugins have been migrated, please restart the server to load them!", 22 | "Overworld": "Thế giới chính", 23 | "Nether": "Địa ngục", 24 | "End": "The End", 25 | "Other dimension": "Không gian khác", 26 | "JSON parse error": "Lỗi phân tích cú pháp JSON", 27 | "Npm finished successfully": { 28 | "": "Npm kết thúc thành công." 29 | }, 30 | "Executing \"npm install\" for plugin {name}": { 31 | "": { 32 | "": { 33 | "": "Đang thực thi \"npm install\" cho plugin {name}..." 34 | } 35 | } 36 | }, 37 | "Error occurred": { 38 | " Exit code: {code}": "Xảy ra lỗi. Mã thoát: {code}" 39 | }, 40 | "Executing \"pip install\" for plugin {name}": { 41 | "": { 42 | "": { 43 | "": "Đang thực thi \"pip install\" cho plugin {name}..." 44 | } 45 | } 46 | }, 47 | "Pip finished successfully": { 48 | "": "Pip kết thúc thành công." 49 | }, 50 | "Runtime command {} already exists, changes will not beapplied except for setOverload!": "Runtime command {} already exists, changes will not beapplied except for setOverload!", 51 | "Failed to initialize file mapping": "Failed to initialize file mapping", 52 | "Failed to initialize map file": "Failed to initialize map file", 53 | "Command {} failed to execute, is the plugin unloaded?": "Command {} failed to execute, is the plugin unloaded?", 54 | "Could not find {} in registered commands": { 55 | "": "Could not find {} in registered commands." 56 | }, 57 | "Event {} not found!": "Event {} not found!" 58 | } 59 | -------------------------------------------------------------------------------- /src/lang/zh_CN.json: -------------------------------------------------------------------------------- 1 | { 2 | "Failed to enable: {0}": "启用 {0} 失败", 3 | "Failed to load: {0}": "{0} 加载失败", 4 | "Cannot save default configurations to {0}": "无法将默认配置保存到 {0}", 5 | "Failed to read BaseLib at {0}": "无法读取 位于 {0} 的BaseLib", 6 | "Failed to register plugin manager": "注册插件管理器失败", 7 | "Failed to load plugin code": "加载插件代码失败", 8 | "Failed to read plugin entry at {0}": "在 {0} 读取插件条目失败", 9 | "Failed to load plugin {0}: {1}\\n{2}": "加载插件 {0} 失败: {1}\\n{2}", 10 | "Failed to unload plugin {0}: {1}": "卸载插件 {0} 失败: {1}", 11 | "Migrating legacy plugin at {0}": "正在迁移旧版插件到 {0}", 12 | "Failed to migrate legacy plugin at {0}: {1} already exists": "迁移旧版插件失败 {0}: {1} 已经存在", 13 | "Failed to create directory {0}": "无法创建目录 {0}", 14 | "Migrating legacy plugins": { 15 | "": { 16 | "": { 17 | "": "正在迁移旧版插件..." 18 | } 19 | } 20 | }, 21 | "Legacy plugins have been migrated, please restart the server to load them!": "旧版插件已迁移,请重启服务器加载!", 22 | "Overworld": "主世界", 23 | "Nether": "下界", 24 | "End": "末地", 25 | "Other dimension": "其他维度", 26 | "JSON parse error": "JSON 解析错误", 27 | "Npm finished successfully": { 28 | "": "Npm 命令成功完成" 29 | }, 30 | "Executing \"npm install\" for plugin {name}": { 31 | "": { 32 | "": { 33 | "": "为插件 {name} 执行 \"npm install\"..." 34 | } 35 | } 36 | }, 37 | "Error occurred": { 38 | " Exit code: {code}": "发生错误。退出代码: {code}" 39 | }, 40 | "Executing \"pip install\" for plugin {name}": { 41 | "": { 42 | "": { 43 | "": "为插件 {name} 执行 \"pip install\"..." 44 | } 45 | } 46 | }, 47 | "Pip finished successfully": { 48 | "": "Pip 命令成功完成" 49 | }, 50 | "Runtime command {} already exists, changes will not beapplied except for setOverload!": "运行时命令 {} 已经存在,除 setOverload 外的更改将不会被应用!", 51 | "Failed to initialize file mapping": "初始化文件映射失败", 52 | "Failed to initialize map file": "初始化映射文件失败", 53 | "Command {} failed to execute, is the plugin unloaded?": "命令 {} 执行失败,是否已卸载该插件?", 54 | "Could not find {} in registered commands": { 55 | "": "在已注册的命令中找不到 {} 。" 56 | }, 57 | "Event {} not found!": "找不到事件 {} !" 58 | } 59 | -------------------------------------------------------------------------------- /src/lang/zh_TW.json: -------------------------------------------------------------------------------- 1 | { 2 | "Failed to enable: {0}": "{0} 啟用失敗", 3 | "Failed to load: {0}": "{0} 加載失敗", 4 | "Cannot save default configurations to {0}": "無法將預設配置儲存到 {0}", 5 | "Failed to read BaseLib at {0}": "無法讀取位於 {0} 的 BaseLib", 6 | "Failed to register plugin manager": "插件管理器註冊失敗", 7 | "Failed to load plugin code": "載入插件程式碼失敗", 8 | "Failed to read plugin entry at {0}": "無法讀取 {0} 處的插件條目", 9 | "Failed to load plugin {0}: {1}\\n{2}": "無法載入插件 {0}:{1}\\n{2}", 10 | "Failed to unload plugin {0}: {1}": "無法卸載插件 {0}:{1}", 11 | "Migrating legacy plugin at {0}": "正在遷移位於 {0} 的舊插件", 12 | "Failed to migrate legacy plugin at {0}: {1} already exists": "無法遷移 {0} 處的舊插件: {1} 已存在", 13 | "Failed to create directory {0}": "未能建立目錄 {0}", 14 | "Migrating legacy plugins": { 15 | "": { 16 | "": { 17 | "": "正在遷移舊插件..." 18 | } 19 | } 20 | }, 21 | "Legacy plugins have been migrated, please restart the server to load them!": "舊插件已遷移,請重新啟動伺服器以載入它們!", 22 | "Overworld": "主世界", 23 | "Nether": "地獄", 24 | "End": "終界", 25 | "Other dimension": "其他維度", 26 | "JSON parse error": "JSON解析錯誤", 27 | "Npm finished successfully": { 28 | "": "Npm 命令已成功完成" 29 | }, 30 | "Executing \"npm install\" for plugin {name}": { 31 | "": { 32 | "": { 33 | "": "正在為 {name} 插件執行 “npm install”..." 34 | } 35 | } 36 | }, 37 | "Error occurred": { 38 | " Exit code: {code}": "發生錯誤. 退出代碼: {code}" 39 | }, 40 | "Executing \"pip install\" for plugin {name}": { 41 | "": { 42 | "": { 43 | "": "正在為 {name} 插件執行 “pip install”..." 44 | } 45 | } 46 | }, 47 | "Pip finished successfully": { 48 | "": "Pip 命令已成功完成" 49 | }, 50 | "Runtime command {} already exists, changes will not beapplied except for setOverload!": "Runtime command {} already exists, changes will not beapplied except for setOverload!", 51 | "Failed to initialize file mapping": "Failed to initialize file mapping", 52 | "Failed to initialize map file": "Failed to initialize map file", 53 | "Command {} failed to execute, is the plugin unloaded?": "Command {} failed to execute, is the plugin unloaded?", 54 | "Could not find {} in registered commands": { 55 | "": "Could not find {} in registered commands." 56 | }, 57 | "Event {} not found!": "Event {} not found!" 58 | } 59 | -------------------------------------------------------------------------------- /src/legacy/api/BlockAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | #include "main/Global.h" 4 | 5 | #include 6 | 7 | //////////////////// Classes //////////////////// 8 | class Block; 9 | class BlockClass : public ScriptClass { 10 | private: 11 | Block const* block; 12 | 13 | // Pre data 14 | std::string name, type; 15 | DimensionType id; 16 | IntVec4 blockPos; 17 | 18 | public: 19 | explicit BlockClass(Block const& block); 20 | BlockClass(Block const& block, BlockPos const& pos, DimensionType dim); 21 | 22 | void preloadData(BlockPos bp, DimensionType dim); 23 | Block const* get() { return block; } 24 | 25 | static Local newBlock(Block const& block, BlockPos const& pos, DimensionType dim); 26 | static Local newBlock(BlockPos const& pos, DimensionType dim); 27 | static Local newBlock(Block const& block, BlockPos const& pos, BlockSource const& bs); 28 | static Local newBlock(IntVec4 pos); 29 | static Block const* extract(Local v); 30 | 31 | Local getName(); 32 | Local getType(); 33 | Local getId(); 34 | Local getPos(); 35 | Local getTileData(); 36 | Local getVariant(); 37 | Local getTranslucency(); 38 | Local getThickness(); 39 | 40 | Local isAir(); 41 | Local isBounceBlock(); 42 | Local isButtonBlock(); 43 | Local isCropBlock(); 44 | Local isDoorBlock(); 45 | Local isFenceBlock(); 46 | Local isFenceGateBlock(); 47 | Local isThinFenceBlock(); 48 | Local isHeavyBlock(); 49 | Local isStemBlock(); 50 | Local isSlabBlock(); 51 | Local isUnbreakable(); 52 | Local isWaterBlockingBlock(); 53 | 54 | Local getNbt(const Arguments& args); 55 | Local setNbt(const Arguments& args); 56 | Local getBlockState(const Arguments& args); 57 | Local hasContainer(const Arguments& args); 58 | Local getContainer(const Arguments& args); 59 | Local hasBlockEntity(const Arguments& args); 60 | Local getBlockEntity(const Arguments& args); 61 | Local removeBlockEntity(const Arguments& args); 62 | Local destroyBlock(const Arguments& args); 63 | }; 64 | extern ClassDefine BlockClassBuilder; 65 | -------------------------------------------------------------------------------- /src/legacy/api/BlockEntityAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | 4 | #include 5 | 6 | //////////////////// Classes //////////////////// 7 | class BlockActor; 8 | class BlockEntityClass : public ScriptClass { 9 | private: 10 | BlockActor* blockEntity = nullptr; 11 | int dim; 12 | 13 | public: 14 | explicit BlockEntityClass(BlockActor* be, int dim); 15 | 16 | BlockActor* get() { return blockEntity; } 17 | 18 | static Local newBlockEntity(BlockActor* be, int dim); 19 | static BlockActor* extract(Local v); 20 | 21 | Local getName(); 22 | Local getPos(); 23 | Local getType(); 24 | 25 | Local getNbt(const Arguments& args); 26 | Local setNbt(const Arguments& args); 27 | Local getBlock(const Arguments& args); 28 | }; 29 | extern ClassDefine BlockEntityClassBuilder; 30 | -------------------------------------------------------------------------------- /src/legacy/api/CommandCompatibleAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | 4 | #include 5 | #include 6 | 7 | //////////////////// LLSE Event Callbacks //////////////////// 8 | 9 | class Player; 10 | // helper 11 | std::vector SplitCmdLine(const std::string& paras); 12 | 13 | // 命令回调查询 14 | std::string 15 | LLSEFindCmdReg(bool isPlayerCmd, const std::string& cmd, std::vector& receiveParas, bool* fromOtherEngine); 16 | // 删除指定引擎的所有命令 17 | bool LLSERemoveCmdRegister(script::ScriptEngine* engine); 18 | 19 | // 处理命令延迟注册 20 | void ProcessRegCmdQueue(); 21 | 22 | // 玩家自定义命令注册回调 23 | bool CallPlayerCmdCallback(Player* player, const std::string& cmdPrefix, const std::vector& paras); 24 | // 控制台自定义命令注册回调 25 | bool CallServerCmdCallback(const std::string& cmdPrefix, const std::vector& paras); 26 | -------------------------------------------------------------------------------- /src/legacy/api/CommandOriginAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | #include "mc/server/commands/CommandOrigin.h" 4 | 5 | class CommandOriginClass; 6 | extern ClassDefine OriginTypeStaticBuilder; 7 | extern ClassDefine CommandOriginClassBuilder; 8 | 9 | class CommandOriginClass : public ScriptClass { 10 | CommandOrigin const* ptr; 11 | inline CommandOrigin const* get() { return ptr; } 12 | 13 | public: 14 | CommandOriginClass(CommandOrigin const* p); 15 | static Local newCommandOrigin(CommandOrigin const* p); 16 | Local getOriginType(); 17 | Local getOriginTypeName(); 18 | Local getOriginName(); 19 | Local getBlockPosition(); 20 | Local getPosition(); 21 | Local getEntity(); 22 | Local getPlayer(); 23 | Local getNbt(const Arguments& args); 24 | Local toString(); 25 | }; 26 | -------------------------------------------------------------------------------- /src/legacy/api/CommandOutputAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | #include "mc/server/commands/CommandOutput.h" 4 | 5 | class CommandOutputClass; 6 | extern ClassDefine CommandOutputClassBuilder; 7 | 8 | class CommandOutputClass : public ScriptClass { 9 | CommandOutput* ptr; 10 | inline CommandOutput* get() { return ptr; } 11 | 12 | public: 13 | CommandOutputClass(CommandOutput* p); 14 | static Local newCommandOutput(CommandOutput* p); 15 | 16 | Local empty(); 17 | 18 | Local getSuccessCount(); 19 | 20 | Local success(const Arguments& args); 21 | 22 | Local addMessage(const Arguments& args); 23 | 24 | Local error(const Arguments& args); 25 | 26 | // Local setHasPlayerText() 27 | //{ 28 | // try 29 | // { 30 | // get()->setHasPlayerText(); 31 | // return Boolean::newBoolean(true); 32 | // } 33 | // CATCH("Fail in getBlockPosition!"); 34 | // }; 35 | 36 | // Local wantsData() 37 | //{ 38 | // try 39 | // { 40 | // return Boolean::newBoolean(get()->wantsData()); 41 | // } 42 | // CATCH("Fail in getBlockPosition!"); 43 | // }; 44 | 45 | // Local addToResultList(const Arguments& args); 46 | 47 | // Local forceOutput(const Arguments& args); 48 | 49 | // Local getData() const; 50 | 51 | // Local getMessages() const; 52 | 53 | // Local load(const Arguments& args); 54 | 55 | Local toString(const Arguments& args); 56 | }; 57 | -------------------------------------------------------------------------------- /src/legacy/api/ContainerAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | #include "mc/world/Container.h" 4 | 5 | #include 6 | 7 | //////////////////// Classes //////////////////// 8 | class Container; 9 | class ContainerClass : public ScriptClass { 10 | private: 11 | Container* container; 12 | 13 | public: 14 | explicit ContainerClass(Container* p); 15 | 16 | Container* get() { return container; } 17 | 18 | static Local newContainer(Container* p); 19 | static Container* extract(Local v); 20 | 21 | Local getSize(); 22 | Local getType(); 23 | 24 | Local addItem(const Arguments& args); 25 | Local addItemToFirstEmptySlot(const Arguments& args); 26 | Local hasRoomFor(const Arguments& args); 27 | Local removeItem(const Arguments& args); 28 | Local getItem(const Arguments& args); 29 | Local setItem(const Arguments& args); 30 | Local getAllItems(const Arguments& args); 31 | Local removeAllItems(const Arguments& args); 32 | Local isEmpty(const Arguments& args); 33 | }; 34 | extern ClassDefine ContainerClassBuilder; 35 | -------------------------------------------------------------------------------- /src/legacy/api/DatabaseAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | #include "legacyapi/db/Session.h" 4 | #include "ll/api/data/KeyValueDB.h" 5 | 6 | //////////////////// Classes //////////////////// 7 | 8 | //// KVDB 9 | class KVDBClass : public ScriptClass { 10 | private: 11 | std::unique_ptr kvdb; 12 | int unloadCallbackIndex = -1; 13 | 14 | public: 15 | explicit KVDBClass(const Local& scriptObj, const std::string& dir); 16 | explicit KVDBClass(const std::string& dir); 17 | ~KVDBClass(); 18 | static KVDBClass* constructor(const Arguments& args); 19 | 20 | bool isValid() { return kvdb.get(); } 21 | 22 | Local get(const Arguments& args); 23 | Local set(const Arguments& args); 24 | Local del(const Arguments& args); 25 | Local close(const Arguments& args); 26 | Local listKey(const Arguments& args); 27 | 28 | // For Compatibility 29 | static Local newDb(const std::string& dir); 30 | }; 31 | extern ClassDefine KVDBClassBuilder; 32 | 33 | //// SQLDB 34 | class DBSessionClass : public ScriptClass { 35 | private: 36 | DB::SharedPointer session; 37 | 38 | public: 39 | explicit DBSessionClass(const Local& scriptObj, const DB::ConnParams& params); 40 | explicit DBSessionClass(const DB::ConnParams& params); 41 | ~DBSessionClass(); 42 | static DBSessionClass* constructor(const Arguments& args); 43 | 44 | Local query(const Arguments& args); 45 | Local exec(const Arguments& args); 46 | Local prepare(const Arguments& args); 47 | Local close(const Arguments& args); 48 | Local isOpen(const Arguments& args); 49 | }; 50 | extern ClassDefine DBSessionClassBuilder; 51 | 52 | class DBStmtClass : public ScriptClass { 53 | private: 54 | DB::SharedPointer stmt; 55 | 56 | public: 57 | explicit DBStmtClass(const Local& scriptObj, const DB::SharedPointer& stmt); 58 | explicit DBStmtClass(const DB::SharedPointer& stmt); 59 | ~DBStmtClass(); 60 | 61 | Local getAffectedRows(); 62 | Local getInsertId(); 63 | 64 | Local bind(const Arguments& args); 65 | Local execute(const Arguments& args); 66 | Local step(const Arguments& args); 67 | Local fetch(const Arguments& args); 68 | Local fetchAll(const Arguments& args); 69 | Local reset(const Arguments& args); 70 | Local reexec(const Arguments& args); 71 | Local clear(const Arguments& args); 72 | }; 73 | extern ClassDefine DBStmtClassBuilder; 74 | -------------------------------------------------------------------------------- /src/legacy/api/DeviceAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | #include "mc/legacy/ActorRuntimeID.h" 4 | #include "mc/deps/ecs/WeakEntityRef.h" 5 | 6 | //////////////////// Classes //////////////////// 7 | class Player; 8 | class DeviceClass : public ScriptClass { 9 | private: 10 | WeakRef mWeakEntity; 11 | bool mValid; 12 | 13 | public: 14 | explicit DeviceClass(Player* player); 15 | 16 | Player* getPlayer(); 17 | 18 | static Local newDevice(Player* player); 19 | 20 | Local getIP(); 21 | Local getAvgPing(); 22 | Local getAvgPacketLoss(); 23 | Local getLastPing(); 24 | Local getLastPacketLoss(); 25 | Local getOs(); 26 | Local getInputMode(); 27 | // Local getPlayMode(); 28 | Local getServerAddress(); 29 | Local getClientId(); 30 | }; 31 | extern ClassDefine DeviceClassBuilder; 32 | -------------------------------------------------------------------------------- /src/legacy/api/GameUtilsAPI.cpp: -------------------------------------------------------------------------------- 1 | #include "api/GameUtilsAPI.h" 2 | 3 | #include "api/APIHelp.h" 4 | 5 | ClassDefine TextClassBuilder = defineClass("Format") 6 | .property("Black", []() { return String::newString("§0"); }) 7 | .property("DarkBlue", []() { return String::newString("§1"); }) 8 | .property("DarkGreen", []() { return String::newString("§2"); }) 9 | .property("DarkAqua", []() { return String::newString("§3"); }) 10 | .property("DarkRed", []() { return String::newString("§4"); }) 11 | .property("DarkPurple", []() { return String::newString("§5"); }) 12 | .property("Gold", []() { return String::newString("§6"); }) 13 | .property("Gray", []() { return String::newString("§7"); }) 14 | .property("DarkGray", []() { return String::newString("§8"); }) 15 | .property("Blue", []() { return String::newString("§9"); }) 16 | .property("Green", []() { return String::newString("§a"); }) 17 | .property("Aqua", []() { return String::newString("§b"); }) 18 | .property("Red", []() { return String::newString("§c"); }) 19 | .property("LightPurple", []() { return String::newString("§d"); }) 20 | .property("Yellow", []() { return String::newString("§e"); }) 21 | .property("White", []() { return String::newString("§f"); }) 22 | .property("MinecoinGold", []() { return String::newString("§g"); }) 23 | .property("Bold", []() { return String::newString("§l"); }) 24 | .property("Italics", []() { return String::newString("§o"); }) 25 | .property("Underline", []() { return String::newString("§n"); }) 26 | .property("StrikeThrough", []() { return String::newString("§m"); }) 27 | .property("Random", []() { return String::newString("§k"); }) 28 | .property("Clear", []() { return String::newString("§r"); }) 29 | .build(); 30 | -------------------------------------------------------------------------------- /src/legacy/api/GameUtilsAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | 4 | extern ClassDefine TextClassBuilder; 5 | -------------------------------------------------------------------------------- /src/legacy/api/GuiAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | #include "ll/api/form/SimpleForm.h" 4 | #include "lse/api/helper/CustomFormWrapper.h" 5 | 6 | //////////////////// Classes //////////////////// 7 | 8 | class SimpleFormClass : public ScriptClass { 9 | private: 10 | ll::form::SimpleForm form; 11 | 12 | public: 13 | SimpleFormClass(); 14 | 15 | ll::form::SimpleForm* get() { return &form; } 16 | 17 | static Local newForm(); 18 | static ll::form::SimpleForm* extract(Local v); 19 | static void 20 | sendForm(ll::form::SimpleForm* form, Player* player, script::Local& callback, bool update = false); 21 | 22 | Local setTitle(const Arguments& args); 23 | Local setContent(const Arguments& args); 24 | Local addButton(const Arguments& args); 25 | Local addHeader(const Arguments& args); 26 | Local addLabel(const Arguments& args); 27 | Local addDivider(const Arguments& args); 28 | }; 29 | extern ClassDefine SimpleFormClassBuilder; 30 | 31 | class CustomFormClass : public ScriptClass { 32 | private: 33 | lse::form::CustomFormWrapper form; 34 | 35 | public: 36 | CustomFormClass(); 37 | 38 | lse::form::CustomFormWrapper* get() { return &form; } 39 | 40 | static Local newForm(); 41 | static lse::form::CustomFormWrapper* extract(Local v); 42 | static void 43 | sendForm(lse::form::CustomFormWrapper* form, Player* player, script::Local& callback, bool update = true); 44 | 45 | Local setTitle(const Arguments& args); 46 | Local addHeader(const Arguments& args); 47 | Local addLabel(const Arguments& args); 48 | Local addDivider(const Arguments& args); 49 | Local addInput(const Arguments& args); 50 | Local addSwitch(const Arguments& args); 51 | Local addDropdown(const Arguments& args); 52 | Local addSlider(const Arguments& args); 53 | Local addStepSlider(const Arguments& args); 54 | Local setSubmitButton(const Arguments& args); 55 | }; 56 | extern ClassDefine CustomFormClassBuilder; 57 | -------------------------------------------------------------------------------- /src/legacy/api/InternationalAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | 4 | class I18nClass { 5 | public: 6 | static Local tr(const Arguments& args); 7 | static Local trl(const Arguments& args); 8 | static Local get(const Arguments& args); 9 | static Local load(const Arguments& args); 10 | }; 11 | extern ClassDefine I18nClassBuilder; 12 | -------------------------------------------------------------------------------- /src/legacy/api/ItemAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | //////////////////// Classes //////////////////// 9 | class ItemStack; 10 | 11 | class ItemClass : public ScriptClass { 12 | private: 13 | std::variant> item; // BDS manages ItemStack* 14 | 15 | // Pre data 16 | std::string name, type; 17 | int id, count, aux; 18 | 19 | public: 20 | explicit ItemClass(ItemStack* itemStack, bool isManagedByBDS = true); 21 | void preloadData(); 22 | 23 | ItemStack* get() { 24 | if (std::holds_alternative>(item)) { 25 | return std::get>(item).get(); 26 | } else { 27 | return std::get(item); 28 | } 29 | } 30 | 31 | static Local newItem(ItemStack* itemStack, bool isManagedByBDS = true); 32 | static ItemStack* extract(Local v); 33 | 34 | Local getName(); 35 | Local getType(); 36 | Local getId(); 37 | Local getCount(); 38 | Local getAux(); 39 | Local getDamage(); 40 | Local getAttackDamage(); 41 | Local getMaxDamage(); 42 | Local getMaxStackSize(); 43 | Local getLore(); 44 | 45 | Local isArmorItem(); 46 | Local isBlock(); 47 | Local isDamageableItem(); 48 | Local isDamaged(); 49 | Local isEnchanted(); 50 | Local isEnchantingBook(); 51 | Local isFireResistant(); 52 | Local isFullStack(); 53 | Local isGlint(); 54 | Local isHorseArmorItem(); 55 | Local isLiquidClipItem(); 56 | Local isMusicDiscItem(); 57 | Local isOffhandItem(); 58 | Local isPotionItem(); 59 | Local isStackable(); 60 | Local isWearableItem(); 61 | 62 | Local set(const Arguments& args); 63 | Local clone(const Arguments& args); 64 | Local isNull(const Arguments& args); 65 | Local setNull(const Arguments& args); 66 | Local setAux(const Arguments& args); 67 | Local setLore(const Arguments& args); 68 | Local setDisplayName(const Arguments& args); 69 | Local setDamage(const Arguments& args); 70 | Local getNbt(const Arguments& args); 71 | Local setNbt(const Arguments& args); 72 | 73 | Local match(const Arguments& args); 74 | }; 75 | 76 | extern ClassDefine ItemClassBuilder; 77 | -------------------------------------------------------------------------------- /src/legacy/api/LlAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "api/APIHelp.h" 4 | 5 | #include 6 | 7 | //////////////////// LLSE Static //////////////////// 8 | 9 | class LlClass { 10 | public: 11 | static Local getLanguage(); 12 | static Local getMajorVersion(); 13 | static Local getMinorVersion(); 14 | static Local getRevisionVersion(); 15 | static Local getScriptEngineVersion(); 16 | static Local getVersionStatus(); 17 | static Local isRelease(); 18 | static Local isBeta(); 19 | static Local isDev(); 20 | static Local isWine(); 21 | static Local isDebugMode(); 22 | static Local getPluginsRoot(); 23 | 24 | static Local registerPlugin(const Arguments& args); 25 | static Local versionString(const Arguments& args); 26 | static Local requireVersion(const Arguments& args); 27 | static Local getAllPluginInfo(const Arguments& args); 28 | static Local listPlugins(const Arguments& args); 29 | static Local exportFunc(const Arguments& args); 30 | static Local importFunc(const Arguments& args); 31 | static Local hasFuncExported(const Arguments& args); 32 | static Local require(const Arguments& args); 33 | static Local eval(const Arguments& args); 34 | static Local getPluginInfo(const Arguments& args); 35 | static Local getCurrentPluginInfo(const Arguments& args); 36 | static Local onUnload(const Arguments& args); 37 | 38 | // For Compatibility 39 | static Local version(const Arguments& args); 40 | }; 41 | extern ClassDefine LlClassBuilder; 42 | extern ClassDefine VersionClassBuilder; 43 | -------------------------------------------------------------------------------- /src/legacy/api/LoggerAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | 4 | //////////////////// Classes //////////////////// 5 | 6 | class LoggerClass { 7 | public: 8 | static Local log(const Arguments& args); 9 | static Local debug(const Arguments& args); 10 | static Local info(const Arguments& args); 11 | static Local warn(const Arguments& args); 12 | static Local error(const Arguments& args); 13 | static Local fatal(const Arguments& args); 14 | 15 | static Local setTitle(const Arguments& args); 16 | static Local setConsole(const Arguments& args); 17 | static Local setFile(const Arguments& args); 18 | static Local setPlayer(const Arguments& args); 19 | 20 | static Local setLogLevel(const Arguments& args); 21 | }; 22 | extern ClassDefine LoggerClassBuilder; 23 | -------------------------------------------------------------------------------- /src/legacy/api/PacketAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | #include "main/Global.h" 4 | #include "mc/deps/core/utility/BinaryStream.h" 5 | 6 | #include 7 | 8 | //////////////////// Classes //////////////////// 9 | class Packet; 10 | class BinaryStream; 11 | 12 | class PacketClass : public ScriptClass { 13 | private: 14 | std::shared_ptr packet; 15 | 16 | public: 17 | explicit PacketClass(std::shared_ptr p); 18 | static std::shared_ptr extract(Local v); 19 | 20 | std::shared_ptr get() { return packet; } 21 | 22 | void set(std::shared_ptr pkt) { packet = pkt; }; 23 | 24 | static Local newPacket(std::shared_ptr pkt); 25 | 26 | Local getId(); 27 | Local getName(); 28 | }; 29 | extern ClassDefine PacketClassBuilder; 30 | 31 | class BinaryStreamClass : public ScriptClass { 32 | private: 33 | BinaryStream* bs; 34 | 35 | public: 36 | explicit BinaryStreamClass(BinaryStream* p); 37 | 38 | BinaryStreamClass(const Local& scriptObj) : ScriptClass(scriptObj), bs(new BinaryStream) {} 39 | 40 | BinaryStream* get() { return bs; } 41 | void set(BinaryStream* pkt) { bs = pkt; }; 42 | 43 | static Local newBinaryStream(); 44 | static BinaryStreamClass* constructor(const Arguments& args); 45 | 46 | Local getAndReleaseData(); 47 | Local reset(); 48 | 49 | Local reserve(const Arguments& args); 50 | Local writeBool(const Arguments& args); 51 | Local writeByte(const Arguments& args); 52 | Local writeDouble(const Arguments& args); 53 | Local writeFloat(const Arguments& args); 54 | Local writeSignedBigEndianInt(const Arguments& args); 55 | Local writeSignedInt(const Arguments& args); 56 | Local writeSignedInt64(const Arguments& args); 57 | Local writeSignedShort(const Arguments& args); 58 | Local writeString(const Arguments& args); 59 | Local writeUnsignedChar(const Arguments& args); 60 | Local writeUnsignedInt(const Arguments& args); 61 | Local writeUnsignedInt64(const Arguments& args); 62 | Local writeUnsignedShort(const Arguments& args); 63 | Local writeUnsignedVarInt(const Arguments& args); 64 | Local writeUnsignedVarInt64(const Arguments& args); 65 | Local writeVarInt(const Arguments& args); 66 | Local writeVarInt64(const Arguments& args); 67 | Local writeVec3(const Arguments& args); 68 | Local writeBlockPos(const Arguments& args); 69 | Local writeCompoundTag(const Arguments& args); 70 | Local writeItem(const Arguments& args); 71 | 72 | Local createPacket(const Arguments& args); 73 | }; 74 | extern ClassDefine BinaryStreamClassBuilder; 75 | -------------------------------------------------------------------------------- /src/legacy/api/ParticleAPI.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by OEOTYAN on 2022/08/27. 3 | // 4 | #pragma once 5 | #include "BaseAPI.h" 6 | 7 | #include 8 | 9 | class ParticleSpawner : public ParticleCUI, public ScriptClass { 10 | public: 11 | explicit ParticleSpawner(const Local& scriptObj) : ScriptClass(scriptObj), ParticleCUI() {} 12 | 13 | static ParticleSpawner* create(const Arguments& args); 14 | 15 | Local getDisplayRadius() { return Number::newNumber(static_cast(displayRadius)); } 16 | Local getHighDetial() { return Boolean::newBoolean(highDetial); } 17 | Local getDoubleSide() { return Boolean::newBoolean(doubleSide); } 18 | void setDisplayRadius(const Local& value) { displayRadius = value.asNumber().toInt64(); } 19 | void setHighDetial(const Local& value) { highDetial = value.asBoolean().value(); } 20 | void setDoubleSide(const Local& value) { doubleSide = value.asBoolean().value(); } 21 | 22 | Local spawnParticle(const Arguments& args); 23 | 24 | Local drawPoint(const Arguments& args); 25 | Local drawNumber(const Arguments& args); 26 | Local drawAxialLine(const Arguments& args); 27 | Local drawOrientedLine(const Arguments& args); 28 | Local drawCuboid(const Arguments& args); 29 | Local drawCircle(const Arguments& args); 30 | }; 31 | 32 | extern ClassDefine ParticleSpawnerBuilder; 33 | extern ClassDefine ParticleColorBuilder; 34 | extern ClassDefine DirectionBuilder; 35 | -------------------------------------------------------------------------------- /src/legacy/api/ScoreboardAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | 4 | //////////////////// Classes //////////////////// 5 | class Objective; 6 | class ObjectiveClass : public ScriptClass { 7 | std::string objname; 8 | bool isValid = false; 9 | 10 | public: 11 | explicit ObjectiveClass(Objective* obj) : ScriptClass(ScriptClass::ConstructFromCpp{}) { set(obj); } 12 | 13 | void set(Objective* obj); 14 | Objective* get(); 15 | static Local newObjective(Objective* obj); 16 | Local getName(); 17 | Local getDisplayName(); 18 | Local setDisplay(const Arguments& args); 19 | Local setScore(const Arguments& args); 20 | Local addScore(const Arguments& args); 21 | Local reduceScore(const Arguments& args); 22 | Local deleteScore(const Arguments& args); 23 | Local getScore(const Arguments& args); 24 | }; 25 | extern ClassDefine ObjectiveClassBuilder; 26 | -------------------------------------------------------------------------------- /src/legacy/api/ScriptAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | 4 | //////////////////// APIs //////////////////// 5 | 6 | Local Log(const Arguments& args); 7 | Local ColorLog(const Arguments& args); 8 | Local FastLog(const Arguments& args); 9 | 10 | Local SetTimeout(const Arguments& args); 11 | Local SetInterval(const Arguments& args); 12 | Local ClearInterval(const Arguments& args); 13 | -------------------------------------------------------------------------------- /src/legacy/api/ServerAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | -------------------------------------------------------------------------------- /src/legacy/api/SystemAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | 4 | //////////////////// System Static //////////////////// 5 | 6 | class SystemClass { 7 | public: 8 | static Local getTimeStr(const Arguments& args); 9 | static Local getTimeObj(const Arguments& args); 10 | static Local randomGuid(const Arguments& args); 11 | 12 | static Local cmd(const Arguments& args); 13 | static Local newProcess(const Arguments& args); 14 | }; 15 | extern ClassDefine SystemClassBuilder; 16 | -------------------------------------------------------------------------------- /src/legacy/engine/EngineManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ScriptX/ScriptX.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class EngineManager { 9 | public: 10 | static script::ScriptEngine* newEngine(std::string pluginName = ""); 11 | static bool registerEngine(script::ScriptEngine* engine); 12 | static bool unregisterEngine(script::ScriptEngine* engine); 13 | static bool isValid(script::ScriptEngine* engine, bool onlyCheckLocal = false); 14 | 15 | static std::vector getLocalEngines(); 16 | static std::vector getGlobalEngines(); 17 | static script::ScriptEngine* getEngine(std::string name, bool onlyLocalEngine = false); 18 | 19 | static std::string getEngineType(script::ScriptEngine* engine); 20 | }; 21 | -------------------------------------------------------------------------------- /src/legacy/engine/GlobalShareData.cpp: -------------------------------------------------------------------------------- 1 | #include "engine/GlobalShareData.h" 2 | 3 | #include "api/APIHelp.h" 4 | #include "engine/LocalShareData.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | // 全局共享数据 14 | GlobalDataType* globalShareData; 15 | 16 | void InitGlobalShareData() { 17 | HANDLE hGlobalData = CreateFileMapping( 18 | INVALID_HANDLE_VALUE, 19 | NULL, 20 | PAGE_READWRITE, 21 | 0, 22 | sizeof(GlobalDataType), 23 | (LLSE_GLOBAL_DATA_NAME + std::to_wstring(GetCurrentProcessId())).c_str() 24 | ); 25 | if (hGlobalData == NULL) { 26 | lse::LegacyScriptEngine::getInstance().getSelf().getLogger().error("Failed to initialize file mapping"_tr()); 27 | localShareData->isFirstInstance = true; 28 | return; 29 | } 30 | 31 | LPVOID address = MapViewOfFile(hGlobalData, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); 32 | if (address == NULL) { 33 | lse::LegacyScriptEngine::getInstance().getSelf().getLogger().error("Failed to initialize map file"_tr()); 34 | localShareData->isFirstInstance = true; 35 | return; 36 | } 37 | 38 | if (GetLastError() != ERROR_ALREADY_EXISTS) { 39 | // First Time 40 | localShareData->isFirstInstance = true; 41 | globalShareData = new (address) GlobalDataType; 42 | } else { 43 | // Existing 44 | localShareData->isFirstInstance = false; 45 | globalShareData = (GlobalDataType*)address; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/legacy/engine/GlobalShareData.h: -------------------------------------------------------------------------------- 1 | #include "api/APIHelp.h" 2 | #include "engine/EngineManager.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | //////////////////// Structs //////////////////// 12 | 13 | // 导出函数表 14 | struct ExportedFuncData { 15 | std::string fromEngineType; 16 | ScriptEngine* engine; 17 | script::Global func; 18 | std::function)> callback; 19 | }; 20 | 21 | // 消息系统处理函数信息 22 | struct MessageHandlers { 23 | script::utils::Message::MessageProc* handler; 24 | script::utils::Message::MessageProc* cleaner; 25 | }; 26 | 27 | // 全局共享数据 28 | struct GlobalDataType { 29 | // 引擎管理器表 30 | std::shared_mutex engineListLock; 31 | std::list globalEngineList; 32 | 33 | // 注册过的命令 34 | std::unordered_map playerRegisteredCmd; 35 | std::unordered_map consoleRegisteredCmd; 36 | 37 | // 导出函数表 38 | std::unordered_map exportedFuncs; 39 | 40 | // 模块消息系统 41 | int messageSystemNextId = 0; 42 | std::map messageSystemHandlers; 43 | std::map messageThreads; 44 | 45 | // OperationCount 46 | std::map operationCountData; 47 | }; 48 | 49 | //////////////////// Externs //////////////////// 50 | 51 | // 全局共享数据 52 | extern GlobalDataType* globalShareData; 53 | 54 | //////////////////// APIs //////////////////// 55 | 56 | void InitGlobalShareData(); 57 | -------------------------------------------------------------------------------- /src/legacy/engine/LocalShareData.cpp: -------------------------------------------------------------------------------- 1 | #include "engine/LocalShareData.h" 2 | 3 | #include 4 | 5 | // DLL本地共享数据 6 | LocalDataType* localShareData; 7 | 8 | // 命令延迟注册队列 9 | std::vector toRegCmdQueue; 10 | 11 | // 线程池 12 | ll::thread::ThreadPoolExecutor pool("LSE_POOL", LLSE_POOL_THREAD_COUNT); 13 | 14 | // std::mutex messageLoopLock; 15 | 16 | void InitLocalShareData() { 17 | srand(clock()); 18 | localShareData = new LocalDataType; 19 | } 20 | -------------------------------------------------------------------------------- /src/legacy/engine/LocalShareData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | #include "ll/api/thread/ThreadPoolExecutor.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | //////////////////// Structs //////////////////// 10 | 11 | // 命令回调信息结构体 12 | struct CmdCallbackData { 13 | ScriptEngine* fromEngine; 14 | int perm; 15 | script::Global func; 16 | }; 17 | 18 | // 命令延迟注册队列 19 | struct RegCmdQueue { 20 | std::string cmd; 21 | std::string describe; 22 | int level; 23 | }; 24 | 25 | // 命令回调map排序 26 | struct CmdCallbackMapCmp { 27 | bool operator()(std::string const& a, std::string const& b) const { 28 | if (a.size() != b.size()) return a.size() > b.size(); 29 | else return a > b; 30 | } 31 | }; 32 | 33 | // DLL本地共享数据 34 | struct LocalDataType { 35 | // 是否是第一个ScriptEngine实例 36 | bool isFirstInstance = true; 37 | 38 | // 玩家命令回调 39 | std::map playerCmdCallbacks; 40 | 41 | // 控制台命令回调 42 | std::map consoleCmdCallbacks; 43 | 44 | // 真指令回调 45 | std::map commandCallbacks; 46 | }; 47 | 48 | //////////////////// Externs //////////////////// 49 | 50 | // DLL本地共享数据 51 | extern LocalDataType* localShareData; 52 | 53 | // 命令延迟注册队列 54 | extern std::vector toRegCmdQueue; 55 | 56 | // 线程池 57 | extern ll::thread::ThreadPoolExecutor pool; 58 | 59 | // extern std::mutex messageLoopLock; 60 | 61 | //////////////////// APIs //////////////////// 62 | 63 | void InitLocalShareData(); 64 | -------------------------------------------------------------------------------- /src/legacy/engine/MessageSystem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | #include "engine/OperationCount.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using std::string; 12 | 13 | //////////////////// Class //////////////////// 14 | 15 | class ModuleMessageResult { 16 | private: 17 | int msgId; 18 | OperationCount resultCount; 19 | std::vector engineList; 20 | 21 | friend class ModuleMessage; 22 | ModuleMessageResult(int messageId, std::vector engineList); 23 | 24 | public: 25 | ModuleMessageResult() : resultCount("") {} 26 | ~ModuleMessageResult(); 27 | operator bool(); 28 | 29 | size_t getSentCount() { return engineList.size(); } 30 | int getMsgId() { return msgId; } 31 | 32 | bool waitForAllResults(int maxWaitTime = -1); 33 | bool waitForOneResult(int maxWaitTime = -1); 34 | bool waitForResultCount(size_t targetCount, int maxWaitTime = -1); 35 | bool cancel(); 36 | }; 37 | 38 | class ModuleMessage { 39 | private: 40 | static int getNextMessageId(); 41 | 42 | public: 43 | enum class MessageType : UINT { 44 | MODULE_MESSAGE_REQUEST, 45 | RequireBroadcast, 46 | RemoteSyncCallRequest, 47 | // RemoteLoadRequest, 48 | MODULE_MESSAGE_RETURN, 49 | RemoteSyncCallReturn, 50 | // RemoteLoadReturn, 51 | }; 52 | struct MessageHeader { 53 | MessageHeader() { 54 | id = getNextMessageId(); 55 | fromEngine = EngineScope::currentEngine(); 56 | fromEngineModuleType = LLSE_BACKEND_TYPE; 57 | } 58 | int id; 59 | ScriptEngine* fromEngine; 60 | string fromEngineModuleType; 61 | }; 62 | 63 | MessageType type; 64 | MessageHeader* header; 65 | std::string* data; 66 | 67 | unsigned getId() { return header->id; } 68 | MessageType getType() { return type; } 69 | std::string getData() { return *data; } 70 | 71 | static ModuleMessageResult broadcastLocal(MessageType type, std::string data, int64_t delay = 0); 72 | static ModuleMessageResult broadcastGlobal(MessageType type, std::string data, int64_t delay = 0); 73 | static ModuleMessageResult 74 | broadcastTo(std::string toModuleType, MessageType type, std::string data, int64_t delay = 0); 75 | static ModuleMessageResult sendTo(ScriptEngine* engine, MessageType type, std::string data, int64_t delay = 0); 76 | static ModuleMessageResult 77 | sendToRandom(std::string toModuleType, MessageType type, std::string data, int64_t delay = 0); 78 | 79 | bool sendResult(MessageType type, std::string data, int64_t delay = 0); 80 | 81 | static void handle(script::utils::Message& engineMsg); 82 | static void cleanup(script::utils::Message& engineMsg); 83 | }; 84 | 85 | ///////////////////////////// Funcs ///////////////////////////// 86 | void InitMessageSystem(); 87 | void MessageSystemLoopOnce(); 88 | bool EndMessageSystemLoop(); 89 | -------------------------------------------------------------------------------- /src/legacy/engine/OperationCount.cpp: -------------------------------------------------------------------------------- 1 | #include "engine/OperationCount.h" 2 | 3 | #include "engine/GlobalShareData.h" 4 | #include "ll/api/mod/ModManager.h" 5 | 6 | #include 7 | 8 | OperationCount::OperationCount(const string& name) : name(name) {} 9 | 10 | OperationCount OperationCount::create(const string& name) { 11 | if (exists(name)) return OperationCount(""); 12 | else { 13 | globalShareData->operationCountData[name] = 0; 14 | return OperationCount(name); 15 | } 16 | } 17 | 18 | bool OperationCount::exists(const string& name) { 19 | return globalShareData->operationCountData.find(name) != globalShareData->operationCountData.end(); 20 | } 21 | 22 | bool OperationCount::remove() { 23 | auto p = globalShareData->operationCountData.find(name); 24 | if (p != globalShareData->operationCountData.end()) { 25 | globalShareData->operationCountData.erase(p); 26 | return true; 27 | } 28 | return false; 29 | } 30 | 31 | bool OperationCount::done() { 32 | auto p = globalShareData->operationCountData.find(name); 33 | if (p != globalShareData->operationCountData.end()) { 34 | InterlockedIncrement((LONG*)&(p->second)); 35 | return true; 36 | } 37 | return false; 38 | } 39 | 40 | int OperationCount::get() { 41 | if (exists(name)) return globalShareData->operationCountData[name]; 42 | else return -1; 43 | } 44 | 45 | bool OperationCount::hasReachCount(int count) { return get() >= count; } 46 | 47 | bool OperationCount::hasReachMaxEngineCount() { 48 | return hasReachCount(lse::LegacyScriptEngine::getInstance().getManager().getModCount()); 49 | } 50 | 51 | bool OperationCount::hasReachMaxBackendCount() { return hasReachCount(LLSE_VALID_BACKENDS_COUNT); } 52 | -------------------------------------------------------------------------------- /src/legacy/engine/OperationCount.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | using std::string; 4 | 5 | class OperationCount { 6 | private: 7 | string name; 8 | 9 | public: 10 | OperationCount(const string& name); 11 | static OperationCount create(const string& name); 12 | static bool exists(const string& name); 13 | bool remove(); 14 | operator bool() { return exists(name); } 15 | 16 | bool done(); 17 | inline bool finish() { return done(); } 18 | 19 | int get(); 20 | bool hasReachCount(int count); 21 | bool hasReachMaxEngineCount(); 22 | bool hasReachMaxBackendCount(); 23 | }; 24 | -------------------------------------------------------------------------------- /src/legacy/engine/RemoteCall.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | 4 | #include 5 | 6 | //////////////////// Funcs //////////////////// 7 | 8 | bool LLSEExportFunc(ScriptEngine* engine, const Local& func, const std::string& exportName); 9 | bool LLSERemoveAllExportedFuncs(ScriptEngine* engine); 10 | 11 | class ModuleMessage; 12 | void RemoteSyncCallRequest(ModuleMessage& msg); 13 | void RemoteSyncCallReturn(ModuleMessage& msg); 14 | -------------------------------------------------------------------------------- /src/legacy/engine/TimeTaskSystem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "api/APIHelp.h" 3 | #include "engine/MessageSystem.h" 4 | 5 | #include 6 | 7 | ///////////////////////// API ///////////////////////// 8 | 9 | // void NewTimeout_s( 10 | // script::Global func, 11 | // vector> paras, 12 | // int timeout, 13 | // ScriptEngine* engine = EngineScope::currentEngine() 14 | // ); 15 | 16 | int NewTimeout(Local func, std::vector> paras, int timeout); 17 | int NewTimeout(Local func, int timeout); 18 | int NewInterval(Local func, std::vector> paras, int timeout); 19 | int NewInterval(Local func, int timeout); 20 | bool ClearTimeTask(int const& id); 21 | bool CheckTimeTask(int const& id); 22 | 23 | ///////////////////////// Func ///////////////////////// 24 | 25 | void LLSERemoveTimeTaskData(ScriptEngine* engine); 26 | -------------------------------------------------------------------------------- /src/legacy/legacyapi/db/Pointer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace DB { 6 | 7 | class Stmt; 8 | 9 | template 10 | class SharedPointer : public std::shared_ptr { 11 | 12 | public: 13 | SharedPointer(T* ptr = nullptr) : std::shared_ptr(ptr) {} 14 | SharedPointer(const std::shared_ptr& ptr) : std::shared_ptr(ptr) {} 15 | SharedPointer(std::shared_ptr&& ptr) : std::shared_ptr(ptr) {} 16 | SharedPointer(const SharedPointer& other) : std::shared_ptr(other) {} 17 | SharedPointer(SharedPointer&& other) : std::shared_ptr(other) {} 18 | ~SharedPointer() {} 19 | inline SharedPointer& operator=(const SharedPointer& other) { 20 | std::shared_ptr::operator=(other); 21 | return *this; 22 | } 23 | inline SharedPointer& operator=(SharedPointer&& other) noexcept { 24 | std::shared_ptr::operator=(other); 25 | return *this; 26 | } 27 | 28 | template 29 | inline SharedPointer operator<<(const U& v) { 30 | auto ptr = std::shared_ptr::get(); 31 | if (!ptr) throw std::runtime_error("The pointer is nullptr"); 32 | return (*ptr) << v; 33 | } 34 | 35 | template 36 | inline SharedPointer operator>>(U& v) { 37 | auto ptr = std::shared_ptr::get(); 38 | if (!ptr) throw std::runtime_error("The pointer is nullptr"); 39 | return (*ptr) >> v; 40 | } 41 | 42 | template 43 | inline SharedPointer operator,(U v) { 44 | auto ptr = std::shared_ptr::get(); 45 | if (!ptr) throw std::runtime_error("The pointer is nullptr"); 46 | return ptr->operator,(v); 47 | } 48 | }; 49 | 50 | } // namespace DB 51 | -------------------------------------------------------------------------------- /src/legacy/legacyapi/db/RowSet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "legacyapi/db/Row.h" 3 | 4 | #include 5 | 6 | #undef max 7 | 8 | namespace DB { 9 | 10 | class RowSet : public std::vector { 11 | 12 | using Base = std::vector; 13 | 14 | public: 15 | std::shared_ptr header; //!< The header of the rows 16 | 17 | /** 18 | * @brief Construct a new Row Set object 19 | * 20 | * @param header The header(column names) of rows(shared_ptr) 21 | */ 22 | RowSet(const std::shared_ptr& header = nullptr); 23 | /** 24 | * @brief Construct a new Row Set object 25 | * 26 | * @param header The header(column names) of rows 27 | */ 28 | RowSet(const RowHeader& header); 29 | /// Move constructor 30 | RowSet(RowSet&& set) noexcept; 31 | /// Copy constructor 32 | RowSet(const RowSet& set); 33 | /// Move assignment operator 34 | RowSet& operator=(RowSet&& set) noexcept; 35 | /// Copy assignment operator 36 | RowSet& operator=(const RowSet& set); 37 | 38 | /** 39 | * @brief Add a row to the set. 40 | * 41 | * @param row The row to add 42 | */ 43 | void add(const Row& row); 44 | /** 45 | * @brief Get if the set is valid 46 | * 47 | * @return bool True if valid 48 | */ 49 | bool valid(); 50 | /** 51 | * @brief Add a row to the set. 52 | * 53 | * @param row The row to add 54 | * @see add(const Row&) 55 | */ 56 | void push_back(const Row& row); 57 | /** 58 | * @brief Convert to the table string. 59 | * 60 | * @param nullPattern When the value is null, what to replace with(default 61 | * '\') 62 | * @return std::string The result string 63 | * @par sample 64 | * @code 65 | * | a | b | 66 | * |=====|========| 67 | * | awa | 114514 | 68 | * | qwq | 233 | 69 | * | ll | | 70 | * |=====|========| 71 | * @endcode 72 | */ 73 | std::string toTableString(const std::string& nullPattern = "") const; 74 | }; 75 | 76 | using ResultSet = RowSet; 77 | 78 | } // namespace DB 79 | -------------------------------------------------------------------------------- /src/legacy/legacyapi/db/Stmt.cpp: -------------------------------------------------------------------------------- 1 | #include "legacyapi/db/Session.h" 2 | 3 | namespace DB { 4 | 5 | Stmt::Stmt(const std::weak_ptr& parent, bool autoExecute) : parent(parent), autoExecute(autoExecute) {} 6 | 7 | Stmt::~Stmt() {} 8 | 9 | void Stmt::setDebugOutput(bool enable) { debugOutput = enable; } 10 | 11 | std::weak_ptr Stmt::getParent() const { return parent; } 12 | 13 | SharedPointer Stmt::getSharedPointer() const { 14 | if (!self.expired()) { 15 | return self.lock(); 16 | } 17 | return nullptr; 18 | /* Get the stmt ptr 19 | if (!session.expired()) 20 | { 21 | auto ptr = session.lock(); 22 | if (ptr) 23 | { 24 | for (auto& wptr : ptr->stmtPool) 25 | { 26 | if (!wptr.expired()) 27 | { 28 | auto stmt = wptr.lock(); 29 | if (stmt.get() == this) 30 | { 31 | self = wptr; 32 | return stmt; 33 | } 34 | } 35 | } 36 | } 37 | } 38 | throw std::runtime_error("Stmt::getSharedPointer: The pointer is not found or 39 | expired"); 40 | */ 41 | } 42 | 43 | SharedPointer Stmt::operator,(const BindType& b) { 44 | if (b.name.empty() && b.idx == -1) { 45 | bind(b.value); 46 | } else if (!b.name.empty()) { 47 | bind(b.value, b.name); 48 | } else if (b.idx != -1) { 49 | bind(b.value, b.idx); 50 | } else { 51 | throw std::invalid_argument("Stmt::operator,: Parameter `b`(const BindType&) is invalid"); 52 | } 53 | return getSharedPointer(); 54 | } 55 | 56 | } // namespace DB 57 | -------------------------------------------------------------------------------- /src/legacy/legacyapi/db/Types.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | // #define LLDB_DEBUG_MODE 4 | 5 | namespace DB { 6 | 7 | enum class DBType : char { 8 | None, 9 | SQLite, 10 | MySQL, 11 | }; 12 | 13 | struct Date { 14 | int year; 15 | int month; 16 | int day; 17 | }; 18 | 19 | struct Time { 20 | int hour; 21 | int minute; 22 | int second; 23 | int timezone = -1; 24 | }; 25 | 26 | struct DateTime { 27 | Date date; 28 | Time time; 29 | }; 30 | 31 | struct Decimal { 32 | int64_t value; 33 | int scale; 34 | }; 35 | 36 | using ByteArray = std::vector; 37 | 38 | } // namespace DB 39 | -------------------------------------------------------------------------------- /src/legacy/legacyapi/db/impl/mysql/Session.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "legacyapi/db/Session.h" 3 | 4 | #include 5 | 6 | namespace DB { 7 | 8 | class MySQLStmt; 9 | 10 | class MySQLSession : public Session { 11 | 12 | MYSQL* conn = nullptr; 13 | 14 | void setSSL(const ConnParams& params); 15 | 16 | public: 17 | MySQLSession(); 18 | MySQLSession(const ConnParams& params); 19 | ~MySQLSession(); 20 | void open(const ConnParams& params); 21 | bool execute(const std::string& query); 22 | bool relogin(const std::string& user, const std::string& password, const std::string& db = ""); 23 | Session& query(const std::string& query, std::function callback); 24 | SharedPointer prepare(const std::string& query, bool autoExecute = false); 25 | std::string getLastError() const; 26 | uint64_t getAffectedRows() const; 27 | uint64_t getLastInsertId() const; 28 | void close(); 29 | bool isOpen(); 30 | DBType getType(); 31 | 32 | SharedPointer operator<<(const std::string& query); 33 | 34 | friend class MySQLStmt; 35 | }; 36 | 37 | } // namespace DB 38 | -------------------------------------------------------------------------------- /src/legacy/legacyapi/db/impl/mysql/Stmt.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "legacyapi/db/Stmt.h" 3 | 4 | #include 5 | 6 | namespace DB { 7 | 8 | class MySQLSession; 9 | 10 | struct Receiver { 11 | MYSQL_FIELD field; 12 | std::shared_ptr buffer; 13 | unsigned long length = 0; 14 | my_bool isNull = false; 15 | bool isUnsigned = false; 16 | my_bool error = false; 17 | }; 18 | 19 | class MySQLStmt : public Stmt { 20 | 21 | MYSQL_STMT* stmt = nullptr; 22 | MYSQL_RES* metadata = nullptr; 23 | std::shared_ptr params = nullptr; ///< Parameters to bind 24 | std::shared_ptr result = nullptr; ///< Result of query 25 | std::shared_ptr resultHeader = nullptr; 26 | std::vector boundIndexes; 27 | std::vector paramValues; 28 | std::vector resultValues; 29 | std::unordered_map paramIndexes; 30 | std::string query; 31 | int boundParamsCount = 0; 32 | int totalParamsCount = 0; 33 | int steps = 0; 34 | bool fetched = false; 35 | 36 | MySQLStmt(MYSQL_STMT* stmt, const std::weak_ptr& parent, bool autoExecute = false); 37 | int getNextParamIndex(); 38 | void bindResult(); 39 | 40 | public: 41 | ~MySQLStmt(); 42 | Stmt& bind(const Any& value, int index); 43 | Stmt& bind(const Any& value, const std::string& name); 44 | Stmt& bind(const Any& value); 45 | Stmt& execute(); 46 | bool step(); 47 | bool next(); 48 | bool done(); 49 | Row _Fetch(); 50 | Stmt& reset(); 51 | Stmt& reexec(); 52 | Stmt& clear(); 53 | void close(); 54 | uint64_t getAffectedRows() const; 55 | uint64_t getInsertId() const; 56 | int getUnboundParams() const; 57 | int getBoundParams() const; 58 | int getParamsCount() const; 59 | DBType getType() const; 60 | 61 | static SharedPointer 62 | create(const std::weak_ptr& sess, const std::string& sql, bool autoExecute = false); 63 | }; 64 | 65 | } // namespace DB 66 | -------------------------------------------------------------------------------- /src/legacy/legacyapi/db/impl/sqlite/Session.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "legacyapi/db/Session.h" 3 | 4 | struct sqlite3; 5 | namespace DB { 6 | 7 | class SQLiteSession : public Session { 8 | 9 | sqlite3* conn = nullptr; 10 | 11 | public: 12 | SQLiteSession(); 13 | SQLiteSession(const ConnParams& params); 14 | ~SQLiteSession(); 15 | void open(const ConnParams& params); 16 | bool execute(const std::string& query); 17 | Session& query(const std::string& query, std::function callback); 18 | SharedPointer prepare(const std::string& query, bool autoExecute = false); 19 | std::string getLastError() const; 20 | uint64_t getAffectedRows() const; 21 | uint64_t getLastInsertId() const; 22 | void close(); 23 | bool isOpen(); 24 | DBType getType(); 25 | 26 | SharedPointer operator<<(const std::string& query); 27 | 28 | friend class SQLiteStmt; 29 | }; 30 | 31 | } // namespace DB 32 | -------------------------------------------------------------------------------- /src/legacy/legacyapi/db/impl/sqlite/Stmt.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "legacyapi/db/Stmt.h" 3 | 4 | struct sqlite3_stmt; 5 | 6 | namespace DB { 7 | 8 | class SQLiteSession; 9 | 10 | class SQLiteStmt : public Stmt { 11 | 12 | std::shared_ptr resultHeader; 13 | sqlite3_stmt* stmt = nullptr; 14 | int boundParamsCount = 0; 15 | int totalParamsCount = 0; 16 | int steps = 0; 17 | uint64_t affectedRowCount = -1; 18 | uint64_t insertRowId = -1; 19 | bool stepped = false; 20 | bool executed = false; 21 | std::vector boundIndexes; 22 | 23 | SQLiteStmt(sqlite3_stmt* stmt, const std::weak_ptr parent, bool autoExecute); 24 | int getNextParamIndex(); 25 | void fetchResultHeader(); 26 | 27 | public: 28 | ~SQLiteStmt(); 29 | Stmt& bind(const Any& value, int index); 30 | Stmt& bind(const Any& value, const std::string& name); 31 | Stmt& bind(const Any& value); 32 | Stmt& execute(); 33 | bool step(); 34 | bool next(); 35 | bool done(); 36 | Row _Fetch(); 37 | Stmt& reset(); 38 | /** 39 | * @see Stmt::reexec for details 40 | * @see https://www.sqlite.org/c3ref/reexec.html 41 | */ 42 | Stmt& reexec(); 43 | Stmt& clear(); 44 | void close(); 45 | uint64_t getAffectedRows() const; 46 | uint64_t getInsertId() const; 47 | int getUnboundParams() const; 48 | int getBoundParams() const; 49 | int getParamsCount() const; 50 | DBType getType() const; 51 | 52 | static SharedPointer 53 | create(const std::weak_ptr& sess, const std::string& sql, bool autoExecute = false); 54 | }; 55 | 56 | } // namespace DB 57 | -------------------------------------------------------------------------------- /src/legacy/legacyapi/utils/FileHelper.cpp: -------------------------------------------------------------------------------- 1 | #include "FileHelper.h" 2 | 3 | #include "ll/api/utils/StringUtils.h" 4 | 5 | #include 6 | 7 | namespace lse::legacy { 8 | 9 | std::pair NewProcessSync(const std::string& process, int timeLimit = -1, bool noReadOutput = true) { 10 | SECURITY_ATTRIBUTES sa; 11 | HANDLE hRead, hWrite; 12 | sa.nLength = sizeof(SECURITY_ATTRIBUTES); 13 | sa.lpSecurityDescriptor = nullptr; 14 | sa.bInheritHandle = TRUE; 15 | 16 | if (!CreatePipe(&hRead, &hWrite, &sa, 0)) return {-1, ""}; 17 | STARTUPINFOW si = {0}; 18 | PROCESS_INFORMATION pi; 19 | 20 | si.cb = sizeof(STARTUPINFO); 21 | GetStartupInfoW(&si); 22 | si.hStdOutput = si.hStdError = hWrite; 23 | si.dwFlags = STARTF_USESTDHANDLES; 24 | 25 | auto wCmd = ll::string_utils::str2wstr(process); 26 | if (!CreateProcessW( 27 | nullptr, 28 | const_cast(wCmd.c_str()), 29 | nullptr, 30 | nullptr, 31 | TRUE, 32 | 0, 33 | nullptr, 34 | nullptr, 35 | &si, 36 | &pi 37 | )) { 38 | return {-1, ""}; 39 | } 40 | CloseHandle(hWrite); 41 | CloseHandle(pi.hThread); 42 | 43 | if (timeLimit == -1) WaitForSingleObject(pi.hProcess, INFINITE); 44 | else { 45 | WaitForSingleObject(pi.hProcess, timeLimit); 46 | TerminateProcess(pi.hProcess, -1); 47 | } 48 | char buffer[8192]; 49 | std::string strOutput; 50 | DWORD bytesRead, exitCode; 51 | 52 | GetExitCodeProcess(pi.hProcess, &exitCode); 53 | if (!noReadOutput) { 54 | while (true) { 55 | ZeroMemory(buffer, 8192); 56 | if (!ReadFile(hRead, buffer, 8192, &bytesRead, nullptr)) break; 57 | strOutput.append(buffer, bytesRead); 58 | } 59 | } 60 | CloseHandle(hRead); 61 | CloseHandle(pi.hProcess); 62 | return {exitCode, strOutput}; 63 | } 64 | 65 | std::pair UncompressFile(const std::string& filePath, const std::string& toDir, int processTimeout) { 66 | std::error_code ec; 67 | std::filesystem::create_directories(toDir, ec); 68 | std::string realToDir = toDir.ends_with('/') ? toDir : toDir + "/"; 69 | auto&& [exitCode, output] = 70 | NewProcessSync(fmt::format(R"({} x "{}" -o"{}" -aoa)", "7za.exe", filePath, realToDir), processTimeout); 71 | return {exitCode, std::move(output)}; 72 | } 73 | } // namespace lse::legacy 74 | -------------------------------------------------------------------------------- /src/legacy/legacyapi/utils/FileHelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ll/api/base/Macro.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace lse::legacy { 10 | std::pair UncompressFile(const std::string& filePath, const std::string& toDir, int processTimeout); 11 | } // namespace lse::legacy 12 | -------------------------------------------------------------------------------- /src/legacy/legacyapi/utils/StringReader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace lse::legacy { 5 | class StringReader { 6 | 7 | const std::string str; 8 | size_t length = 0; 9 | std::string::const_iterator begin; 10 | std::string::const_iterator end; 11 | std::string::const_iterator it; 12 | 13 | public: 14 | StringReader(const std::string& str); 15 | StringReader(const char* str); 16 | StringReader(const char* str, size_t len); 17 | StringReader(const StringReader& other) = default; 18 | StringReader(StringReader&& other) = default; 19 | StringReader& operator=(const StringReader& other) = default; 20 | StringReader& operator=(StringReader&& other) = default; 21 | 22 | bool isEmpty() const; 23 | bool isEnd() const; 24 | bool isStart() const; 25 | bool isValid() const; 26 | size_t getPos() const; 27 | size_t getLength() const; 28 | size_t getRemaining() const; 29 | 30 | char read(); 31 | char read(char& c); 32 | std::string read(size_t len); 33 | std::string readUntil(char c); 34 | std::string readUntil(const std::string& chars); 35 | std::string readUntilNot(const std::string& chars); 36 | std::string readUntilNot(char c); 37 | std::string readLine(); 38 | std::string readLetters(const std::string& chars = ""); 39 | std::string readLower(const std::string& chars = ""); 40 | std::string readUpper(const std::string& chars = ""); 41 | std::string readDigits(const std::string& chars = ""); 42 | std::string readLettersAndDigits(const std::string& chars = ""); 43 | std::string readVariableName(); 44 | std::string readToEnd(); 45 | char peek(); 46 | char peek(char& c); 47 | char peek(size_t offset); 48 | std::string peek(size_t offset, size_t len); 49 | void skip(); 50 | void skip(size_t len); 51 | void skipUntil(char c); 52 | void skipUntil(const std::string& chars); 53 | void skipUntilNot(char c); 54 | void skipUntilNot(const std::string& chars); 55 | void skipWhitespace(); 56 | void skipLine(); 57 | void skipLetters(const std::string& chars = ""); 58 | void skipLower(const std::string& chars = ""); 59 | void skipUpper(const std::string& chars = ""); 60 | void skipDigits(const std::string& chars = ""); 61 | void skipLettersAndDigits(const std::string& chars = ""); 62 | 63 | template 64 | inline T readInteger() { 65 | T result = 0; 66 | while (isValid() && isdigit(read())) { 67 | result = result * 10 + (read() - '0'); 68 | } 69 | return result; 70 | } 71 | }; 72 | } // namespace lse::legacy 73 | -------------------------------------------------------------------------------- /src/legacy/main/BuiltinCommands.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | bool ProcessDebugEngine(const std::string& cmd); 5 | void RegisterDebugCommand(); 6 | -------------------------------------------------------------------------------- /src/legacy/main/EconomicSystem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "LLMoney.h" 3 | 4 | #include 5 | 6 | using std::string; 7 | class EconomySystem { 8 | public: 9 | static bool init(); 10 | 11 | static long long getMoney(std::string player); 12 | static bool setMoney(std::string player, long long money); 13 | static bool addMoney(std::string player, long long money); 14 | static bool reduceMoney(std::string player, long long money); 15 | static bool transMoney(std::string player1, std::string player2, long long money, string const& notes); 16 | static std::string getMoneyHist(std::string player, int time); 17 | static void clearMoneyHist(int time); 18 | }; 19 | -------------------------------------------------------------------------------- /src/legacy/main/EconomySystem.cpp: -------------------------------------------------------------------------------- 1 | #include "LLMoney.h" 2 | #include "api/EventAPI.h" 3 | #include "ll/api/io/Logger.h" 4 | #include "main/EconomicSystem.h" 5 | 6 | #include 7 | 8 | ////////////// Helper ////////////// 9 | 10 | bool EconomySystem::init() { 11 | LLMoney_ListenBeforeEvent(MoneyBeforeEventCallback); 12 | LLMoney_ListenAfterEvent(MoneyEventCallback); 13 | return true; 14 | } 15 | 16 | long long EconomySystem::getMoney(std::string player) { return LLMoney_Get(player); } 17 | 18 | bool EconomySystem::setMoney(std::string player, long long money) { return LLMoney_Set(player, money); } 19 | 20 | bool EconomySystem::addMoney(std::string player, long long money) { 21 | return LLMoney_Set(player, LLMoney_Get(player) + money); 22 | } 23 | 24 | bool EconomySystem::reduceMoney(std::string player, long long money) { return LLMoney_Reduce(player, money); } 25 | 26 | bool EconomySystem::transMoney(std::string player1, std::string player2, long long money, string const& notes) { 27 | return LLMoney_Trans(player1, player2, money, notes); 28 | } 29 | 30 | std::string EconomySystem::getMoneyHist(std::string player, int time) { return LLMoney_GetHist(player, time); } 31 | 32 | void EconomySystem::clearMoneyHist(int time) { LLMoney_ClearHist(time); } 33 | -------------------------------------------------------------------------------- /src/legacy/main/Global.cpp: -------------------------------------------------------------------------------- 1 | #include "main/Global.h" 2 | 3 | // 全局变量 4 | bool isCmdRegisterEnabled = false; -------------------------------------------------------------------------------- /src/legacy/main/Global.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ll/api/i18n/I18n.h" 4 | #include "mc/deps/core/math/Vec3.h" 5 | #include "mc/world/level/BlockPos.h" 6 | 7 | #include 8 | #include 9 | 10 | class IntVec4 { 11 | public: 12 | int x, y, z; 13 | int dim; 14 | 15 | inline BlockPos getBlockPos() { return {x, y, z}; } 16 | 17 | inline int getDimensionId() { return dim; } 18 | }; 19 | 20 | class FloatVec4 { 21 | public: 22 | float x, y, z; 23 | int dim; 24 | 25 | inline Vec3 getVec3() { return {x, y, z}; } 26 | 27 | inline int getDimensionId() { return dim; } 28 | 29 | inline IntVec4 toIntVec4() { 30 | auto px = (int)x; 31 | auto py = (int)y; 32 | auto pz = (int)z; 33 | if (px < 0 && px != x) px = px - 1; 34 | if (py < 0 && py != y) py = py - 1; 35 | if (pz < 0 && pz != z) pz = pz - 1; 36 | return {px, py, pz, dim}; 37 | } 38 | }; 39 | 40 | using namespace ll::i18n_literals; 41 | 42 | inline std::string DimId2Name(int dimid) { 43 | std::string name; 44 | switch (dimid) { 45 | case 0: 46 | name = "Overworld"_tr(); 47 | break; 48 | case 1: 49 | name = "Nether"_tr(); 50 | break; 51 | case 2: 52 | name = "End"_tr(); 53 | break; 54 | default: 55 | name = "Other dimension"_tr(); 56 | break; 57 | } 58 | return name; 59 | } 60 | 61 | // 全局变量 62 | extern bool isCmdRegisterEnabled; 63 | 64 | #if defined(LEGACY_SCRIPT_ENGINE_BACKEND_QUICKJS) 65 | // QuickJs 66 | constexpr std::string LLSE_BACKEND_TYPE = "Js"; 67 | 68 | #elif defined(LEGACY_SCRIPT_ENGINE_BACKEND_LUA) 69 | // Lua 70 | constexpr std::string LLSE_BACKEND_TYPE = "Lua"; 71 | 72 | #elif defined(LEGACY_SCRIPT_ENGINE_BACKEND_NODEJS) 73 | // NodeJs 74 | const std::string LLSE_BACKEND_TYPE = "NodeJs"; 75 | 76 | #elif defined(LEGACY_SCRIPT_ENGINE_BACKEND_PYTHON) 77 | // Python 78 | const std::string LLSE_BACKEND_TYPE = "Python"; 79 | #endif 80 | 81 | // Debug engine information 82 | #if defined(LEGACY_SCRIPT_ENGINE_BACKEND_NODEJS) 83 | constexpr std::string LLSE_DEBUG_CMD = "nodejsdebug"; 84 | #elif defined(LEGACY_SCRIPT_ENGINE_BACKEND_QUICKJS) 85 | constexpr std::string LLSE_DEBUG_CMD = "jsdebug"; 86 | #elif defined(LEGACY_SCRIPT_ENGINE_BACKEND_LUA) 87 | constexpr std::string LLSE_DEBUG_CMD = "luadebug"; 88 | #elif defined(LEGACY_SCRIPT_ENGINE_BACKEND_PYTHON) 89 | constexpr std::string LLSE_DEBUG_CMD = "pydebug"; 90 | #endif 91 | 92 | constexpr wchar_t LLSE_GLOBAL_DATA_NAME[] = L"LLSE_GLOBAL_DATA_SECTION"; 93 | constexpr unsigned long LLSE_MESSAGE_SYSTEM_WAIT_CHECK_INTERVAL = 5; 94 | constexpr size_t LLSE_POOL_THREAD_COUNT = 4; 95 | constexpr int LLSE_VALID_BACKENDS_COUNT = 4; 96 | -------------------------------------------------------------------------------- /src/legacy/main/NodeJsHelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma warning(disable : 4251) 3 | #include "legacy/main/Global.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace NodeJsHelper { 11 | 12 | bool initNodeJs(); 13 | void shutdownNodeJs(); 14 | 15 | script::ScriptEngine* newEngine(); 16 | bool stopEngine(script::ScriptEngine* engine); 17 | bool stopEngine(node::Environment* env); 18 | script::ScriptEngine* getEngine(node::Environment* env); 19 | 20 | bool loadPluginCode( 21 | script::ScriptEngine* engine, 22 | std::string entryScriptPath, 23 | std::string pluginDirPath, 24 | bool esm = false 25 | ); // raw 26 | 27 | std::string findEntryScript(const std::string& dirPath); 28 | std::string getPluginPackageName(const std::string& dirPath); 29 | bool doesPluginPackHasDependency(const std::string& dirPath); 30 | bool isESModulesSystem(const std::string& dirPath); 31 | 32 | bool processConsoleNpmCmd(const std::string& cmd); 33 | int executeNpmCommand(const std::string& cmd, std::string workingDir = ""); 34 | 35 | } // namespace NodeJsHelper 36 | -------------------------------------------------------------------------------- /src/legacy/main/PythonHelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace PythonHelper { 8 | 9 | bool initPythonRuntime(); 10 | 11 | // raw, will throw exception if fail 12 | bool loadPluginCode(script::ScriptEngine* engine, std::string entryScriptPath, std::string pluginDirPath); 13 | 14 | std::string findEntryScript(const std::string& dirPath); 15 | std::string getPluginPackageName(const std::string& dirPath); 16 | std::string getPluginPackDependencyFilePath(const std::string& dirPath); 17 | 18 | bool processPythonDebugEngine(const std::string& cmd); 19 | 20 | bool processConsolePipCmd(const std::string& cmd); 21 | int executePipCommand(std::string cmd); 22 | 23 | } // namespace PythonHelper 24 | -------------------------------------------------------------------------------- /src/legacy/main/SafeGuardRecord.cpp: -------------------------------------------------------------------------------- 1 | #include "legacy/main/Global.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | std::ofstream record; 8 | 9 | void InitSafeGuardRecord() { 10 | std::filesystem::create_directories("logs/LegacyScriptEngine"); 11 | record.open( 12 | std::string("logs/LegacyScriptEngine/Sensitive_Operation_Records-") + LLSE_BACKEND_TYPE + ".log", 13 | std::ios::app 14 | ); 15 | } 16 | 17 | void RecordOperation(const std::string& pluginName, const std::string& operation, const std::string& content) { 18 | if (record.is_open()) record << "[" << operation << "]<" << pluginName << "> " << content << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /src/legacy/main/SafeGuardRecord.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | void InitSafeGuardRecord(); 5 | void RecordOperation(const std::string& pluginName, const std::string& operation, const std::string& content); 6 | -------------------------------------------------------------------------------- /src/legacy/utils/IniHelper.cpp: -------------------------------------------------------------------------------- 1 | #include "utils/IniHelper.h" 2 | 3 | #include "ll/api/io/Logger.h" 4 | #include "lse/Entry.h" 5 | 6 | #include 7 | 8 | SimpleIni* SimpleIni::create(const std::string& path, const std::string& defContent) { 9 | if (!std::filesystem::exists(ll::string_utils::str2wstr(path))) { 10 | // 创建新的 11 | std::filesystem::create_directories( 12 | std::filesystem::path(ll::string_utils::str2wstr(path)).remove_filename().u8string() 13 | ); 14 | 15 | std::ofstream iniFile(path); 16 | if (iniFile.is_open() && defContent != "") iniFile << defContent; 17 | iniFile.close(); 18 | } 19 | 20 | // 已存在 21 | auto root = new SimpleIni; 22 | root->SetUnicode(true); 23 | auto res = root->LoadFile(path.c_str()); 24 | if (res < 0) { 25 | lse::LegacyScriptEngine::getInstance().getSelf().getLogger().error("Failed in loading ini file"); 26 | lse::LegacyScriptEngine::getInstance().getSelf().getLogger().error( 27 | string("Error Code:") + std::to_string((int)res) 28 | ); 29 | delete root; 30 | return nullptr; 31 | } else { 32 | root->filePath = path; 33 | return root; 34 | } 35 | } 36 | 37 | bool SimpleIni::setInt(const string& sec, const string& key, int value) { 38 | bool isOk = SetLongValue(sec.c_str(), key.c_str(), value) >= 0; 39 | SaveFile(filePath.c_str()); 40 | return isOk; 41 | } 42 | 43 | bool SimpleIni::setFloat(const string& sec, const string& key, float value) { 44 | bool isOk = SetDoubleValue(sec.c_str(), key.c_str(), value) >= 0; 45 | SaveFile(filePath.c_str()); 46 | return isOk; 47 | } 48 | 49 | bool SimpleIni::setString(const string& sec, const string& key, const string& value) { 50 | bool isOk = SetValue(sec.c_str(), key.c_str(), value.c_str()) >= 0; 51 | SaveFile(filePath.c_str()); 52 | return isOk; 53 | } 54 | 55 | bool SimpleIni::setBool(const string& sec, const string& key, bool value) { 56 | bool isOk = SetBoolValue(sec.c_str(), key.c_str(), value) >= 0; 57 | SaveFile(filePath.c_str()); 58 | return isOk; 59 | } 60 | 61 | int SimpleIni::getInt(const string& sec, const string& key, int def) { 62 | return GetLongValue(sec.c_str(), key.c_str(), def); 63 | } 64 | 65 | float SimpleIni::getFloat(const string& sec, const string& key, float def) { 66 | return (float)GetDoubleValue(sec.c_str(), key.c_str(), def); 67 | } 68 | 69 | string SimpleIni::getString(const string& sec, const string& key, const string& def) { 70 | return GetValue(sec.c_str(), key.c_str(), def.c_str()); 71 | } 72 | 73 | bool SimpleIni::getBool(const string& sec, const string& key, bool def) { 74 | return GetBoolValue(sec.c_str(), key.c_str(), def); 75 | } 76 | 77 | bool SimpleIni::deleteKey(const std::string& sec, const std::string& key) { 78 | return Delete(sec.c_str(), key.c_str(), true); 79 | } 80 | -------------------------------------------------------------------------------- /src/legacy/utils/IniHelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "SimpleIni.h" 3 | 4 | #include 5 | 6 | using std::string; 7 | 8 | class SimpleIni : public CSimpleIniA { 9 | public: 10 | std::string filePath; 11 | 12 | static inline SimpleIni* create(const std::string& path) { return create(path, ""); } 13 | static SimpleIni* create(const std::string& path, const std::string& defContent); 14 | 15 | bool setInt(const string& sec, const string& key, int value); 16 | bool setFloat(const string& sec, const string& key, float value); 17 | bool setString(const string& sec, const string& key, const string& value); 18 | bool setBool(const string& sec, const string& key, bool value); 19 | int getInt(const string& sec, const string& key, int def); 20 | float getFloat(const string& sec, const string& key, float def); 21 | string getString(const string& sec, const string& key, const string& def); 22 | bool getBool(const string& sec, const string& key, bool def); 23 | bool deleteKey(const std::string& sec, const std::string& key); 24 | }; 25 | -------------------------------------------------------------------------------- /src/legacy/utils/UsingScriptX.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | using script::Arguments; 6 | using script::Array; 7 | using script::Boolean; 8 | using script::ByteBuffer; 9 | using script::ClassDefine; 10 | using script::defineClass; 11 | using script::EngineScope; 12 | using script::Exception; 13 | using script::ExitEngineScope; 14 | using script::Function; 15 | using script::Local; 16 | using script::Number; 17 | using script::Object; 18 | using script::ScriptClass; 19 | using script::ScriptEngine; 20 | using script::ScriptEngineImpl; 21 | using script::selectOverloadedFunc; 22 | using script::String; 23 | using script::Value; 24 | using script::ValueKind; 25 | -------------------------------------------------------------------------------- /src/legacy/utils/Utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | std::vector SplitCmdLine(const std::string& paras); 8 | 9 | bool IsVersionLess(const std::string& v1, const std::string& v2); 10 | bool IsVersionLess(int v1a, int v1b, int v1c, int v2a, int v2b, int v2c); 11 | 12 | unsigned long long GetCurrentTimeStampMS(); 13 | wchar_t* str2cwstr(std::string str); 14 | 15 | // System 16 | std::string Raw_GetDateTimeStr(); 17 | std::string Raw_RandomGuid(); 18 | std::wstring Raw_RandomGuidW(); 19 | -------------------------------------------------------------------------------- /src/lse/Config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace lse { 4 | 5 | struct Config { 6 | int version = 1; 7 | bool migratePlugins = true; 8 | }; 9 | 10 | } // namespace lse 11 | -------------------------------------------------------------------------------- /src/lse/Entry.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Config.h" 4 | #include "PluginManager.h" 5 | #include "ll/api/mod/NativeMod.h" 6 | 7 | namespace lse { 8 | 9 | class LegacyScriptEngine { 10 | public: 11 | static LegacyScriptEngine& getInstance(); 12 | 13 | LegacyScriptEngine() : mSelf(*ll::mod::NativeMod::current()) {} 14 | 15 | [[nodiscard]] ll::mod::NativeMod& getSelf() const { return mSelf; } 16 | 17 | [[nodiscard]] Config const& getConfig(); 18 | 19 | [[nodiscard]] PluginManager& getManager(); 20 | 21 | bool load(); 22 | 23 | bool enable(); 24 | 25 | bool disable(); 26 | 27 | // bool unload(); 28 | 29 | private: 30 | ll::mod::NativeMod& mSelf; 31 | Config config; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) 32 | std::shared_ptr pluginManager; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) 33 | }; 34 | 35 | } // namespace lse 36 | -------------------------------------------------------------------------------- /src/lse/MemoryOperators.cpp: -------------------------------------------------------------------------------- 1 | // This file will make your plugin use LeviLamina's memory operators by default. 2 | // This improves the memory management of your plugin and is recommended to use. 3 | 4 | #define LL_MEMORY_OPERATORS 5 | 6 | #include 7 | -------------------------------------------------------------------------------- /src/lse/Plugin.cpp: -------------------------------------------------------------------------------- 1 | #include "Plugin.h" 2 | 3 | #include "Entry.h" 4 | #include "legacy/engine/EngineOwnData.h" 5 | #include "ll/api/mod/Manifest.h" 6 | #include "ll/api/mod/Mod.h" 7 | 8 | namespace lse { 9 | 10 | Plugin::Plugin(const ll::mod::Manifest& manifest) : ll::mod::Mod(std::move(manifest)) {} 11 | 12 | Plugin::~Plugin() { release(); } 13 | 14 | std::shared_ptr Plugin::current() { 15 | return lse::LegacyScriptEngine::getInstance().getManager().getMod(getEngineOwnData()->pluginName); 16 | } 17 | } // namespace lse 18 | -------------------------------------------------------------------------------- /src/lse/Plugin.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PluginManager.h" 4 | #include "ll/api/command/runtime/ParamKind.h" 5 | #include "ll/api/mod/Manifest.h" 6 | #include "ll/api/mod/Mod.h" 7 | 8 | namespace lse { 9 | 10 | class Plugin : public ll::mod::Mod { 11 | friend PluginManager; 12 | 13 | public: 14 | struct ParamInfo { 15 | std::string name; 16 | ll::command::ParamKind::Kind type; 17 | bool optional; 18 | std::string enumName; 19 | CommandParameterOption option; 20 | std::string identifier; 21 | }; 22 | 23 | std::unordered_map> registeredCommands; 24 | 25 | Plugin(const ll::mod::Manifest& manifest); 26 | ~Plugin(); 27 | 28 | static std::shared_ptr current(); 29 | }; 30 | } // namespace lse 31 | -------------------------------------------------------------------------------- /src/lse/PluginManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ll/api/Expected.h" 3 | #include "ll/api/base/Macro.h" 4 | #include "ll/api/mod/Manifest.h" 5 | #include "ll/api/mod/ModManager.h" 6 | 7 | #include 8 | 9 | namespace lse { 10 | 11 | class PluginManager final : public ll::mod::ModManager { 12 | public: 13 | PluginManager(); 14 | ~PluginManager() override; 15 | 16 | private: 17 | ll::Expected<> load(ll::mod::Manifest manifest) override; 18 | ll::Expected<> unload(std::string_view name) override; 19 | }; 20 | 21 | } // namespace lse 22 | -------------------------------------------------------------------------------- /src/lse/PluginMigration.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PluginManager.h" 4 | 5 | namespace lse { 6 | 7 | auto migratePlugins(const PluginManager& pluginManager) -> void; 8 | 9 | } // namespace lse 10 | -------------------------------------------------------------------------------- /src/lse/api/DirectFormatter.cpp: -------------------------------------------------------------------------------- 1 | #include "lse/api/DirectFormatter.h" 2 | 3 | namespace lse::io { 4 | void DirectFormatter::format(const ll::io::LogMessageView& view, std::string& buffer) const noexcept { 5 | buffer = view.msg; 6 | } 7 | } // namespace lse::io -------------------------------------------------------------------------------- /src/lse/api/DirectFormatter.h: -------------------------------------------------------------------------------- 1 | #include "ll/api/io/Formatter.h" 2 | 3 | namespace lse::io { 4 | using namespace ll::io; 5 | class DirectFormatter : public Formatter { 6 | public: 7 | DirectFormatter() = default; 8 | virtual ~DirectFormatter() override = default; 9 | 10 | void format(LogMessageView const& view, std::string& buffer) const noexcept override; 11 | }; 12 | 13 | } // namespace lse::io -------------------------------------------------------------------------------- /src/lse/api/MoreGlobal.cpp: -------------------------------------------------------------------------------- 1 | #include "MoreGlobal.h" 2 | 3 | #include "ll/api/memory/Hook.h" 4 | #include "mc/dataloadhelper/DefaultDataLoadHelper.h" 5 | #include "mc/world/level/storage/DBStorage.h" 6 | #include "mc/world/level/storage/DBStorageConfig.h" 7 | 8 | namespace lse::api::MoreGlobal { 9 | DBStorage* dbStorage; 10 | DefaultDataLoadHelper helper; 11 | DefaultDataLoadHelper& defaultDataLoadHelper() { return helper; } 12 | 13 | LL_TYPE_INSTANCE_HOOK( 14 | DBStorageHook, 15 | HookPriority::Normal, 16 | DBStorage, 17 | &DBStorage::$ctor, 18 | void*, 19 | ::DBStorageConfig config, 20 | ::Bedrock::NotNullNonOwnerPtr<::LevelDbEnv> levelDbEnv 21 | ) { 22 | void* ori = origin(std::move(config), levelDbEnv); 23 | MoreGlobal::dbStorage = (DBStorage*)ori; 24 | return ori; 25 | }; 26 | 27 | void onLoad() { DBStorageHook::hook(); } 28 | 29 | bool onEnable() { 30 | if (dbStorage && DBStorageHook::unhook()) { 31 | return true; 32 | } 33 | return false; 34 | } 35 | } // namespace lse::api::MoreGlobal 36 | -------------------------------------------------------------------------------- /src/lse/api/MoreGlobal.h: -------------------------------------------------------------------------------- 1 | #include "mc/dataloadhelper/DefaultDataLoadHelper.h" 2 | class DBStorage; 3 | namespace lse::api::MoreGlobal { 4 | extern DBStorage* dbStorage; 5 | extern DefaultDataLoadHelper& defaultDataLoadHelper(); 6 | extern void onLoad(); 7 | extern bool onEnable(); 8 | }; // namespace lse::api::MoreGlobal 9 | -------------------------------------------------------------------------------- /src/lse/api/NetworkPacket.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ll/api/memory/Memory.h" 4 | #include "mc/deps/core/platform/Result.h" 5 | #include "mc/deps/core/utility/BinaryStream.h" 6 | #include "mc/network/MinecraftPacketIds.h" 7 | #include "mc/network/packet/Packet.h" 8 | 9 | #include 10 | #include 11 | 12 | namespace lse::api { 13 | 14 | template 15 | class NetworkPacket final : public Packet { 16 | public: 17 | NetworkPacket(std::string data) : mData(std::move(data)) {} 18 | 19 | NetworkPacket() = default; 20 | NetworkPacket(NetworkPacket&&) = default; 21 | auto operator=(NetworkPacket&&) -> NetworkPacket& = default; 22 | ~NetworkPacket() = default; 23 | 24 | NetworkPacket(const NetworkPacket&) = delete; 25 | auto operator=(const NetworkPacket&) -> NetworkPacket& = delete; 26 | 27 | [[nodiscard]] auto getId() const -> MinecraftPacketIds override { return packetId; } 28 | 29 | [[nodiscard]] auto getName() const -> std::string override { return "NetworkPacket"; } 30 | 31 | void write(BinaryStream& stream) const override { stream.mBuffer.append(mData); } 32 | 33 | auto _read(class ReadOnlyBinaryStream& /*stream*/) -> Bedrock::Result override { 34 | return Bedrock::Result{}; 35 | } 36 | 37 | private: 38 | std::string mData; 39 | }; 40 | 41 | } // namespace lse::api 42 | -------------------------------------------------------------------------------- /src/lse/api/PlayerSink.cpp: -------------------------------------------------------------------------------- 1 | #include "lse/api/PlayerSink.h" 2 | 3 | #include "ll/api/io/FileUtils.h" 4 | #include "ll/api/io/PatternFormatter.h" 5 | #include "ll/api/service/Bedrock.h" 6 | #include "mc/world/actor/player/Player.h" 7 | #include "mc/world/level/Level.h" 8 | 9 | namespace lse::io { 10 | 11 | PlayerSink::PlayerSink(mce::UUID const& uuid) 12 | : Sink(ll::makePolymorphic("<{tit}|{lvl}> [{tm:%T}] {msg}", false)), 13 | playerUuid(uuid) {} 14 | 15 | PlayerSink::~PlayerSink() = default; 16 | 17 | void PlayerSink::setFormatter(ll::Polymorphic fmter) { 18 | std::lock_guard lock(mutex); 19 | formatter = std::move(fmter); 20 | } 21 | void PlayerSink::append(ll::io::LogMessageView const& view) { 22 | std::lock_guard lock(mutex); 23 | std::string buffer; 24 | formatter->format(view, buffer); 25 | if (auto* player = ll::service::getLevel()->getPlayer(playerUuid)) { 26 | player->sendMessage(buffer); 27 | } 28 | } 29 | 30 | void PlayerSink::setUUID(mce::UUID const& uuid) { playerUuid = uuid; } 31 | } // namespace lse::io -------------------------------------------------------------------------------- /src/lse/api/PlayerSink.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ll/api/io/Sink.h" 4 | #include "mc/platform/UUID.h" 5 | 6 | #include 7 | 8 | namespace lse::io { 9 | class PlayerSink : public ll::io::Sink { 10 | std::mutex mutex; 11 | mce::UUID playerUuid; 12 | 13 | public: 14 | PlayerSink(mce::UUID const& uuid); 15 | 16 | ~PlayerSink() override; 17 | 18 | void setFormatter(ll::Polymorphic fmter) override; 19 | 20 | void append(ll::io::LogMessageView const& view) override; 21 | 22 | void setUUID(mce::UUID const& uuid); 23 | }; 24 | } // namespace lse::io -------------------------------------------------------------------------------- /src/lse/api/helper/AttributeHelper.cpp: -------------------------------------------------------------------------------- 1 | #include "AttributeHelper.h" 2 | 3 | #include "mc/world/attribute/AttributeInstance.h" 4 | #include "mc/world/attribute/AttributeModificationContext.h" 5 | #include "mc/world/attribute/BaseAttributeMap.h" 6 | 7 | namespace lse::api { 8 | inline void AttributeHelper::setDirty(MutableAttributeWithContext& attribute) { 9 | auto map = attribute.mContext->mAttributeMap; 10 | if (map) { 11 | map->_onAttributeModified(*attribute.mInstance); 12 | } 13 | } 14 | 15 | void AttributeHelper::setCurrentValue(MutableAttributeWithContext& attribute, float value) { 16 | auto& instance = attribute.mInstance; 17 | instance->mCurrentValue = value; 18 | setDirty(attribute); 19 | } 20 | 21 | void AttributeHelper::setMaxValue(MutableAttributeWithContext& attribute, float value) { 22 | auto& instance = attribute.mInstance; 23 | instance->mCurrentMaxValue = value; 24 | instance->mDefaultMaxValue = value; 25 | float& currentValue = instance->mCurrentValue; 26 | currentValue = std::max(currentValue, instance->mCurrentMinValue); 27 | setDirty(attribute); 28 | } 29 | 30 | void AttributeHelper::setDefaultValue(MutableAttributeWithContext& attribute, float value) { 31 | auto& instance = attribute.mInstance; 32 | float& defaultValue = instance->mDefaultValue; 33 | if (value != defaultValue) { 34 | defaultValue = value; 35 | instance->mCurrentValue = value; 36 | setDirty(attribute); 37 | } 38 | } 39 | } // namespace lse::api::AttributeHelper -------------------------------------------------------------------------------- /src/lse/api/helper/AttributeHelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "mc/world/attribute/MutableAttributeWithContext.h" 3 | 4 | namespace lse::api { 5 | class AttributeHelper { 6 | static void setDirty(MutableAttributeWithContext& attribute); 7 | 8 | public: 9 | static void setCurrentValue(MutableAttributeWithContext& attribute, float value); 10 | static void setMaxValue(MutableAttributeWithContext& attribute, float value); 11 | static void setDefaultValue(MutableAttributeWithContext& attribute, float value); 12 | }; 13 | } // namespace lse::api -------------------------------------------------------------------------------- /src/lse/api/helper/BlockHelper.cpp: -------------------------------------------------------------------------------- 1 | #include "BlockHelper.h" 2 | 3 | #include "mc/world/level/dimension/DimensionHeightRange.h" 4 | 5 | namespace lse::api { 6 | bool BlockHelper::isValidHeight(WeakRef dimension, std::variant height) { 7 | auto dim = dimension.lock(); 8 | if (dim) { 9 | if (std::holds_alternative(height)) { 10 | int y = std::get(height); 11 | return dim->mHeightRange->mMin <= y && dim->mHeightRange->mMax >= y; 12 | } else { 13 | float y = std::get(height); 14 | return dim->mHeightRange->mMin <= y && dim->mHeightRange->mMax >= y; 15 | } 16 | } 17 | 18 | return false; 19 | } 20 | } // namespace lse::api -------------------------------------------------------------------------------- /src/lse/api/helper/BlockHelper.h: -------------------------------------------------------------------------------- 1 | #include "mc/world/level/dimension/Dimension.h" 2 | 3 | namespace lse::api { 4 | class BlockHelper { 5 | public: 6 | static bool isValidHeight(WeakRef dimension, std::variant height); 7 | }; 8 | } // namespace lse::api -------------------------------------------------------------------------------- /src/lse/api/helper/CustomFormWrapper.cpp: -------------------------------------------------------------------------------- 1 | #include "CustomFormWrapper.h" 2 | 3 | #include "nlohmann/json.hpp" 4 | #include "nlohmann/json_fwd.hpp" 5 | 6 | namespace lse::form { 7 | 8 | std::set const CustomFormWrapper::COMMON_ELEMENT_TYPENAMES{"header", "label", "divider"}; 9 | 10 | CustomFormResult 11 | CustomFormWrapper::convertResult(std::optional const& result, std::vector const& resultIndices) { 12 | if (!result) return {}; 13 | auto data = nlohmann::ordered_json::parse(*result); 14 | if (!data.is_null() && !data.is_array()) return {}; 15 | 16 | size_t count = resultIndices.size(); 17 | if (data.size() == 0) return nlohmann::ordered_json::array({}); 18 | if (data.size() == count) { 19 | return data; 20 | } 21 | 22 | auto views = resultIndices | std::views::transform([&](int index) { 23 | if (index < 0) return nlohmann::ordered_json(); 24 | return data[index]; 25 | }); 26 | return std::vector(views.begin(), views.end()); 27 | } 28 | 29 | CustomFormResult 30 | CustomFormWrapper::convertResult(std::optional const& result, nlohmann::ordered_json const& formData) { 31 | if (!result) return {}; 32 | auto formType = formData.find("type"); 33 | auto content = formData.find("content"); 34 | if (content == formData.end() || formType == formData.end() || *formType != "custom_form") { 35 | return nlohmann::ordered_json::parse(*result); 36 | } 37 | std::vector resultIndices{}; 38 | resultIndices.reserve(content->size()); 39 | int index = 0; 40 | for (auto& element : *content) { 41 | auto elementType = element.find("type"); 42 | if (elementType == element.end()) return {}; 43 | if (COMMON_ELEMENT_TYPENAMES.contains(*elementType)) resultIndices.emplace_back(-1); 44 | else resultIndices.emplace_back(index++); 45 | } 46 | return convertResult(result, resultIndices); 47 | } 48 | 49 | ll::form::Form::RawFormCallback 50 | CustomFormWrapper::convertCallback(Callback&& callback, std::vector resultIndices) { 51 | ll::form::Form::RawFormCallback oriCallback{}; 52 | if (callback) 53 | oriCallback = [resultIndices = std::move(resultIndices), 54 | callback = std::move(callback 55 | )](Player& player, std::optional const& data, ll::form::FormCancelReason reason) { 56 | callback(player, convertResult(data, resultIndices), reason); 57 | }; 58 | return oriCallback; 59 | } 60 | 61 | } // namespace lse::form -------------------------------------------------------------------------------- /src/lse/api/helper/ItemHelper.cpp: -------------------------------------------------------------------------------- 1 | #include "ItemHelper.h" 2 | 3 | #include "mc/nbt/CompoundTag.h" 4 | #include "mc/world/item/Item.h" 5 | 6 | namespace lse::api { 7 | void ItemHelper::load(ItemStack& itemStack, CompoundTag& tag) { 8 | itemStack._loadItem(tag); 9 | auto mItem = itemStack.mItem; 10 | if (mItem) { 11 | mItem->fixupCommon(itemStack); 12 | if (itemStack.getAuxValue() == 0x7FFF) { 13 | itemStack.mAuxValue = 0; 14 | } 15 | } 16 | }; 17 | } // namespace lse::api -------------------------------------------------------------------------------- /src/lse/api/helper/ItemHelper.h: -------------------------------------------------------------------------------- 1 | #include "mc/world/item/ItemStack.h" 2 | 3 | namespace lse::api { 4 | class ItemHelper { 5 | public: 6 | static void load(ItemStack& itemStack, CompoundTag& tag); 7 | }; 8 | } // namespace lse::api -------------------------------------------------------------------------------- /src/lse/api/helper/ItemStackSerializerHelpers.h: -------------------------------------------------------------------------------- 1 | #include "mc/deps/core/utility/BinaryStream.h" 2 | #include "mc/platform/Result.h" 3 | 4 | namespace ItemStackSerializerHelpers { 5 | template 6 | MCAPI void write(const T& item, BinaryStream& stream); 7 | template 8 | MCAPI Bedrock::Result read(ReadOnlyBinaryStream& stream); 9 | } // namespace ItemStackSerializerHelpers -------------------------------------------------------------------------------- /src/lse/api/helper/PlayerHelper.cpp: -------------------------------------------------------------------------------- 1 | #include "PlayerHelper.h" 2 | 3 | #include "AttributeHelper.h" 4 | #include "mc/world/actor/player/Player.h" 5 | #include "mc/world/attribute/AttributeInstance.h" 6 | #include "mc/world/attribute/AttributeModificationContext.h" 7 | #include "mc/world/attribute/MutableAttributeWithContext.h" 8 | 9 | namespace lse::api { 10 | 11 | unsigned int PlayerHelper::getPreviousLevelRequirement(Player* player) { 12 | int prevLevelReq = player->mPreviousLevelRequirement; 13 | if (player->mPlayerLevelChanged) { 14 | int curLvl = player->getAttribute(Player::LEVEL()).mCurrentValue; 15 | int plus = (curLvl / 15 == 1) ? (curLvl * 4 - 38) : (curLvl * 8 - 158); 16 | prevLevelReq = (curLvl / 15) ? (curLvl + plus) : (curLvl * 2 + 7); 17 | player->mPlayerLevelChanged = false; 18 | player->mPreviousLevelRequirement = prevLevelReq; 19 | } 20 | return prevLevelReq; 21 | } 22 | 23 | unsigned int PlayerHelper::getXpEarnedAtCurrentLevel(Player* player) { 24 | unsigned int prevLevelReq = PlayerHelper::getPreviousLevelRequirement(player); 25 | auto& attribute = player->getAttribute(Player::EXPERIENCE()); 26 | return (unsigned int)roundf(attribute.mCurrentValue * (float)prevLevelReq); 27 | } 28 | 29 | bool PlayerHelper::setXpEarnedAtCurrentLevel(Player* player, unsigned int xp) { 30 | unsigned int prevLevelReq = PlayerHelper::getPreviousLevelRequirement(player); 31 | auto attribute = player->getMutableAttribute(Player::EXPERIENCE()); 32 | AttributeHelper::setCurrentValue(attribute, (float)xp / (float)prevLevelReq); 33 | return true; 34 | } 35 | 36 | } // namespace lse::api -------------------------------------------------------------------------------- /src/lse/api/helper/PlayerHelper.h: -------------------------------------------------------------------------------- 1 | class Player; 2 | 3 | namespace lse::api { 4 | class PlayerHelper { 5 | public: 6 | static unsigned int getPreviousLevelRequirement(Player* player); 7 | 8 | static unsigned int getXpEarnedAtCurrentLevel(Player* player); 9 | 10 | static bool setXpEarnedAtCurrentLevel(Player* player, unsigned int xp); 11 | }; 12 | } // namespace lse::api 13 | -------------------------------------------------------------------------------- /src/lse/api/helper/ScoreboardHelper.cpp: -------------------------------------------------------------------------------- 1 | #include "ScoreboardHelper.h" 2 | 3 | #include "mc/world/scores/IdentityDictionary.h" 4 | 5 | namespace lse::api { 6 | ScoreboardId ScoreboardHelper::getId(Scoreboard const& scoreboard, PlayerScoreboardId const& playerId) { 7 | auto& dict = scoreboard.mIdentityDict->mPlayers; 8 | auto found = dict->find(playerId); 9 | if (found != dict->end()) { 10 | return found->second; 11 | } else { 12 | return ScoreboardId::INVALID(); 13 | } 14 | } 15 | } // namespace lse::api -------------------------------------------------------------------------------- /src/lse/api/helper/ScoreboardHelper.h: -------------------------------------------------------------------------------- 1 | #include "mc/world/scores/PlayerScoreboardId.h" 2 | #include "mc/world/scores/Scoreboard.h" 3 | #include "mc/world/scores/ScoreboardId.h" 4 | 5 | namespace lse::api { 6 | class ScoreboardHelper { 7 | public: 8 | static ScoreboardId getId(Scoreboard const& scoreboard, PlayerScoreboardId const& playerId); 9 | }; 10 | } // namespace lse::api -------------------------------------------------------------------------------- /src/lse/api/helper/SimulatedPlayerHelper.h: -------------------------------------------------------------------------------- 1 | #include "mc/server/SimulatedPlayer.h" 2 | #include "mc/server/sim/LookDuration.h" 3 | 4 | namespace lse::api { 5 | class SimulatedPlayerHelper { 6 | public: 7 | static bool simulateRespawn(SimulatedPlayer& player); 8 | static void simulateLookAt(SimulatedPlayer& player, Actor& actor, sim::LookDuration lookType); 9 | static void simulateLookAt(SimulatedPlayer& player, BlockPos const& blockPos, sim::LookDuration lookType); 10 | static void simulateLookAt(SimulatedPlayer& player, Vec3 const& pos, sim::LookDuration lookType); 11 | static bool simulateUseItem(SimulatedPlayer& player, ItemStack& item); 12 | static bool simulateUseItemInSlotOnBlock( 13 | SimulatedPlayer& player, 14 | int slot, 15 | BlockPos const& pos, 16 | ScriptModuleMinecraft::ScriptFacing face, 17 | Vec3 const& facePos 18 | ); 19 | static void simulateStopUsingItem(SimulatedPlayer& player); 20 | static void simulateStopMoving(SimulatedPlayer& player); 21 | }; 22 | } // namespace lse::api -------------------------------------------------------------------------------- /src/lse/events/BlockEvents.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace lse::events::block { 4 | void ContainerChangeEvent(); 5 | void ArmorStandSwapItemEvent(); 6 | void PressurePlateTriggerEvent(); 7 | void FarmDecayEvent(); 8 | void PistonPushEvent(); 9 | void ExplodeEvent(); 10 | void RespawnAnchorExplodeEvent(); 11 | void BlockExplodedEvent(); 12 | void RedstoneUpdateEvent(); 13 | void LiquidFlowEvent(); 14 | void CommandBlockExecuteEvent(); 15 | void HopperEvent(bool pullIn); 16 | } -------------------------------------------------------------------------------- /src/lse/events/EntityEvents.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace lse::events::entity { 4 | void ProjectileSpawnEvent(); 5 | void ProjectileCreatedEvent(); 6 | void ActorRideEvent(); 7 | void WitherDestroyEvent(); 8 | void ProjectileHitEntityEvent(); 9 | void ProjectileHitBlockEvent(); 10 | void MobHurtEvent(); 11 | void NpcCommandEvent(); 12 | void EndermanTakeBlockEvent(); 13 | void EffectUpdateEvent(); 14 | void TransformationEvent(); 15 | } // namespace lse::events::entity -------------------------------------------------------------------------------- /src/lse/events/OtherEvents.cpp: -------------------------------------------------------------------------------- 1 | #include "legacy/api/EventAPI.h" 2 | #include "legacy/api/PlayerAPI.h" 3 | #include "ll/api/memory/Hook.h" 4 | #include "ll/api/service/Bedrock.h" 5 | #include "mc/legacy/ActorRuntimeID.h" 6 | #include "mc/legacy/ActorUniqueID.h" 7 | #include "mc/world/scores/IdentityDefinition.h" 8 | #include "mc/world/scores/Objective.h" 9 | #include "mc/world/scores/PlayerScoreboardId.h" 10 | #include "mc/world/scores/ScoreInfo.h" 11 | #include "mc/world/scores/ScoreboardId.h" 12 | #include "mc/world/scores/ServerScoreboard.h" 13 | 14 | namespace lse::events::other { 15 | LL_TYPE_INSTANCE_HOOK( 16 | ScoreChangedHook, 17 | HookPriority::Normal, 18 | ServerScoreboard, 19 | &ServerScoreboard::$onScoreChanged, 20 | void, 21 | ScoreboardId const& id, 22 | Objective const& obj 23 | ) { 24 | IF_LISTENED(EVENT_TYPES::onScoreChanged) { 25 | auto& idRef = id.mIdentityDef; 26 | if (idRef && idRef->mIdentityType == IdentityDefinition::Type::Player) { 27 | if (!CallEvent( 28 | EVENT_TYPES::onScoreChanged, 29 | PlayerClass::newPlayer( 30 | ll::service::getLevel()->getPlayer(ActorUniqueID(idRef->mPlayerId->mActorUniqueId)) 31 | ), 32 | Number::newNumber(obj.getPlayerScore(id).mValue), 33 | String::newString(obj.mName), 34 | String::newString(obj.mDisplayName) 35 | )) { 36 | return; 37 | } 38 | } 39 | } 40 | IF_LISTENED_END(EVENT_TYPES::onScoreChanged); 41 | origin(id, obj); 42 | } 43 | 44 | void ScoreChangedEvent() { ScoreChangedHook::hook(); } 45 | } // namespace lse::events::other -------------------------------------------------------------------------------- /src/lse/events/OtherEvents.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace lse::events::other { 4 | void ScoreChangedEvent(); 5 | } -------------------------------------------------------------------------------- /src/lse/events/PlayerEvents.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace lse::events::player { 4 | void AttackBlockEvent(); 5 | void ChangeSlotEvent(); 6 | void CloseContainerEvent(); 7 | void DropItem(); 8 | void OpenContainerEvent(); 9 | void StartDestroyBlock(); 10 | void UseFrameEvent(); 11 | void EatEvent(); 12 | void ChangeDimensionEvent(); 13 | void OpenContainerScreenEvent(); 14 | void UseRespawnAnchorEvent(); 15 | void SleepEvent(); 16 | void OpenInventoryEvent(); 17 | void PullFishingHookEvent(); 18 | void UseBucketPlaceEvent(); 19 | void UseBucketTakeEvent(); 20 | void ConsumeTotemEvent(); 21 | void SetArmorEvent(); 22 | void InteractEntityEvent(); 23 | void AddEffectEvent(); 24 | void RemoveEffectEvent(); 25 | } // namespace lse::events::player -------------------------------------------------------------------------------- /src/tests/LSETests/EventTests.js: -------------------------------------------------------------------------------- 1 | export const events = [ 2 | "onPreJoin", 3 | "onJoin", 4 | "onLeft", 5 | "onRespawn", 6 | "onPlayerDie", 7 | "onPlayerCmd", 8 | "onChat", 9 | "onChangeDim", 10 | "onJump", 11 | "onSneak", 12 | "onPlayerSwing", 13 | "onAttackEntity", 14 | "onAttackBlock", 15 | "onUseItem", 16 | "onUseItemOn", 17 | "onUseBucketPlace", 18 | "onUseBucketTake", 19 | "onTakeItem", 20 | "onDropItem", 21 | "onEat", 22 | "onAte", 23 | "onConsumeTotem", 24 | "onStartDestroyBlock", 25 | "onDestroyBlock", 26 | "onPlaceBlock", 27 | "afterPlaceBlock", 28 | "onOpenContainer", 29 | "onCloseContainer", 30 | "onInventoryChange", 31 | "onPlayerPullFishingHook", 32 | "onChangeSprinting", 33 | "onSetArmor", 34 | "onUseRespawnAnchor", 35 | "onOpenContainerScreen", 36 | "onExperienceAdd", 37 | "onBedEnter", 38 | "onOpenInventory", 39 | "onMobDie", 40 | "onMobHurt", 41 | "onEntityExplode", 42 | "onProjectileHitEntity", 43 | "onWitherBossDestroy", 44 | "onRide", 45 | "onStepOnPressurePlate", 46 | "onSpawnProjectile", 47 | "onProjectileCreated", 48 | "onChangeArmorStand", 49 | "onBlockInteracted", 50 | "onBlockChanged", 51 | "onBlockExplode", 52 | "onRespawnAnchorExplode", 53 | "onBlockExploded", 54 | "onFireSpread", 55 | "onCmdBlockExecute", 56 | "onContainerChange", 57 | "onProjectileHitBlock", 58 | "onRedStoneUpdate", 59 | "onHopperSearchItem", 60 | "onHopperPushOut", 61 | "onPistonTryPush", 62 | "onPistonPush", 63 | "onFarmLandDecay", 64 | "onUseFrameBlock", 65 | "onLiquidFlow", 66 | "onScoreChanged", 67 | "onServerStarted", 68 | "onConsoleCmd", 69 | "onMoneyAdd", 70 | "onMoneyReduce", 71 | "onMoneyTrans", 72 | "onMoneySet", 73 | "beforeMoneyAdd", 74 | "beforeMoneyReduce", 75 | "beforeMoneyTrans", 76 | "beforeMoneySet", 77 | "onMobTrySpawn", 78 | "onMobSpawned", 79 | "onNpcCmd", 80 | "onEffectAdded", 81 | "onEffectRemoved", 82 | "onEffectUpdated" 83 | ]; 84 | 85 | export const triggeredEvents = new Set(); 86 | 87 | export function RegisterEvents() { 88 | events.forEach(event => { 89 | mc.listen(event, (...args) => { 90 | if (triggeredEvents.has(event)) { 91 | return; 92 | } 93 | logger.info(`Event ${event} triggered with parameters: ${args}`); 94 | triggeredEvents.add(event); 95 | logger.info(`${triggeredEvents.size}/${events.length} events called`); 96 | }); 97 | }); 98 | } -------------------------------------------------------------------------------- /src/tests/LSETests/ScriptTests.js: -------------------------------------------------------------------------------- 1 | export function TestLogger(players) { 2 | for (let player of players) { 3 | logger.setPlayer(player) 4 | } 5 | logger.setFile("logs/LegacyScriptEngine/ScriptTests.log"); 6 | logger.log("This is a log message"); 7 | logger.warn("This is a warning message"); 8 | logger.error("This is an error message"); 9 | logger.debug("This is a debug message"); 10 | logger.info("This is an info message"); 11 | logger.fatal("This is a fetal message"); 12 | } -------------------------------------------------------------------------------- /src/tests/LSETests/main.js: -------------------------------------------------------------------------------- 1 | import {RegisterEvents, events, triggeredEvents} from './plugins/LSETests/EventTests.js'; 2 | import {TestLogger} from './plugins/LSETests/ScriptTests.js'; 3 | import {TestPlayer} from './plugins/LSETests/PlayerTests.js'; 4 | 5 | RegisterEvents(); 6 | 7 | mc.listen('onServerStarted', () => { 8 | let cmd = mc.newCommand('lsetests', "LegacyScriptEngine tests", PermType.Console); 9 | cmd.setEnum('testOption', ['logger', 'events', 'player']); 10 | cmd.mandatory('testOption', ParamType.Enum, 'testOption'); 11 | cmd.optional('player', ParamType.Player); 12 | cmd.overload('testOption', 'player'); 13 | cmd.setCallback((cmd, origin, output, results) => { 14 | switch (results.testOption) { 15 | case 'logger': 16 | TestLogger(results.player); 17 | break; 18 | case 'events': 19 | const 20 | notTriggeredEvents = events.filter(event => !triggeredEvents.has(event)); 21 | logger.info(`Events not triggered: ${notTriggeredEvents.join(', ')}`); 22 | break; 23 | case 'player': 24 | TestPlayer(results.player); 25 | break; 26 | default: 27 | logger.error(`Invalid test option ${results.testOption}`); 28 | break; 29 | } 30 | }); 31 | }) 32 | 33 | -------------------------------------------------------------------------------- /src/tests/LSETests/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "entry": "main.js", 3 | "name": "LSETests", 4 | "type": "lse-quickjs", 5 | "author": "LiteLDev", 6 | "version": "1.0.0", 7 | "dependencies": [ 8 | { 9 | "name": "legacy-script-engine-quickjs" 10 | } 11 | ] 12 | } --------------------------------------------------------------------------------