├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── bug_report_cn.yml │ └── feature_request.md └── workflows │ ├── codeql-analysis.yml │ └── gradle-builder.yml ├── .gitignore ├── LICENSE ├── README.md ├── Version Infos.json ├── Version_Info.json ├── build.gradle.kts ├── bukkit ├── build.gradle.kts ├── nms │ ├── build.gradle.kts │ ├── common │ │ ├── build.gradle.kts │ │ ├── generic_v1_19_3 │ │ │ ├── build.gradle.kts │ │ │ └── src │ │ │ │ └── main │ │ │ │ └── kotlin │ │ │ │ └── io │ │ │ │ └── github │ │ │ │ └── rothes │ │ │ │ └── protocolstringreplacer │ │ │ │ └── nms │ │ │ │ └── generic │ │ │ │ └── packetreader │ │ │ │ ├── BlockEntityTypeGetter.kt │ │ │ │ ├── MenuTypeGetter.kt │ │ │ │ └── PacketReader.kt │ │ ├── generic_v1_21 │ │ │ ├── build.gradle.kts │ │ │ └── src │ │ │ │ └── main │ │ │ │ └── kotlin │ │ │ │ └── io │ │ │ │ └── github │ │ │ │ └── rothes │ │ │ │ └── protocolstringreplacer │ │ │ │ └── nms │ │ │ │ └── generic │ │ │ │ └── packetreader │ │ │ │ ├── BlockEntityTypeGetter.kt │ │ │ │ ├── DisguisedPacketHandler.kt │ │ │ │ ├── MenuTypeGetter.kt │ │ │ │ └── PacketReader.kt │ │ ├── generic_v1_21_3 │ │ │ ├── build.gradle.kts │ │ │ └── src │ │ │ │ └── main │ │ │ │ └── kotlin │ │ │ │ └── io │ │ │ │ └── github │ │ │ │ └── rothes │ │ │ │ └── protocolstringreplacer │ │ │ │ └── nms │ │ │ │ └── generic │ │ │ │ └── packetreader │ │ │ │ ├── BlockEntityTypeGetter.kt │ │ │ │ ├── DisguisedPacketHandler.kt │ │ │ │ ├── MenuTypeGetter.kt │ │ │ │ └── PacketReader.kt │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── io │ │ │ │ └── github │ │ │ │ └── rothes │ │ │ │ └── protocolstringreplacer │ │ │ │ └── nms │ │ │ │ └── packetreader │ │ │ │ ├── ChatType.java │ │ │ │ ├── IBlockEntityTypeGetter.java │ │ │ │ ├── IMenuTypeGetter.java │ │ │ │ └── IPacketReader.java │ │ │ └── kotlin │ │ │ └── io │ │ │ └── github │ │ │ └── rothes │ │ │ └── protocolstringreplacer │ │ │ └── nms │ │ │ └── packetreader │ │ │ └── IDisguisedPacketHandler.kt │ ├── src │ │ └── main │ │ │ └── kotlin │ │ │ └── io │ │ │ └── github │ │ │ └── rothes │ │ │ └── protocolstringreplacer │ │ │ └── nms │ │ │ └── NmsManager.kt │ ├── v1_19_1 │ │ ├── build.gradle.kts │ │ └── src │ │ │ └── main │ │ │ └── kotlin │ │ │ └── io │ │ │ └── github │ │ │ └── rothes │ │ │ └── protocolstringreplacer │ │ │ └── nms │ │ │ └── v1_19_1 │ │ │ └── packetreader │ │ │ └── PacketReader.kt │ ├── v1_19_2 │ │ ├── build.gradle.kts │ │ └── src │ │ │ └── main │ │ │ └── kotlin │ │ │ └── io │ │ │ └── github │ │ │ └── rothes │ │ │ └── protocolstringreplacer │ │ │ └── nms │ │ │ └── v1_19_2 │ │ │ └── packetreader │ │ │ └── PacketReader.kt │ ├── v1_19_3 │ │ └── build.gradle.kts │ ├── v1_19_4 │ │ └── build.gradle.kts │ ├── v1_20_1 │ │ └── build.gradle.kts │ ├── v1_20_2 │ │ └── build.gradle.kts │ ├── v1_20_4 │ │ └── build.gradle.kts │ ├── v1_20_6 │ │ ├── build.gradle.kts │ │ └── src │ │ │ └── main │ │ │ └── kotlin │ │ │ └── io │ │ │ └── github │ │ │ └── rothes │ │ │ └── protocolstringreplacer │ │ │ └── nms │ │ │ └── v1_20_6 │ │ │ └── packetreader │ │ │ ├── BlockEntityTypeGetter.kt │ │ │ ├── DisguisedPacketHandler.kt │ │ │ ├── MenuTypeGetter.kt │ │ │ └── PacketReader.kt │ ├── v1_21_1 │ │ └── build.gradle.kts │ ├── v1_21_3 │ │ └── build.gradle.kts │ ├── v1_21_4 │ │ └── build.gradle.kts │ └── v1_21_5 │ │ └── build.gradle.kts └── src │ └── main │ ├── java │ ├── com │ │ └── sk89q │ │ │ └── protocolstringreplacer │ │ │ └── PsrDisguisePlugin.java │ └── io │ │ └── github │ │ └── rothes │ │ └── protocolstringreplacer │ │ ├── ConfigManager.java │ │ ├── ProtocolStringReplacer.java │ │ ├── PsrLocalization.java │ │ ├── Updater.java │ │ ├── api │ │ ├── capture │ │ │ ├── CaptureInfo.java │ │ │ └── CaptureInfoImpl.java │ │ ├── configuration │ │ │ ├── CommentYamlConfiguration.java │ │ │ └── DotYamlConfiguration.java │ │ ├── exceptions │ │ │ ├── IncompatibleServerException.java │ │ │ ├── JsonSyntaxException.java │ │ │ └── MissingInitialResourceException.java │ │ ├── replacer │ │ │ └── ReplacerConfig.java │ │ └── user │ │ │ ├── PsrUser.java │ │ │ └── PsrUserManager.java │ │ ├── command │ │ ├── CommandHandler.java │ │ ├── SubCommand.java │ │ └── subcommands │ │ │ ├── Capture.java │ │ │ ├── Edit.java │ │ │ ├── Parse.java │ │ │ ├── Reload.java │ │ │ └── editchildren │ │ │ ├── Block.java │ │ │ ├── File.java │ │ │ └── Replace.java │ │ ├── console │ │ ├── ConsoleReplaceManager.java │ │ ├── PsrFilter.java │ │ ├── PsrJndiLookup.java │ │ ├── PsrLogEventPatternConverter.java │ │ ├── PsrMessage.java │ │ ├── PsrMessageFactory.java │ │ └── PsrWrappedLineReader.java │ │ ├── events │ │ └── PsrReloadEvent.java │ │ ├── listeners │ │ ├── PlayerJoinListener.java │ │ ├── PlayerQuitListener.java │ │ └── PsrInternalListeners.java │ │ ├── packetlistener │ │ ├── BasePacketListener.java │ │ ├── PacketListenerManager.java │ │ ├── client │ │ │ ├── BaseClientPacketListener.java │ │ │ ├── CloseWindow.java │ │ │ ├── SettingsLocale.java │ │ │ ├── SettingsLocaleUpper20.java │ │ │ └── itemstack │ │ │ │ ├── BaseClientItemPacketListener.java │ │ │ │ ├── SetCreativeSlot.java │ │ │ │ └── WindowClick.java │ │ └── server │ │ │ ├── BaseServerComponentsPacketListener.java │ │ │ ├── BaseServerPacketListener.java │ │ │ ├── EntityMetadata.java │ │ │ ├── KickDisconnect.java │ │ │ ├── OpenWindow.java │ │ │ ├── actionbar │ │ │ ├── ChatActionBar.java │ │ │ ├── SetActionBar.java │ │ │ ├── SystemChatActionBar.java │ │ │ └── TitleActionBar.java │ │ │ ├── bossbar │ │ │ ├── BossBar.java │ │ │ └── BossBarPost17.java │ │ │ ├── chat │ │ │ ├── Chat.java │ │ │ ├── ChatPreview.java │ │ │ ├── DisguisedChat.java │ │ │ ├── PlayerChatHelper.java │ │ │ ├── SystemChat.java │ │ │ └── TabComplete.java │ │ │ ├── combat │ │ │ ├── CombatEvent.java │ │ │ └── PlayerCombatKill.java │ │ │ ├── itemstack │ │ │ ├── BaseServerItemPacketListener.java │ │ │ └── SetSlot.java │ │ │ ├── scoreboard │ │ │ ├── BaseScoreBoardListener.java │ │ │ ├── BaseUpdateTeamListener.java │ │ │ ├── ScoreBoardObjective.java │ │ │ ├── UpdateScore.java │ │ │ ├── UpdateTeam.java │ │ │ ├── UpdateTeamPost13.java │ │ │ └── UpdateTeamPost17.java │ │ │ ├── sign │ │ │ ├── BaseServerSignPacketListener.java │ │ │ ├── MapChunk.java │ │ │ ├── TileEntityData.java │ │ │ ├── TileEntityDataPost18.java │ │ │ └── UpdateSign.java │ │ │ └── title │ │ │ ├── BaseTitleListener.java │ │ │ ├── SetSubtitleText.java │ │ │ ├── SetTitleText.java │ │ │ └── Title.java │ │ ├── replacer │ │ ├── FileReplacerConfig.java │ │ ├── ListenType.java │ │ ├── MatchMode.java │ │ ├── PAPIReplacer.java │ │ ├── ReplaceMode.java │ │ ├── ReplacerManager.java │ │ ├── containers │ │ │ ├── AbstractContainer.java │ │ │ ├── ChatJsonContainer.java │ │ │ ├── ComponentContainer.java │ │ │ ├── ComponentsContainer.java │ │ │ ├── Container.java │ │ │ ├── EntityContentContainer.java │ │ │ ├── HoverContentContainer.java │ │ │ ├── HoverEventContainer.java │ │ │ ├── ItemContentContainer.java │ │ │ ├── Replaceable.java │ │ │ ├── SignNbtContainer.java │ │ │ ├── SimpleTextContainer.java │ │ │ └── TextContentContainer.java │ │ └── helpers │ │ │ └── ItemHelper.java │ │ ├── upgrade │ │ ├── AbstractUpgradeHandler.java │ │ ├── DotConfigUpgradeHandler.java │ │ ├── UpgradeEnum.java │ │ ├── UpgradeHandler1To2.java │ │ ├── UpgradeHandler2To3.java │ │ ├── UpgradeHandler3To4.java │ │ ├── UpgradeHandler4To5.java │ │ └── UpgradeHandler5To6.java │ │ └── util │ │ ├── ArgUtils.java │ │ ├── ColorUtils.java │ │ ├── FileUtils.java │ │ ├── MessageUtils.java │ │ ├── PaperUtils.java │ │ ├── SpigotUtils.java │ │ └── scheduler │ │ ├── PsrScheduler.java │ │ └── PsrTask.java │ ├── kotlin │ └── io │ │ └── github │ │ └── rothes │ │ └── protocolstringreplacer │ │ ├── InternalExtensions.kt │ │ ├── InternalFunctions.kt │ │ ├── command │ │ └── subcommands │ │ │ └── About.kt │ │ ├── packetlistener │ │ └── server │ │ │ ├── chat │ │ │ ├── DisguisedChatPost21.kt │ │ │ └── TabCompletePost20_5.kt │ │ │ ├── itemstack │ │ │ ├── MerchantTradeList.kt │ │ │ ├── WindowItems.kt │ │ │ └── WindowItemsPost11.kt │ │ │ └── sign │ │ │ ├── MapChunkPost18.kt │ │ │ └── TileTypeHelper.kt │ │ └── replacer │ │ └── containers │ │ └── ItemStackContainer.kt │ └── resources │ ├── Languages │ ├── Global │ │ └── ExampleReplacers │ │ │ └── Slimefun │ │ │ └── Translation_CN │ │ │ ├── Chat │ │ │ └── Text_Contain.yml │ │ │ ├── Console │ │ │ ├── Regex.yml │ │ │ └── Text_Contain.yml │ │ │ ├── Entity │ │ │ └── Cargo 货运.yml │ │ │ ├── Interfaces │ │ │ ├── Machine Interfaces │ │ │ │ ├── Android 可编程式机器人.yml │ │ │ │ ├── Auto-Crafter 自动合成器.yml │ │ │ │ └── Cargo 货运.yml │ │ │ └── Window-Title.yml │ │ │ └── ItemStack │ │ │ ├── Regex.yml │ │ │ └── Text_Contain.yml │ ├── en-US │ │ ├── Configs │ │ │ └── Config.yml │ │ ├── ExampleReplacers │ │ │ ├── ReadMe.md │ │ │ └── Slimefun │ │ │ │ └── Translation_CN │ │ │ │ └── ReadMe.md │ │ ├── Example_Replacers.txt │ │ ├── Locales │ │ │ └── Locale.yml │ │ └── Replacers │ │ │ ├── ConsoleColor.yml │ │ │ └── Example.yml │ └── zh-CN │ │ ├── Configs │ │ └── Config.yml │ │ ├── ExampleReplacers │ │ ├── ReadMe.md │ │ └── Slimefun │ │ │ └── Translation_CN │ │ │ └── ReadMe.md │ │ ├── Example_Replacers.txt │ │ ├── Locales │ │ └── Locale.yml │ │ └── Replacers │ │ ├── ConsoleColor.yml │ │ └── Example.yml │ ├── metadata.yml │ └── plugin.yml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── jitpack.yml └── settings.gradle.kts /.github/ISSUE_TEMPLATE/bug_report_cn.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report | 错误报告 2 | description: 报告错误或议题 [中文|Chinese] 3 | title: "[Bug] " 4 | labels: [🐞 Unconfirmed bug] 5 | assignees: 6 | - Rothes 7 | 8 | body: 9 | - type: markdown 10 | attributes: 11 | value: | 12 | ## 欢迎来到 ProtocolStringReplacer 问题追踪器 13 | 如果您需要帮助, 可以加入我们的 [Discord 服务器](https://discord.gg/zwzzkmYCBb) 或 [QQ群](https://qm.qq.com/cgi-bin/qm/qr?k=mDtcrvBGzqbA05mPLzBnPAYXm5lskYxg&jump_from=webapi). 14 | 感谢您愿意花费一些时间来帮助我们填写这个错误报告. 15 | 16 | - id: checklist 17 | type: checkboxes 18 | attributes: 19 | label: '检查清单' 20 | description: 在创建问题之前,请先检查此清单. 21 | options: 22 | - label: 我已经尝试过了最新开发版本的 ProtocolLib. 23 | - label: 我正在使用最新的官方 PSR. 24 | required: true 25 | - label: 我搜寻了类似的未关闭议题, 但没有找到任何有关的错误报告。 26 | required: true 27 | 28 | - id: description 29 | type: textarea 30 | validations: 31 | required: true 32 | attributes: 33 | label: '描述' 34 | description: | 35 | 清楚、详细地描述您遇到的错误是什么. 36 | 您提供的信息越多, 我们就越容易处理这个问题. 37 | placeholder: | 38 | 当我在做 [...] 时, 我遇到了 [...]. 39 | 40 | - id: reproduction-steps 41 | type: textarea 42 | validations: 43 | required: true 44 | attributes: 45 | label: '重现步骤' 46 | description: | 47 | 重现此问题的完整步骤. 48 | 您描述地越清晰, 我们就越容易复现这个问题. 49 | placeholder: | 50 | 1. 先做 [...] 51 | 2. 再做 [...] 52 | 3. 错误 [...] 发生了 53 | 54 | - id: expected-behaviour 55 | type: textarea 56 | validations: 57 | required: true 58 | attributes: 59 | label: '预期行为' 60 | description: | 61 | 您认为怎么样才是正确、预期的行为? 62 | placeholder: | 63 | 我希望它能够 [...]. 64 | 65 | - id: stacktrace 66 | type: input 67 | attributes: 68 | label: '堆栈轨迹' 69 | description: | 70 | 检查您的服务端日志, 搜索任何来自 ProtocolStringReplacer 的警告及错误信息. 71 | 如果您不确定, 请发送您的完整日志. 72 | placeholder: https://pastebin.com/... 73 | 74 | - id: server-software 75 | type: input 76 | validations: 77 | required: true 78 | attributes: 79 | label: '服务端版本' 80 | description: | 81 | 请输入您使用的服务端, 包括版本号. 82 | 执行 /about 指令并粘贴其输出. 83 | placeholder: 'git-Purpur-1894 (MC: 1.19.3)*' 84 | 85 | - id: psr-version 86 | type: input 87 | validations: 88 | required: true 89 | attributes: 90 | label: 'ProtocolStringReplacer 版本' 91 | description: | 92 | **"最新" 不是版本号, 我们需要的是一个确切的版本号.** 93 | 请输入 ProtocolStringReplacer 的版本号. 94 | placeholder: '2.17.3' 95 | 96 | - id: protocollib-version 97 | type: input 98 | validations: 99 | required: true 100 | attributes: 101 | label: 'ProtocolLib 版本' 102 | description: | 103 | 执行 /protocol version 指令并粘贴其输出. 104 | placeholder: 'v5.0.0-SNAPSHOT-b612' 105 | 106 | - id: other-versions 107 | type: textarea 108 | attributes: 109 | label: '其它插件' 110 | description: | 111 | 如果您的议题与其它插件有关系, 请在此处填写. 112 | placeholder: MyPluginA v1.0, MyPluginB v1.1 ... 113 | 114 | - id: additional-context 115 | type: textarea 116 | attributes: 117 | label: '额外内容' 118 | description: | 119 | 您可以在此处添加有关本议题的补充. 120 | placeholder: | 121 | 截图, 视频, 系统版本, 以及其它的更多信息... 122 | 123 | - type: markdown 124 | attributes: 125 | value: | 126 | ## 非常感谢您能够提交此错误报告! 127 | 如果您之后发现了任何有助于解决此议题的其他信息, 请立即在此议题下回复! 128 | 任何更多信息都有助于我们解决此议题! 129 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: Rothes 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master, '3.0.0-dev' ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master, '3.0.0-dev' ] 20 | schedule: 21 | - cron: '26 10 * * 4' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'java' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v2 42 | - name: Setup Java JDK 43 | uses: actions/setup-java@v2.4.0 44 | with: 45 | distribution: zulu 46 | java-version: 17 47 | - name: Initialize CodeQL 48 | uses: github/codeql-action/init@v1 49 | with: 50 | languages: ${{ matrix.language }} 51 | # If you wish to specify custom queries, you can do so here or in a config file. 52 | # By default, queries listed here will override any specified in a config file. 53 | # Prefix the list here with "+" to use these queries and those in the config file. 54 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 55 | 56 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 57 | # If this step fails, then you should remove it and run the build manually (see below) 58 | - name: Autobuild 59 | uses: github/codeql-action/autobuild@v1 60 | 61 | # ℹ️ Command-line programs to run using the OS shell. 62 | # 📚 https://git.io/JvXDl 63 | 64 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 65 | # and modify them (or add more) to build your code if your project 66 | # uses a compiled language 67 | 68 | #- run: | 69 | # make bootstrap 70 | # make release 71 | 72 | - name: Perform CodeQL Analysis 73 | uses: github/codeql-action/analyze@v1 74 | -------------------------------------------------------------------------------- /.github/workflows/gradle-builder.yml: -------------------------------------------------------------------------------- 1 | name: ProtocolStringReplacer Snapshot Builder 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v3 11 | 12 | - name: Set up JDK 21 13 | uses: actions/setup-java@v3 14 | with: 15 | java-version: '21' 16 | distribution: 'temurin' 17 | 18 | - name: Make gradlew executable 19 | run: chmod +x ./gradlew 20 | 21 | - name: Setup Gradle 22 | uses: gradle/gradle-build-action@v3 23 | with: 24 | gradle-version: 8.6 25 | 26 | - name: Execute Gradle build 27 | run: ./gradlew createJars 28 | 29 | - run: mkdir ProtocolStringReplacer && cp build/allJars/*.jar ProtocolStringReplacer 30 | 31 | - uses: actions/upload-artifact@v4 32 | with: 33 | name: ProtocolStringReplacer-Snapshot 34 | path: ProtocolStringReplacer 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | 3 | # Numerous always-ignore extensions 4 | *.diff 5 | *.err 6 | *.orig 7 | *.log 8 | *.rej 9 | *.swo 10 | *.swp 11 | *.vi 12 | *~ 13 | # OS or Editor folders 14 | .DS_Store 15 | .cache 16 | .project 17 | .settings 18 | .tmproj 19 | nbproject 20 | Thumbs.db 21 | 22 | # Dreamweaver added files 23 | _notes 24 | dwsync.xml 25 | 26 | # Komodo 27 | *.komodoproject 28 | .komodotools 29 | 30 | # Folders to ignore 31 | .hg 32 | .svn 33 | .CVS 34 | intermediate 35 | publish 36 | .idea 37 | 38 | 39 | # Eclipse stuff 40 | .classpath 41 | build.xml 42 | target 43 | 44 | # various other potential build files 45 | build 46 | bin 47 | dist 48 | manifest.mf 49 | 50 | # Mac filesystem dust 51 | 52 | 53 | *.iml 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ProtocolStringReplacer 2 | 3 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/10b4b7cb53d34e8289d708fa3a5e3caf)](https://app.codacy.com/gh/Rothes/ProtocolStringReplacer?utm_source=github.com&utm_medium=referral&utm_content=Rothes/ProtocolStringReplacer&utm_campaign=Badge_Grade_Settings) 4 | 5 | A Spigot plugin for Minecraft 1.8 - 1.21.1 that gives you the ability to edit the strings/components in packet sends to players. 6 | 7 | Please visit [SpigotMC](#links) or [MCBBS](#links) for a detailed description. 8 | 9 | ## Download 10 | For stable releases, go SpigotMC or MCBBS. Also, we create a tag for each published version on GitHub. You can compile it yourself. 11 | For development builds, you can download on GitHub Actions. 12 | 13 | ## Support 14 | We provide support on our [Discord Server](https://discord.gg/zwzzkmYCBb), and [Tencent QQ group](https://qm.qq.com/cgi-bin/qm/qr?k=mDtcrvBGzqbA05mPLzBnPAYXm5lskYxg&jump_from=webapi). 15 | If you are going to open a ticket, you may ask for help first. 16 | 17 | ## Contribute 18 | We accept pull requests, feel free to contribute. 19 | But please discuss the changes with us first unless it's a minor fix, 20 | so we can let you know if we are willing to merge it and give you some suggestions. 21 | 22 | ## Related Links 23 | 24 | * **Wiki**: 25 | [https://rothes.gitbook.io/protocolstringreplacer](https://rothes.gitbook.io/protocolstringreplacer) 26 | 27 | * **MCBBS** (Down) : 28 | [https://www.mcbbs.net/thread-1209429-1-1.html](https://www.mcbbs.net/thread-1209429-1-1.html) 29 | 30 | * **SpigotMC**: 31 | [https://www.spigotmc.org/resources/protocolstringreplacer.96573](https://www.spigotmc.org/resources/protocolstringreplacer.96573/) 32 | 33 | * **bStats**: 34 | [https://bstats.org/plugin/bukkit/ProtocolStringReplacer/11740](https://bstats.org/plugin/bukkit/ProtocolStringReplacer/11740) 35 | ![bStats Preview](https://bstats.org/signatures/bukkit/ProtocolStringReplacer.svg) 36 | 37 | ## License 38 | ProtocolStringReplacer is licensed under GNU General Public License v3.0. Please see LICENSE for the full license. 39 | -------------------------------------------------------------------------------- /Version Infos.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version_Channels": { 3 | "Stable": { 4 | "Latest_Version_Number": 999, 5 | "Log_Level": "Info", 6 | "Actions": [], 7 | "Message": { 8 | "en-US": "§bA new version of PSR is available! You are really out of dated!\n§bDownload here: https://www.spigotmc.org/resources/protocolstringreplacer.96573/" 9 | } 10 | } 11 | }, 12 | "Version_Actions": { 13 | "0-999": { 14 | "Log_Level": "Info", 15 | "Actions": [], 16 | "Message_Times": 1, 17 | "Notify_In_Game": false, 18 | "Message": { 19 | "en-US": "§bEnjoy PSR? Join our Discord: https://discord.gg/zwzzkmYCBb", 20 | "zh-CN": "§b喜欢PSR吗? 欢迎加入我们的 QQ群: 422532220 !" 21 | } 22 | }, 23 | "0-45": { 24 | "Log_Level": "Error", 25 | "Actions": ["Prohibit"], 26 | "Message_Times": 1, 27 | "Message": { 28 | "en-US": "§cThe version of PSR you are running has been prohibited by the server. This is usually due to a serious problem. Please update the plugin.", 29 | "zh-CN": "§c您使用的版本已被远程服务器禁止. 这通常是因为该版本存在重大问题. 请更新插件." 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Version_Info.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version_Channels": { 3 | "Stable": { 4 | "Latest_Version_Number": 126, 5 | "Log_Level": "Info", 6 | "Actions": [], 7 | "Message": { 8 | "en-US": "§bA new version of PSR (\"3.1.2\") is available!\n§bDownload here: https://www.spigotmc.org/resources/96573/" 9 | } 10 | } 11 | }, 12 | "Version_Actions": { 13 | "0-999": { 14 | "Log_Level": "Info", 15 | "Actions": [], 16 | "Message_Times": 1, 17 | "Notify_In_Game": false, 18 | "Message": { 19 | "en-US": "§bEnjoy PSR? Join our Discord: https://discord.gg/zwzzkmYCBb", 20 | "zh-CN": "§b喜欢PSR吗? 欢迎加入我们的 QQ群: 422532220 !" 21 | } 22 | }, 23 | "0-45": { 24 | "Log_Level": "Error", 25 | "Actions": ["Prohibit"], 26 | "Message_Times": 1, 27 | "Message": { 28 | "en-US": "§cThe version of PSR you are running has been prohibited by the server. This is usually due to a serious problem. Please update the plugin.", 29 | "zh-CN": "§c您使用的版本已被远程服务器禁止. 这通常是因为该版本存在重大问题. 请更新插件." 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") version "1.9.22" 3 | id("java") 4 | id("io.github.goooler.shadow") version "8.1.8" 5 | id("io.papermc.paperweight.userdev") version "2.0.0-beta.11" apply false 6 | } 7 | 8 | repositories { 9 | mavenCentral() 10 | } 11 | 12 | group = "io.github.rothes" 13 | version = rootProject.property("versionName").toString() 14 | 15 | tasks.register("createJars") { 16 | from(project(":bukkit").tasks.named("reobfJar")) 17 | into("$buildDir/allJars") 18 | } 19 | 20 | 21 | allprojects { 22 | apply(plugin = "java") 23 | apply(plugin = "kotlin") 24 | apply(plugin = "io.github.goooler.shadow") 25 | 26 | group = "io.github.rothes.protocolstringreplacer" 27 | version = rootProject.property("versionName").toString() 28 | 29 | val javaVer = JavaVersion.VERSION_1_8 30 | 31 | java { 32 | disableAutoTargetJvm() 33 | sourceCompatibility = javaVer 34 | targetCompatibility = javaVer 35 | withSourcesJar() 36 | withJavadocJar() 37 | } 38 | 39 | tasks.compileJava { 40 | options.encoding = "UTF-8" 41 | sourceCompatibility = javaVer.toString() 42 | targetCompatibility = javaVer.toString() 43 | } 44 | 45 | tasks.compileKotlin { 46 | kotlinOptions { 47 | jvmTarget = javaVer.toString() 48 | } 49 | } 50 | 51 | tasks.javadoc { 52 | options.encoding = "UTF-8" 53 | } 54 | } -------------------------------------------------------------------------------- /bukkit/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.apache.tools.ant.filters.ReplaceTokens 2 | 3 | plugins { 4 | kotlin("jvm") version "1.9.22" 5 | id("java") 6 | id("io.github.goooler.shadow") version "8.1.8" 7 | id("io.papermc.paperweight.userdev") version "2.0.0-beta.11" 8 | } 9 | 10 | val serverVer = rootProject.property("targetMinecraftVersion").toString() 11 | 12 | dependencies { 13 | implementation(project(":bukkit:nms")) 14 | paperweight.paperDevBundle("$serverVer-R0.1-SNAPSHOT") 15 | implementation("commons-collections:commons-collections:3.2.2") 16 | implementation("org.neosearch.stringsearcher:multiple-string-searcher:0.1.1") 17 | implementation("de.tr7zw:item-nbt-api:2.15.0") 18 | implementation("org.bstats:bstats-bukkit:3.0.2") 19 | compileOnly("com.comphenix.protocol:ProtocolLib:5.3.0") 20 | compileOnly("me.clip:placeholderapi:2.11.6") 21 | compileOnly("org.apache.logging.log4j:log4j-api:2.23.1") 22 | compileOnly("org.apache.logging.log4j:log4j-core:2.23.1") 23 | compileOnly("org.jline:jline-reader:3.26.2") 24 | compileOnly("net.minecrell:terminalconsoleappender:1.3.0") 25 | compileOnly("com.mojang:brigadier:1.0.18") 26 | compileOnly("commons-lang:commons-lang:2.6") 27 | } 28 | 29 | val fileName = "${rootProject.name}-${project.name}" 30 | base.archivesName = fileName 31 | 32 | tasks { 33 | shadowJar { 34 | archiveFileName = "${fileName}-${project.version}-mojmap.jar" 35 | 36 | relocate("org.bstats", "io.github.rothes.protocolstringreplacer.lib.org.bstats") 37 | relocate("org.apache.commons.collections", "io.github.rothes.protocolstringreplacer.lib.org.apache.commons.collections") 38 | relocate("org.neosearch.stringsearcher", "io.github.rothes.protocolstringreplacer.lib.org.neosearch.stringsearcher") 39 | relocate("de.tr7zw.changeme.nbtapi", "io.github.rothes.protocolstringreplacer.lib.de.tr7zw.changeme.nbtapi") 40 | relocate("kotlin", "io.github.rothes.protocolstringreplacer.lib.kotlin") 41 | } 42 | 43 | processResources { 44 | filter( 45 | "tokens" to mapOf( 46 | "versionName" to project.property("versionName"), 47 | "versionChannel" to project.property("versionChannel"), 48 | "versionId" to project.property("versionId"), 49 | )) 50 | outputs.doNotCacheIf("MakeReplacementsWork") { true } 51 | } 52 | } 53 | 54 | tasks { 55 | build { 56 | dependsOn(reobfJar) 57 | } 58 | 59 | reobfJar { 60 | mustRunAfter(shadowJar) 61 | } 62 | } 63 | 64 | paperweight.reobfArtifactConfiguration = io.papermc.paperweight.userdev.ReobfArtifactConfiguration.REOBF_PRODUCTION 65 | 66 | allprojects { 67 | repositories { 68 | mavenLocal() 69 | mavenCentral() 70 | 71 | maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") 72 | maven("https://repo.papermc.io/repository/maven-public/") 73 | maven("https://repo.papermc.io/repository/maven-snapshots/") 74 | maven("https://repo.dmulloy2.net/repository/public/") 75 | maven("https://repo.extendedclip.com/content/repositories/placeholderapi/") 76 | maven("https://repo.codemc.org/repository/maven-public/") 77 | maven("https://jitpack.io/") 78 | maven("https://libraries.minecraft.net/") 79 | } 80 | 81 | tasks.shadowJar { 82 | dependencies { 83 | exclude(dependency("org.jetbrains:annotations")) 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /bukkit/nms/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") version "1.9.22" 3 | id("java") 4 | id("io.github.goooler.shadow") version "8.1.8" 5 | id("io.papermc.paperweight.userdev") version "2.0.0-beta.11" 6 | } 7 | 8 | val serverVer = rootProject.property("targetMinecraftVersion").toString() 9 | 10 | dependencies { 11 | paperweight.paperDevBundle("$serverVer-R0.1-SNAPSHOT") 12 | subprojects.filter { 13 | it.parent == project 14 | }.forEach { 15 | api(project(it.path, configuration = "reobf")) 16 | } 17 | } 18 | 19 | subprojects { 20 | apply(plugin = "io.papermc.paperweight.userdev") 21 | if (this.name != "common") { 22 | dependencies { 23 | compileOnly(project(":bukkit:nms:common")) 24 | } 25 | } 26 | 27 | tasks.shadowJar { 28 | relocate( 29 | "io.github.rothes.protocolstringreplacer.nms.generic", 30 | "io.github.rothes.protocolstringreplacer.nms.${project.name}" 31 | ) 32 | } 33 | } 34 | 35 | allprojects { 36 | tasks { 37 | build { 38 | dependsOn(reobfJar) 39 | } 40 | 41 | reobfJar { 42 | mustRunAfter(shadowJar) 43 | } 44 | } 45 | 46 | paperweight.reobfArtifactConfiguration = io.papermc.paperweight.userdev.ReobfArtifactConfiguration.REOBF_PRODUCTION 47 | } -------------------------------------------------------------------------------- /bukkit/nms/common/build.gradle.kts: -------------------------------------------------------------------------------- 1 | val serverVer = rootProject.property("targetMinecraftVersion").toString() 2 | 3 | dependencies { 4 | paperweight.paperDevBundle("$serverVer-R0.1-SNAPSHOT") 5 | } -------------------------------------------------------------------------------- /bukkit/nms/common/generic_v1_19_3/build.gradle.kts: -------------------------------------------------------------------------------- 1 | val serverVer = "1.19.3" 2 | 3 | dependencies { 4 | paperweight.paperDevBundle("$serverVer-R0.1-SNAPSHOT") 5 | } -------------------------------------------------------------------------------- /bukkit/nms/common/generic_v1_19_3/src/main/kotlin/io/github/rothes/protocolstringreplacer/nms/generic/packetreader/BlockEntityTypeGetter.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.generic.packetreader 2 | 3 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IBlockEntityTypeGetter 4 | import net.minecraft.world.level.block.entity.BlockEntityType 5 | 6 | class BlockEntityTypeGetter: IBlockEntityTypeGetter { 7 | 8 | override fun getSignType(): Any = BlockEntityType.SIGN 9 | 10 | override fun getHangingSignType(): Any = BlockEntityType.HANGING_SIGN 11 | } -------------------------------------------------------------------------------- /bukkit/nms/common/generic_v1_19_3/src/main/kotlin/io/github/rothes/protocolstringreplacer/nms/generic/packetreader/MenuTypeGetter.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.generic.packetreader 2 | 3 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IMenuTypeGetter 4 | import net.minecraft.world.inventory.MenuType 5 | 6 | class MenuTypeGetter: IMenuTypeGetter { 7 | 8 | override fun getAnvilMenuType(): Any { 9 | return MenuType.ANVIL 10 | } 11 | 12 | } -------------------------------------------------------------------------------- /bukkit/nms/common/generic_v1_19_3/src/main/kotlin/io/github/rothes/protocolstringreplacer/nms/generic/packetreader/PacketReader.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.generic.packetreader 2 | 3 | import io.github.rothes.protocolstringreplacer.nms.packetreader.ChatType 4 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IPacketReader 5 | import net.minecraft.core.MappedRegistry 6 | import net.minecraft.core.registries.Registries 7 | import net.minecraft.network.protocol.game.ClientboundDisguisedChatPacket 8 | import net.minecraft.network.protocol.game.ClientboundPlayerChatPacket 9 | import net.minecraft.server.MinecraftServer 10 | 11 | class PacketReader: IPacketReader { 12 | 13 | private val chatTypes = with( 14 | MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.CHAT_TYPE) as MappedRegistry) 15 | { 16 | registryKeySet() 17 | .sortedBy { 18 | getId(this.get(it)) 19 | } 20 | .map { it.location().path } 21 | .map { ChatType.entries.find { type -> type.keys.contains(it) }!! } 22 | .toTypedArray() 23 | } 24 | 25 | override fun readChatType(packet: ClientboundPlayerChatPacket): ChatType { 26 | return chatTypes[packet.chatType.chatType] 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /bukkit/nms/common/generic_v1_21/build.gradle.kts: -------------------------------------------------------------------------------- 1 | val serverVer = "1.21" 2 | 3 | dependencies { 4 | paperweight.paperDevBundle("$serverVer-R0.1-SNAPSHOT") 5 | } -------------------------------------------------------------------------------- /bukkit/nms/common/generic_v1_21/src/main/kotlin/io/github/rothes/protocolstringreplacer/nms/generic/packetreader/BlockEntityTypeGetter.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.generic.packetreader 2 | 3 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IBlockEntityTypeGetter 4 | import net.minecraft.world.level.block.entity.BlockEntityType 5 | 6 | class BlockEntityTypeGetter: IBlockEntityTypeGetter { 7 | 8 | override fun getSignType(): Any = BlockEntityType.SIGN 9 | 10 | override fun getHangingSignType(): Any = BlockEntityType.HANGING_SIGN 11 | } -------------------------------------------------------------------------------- /bukkit/nms/common/generic_v1_21/src/main/kotlin/io/github/rothes/protocolstringreplacer/nms/generic/packetreader/DisguisedPacketHandler.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.generic.packetreader 2 | 3 | import net.minecraft.network.chat.ChatType 4 | import net.minecraft.network.chat.Component 5 | import net.minecraft.network.protocol.game.ClientboundDisguisedChatPacket 6 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IDisguisedPacketHandler 7 | import java.lang.reflect.Field 8 | import java.util.Optional 9 | 10 | class DisguisedPacketHandler: IDisguisedPacketHandler { 11 | 12 | override val displayNameField: Field = ChatType.Bound::class.java.declaredFields.first { it.type == Component::class.java } 13 | override val targetField: Field = ChatType.Bound::class.java.declaredFields.first { it.type == Optional::class.java } 14 | 15 | override fun boundRecord(packet: ClientboundDisguisedChatPacket): Any { 16 | return packet.chatType 17 | } 18 | } -------------------------------------------------------------------------------- /bukkit/nms/common/generic_v1_21/src/main/kotlin/io/github/rothes/protocolstringreplacer/nms/generic/packetreader/MenuTypeGetter.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.generic.packetreader 2 | 3 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IMenuTypeGetter 4 | import net.minecraft.world.inventory.MenuType 5 | 6 | class MenuTypeGetter: IMenuTypeGetter { 7 | 8 | override fun getAnvilMenuType(): Any { 9 | return MenuType.ANVIL 10 | } 11 | 12 | } -------------------------------------------------------------------------------- /bukkit/nms/common/generic_v1_21/src/main/kotlin/io/github/rothes/protocolstringreplacer/nms/generic/packetreader/PacketReader.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.generic.packetreader 2 | 3 | import io.github.rothes.protocolstringreplacer.nms.packetreader.ChatType 4 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IPacketReader 5 | import net.minecraft.core.MappedRegistry 6 | import net.minecraft.core.registries.Registries 7 | import net.minecraft.network.protocol.game.ClientboundPlayerChatPacket 8 | import net.minecraft.server.MinecraftServer 9 | 10 | class PacketReader: IPacketReader { 11 | 12 | private val registry = MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.CHAT_TYPE) 13 | private val chatTypes = with(registry as MappedRegistry) { 14 | registryKeySet() 15 | .sortedBy { 16 | getId(this.get(it)) 17 | } 18 | .map { it.location().path } 19 | .map { ChatType.entries.find { type -> type.keys.contains(it) }!! } 20 | .toTypedArray() 21 | } 22 | 23 | override fun readChatType(packet: ClientboundPlayerChatPacket): ChatType { 24 | return chatTypes[registry.getId(packet.chatType.chatType.value())] 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /bukkit/nms/common/generic_v1_21_3/build.gradle.kts: -------------------------------------------------------------------------------- 1 | val serverVer = "1.21.3" 2 | 3 | dependencies { 4 | paperweight.paperDevBundle("$serverVer-R0.1-SNAPSHOT") 5 | } -------------------------------------------------------------------------------- /bukkit/nms/common/generic_v1_21_3/src/main/kotlin/io/github/rothes/protocolstringreplacer/nms/generic/packetreader/BlockEntityTypeGetter.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.generic.packetreader 2 | 3 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IBlockEntityTypeGetter 4 | import net.minecraft.world.level.block.entity.BlockEntityType 5 | 6 | class BlockEntityTypeGetter: IBlockEntityTypeGetter { 7 | 8 | override fun getSignType(): Any = BlockEntityType.SIGN 9 | 10 | override fun getHangingSignType(): Any = BlockEntityType.HANGING_SIGN 11 | } -------------------------------------------------------------------------------- /bukkit/nms/common/generic_v1_21_3/src/main/kotlin/io/github/rothes/protocolstringreplacer/nms/generic/packetreader/DisguisedPacketHandler.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.generic.packetreader 2 | 3 | import net.minecraft.network.chat.ChatType 4 | import net.minecraft.network.chat.Component 5 | import net.minecraft.network.protocol.game.ClientboundDisguisedChatPacket 6 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IDisguisedPacketHandler 7 | import java.lang.reflect.Field 8 | import java.util.Optional 9 | 10 | class DisguisedPacketHandler: IDisguisedPacketHandler { 11 | 12 | override val displayNameField: Field = ChatType.Bound::class.java.declaredFields.first { it.type == Component::class.java } 13 | override val targetField: Field = ChatType.Bound::class.java.declaredFields.first { it.type == Optional::class.java } 14 | 15 | override fun boundRecord(packet: ClientboundDisguisedChatPacket): Any { 16 | return packet.chatType 17 | } 18 | } -------------------------------------------------------------------------------- /bukkit/nms/common/generic_v1_21_3/src/main/kotlin/io/github/rothes/protocolstringreplacer/nms/generic/packetreader/MenuTypeGetter.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.generic.packetreader 2 | 3 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IMenuTypeGetter 4 | import net.minecraft.world.inventory.MenuType 5 | 6 | class MenuTypeGetter: IMenuTypeGetter { 7 | 8 | override fun getAnvilMenuType(): Any { 9 | return MenuType.ANVIL 10 | } 11 | 12 | } -------------------------------------------------------------------------------- /bukkit/nms/common/generic_v1_21_3/src/main/kotlin/io/github/rothes/protocolstringreplacer/nms/generic/packetreader/PacketReader.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.generic.packetreader 2 | 3 | import io.github.rothes.protocolstringreplacer.nms.packetreader.ChatType 4 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IPacketReader 5 | import net.minecraft.core.MappedRegistry 6 | import net.minecraft.core.registries.Registries 7 | import net.minecraft.network.protocol.game.ClientboundPlayerChatPacket 8 | import net.minecraft.server.MinecraftServer 9 | 10 | class PacketReader: IPacketReader { 11 | 12 | private val registry = MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.CHAT_TYPE) 13 | private val chatTypes = with(registry as MappedRegistry) { 14 | registryKeySet() 15 | .sortedBy { getId(this.getValue(it)) } 16 | .map { it.location().path } 17 | .map { ChatType.entries.find { type -> type.keys.contains(it) }!! } 18 | .toTypedArray() 19 | } 20 | 21 | override fun readChatType(packet: ClientboundPlayerChatPacket): ChatType { 22 | return chatTypes[registry.getId(packet.chatType.chatType.value())] 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /bukkit/nms/common/src/main/java/io/github/rothes/protocolstringreplacer/nms/packetreader/ChatType.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.packetreader; 2 | 3 | public enum ChatType { 4 | 5 | PLAYER_CHAT("chat"), 6 | SYSTEM_CHAT("system"), 7 | GAME_INFO("game_info"), 8 | SAY("say_command"), 9 | MSG_INCOMING( 10 | "msg_command_incoming", 11 | "msg_command" // 1.19 12 | ), 13 | MSG_OUTGOING("msg_command_outgoing"), 14 | TEAM_MSG_INCOMING( 15 | "team_msg_command_incoming", 16 | "team_msg_command" // 1.19 17 | ), 18 | TEAM_MSG_OUTGOING("team_msg_command_outgoing"), 19 | EMOTE("emote_command"), 20 | TELLRAW( 21 | "raw", 22 | "tellraw_command" // 1.19 23 | ); 24 | 25 | private final String[] keys; 26 | 27 | ChatType(String... keys) { 28 | this.keys = keys; 29 | } 30 | 31 | public String[] getKeys() { 32 | return keys; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /bukkit/nms/common/src/main/java/io/github/rothes/protocolstringreplacer/nms/packetreader/IBlockEntityTypeGetter.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.packetreader; 2 | 3 | public interface IBlockEntityTypeGetter { 4 | 5 | Object getSignType(); 6 | Object getHangingSignType(); 7 | 8 | } 9 | -------------------------------------------------------------------------------- /bukkit/nms/common/src/main/java/io/github/rothes/protocolstringreplacer/nms/packetreader/IMenuTypeGetter.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.packetreader; 2 | 3 | public interface IMenuTypeGetter { 4 | 5 | Object getAnvilMenuType(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /bukkit/nms/common/src/main/java/io/github/rothes/protocolstringreplacer/nms/packetreader/IPacketReader.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.packetreader; 2 | 3 | import net.minecraft.network.protocol.game.ClientboundPlayerChatPacket; 4 | 5 | public interface IPacketReader { 6 | 7 | ChatType readChatType(ClientboundPlayerChatPacket packet); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /bukkit/nms/common/src/main/kotlin/io/github/rothes/protocolstringreplacer/nms/packetreader/IDisguisedPacketHandler.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.packetreader 2 | 3 | import net.minecraft.network.protocol.game.ClientboundDisguisedChatPacket 4 | import java.lang.reflect.Field 5 | 6 | interface IDisguisedPacketHandler { 7 | 8 | val displayNameField: Field 9 | val targetField: Field 10 | fun boundRecord(packet: ClientboundDisguisedChatPacket): Any 11 | } 12 | -------------------------------------------------------------------------------- /bukkit/nms/src/main/kotlin/io/github/rothes/protocolstringreplacer/nms/NmsManager.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms 2 | 3 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IBlockEntityTypeGetter 4 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IDisguisedPacketHandler 5 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IMenuTypeGetter 6 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IPacketReader 7 | import java.util.function.Consumer 8 | 9 | object NmsManager { 10 | 11 | private const val PACKAGE_PREFIX = "io.github.rothes.protocolstringreplacer.nms" 12 | 13 | private lateinit var minecraftVersion: String 14 | lateinit var warningFunction: Consumer 15 | 16 | fun setVersion(major: Int, minor: Int) { 17 | var m = minor 18 | while (m < 10) { 19 | setVersionProp(major, m) 20 | try { 21 | create() 22 | return 23 | } catch (ignored: ClassNotFoundException) { 24 | m++ 25 | } 26 | } 27 | // On older versions we are not using NMS. 28 | if (major >= 19) { 29 | warningFunction.accept("Minecraft version 1.$major.$minor is not supported by the plugin version you are running on.") 30 | m = minor 31 | while (--m >= 0) { 32 | setVersionProp(major, m) 33 | try { 34 | create() 35 | warningFunction.accept("Fallback to 1.$major.$m support and luckily it could be compatible.") 36 | return 37 | } catch (ignored: ClassNotFoundException) { 38 | } 39 | } 40 | } 41 | setVersionProp(major, minor) 42 | } 43 | 44 | private fun setVersionProp(major: Int, minor: Int) { 45 | minecraftVersion = if (minor == 0) "v1_$major" else "v1_${major}_$minor" 46 | } 47 | 48 | val packetReader by lazy { create() } 49 | val disguisedPacketHandler by lazy { create() } 50 | val menuTypeGetter by lazy { create() } 51 | val blockEntityTypeGetter by lazy { create() } 52 | 53 | private inline fun create(): T { 54 | return T::class.java.instance 55 | } 56 | 57 | @Suppress("UNCHECKED_CAST") 58 | private val Class.versioned: Class 59 | get() = Class.forName(buildString { 60 | append(PACKAGE_PREFIX) 61 | append(".") 62 | append(minecraftVersion) 63 | append(this@versioned.`package`.name.substring(PACKAGE_PREFIX.length)) 64 | append('.') 65 | append(this@versioned.simpleName.substring(1)) 66 | }) as Class 67 | 68 | private val Class.instance: T 69 | get() = this.versioned.getConstructor().newInstance() as T 70 | 71 | } -------------------------------------------------------------------------------- /bukkit/nms/v1_19_1/build.gradle.kts: -------------------------------------------------------------------------------- 1 | val serverVer = "1.19" // 1.19.1 bundle is broken, so we're using 1.19 2 | 3 | dependencies { 4 | paperweight.paperDevBundle("$serverVer-R0.1-SNAPSHOT") 5 | pluginRemapper("net.fabricmc:tiny-remapper:0.10.3:fat") 6 | } 7 | 8 | java { 9 | toolchain { 10 | languageVersion = JavaLanguageVersion.of(17) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /bukkit/nms/v1_19_1/src/main/kotlin/io/github/rothes/protocolstringreplacer/nms/v1_19_1/packetreader/PacketReader.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.v1_19_1.packetreader 2 | 3 | import io.github.rothes.protocolstringreplacer.nms.packetreader.ChatType 4 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IPacketReader 5 | import net.minecraft.core.MappedRegistry 6 | import net.minecraft.core.Registry 7 | import net.minecraft.network.protocol.game.ClientboundPlayerChatPacket 8 | import net.minecraft.server.MinecraftServer 9 | 10 | class PacketReader: IPacketReader { 11 | 12 | private val chatTypes = with( 13 | MinecraftServer.getServer().registryAccess().registryOrThrow(Registry.CHAT_TYPE_REGISTRY) as MappedRegistry 14 | ) { 15 | registryKeySet() 16 | .sortedBy { 17 | getId(this.get(it)) 18 | } 19 | .map { it.location().path } 20 | .map { ChatType.entries.find { type -> type.keys.contains(it) }!! } 21 | .toTypedArray() 22 | } 23 | 24 | override fun readChatType(packet: ClientboundPlayerChatPacket): ChatType { 25 | return chatTypes[packet.typeId] 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /bukkit/nms/v1_19_2/build.gradle.kts: -------------------------------------------------------------------------------- 1 | val serverVer = "1.19.2" 2 | 3 | dependencies { 4 | paperweight.paperDevBundle("$serverVer-R0.1-SNAPSHOT") 5 | pluginRemapper("net.fabricmc:tiny-remapper:0.10.3:fat") 6 | } 7 | 8 | java { 9 | toolchain { 10 | languageVersion = JavaLanguageVersion.of(17) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /bukkit/nms/v1_19_2/src/main/kotlin/io/github/rothes/protocolstringreplacer/nms/v1_19_2/packetreader/PacketReader.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.v1_19_2.packetreader 2 | 3 | import io.github.rothes.protocolstringreplacer.nms.packetreader.ChatType 4 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IPacketReader 5 | import net.minecraft.core.MappedRegistry 6 | import net.minecraft.core.Registry 7 | import net.minecraft.network.protocol.game.ClientboundPlayerChatPacket 8 | import net.minecraft.server.MinecraftServer 9 | 10 | class PacketReader: IPacketReader { 11 | 12 | private val chatTypes = with( 13 | MinecraftServer.getServer().registryAccess().registryOrThrow(Registry.CHAT_TYPE_REGISTRY) as MappedRegistry 14 | ) { 15 | registryKeySet() 16 | .sortedBy { 17 | getId(this.get(it)) 18 | } 19 | .map { it.location().path } 20 | .map { ChatType.entries.find { type -> type.keys.contains(it) }!! } 21 | .toTypedArray() 22 | } 23 | 24 | override fun readChatType(packet: ClientboundPlayerChatPacket): ChatType { 25 | return chatTypes[packet.chatType.chatType] 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /bukkit/nms/v1_19_3/build.gradle.kts: -------------------------------------------------------------------------------- 1 | val serverVer = "1.19.3" 2 | 3 | dependencies { 4 | paperweight.paperDevBundle("$serverVer-R0.1-SNAPSHOT") 5 | implementation(project(":bukkit:nms:common:generic_v1_19_3")) 6 | } 7 | -------------------------------------------------------------------------------- /bukkit/nms/v1_19_4/build.gradle.kts: -------------------------------------------------------------------------------- 1 | val serverVer = "1.19.4" 2 | 3 | dependencies { 4 | paperweight.paperDevBundle("$serverVer-R0.1-SNAPSHOT") 5 | implementation(project(":bukkit:nms:common:generic_v1_19_3")) 6 | } 7 | -------------------------------------------------------------------------------- /bukkit/nms/v1_20_1/build.gradle.kts: -------------------------------------------------------------------------------- 1 | val serverVer = "1.20.1" 2 | 3 | dependencies { 4 | paperweight.paperDevBundle("$serverVer-R0.1-SNAPSHOT") 5 | implementation(project(":bukkit:nms:common:generic_v1_19_3")) 6 | } 7 | -------------------------------------------------------------------------------- /bukkit/nms/v1_20_2/build.gradle.kts: -------------------------------------------------------------------------------- 1 | val serverVer = "1.20.2" 2 | 3 | dependencies { 4 | paperweight.paperDevBundle("$serverVer-R0.1-SNAPSHOT") 5 | implementation(project(":bukkit:nms:common:generic_v1_19_3")) 6 | } -------------------------------------------------------------------------------- /bukkit/nms/v1_20_4/build.gradle.kts: -------------------------------------------------------------------------------- 1 | val serverVer = "1.20.4" 2 | 3 | dependencies { 4 | paperweight.paperDevBundle("$serverVer-R0.1-SNAPSHOT") 5 | implementation(project(":bukkit:nms:common:generic_v1_19_3")) 6 | } 7 | -------------------------------------------------------------------------------- /bukkit/nms/v1_20_6/build.gradle.kts: -------------------------------------------------------------------------------- 1 | val serverVer = "1.20.6" 2 | 3 | dependencies { 4 | paperweight.paperDevBundle("$serverVer-R0.1-SNAPSHOT") 5 | } 6 | -------------------------------------------------------------------------------- /bukkit/nms/v1_20_6/src/main/kotlin/io/github/rothes/protocolstringreplacer/nms/v1_20_6/packetreader/BlockEntityTypeGetter.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.v1_20_6.packetreader 2 | 3 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IBlockEntityTypeGetter 4 | import net.minecraft.world.level.block.entity.BlockEntityType 5 | 6 | class BlockEntityTypeGetter: IBlockEntityTypeGetter { 7 | 8 | override fun getSignType(): Any = BlockEntityType.SIGN 9 | 10 | override fun getHangingSignType(): Any = BlockEntityType.HANGING_SIGN 11 | } -------------------------------------------------------------------------------- /bukkit/nms/v1_20_6/src/main/kotlin/io/github/rothes/protocolstringreplacer/nms/v1_20_6/packetreader/DisguisedPacketHandler.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.v1_20_6.packetreader 2 | 3 | import net.minecraft.network.chat.ChatType 4 | import net.minecraft.network.chat.Component 5 | import net.minecraft.network.protocol.game.ClientboundDisguisedChatPacket 6 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IDisguisedPacketHandler 7 | import java.lang.reflect.Field 8 | import java.util.Optional 9 | 10 | class DisguisedPacketHandler: IDisguisedPacketHandler { 11 | 12 | override val displayNameField: Field = ChatType.Bound::class.java.declaredFields.first { it.type == Component::class.java } 13 | override val targetField: Field = ChatType.Bound::class.java.declaredFields.first { it.type == Optional::class.java } 14 | 15 | override fun boundRecord(packet: ClientboundDisguisedChatPacket): Any { 16 | return packet.chatType 17 | } 18 | } -------------------------------------------------------------------------------- /bukkit/nms/v1_20_6/src/main/kotlin/io/github/rothes/protocolstringreplacer/nms/v1_20_6/packetreader/MenuTypeGetter.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.v1_20_6.packetreader 2 | 3 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IMenuTypeGetter 4 | import net.minecraft.world.inventory.MenuType 5 | 6 | class MenuTypeGetter: IMenuTypeGetter { 7 | 8 | override fun getAnvilMenuType(): Any { 9 | return MenuType.ANVIL 10 | } 11 | 12 | } -------------------------------------------------------------------------------- /bukkit/nms/v1_20_6/src/main/kotlin/io/github/rothes/protocolstringreplacer/nms/v1_20_6/packetreader/PacketReader.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.nms.v1_20_6.packetreader 2 | 3 | import io.github.rothes.protocolstringreplacer.nms.packetreader.ChatType 4 | import io.github.rothes.protocolstringreplacer.nms.packetreader.IPacketReader 5 | import net.minecraft.core.MappedRegistry 6 | import net.minecraft.core.registries.Registries 7 | import net.minecraft.network.protocol.game.ClientboundPlayerChatPacket 8 | import net.minecraft.server.MinecraftServer 9 | 10 | class PacketReader: IPacketReader { 11 | 12 | private val registry = MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.CHAT_TYPE) 13 | private val chatTypes = with(registry as MappedRegistry) { 14 | registryKeySet() 15 | .sortedBy { 16 | getId(this.get(it)) 17 | } 18 | .map { it.location().path } 19 | .map { ChatType.entries.find { type -> type.keys.contains(it) }!! } 20 | .toTypedArray() 21 | } 22 | 23 | override fun readChatType(packet: ClientboundPlayerChatPacket): ChatType { 24 | return chatTypes[registry.getId(packet.chatType.chatType.value())] 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /bukkit/nms/v1_21_1/build.gradle.kts: -------------------------------------------------------------------------------- 1 | val serverVer = "1.21.1" 2 | 3 | dependencies { 4 | paperweight.paperDevBundle("$serverVer-R0.1-SNAPSHOT") 5 | implementation(project(":bukkit:nms:common:generic_v1_21")) 6 | } -------------------------------------------------------------------------------- /bukkit/nms/v1_21_3/build.gradle.kts: -------------------------------------------------------------------------------- 1 | val serverVer = "1.21.3" 2 | 3 | dependencies { 4 | paperweight.paperDevBundle("$serverVer-R0.1-SNAPSHOT") 5 | implementation(project(":bukkit:nms:common:generic_v1_21_3")) 6 | } -------------------------------------------------------------------------------- /bukkit/nms/v1_21_4/build.gradle.kts: -------------------------------------------------------------------------------- 1 | val serverVer = "1.21.4" 2 | 3 | dependencies { 4 | paperweight.paperDevBundle("$serverVer-R0.1-SNAPSHOT") 5 | implementation(project(":bukkit:nms:common:generic_v1_21_3")) 6 | } -------------------------------------------------------------------------------- /bukkit/nms/v1_21_5/build.gradle.kts: -------------------------------------------------------------------------------- 1 | val serverVer = "1.21.5" 2 | 3 | dependencies { 4 | paperweight.paperDevBundle("$serverVer-no-moonrise-SNAPSHOT") 5 | implementation(project(":bukkit:nms:common:generic_v1_21_3")) 6 | } -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/api/configuration/DotYamlConfiguration.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.api.configuration; 2 | 3 | import org.apache.commons.lang.Validate; 4 | import org.bukkit.Bukkit; 5 | import org.bukkit.configuration.InvalidConfigurationException; 6 | 7 | import javax.annotation.Nonnull; 8 | import java.io.File; 9 | import java.io.FileNotFoundException; 10 | import java.io.IOException; 11 | import java.util.logging.Level; 12 | 13 | /** 14 | * Only used to upgrade old configs currently. 15 | */ 16 | @SuppressWarnings("DeprecatedIsStillUsed") 17 | @Deprecated 18 | public class DotYamlConfiguration extends CommentYamlConfiguration { 19 | 20 | public DotYamlConfiguration() { 21 | super(); 22 | options().pathSeparator('鰠'); 23 | } 24 | 25 | @Nonnull 26 | public static DotYamlConfiguration loadConfiguration(@Nonnull File file) { 27 | Validate.notNull(file, "File cannot be null"); 28 | DotYamlConfiguration config = new DotYamlConfiguration(); 29 | 30 | try { 31 | config.load(file); 32 | } catch (FileNotFoundException ignored) { 33 | } catch (IOException | InvalidConfigurationException var4) { 34 | Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file, var4); 35 | } 36 | 37 | return config; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/api/exceptions/IncompatibleServerException.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.api.exceptions; 2 | 3 | public class IncompatibleServerException extends RuntimeException { 4 | 5 | public IncompatibleServerException(Throwable throwable) { 6 | super(throwable); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/api/exceptions/JsonSyntaxException.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.api.exceptions; 2 | 3 | public class JsonSyntaxException extends RuntimeException { 4 | 5 | public JsonSyntaxException(String msg, Throwable throwable) { 6 | super(msg, throwable); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/api/exceptions/MissingInitialResourceException.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.api.exceptions; 2 | 3 | public class MissingInitialResourceException extends RuntimeException { 4 | 5 | public MissingInitialResourceException(String message) { 6 | super(message); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/api/user/PsrUserManager.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.api.user; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.command.CommandSender; 5 | import org.bukkit.entity.Player; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import javax.annotation.Nonnull; 9 | import java.util.HashMap; 10 | import java.util.UUID; 11 | 12 | public class PsrUserManager { 13 | 14 | private final HashMap users = new HashMap<>(); 15 | private final PsrUser console = new PsrUser(Bukkit.getConsoleSender()); 16 | 17 | public PsrUser getUser(@NotNull UUID uuid) { 18 | return users.getOrDefault(uuid, loadUser(uuid)); 19 | } 20 | 21 | @Nonnull 22 | public PsrUser getUser(@NotNull Player player) { 23 | return users.getOrDefault(player.getUniqueId(), loadUser(player)); 24 | } 25 | 26 | @Nonnull 27 | public PsrUser getUser(@NotNull CommandSender sender) { 28 | return sender instanceof Player? getUser((Player) sender) : console; 29 | } 30 | 31 | public PsrUser getConsoleUser() { 32 | return console; 33 | } 34 | 35 | public PsrUser loadUser(@NotNull UUID uuid) { 36 | return users.putIfAbsent(uuid, new PsrUser(uuid)); 37 | } 38 | 39 | public PsrUser loadUser(@NotNull Player player) { 40 | return users.putIfAbsent(player.getUniqueId(), new PsrUser(player)); 41 | } 42 | 43 | public void unloadUser(@NotNull UUID uuid) { 44 | users.remove(uuid); 45 | } 46 | 47 | public void unloadUser(@NotNull Player player) { 48 | unloadUser(player.getUniqueId()); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/command/SubCommand.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.command; 2 | 3 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 4 | 5 | import javax.annotation.Nonnull; 6 | import java.util.List; 7 | 8 | public abstract class SubCommand { 9 | 10 | private final String name; 11 | private final String permission; 12 | private final String description; 13 | 14 | public SubCommand(@Nonnull String name, @Nonnull String permission, @Nonnull String description) { 15 | this.name = name; 16 | this.permission = permission; 17 | this.description = description; 18 | } 19 | 20 | public abstract void onExecute(@Nonnull PsrUser user, @Nonnull String[] args); 21 | 22 | public abstract List onTab(@Nonnull PsrUser user, @Nonnull String[] args); 23 | 24 | @Nonnull 25 | public final String getName() { 26 | return name; 27 | } 28 | 29 | @Nonnull 30 | public String getPermission() { 31 | return permission; 32 | } 33 | 34 | @Nonnull 35 | public String getDescription() { 36 | return description; 37 | } 38 | 39 | public abstract void sendHelp(@Nonnull PsrUser user); 40 | } 41 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/command/subcommands/Edit.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.command.subcommands; 2 | 3 | import io.github.rothes.protocolstringreplacer.PsrLocalization; 4 | import io.github.rothes.protocolstringreplacer.command.subcommands.editchildren.Block; 5 | import io.github.rothes.protocolstringreplacer.command.subcommands.editchildren.File; 6 | import io.github.rothes.protocolstringreplacer.command.subcommands.editchildren.Replace; 7 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 8 | import io.github.rothes.protocolstringreplacer.command.SubCommand; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | import javax.annotation.Nonnull; 12 | import java.util.ArrayList; 13 | import java.util.LinkedList; 14 | import java.util.List; 15 | 16 | public class Edit extends SubCommand { 17 | 18 | private final LinkedList childCommands = new LinkedList<>(); 19 | 20 | public Edit() { 21 | super("edit", "protocolstringreplacer.command.edit", 22 | PsrLocalization.getLocaledMessage("Sender.Commands.Edit.Description")); 23 | 24 | childCommands.add(new File()); 25 | childCommands.add(new Replace()); 26 | childCommands.add(new Block()); 27 | // TODO: childCommands.add(new Option()); 28 | } 29 | 30 | @Override 31 | public void onExecute(@Nonnull PsrUser user, @Nonnull String[] args) { 32 | if (args.length > 1) { 33 | for (SubCommand childCommand : childCommands) { 34 | if (childCommand.getName().equalsIgnoreCase(args[1])) { 35 | if (user.hasPermissionOrOp(childCommand.getPermission())) { 36 | childCommand.onExecute(user, args); 37 | } else { 38 | user.sendFilteredText(PsrLocalization.getPrefixedLocaledMessage("Sender.Commands.No-Permission")); 39 | } 40 | return; 41 | } 42 | } 43 | } 44 | sendHelp(user); 45 | } 46 | 47 | @Override 48 | public List onTab(@NotNull PsrUser user, @NotNull String[] args) { 49 | List list = new ArrayList<>(); 50 | if (args.length == 2) { 51 | list.add("help"); 52 | for (SubCommand childCommand : childCommands) { 53 | if (user.hasPermissionOrOp(childCommand.getPermission())) { 54 | list.add(childCommand.getName()); 55 | } 56 | } 57 | } else { 58 | for (SubCommand childCommand : childCommands) { 59 | if (childCommand.getName().equalsIgnoreCase(args[1])) { 60 | list = childCommand.onTab(user, args); 61 | } 62 | } 63 | } 64 | return list; 65 | } 66 | 67 | @Override 68 | public void sendHelp(@Nonnull PsrUser user) { 69 | user.sendFilteredText(PsrLocalization.getLocaledMessage("Sender.Commands.Edit.Help.Header")); 70 | for (SubCommand childCommand : childCommands) { 71 | user.sendFilteredText(PsrLocalization.getLocaledMessage("Sender.Commands.Subcommand-Help-Format", 72 | "/psr edit " + childCommand.getName(), childCommand.getDescription())); 73 | } 74 | user.sendFilteredText(PsrLocalization.getLocaledMessage("Sender.Commands.Edit.Help.Footer")); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/command/subcommands/Reload.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.command.subcommands; 2 | 3 | import io.github.rothes.protocolstringreplacer.PsrLocalization; 4 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer; 5 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 6 | import io.github.rothes.protocolstringreplacer.command.SubCommand; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | import javax.annotation.Nonnull; 10 | import java.util.List; 11 | 12 | public class Reload extends SubCommand { 13 | 14 | public Reload() { 15 | super("reload", "protocolstringreplacer.command.reload", PsrLocalization 16 | .getLocaledMessage("Sender.Commands.Reload.Description")); 17 | } 18 | 19 | @Override 20 | public void onExecute(@Nonnull PsrUser user, @Nonnull String[] args) { 21 | if (args.length == 1) { 22 | if (ProtocolStringReplacer.getInstance().isReloading()) { 23 | user.sendFilteredText(PsrLocalization.getPrefixedLocaledMessage("Sender.Commands.Reload.Already-Reloading")); 24 | return; 25 | } 26 | ProtocolStringReplacer.getInstance().reload(user); 27 | } else { 28 | sendHelp(user); 29 | } 30 | } 31 | 32 | @Override 33 | public List onTab(@NotNull PsrUser user, @NotNull String[] args) { 34 | return null; 35 | } 36 | 37 | @Override 38 | public void sendHelp(@Nonnull PsrUser user) { 39 | user.sendFilteredText(PsrLocalization.getLocaledMessage("Sender.Commands.Reload.Help.Header")); 40 | user.sendFilteredText("§7 * §e/psr reload§7- §b " + this.getDescription()); 41 | user.sendFilteredText(PsrLocalization.getLocaledMessage("Sender.Commands.Reload.Help.Footer")); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/console/PsrJndiLookup.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.console; 2 | 3 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer; 4 | import io.github.rothes.protocolstringreplacer.util.scheduler.PsrScheduler; 5 | import org.apache.logging.log4j.core.LogEvent; 6 | import org.apache.logging.log4j.core.config.plugins.Plugin; 7 | import org.apache.logging.log4j.core.lookup.StrLookup; 8 | 9 | @Plugin(name = "jndi", category = StrLookup.CATEGORY) 10 | public class PsrJndiLookup implements StrLookup { 11 | 12 | // static final String CONTAINER_JNDI_RESOURCE_PATH_PREFIX = "java:comp/env/"; 13 | 14 | @Override 15 | public String lookup(final String key) { 16 | return lookup(null, key); 17 | } 18 | 19 | @Override 20 | public String lookup(LogEvent event, String key) { 21 | if (key == null) { 22 | return null; 23 | } 24 | // runTaskLater to avoid errors. 25 | PsrScheduler.runTaskLater(() -> ProtocolStringReplacer.info("Blocked not whitelisted Jndi looking up [" + key + "]") 26 | , 0L); 27 | return null; 28 | 29 | // TODO: Maybe add a config for those really need jndi..? 30 | // try (final JndiManager jndiManager = JndiManager.getDefaultManager()) { 31 | // final String jndiName = convertJndiName(key); 32 | // return Objects.toString(jndiManager.lookup(jndiName), null); 33 | // } catch (final NamingException e) { 34 | // return null; 35 | // } 36 | } 37 | 38 | // private String convertJndiName(final String jndiName) { 39 | // if (!jndiName.startsWith(CONTAINER_JNDI_RESOURCE_PATH_PREFIX) && jndiName.indexOf(':') == -1) { 40 | // return CONTAINER_JNDI_RESOURCE_PATH_PREFIX + jndiName; 41 | // } 42 | // return jndiName; 43 | // } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/console/PsrMessageFactory.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.console; 2 | 3 | import org.apache.logging.log4j.message.AbstractMessageFactory; 4 | import org.apache.logging.log4j.message.Message; 5 | 6 | public class PsrMessageFactory extends AbstractMessageFactory { 7 | 8 | @Override 9 | public Message newMessage(String message) { 10 | return new PsrMessage(message); 11 | } 12 | 13 | @Override 14 | public Message newMessage(CharSequence message) { 15 | return new PsrMessage(message); 16 | } 17 | 18 | @Override 19 | public Message newMessage(String message, Object... params) { 20 | return new PsrMessage(message); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/events/PsrReloadEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.events; 2 | 3 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 4 | import org.bukkit.command.CommandSender; 5 | import org.bukkit.event.Cancellable; 6 | import org.bukkit.event.Event; 7 | import org.bukkit.event.HandlerList; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | public class PsrReloadEvent extends Event implements Cancellable { 11 | 12 | private static final HandlerList handlers = new HandlerList(); 13 | private final ReloadState reloadState; 14 | private final PsrUser user; 15 | private boolean cancelled = false; 16 | 17 | public PsrReloadEvent(ReloadState reloadState, PsrUser user) { 18 | this.reloadState = reloadState; 19 | this.user = user; 20 | } 21 | 22 | public ReloadState getReloadState() { 23 | return reloadState; 24 | } 25 | 26 | public PsrUser getUser() { 27 | return user; 28 | } 29 | 30 | public CommandSender getActor() { 31 | return user.getSender(); 32 | } 33 | 34 | @NotNull 35 | @Override 36 | public HandlerList getHandlers() { 37 | return handlers; 38 | } 39 | 40 | @Override 41 | public boolean isCancelled() { 42 | return cancelled; 43 | } 44 | 45 | @Override 46 | public void setCancelled(boolean cancelled) { 47 | this.cancelled = cancelled; 48 | } 49 | 50 | @NotNull 51 | public static HandlerList getHandlerList() { 52 | return handlers; 53 | } 54 | 55 | public enum ReloadState { 56 | BEFORE, 57 | FINISH 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/listeners/PlayerJoinListener.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.listeners; 2 | 3 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.EventHandler; 6 | import org.bukkit.event.Listener; 7 | import org.bukkit.event.player.PlayerJoinEvent; 8 | 9 | public class PlayerJoinListener implements Listener { 10 | 11 | @EventHandler 12 | public void onPlayerJoin(PlayerJoinEvent event) { 13 | Player player = event.getPlayer(); 14 | ProtocolStringReplacer.getInstance().getUserManager().loadUser(player); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/listeners/PlayerQuitListener.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.listeners; 2 | 3 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.EventHandler; 6 | import org.bukkit.event.Listener; 7 | import org.bukkit.event.player.PlayerQuitEvent; 8 | 9 | public class PlayerQuitListener implements Listener { 10 | 11 | @EventHandler 12 | public void onPlayerQuit(PlayerQuitEvent event) { 13 | Player player = event.getPlayer(); 14 | ProtocolStringReplacer.getInstance().getUserManager().unloadUser(player); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/listeners/PsrInternalListeners.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.listeners; 2 | 3 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer; 4 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 5 | import io.github.rothes.protocolstringreplacer.api.user.PsrUserManager; 6 | import io.github.rothes.protocolstringreplacer.events.PsrReloadEvent; 7 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 8 | import org.bukkit.Bukkit; 9 | import org.bukkit.entity.Player; 10 | import org.bukkit.event.EventHandler; 11 | import org.bukkit.event.EventPriority; 12 | import org.bukkit.event.Listener; 13 | 14 | public class PsrInternalListeners implements Listener { 15 | 16 | private int maxRecords; 17 | 18 | @EventHandler(priority = EventPriority.MONITOR) 19 | public void onPsrReload(PsrReloadEvent e) { 20 | if (e.getReloadState() == PsrReloadEvent.ReloadState.BEFORE) { 21 | maxRecords = ProtocolStringReplacer.getInstance().getConfigManager().maxCaptureRecords; 22 | } else if (e.getReloadState() == PsrReloadEvent.ReloadState.FINISH 23 | // maxCaptureRecords changed, reset user capture status. 24 | && maxRecords != ProtocolStringReplacer.getInstance().getConfigManager().maxCaptureRecords) { 25 | PsrUserManager userManager = ProtocolStringReplacer.getInstance().getUserManager(); 26 | for (Player player : Bukkit.getOnlinePlayers()) { 27 | PsrUser user = userManager.getUser(player); 28 | for (ListenType value : ListenType.values()) { 29 | user.removeCaptureType(value); 30 | } 31 | } 32 | } 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/BasePacketListener.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.ProtocolLibrary; 5 | import com.comphenix.protocol.events.PacketAdapter; 6 | import com.comphenix.protocol.events.PacketEvent; 7 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer; 8 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 9 | import org.apache.commons.lang.Validate; 10 | import org.bukkit.entity.Player; 11 | import org.jetbrains.annotations.Nullable; 12 | 13 | import javax.annotation.Nonnull; 14 | 15 | public abstract class BasePacketListener { 16 | 17 | protected final PacketType packetType; 18 | protected PacketAdapter packetAdapter; 19 | 20 | protected BasePacketListener(@Nonnull PacketType packetType) { 21 | this.packetType = packetType; 22 | } 23 | 24 | protected void register() { 25 | ProtocolLibrary.getProtocolManager().addPacketListener(packetAdapter); 26 | } 27 | 28 | @Nullable 29 | protected final PsrUser getEventUser(@Nonnull PacketEvent packetEvent) { 30 | Validate.notNull(packetEvent, "Packet Event cannot be null"); 31 | Player player = packetEvent.getPlayer(); 32 | if (packetEvent.isPlayerTemporary()) { 33 | ProtocolStringReplacer.warn("ProtocolLib returns temporary player [" + player.getAddress() + "] for packet " + packetType.name() + ". " 34 | + "It cannot be processed."); 35 | return null; 36 | } else { 37 | return ProtocolStringReplacer.getInstance().getUserManager().getUser(player); 38 | } 39 | } 40 | 41 | protected boolean canWrite(@Nonnull PacketEvent packetEvent) { 42 | Validate.notNull(packetEvent, "Packet Event cannot be null"); 43 | 44 | if (packetEvent.isReadOnly()) { 45 | if (ProtocolStringReplacer.getInstance().getConfigManager().forceReplace) { 46 | packetEvent.setReadOnly(false); 47 | } else { 48 | return false; 49 | } 50 | } 51 | return true; 52 | } 53 | 54 | abstract protected void process(@Nonnull PacketEvent packetEvent); 55 | 56 | } 57 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/client/BaseClientPacketListener.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.client; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketAdapter; 5 | import com.comphenix.protocol.events.PacketEvent; 6 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer; 7 | import io.github.rothes.protocolstringreplacer.packetlistener.BasePacketListener; 8 | 9 | public abstract class BaseClientPacketListener extends BasePacketListener { 10 | 11 | protected BaseClientPacketListener(PacketType packetType) { 12 | super(packetType); 13 | packetAdapter = new PacketAdapter(ProtocolStringReplacer.getInstance(), ProtocolStringReplacer.getInstance().getPacketListenerManager().getListenerPriority(), packetType) { 14 | public void onPacketReceiving(PacketEvent packetEvent) { 15 | boolean readOnly = packetEvent.isReadOnly(); 16 | if (!canWrite(packetEvent)) { 17 | return; 18 | } 19 | process(packetEvent); 20 | if (readOnly) { 21 | packetEvent.setReadOnly(true); 22 | } 23 | } 24 | }; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/client/CloseWindow.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.client; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketEvent; 5 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 6 | import io.github.rothes.protocolstringreplacer.packetlistener.client.itemstack.BaseClientItemPacketListener; 7 | import io.github.rothes.protocolstringreplacer.util.scheduler.PsrScheduler; 8 | 9 | public class CloseWindow extends BaseClientItemPacketListener { 10 | 11 | public CloseWindow() { 12 | super(PacketType.Play.Client.CLOSE_WINDOW); 13 | } 14 | 15 | protected void process(PacketEvent packetEvent) { 16 | PsrUser user = getEventUser(packetEvent); 17 | user.setCurrentWindowTitle(null); 18 | user.setInAnvil(false); 19 | if (user.isInMerchant()) { 20 | user.setInMerchant(false); 21 | // Must be called in other threads or the inventory won't update. 22 | PsrScheduler.runTaskAsynchronously(() -> user.getPlayer().updateInventory()); 23 | } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/client/SettingsLocale.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.client; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketEvent; 5 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.util.Locale; 9 | 10 | public class SettingsLocale extends BaseClientPacketListener { 11 | 12 | public SettingsLocale() { 13 | super(PacketType.Play.Client.SETTINGS); 14 | } 15 | 16 | @Override 17 | protected void process(@NotNull PacketEvent packetEvent) { 18 | PsrUser user = getEventUser(packetEvent); 19 | if (user == null) { 20 | return; 21 | } 22 | String read = packetEvent.getPacket().getStrings().read(0); 23 | user.setClientLocale(read.toLowerCase(Locale.ROOT).replace('-', '_')); 24 | } 25 | 26 | @Override 27 | protected boolean canWrite(@NotNull PacketEvent packetEvent) { 28 | // We just read it. 29 | return true; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/client/SettingsLocaleUpper20.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.client; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketEvent; 5 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.lang.reflect.Field; 9 | import java.util.Locale; 10 | 11 | public class SettingsLocaleUpper20 extends BaseClientPacketListener { 12 | 13 | private Field language; 14 | 15 | public SettingsLocaleUpper20() { 16 | super(PacketType.Play.Client.SETTINGS); 17 | } 18 | 19 | @Override 20 | protected void process(@NotNull PacketEvent packetEvent) { 21 | PsrUser user = getEventUser(packetEvent); 22 | if (user == null) { 23 | return; 24 | } 25 | Object record = packetEvent.getPacket().getModifier().read(0); 26 | String read; 27 | try { 28 | read = (String) field().get(record); 29 | } catch (IllegalAccessException e) { 30 | throw new RuntimeException(e); 31 | } 32 | user.setClientLocale(read.toLowerCase(Locale.ROOT).replace('-', '_')); 33 | } 34 | 35 | private Field field() { 36 | if (language == null) { 37 | language = PacketType.Play.Client.SETTINGS.getPacketClass().getDeclaredFields()[0].getType().getDeclaredFields()[0]; 38 | language.setAccessible(true); 39 | } 40 | return language; 41 | } 42 | 43 | @Override 44 | protected boolean canWrite(@NotNull PacketEvent packetEvent) { 45 | // We just read it. 46 | return true; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/client/itemstack/BaseClientItemPacketListener.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.client.itemstack; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import de.tr7zw.changeme.nbtapi.NBT; 5 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer; 6 | import io.github.rothes.protocolstringreplacer.packetlistener.client.BaseClientPacketListener; 7 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 8 | import org.bukkit.inventory.ItemStack; 9 | 10 | import java.util.HashMap; 11 | 12 | public abstract class BaseClientItemPacketListener extends BaseClientPacketListener { 13 | 14 | protected BaseClientItemPacketListener(PacketType packetType) { 15 | super(packetType); 16 | } 17 | 18 | protected ItemStack restoreItem(PsrUser user, ItemStack itemStack) { 19 | if (!itemStack.hasItemMeta()) { 20 | return itemStack; 21 | } 22 | return NBT.get(itemStack, nbt -> { 23 | if (nbt.hasTag("ProtocolStringReplacer")) { 24 | Short uniqueCacheKey = nbt.getCompound("ProtocolStringReplacer").getShort("UserMetaCacheKey"); 25 | if (uniqueCacheKey != null) { 26 | HashMap userItemRestoreCache = user.getItemRestoreCache(); 27 | ItemStack original = userItemRestoreCache.get(uniqueCacheKey); 28 | if (original == null) { 29 | ProtocolStringReplacer.warn("Failed to get original ItemMeta by meta-cache key, ignoring.\n" + itemStack); 30 | return itemStack; 31 | } 32 | return original; 33 | } else { 34 | ProtocolStringReplacer.warn("Failed to get original ItemMeta by meta-cache key due to null, ignoring.\n" + itemStack); 35 | } 36 | } 37 | return itemStack; 38 | }); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/client/itemstack/SetCreativeSlot.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.client.itemstack; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketEvent; 5 | import com.comphenix.protocol.reflect.StructureModifier; 6 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 7 | import org.bukkit.inventory.ItemStack; 8 | 9 | public final class SetCreativeSlot extends BaseClientItemPacketListener { 10 | 11 | public SetCreativeSlot() { 12 | super(PacketType.Play.Client.SET_CREATIVE_SLOT); 13 | } 14 | 15 | protected void process(PacketEvent packetEvent) { 16 | PsrUser user = getEventUser(packetEvent); 17 | if (user == null) { 18 | return; 19 | } 20 | if (user.hasPermission("protocolstringreplacer.feature.usermetacache")) { 21 | StructureModifier itemModifier = packetEvent.getPacket().getItemModifier(); 22 | ItemStack itemStack = itemModifier.read(0); 23 | itemModifier.write(0, restoreItem(user, itemStack)); 24 | } 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/client/itemstack/WindowClick.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.client.itemstack; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketEvent; 5 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 6 | import org.bukkit.inventory.ItemStack; 7 | 8 | public final class WindowClick extends BaseClientItemPacketListener { 9 | 10 | public WindowClick() { 11 | super(PacketType.Play.Client.WINDOW_CLICK); 12 | } 13 | 14 | protected void process(PacketEvent packetEvent) { 15 | PsrUser user = getEventUser(packetEvent); 16 | if (user == null) { 17 | return; 18 | } 19 | if (user.hasPermission("protocolstringreplacer.feature.usermetacache.noncreative")) { 20 | com.comphenix.protocol.reflect.StructureModifier itemModifier = packetEvent.getPacket().getItemModifier(); 21 | ItemStack itemStack = itemModifier.read(0); 22 | itemModifier.write(0, restoreItem(user, itemStack)); 23 | } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/BaseServerComponentsPacketListener.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketEvent; 5 | import com.comphenix.protocol.reflect.StructureModifier; 6 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer; 7 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 8 | import io.github.rothes.protocolstringreplacer.util.SpigotUtils; 9 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 10 | import io.github.rothes.protocolstringreplacer.util.PaperUtils; 11 | import net.kyori.adventure.text.Component; 12 | import net.md_5.bungee.api.chat.BaseComponent; 13 | 14 | public abstract class BaseServerComponentsPacketListener extends BaseServerPacketListener { 15 | 16 | protected static final String BLOCKED_JSON = "{\"text\":\"ProtocolStringReplacer blocked message. If you see this, it's caused by other plugin(s).\"}"; 17 | 18 | protected BaseServerComponentsPacketListener(PacketType packetType, ListenType listenType) { 19 | super(packetType, listenType); 20 | } 21 | 22 | protected static BaseComponent[] getSpigotComponent(StructureModifier modifier) { 23 | if (!ProtocolStringReplacer.getInstance().isSpigot()) { 24 | return null; 25 | } 26 | StructureModifier componentModifier = modifier.withType(BaseComponent[].class); 27 | if (componentModifier.size() == 0) { 28 | return null; 29 | } 30 | return componentModifier.read(0); 31 | } 32 | 33 | protected String processSpigotComponent(StructureModifier modifier, PacketEvent packetEvent, PsrUser user) { 34 | if (!ProtocolStringReplacer.getInstance().isSpigot()) { 35 | return null; 36 | } 37 | StructureModifier componentModifier = modifier.withType(BaseComponent[].class); 38 | if (componentModifier.size() == 0) { 39 | return null; 40 | } 41 | BaseComponent[] read = componentModifier.read(0); 42 | if (read == null) { 43 | return null; 44 | } 45 | 46 | String result = getReplacedJson(packetEvent, user, listenType, SpigotUtils.serializeComponents(read), filter); 47 | componentModifier.write(0, null); 48 | return result == null ? BLOCKED_JSON : result; 49 | } 50 | 51 | protected static Component getPaperComponent(StructureModifier modifier) { 52 | if (!ProtocolStringReplacer.getInstance().hasPaperComponent()) { 53 | return null; 54 | } 55 | StructureModifier componentModifier = modifier.withType(Component.class); 56 | return componentModifier.read(0); 57 | } 58 | 59 | protected String processPaperComponent(StructureModifier modifier, PacketEvent packetEvent, PsrUser user) { 60 | if (!ProtocolStringReplacer.getInstance().hasPaperComponent()) { 61 | return null; 62 | } 63 | StructureModifier componentModifier = modifier.withType(Component.class); 64 | Component read = componentModifier.read(0); 65 | if (read == null) { 66 | return null; 67 | } 68 | 69 | String result = getReplacedJson(packetEvent, user, listenType, PaperUtils.serializeComponent(read), filter); 70 | componentModifier.write(0, null); 71 | return result == null ? BLOCKED_JSON : result; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/KickDisconnect.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketContainer; 5 | import com.comphenix.protocol.events.PacketEvent; 6 | import com.comphenix.protocol.reflect.StructureModifier; 7 | import com.comphenix.protocol.wrappers.WrappedChatComponent; 8 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 9 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 10 | import org.jetbrains.annotations.NotNull; 11 | 12 | public class KickDisconnect extends BaseServerPacketListener { 13 | 14 | public KickDisconnect() { 15 | super(PacketType.Play.Server.KICK_DISCONNECT, ListenType.KICK_DISCONNECT); 16 | } 17 | 18 | @Override 19 | protected void process(@NotNull PacketEvent packetEvent) { 20 | PsrUser user = getEventUser(packetEvent); 21 | if (user == null) { 22 | return; 23 | } 24 | PacketContainer packet = packetEvent.getPacket(); 25 | StructureModifier chatComponents = packet.getChatComponents(); 26 | String json = chatComponents.read(0).getJson(); 27 | WrappedChatComponent replaced = getReplacedJsonWrappedComponent(packetEvent, user, listenType, json, filter); 28 | if (replaced != null) { 29 | chatComponents.write(0, replaced); 30 | } 31 | 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/actionbar/ChatActionBar.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.actionbar; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketContainer; 5 | import com.comphenix.protocol.events.PacketEvent; 6 | import com.comphenix.protocol.reflect.StructureModifier; 7 | import com.comphenix.protocol.wrappers.EnumWrappers; 8 | import com.comphenix.protocol.wrappers.WrappedChatComponent; 9 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 10 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerComponentsPacketListener; 11 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 12 | import org.jetbrains.annotations.NotNull; 13 | 14 | public class ChatActionBar extends BaseServerComponentsPacketListener { 15 | 16 | public ChatActionBar() { 17 | super(PacketType.Play.Server.CHAT, ListenType.ACTIONBAR); 18 | } 19 | 20 | @Override 21 | protected void process(@NotNull PacketEvent packetEvent) { 22 | PacketContainer packet = packetEvent.getPacket(); 23 | 24 | if (packet.getChatTypes().read(0) != EnumWrappers.ChatType.GAME_INFO 25 | && (packet.getBytes().size() < 1 || packet.getBytes().read(0) != 2)) { 26 | // Not a ActionBar Message. 27 | return; 28 | } 29 | 30 | PsrUser user = getEventUser(packetEvent); 31 | if (user == null) { 32 | return; 33 | } 34 | 35 | StructureModifier componentModifier = packet.getChatComponents(); 36 | WrappedChatComponent wrappedChatComponent = componentModifier.read(0); 37 | String replaced; 38 | 39 | if (wrappedChatComponent != null) { 40 | String json = wrappedChatComponent.getJson(); 41 | replaced = getReplacedJson(packetEvent, user, listenType, json, filter); 42 | } else { 43 | StructureModifier modifier = packet.getModifier(); 44 | replaced = processSpigotComponent(modifier, packetEvent, user); 45 | if (replaced == null) { 46 | replaced = processPaperComponent(modifier, packetEvent, user); 47 | } 48 | } 49 | 50 | if (replaced != null) { 51 | componentModifier.write(0, WrappedChatComponent.fromJson(replaced)); 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/actionbar/SetActionBar.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.actionbar; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketContainer; 5 | import com.comphenix.protocol.events.PacketEvent; 6 | import com.comphenix.protocol.reflect.StructureModifier; 7 | import com.comphenix.protocol.wrappers.WrappedChatComponent; 8 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 9 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerComponentsPacketListener; 10 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 11 | import org.jetbrains.annotations.NotNull; 12 | 13 | public final class SetActionBar extends BaseServerComponentsPacketListener { 14 | 15 | public SetActionBar() { 16 | super(PacketType.Play.Server.SET_ACTION_BAR_TEXT, ListenType.ACTIONBAR); 17 | } 18 | 19 | protected void process(@NotNull PacketEvent packetEvent) { 20 | PsrUser user = getEventUser(packetEvent); 21 | if (user == null) { 22 | return; 23 | } 24 | PacketContainer packet = packetEvent.getPacket(); 25 | 26 | String replaced; 27 | StructureModifier wrappedChatComponentStructureModifier = packet.getChatComponents(); 28 | WrappedChatComponent wrappedChatComponent = wrappedChatComponentStructureModifier.read(0); 29 | if (wrappedChatComponent != null) { 30 | String json = wrappedChatComponent.getJson(); 31 | replaced = getReplacedJson(packetEvent, user, listenType, json, filter); 32 | } else { 33 | replaced = processSpigotComponent(packet.getModifier(), packetEvent, user); 34 | if (replaced == null) { 35 | replaced = processPaperComponent(packet.getModifier(), packetEvent, user); 36 | } 37 | } 38 | 39 | if (replaced != null) { 40 | wrappedChatComponentStructureModifier.write(0, WrappedChatComponent.fromJson(replaced)); 41 | } 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/actionbar/SystemChatActionBar.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.actionbar; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketContainer; 5 | import com.comphenix.protocol.events.PacketEvent; 6 | import com.comphenix.protocol.reflect.StructureModifier; 7 | import com.comphenix.protocol.wrappers.EnumWrappers; 8 | import com.comphenix.protocol.wrappers.WrappedChatComponent; 9 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 10 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerComponentsPacketListener; 11 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 12 | 13 | public class SystemChatActionBar extends BaseServerComponentsPacketListener { 14 | 15 | public SystemChatActionBar() { 16 | super(PacketType.Play.Server.SYSTEM_CHAT, ListenType.ACTIONBAR); 17 | } 18 | 19 | protected void process(PacketEvent packetEvent) { 20 | PacketContainer packet = packetEvent.getPacket(); 21 | 22 | StructureModifier booleans = packet.getBooleans(); 23 | if (booleans.size() == 1) { 24 | if (!booleans.read(0)) { 25 | return; 26 | } 27 | } else if (packet.getIntegers().read(0) != EnumWrappers.ChatType.GAME_INFO.getId()) { 28 | return; 29 | } 30 | 31 | PsrUser user = getEventUser(packetEvent); 32 | if (user == null) { 33 | return; 34 | } 35 | 36 | StructureModifier stringModifier = packet.getStrings(); 37 | if (stringModifier.size() == 0) { 38 | // Since 1.20.3 39 | StructureModifier components = packet.getChatComponents(); 40 | WrappedChatComponent replaced = getReplacedJsonWrappedComponent(packetEvent, user, listenType, components.read(0).getJson(), filter); 41 | if (replaced == null) { 42 | return; 43 | } 44 | components.write(0, replaced); 45 | } else { 46 | String replaced; 47 | String read = stringModifier.read(0); 48 | if (read != null) { 49 | replaced = getReplacedJson(packetEvent, user, listenType, read, filter); 50 | } else { 51 | replaced = processPaperComponent(packet.getModifier(), packetEvent, user); 52 | } 53 | 54 | if (replaced != null) { 55 | stringModifier.write(0, replaced); 56 | } 57 | } 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/actionbar/TitleActionBar.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.actionbar; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketEvent; 5 | import com.comphenix.protocol.wrappers.EnumWrappers; 6 | import io.github.rothes.protocolstringreplacer.packetlistener.server.title.BaseTitleListener; 7 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 8 | 9 | public class TitleActionBar extends BaseTitleListener { 10 | 11 | public TitleActionBar() { 12 | super(PacketType.Play.Server.TITLE, ListenType.ACTIONBAR); 13 | } 14 | 15 | @Override 16 | protected void process(PacketEvent packetEvent) { 17 | if (packetEvent.getPacket().getTitleActions().read(0) != EnumWrappers.TitleAction.ACTIONBAR) { 18 | return; 19 | } 20 | super.process(packetEvent); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/bossbar/BossBar.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.bossbar; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketEvent; 5 | import com.comphenix.protocol.reflect.StructureModifier; 6 | import com.comphenix.protocol.wrappers.WrappedChatComponent; 7 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 8 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerPacketListener; 9 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 10 | 11 | public final class BossBar extends BaseServerPacketListener { 12 | 13 | public BossBar() { 14 | super(PacketType.Play.Server.BOSS, ListenType.BOSS_BAR); 15 | } 16 | 17 | protected void process(PacketEvent packetEvent) { 18 | PsrUser user = getEventUser(packetEvent); 19 | if (user == null) { 20 | return; 21 | } 22 | StructureModifier wrappedChatComponentStructureModifier = packetEvent.getPacket().getChatComponents(); 23 | if (wrappedChatComponentStructureModifier.size() != 0) { 24 | WrappedChatComponent wrappedChatComponent = wrappedChatComponentStructureModifier.read(0); 25 | String json = wrappedChatComponent.getJson(); 26 | 27 | WrappedChatComponent replaced = getReplacedJsonWrappedComponent(packetEvent, user, listenType, json, filter); 28 | if (replaced != null) { 29 | wrappedChatComponentStructureModifier.write(0, replaced); 30 | } 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/chat/ChatPreview.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.chat; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketContainer; 5 | import com.comphenix.protocol.events.PacketEvent; 6 | import com.comphenix.protocol.reflect.StructureModifier; 7 | import com.comphenix.protocol.wrappers.WrappedChatComponent; 8 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 9 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerPacketListener; 10 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 11 | import org.jetbrains.annotations.NotNull; 12 | 13 | public class ChatPreview extends BaseServerPacketListener { 14 | 15 | public ChatPreview() { 16 | super(PacketType.Play.Server.CHAT_PREVIEW, ListenType.CHAT_PREVIEW); 17 | } 18 | 19 | @Override 20 | protected void process(@NotNull PacketEvent packetEvent) { 21 | PacketContainer packet = packetEvent.getPacket(); 22 | PsrUser user = getEventUser(packetEvent); 23 | if (user == null) { 24 | return; 25 | } 26 | 27 | StructureModifier chatComponents = packet.getChatComponents(); 28 | WrappedChatComponent read = chatComponents.read(0); 29 | if (read == null) { 30 | return; 31 | } 32 | WrappedChatComponent replaced = getReplacedJsonWrappedComponent(packetEvent, user, listenType, 33 | read.getJson(), filter); 34 | if (replaced != null) { 35 | chatComponents.write(0, replaced); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/chat/DisguisedChat.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.chat; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketEvent; 5 | import com.comphenix.protocol.reflect.StructureModifier; 6 | import com.comphenix.protocol.wrappers.WrappedChatComponent; 7 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 8 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerComponentsPacketListener; 9 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 10 | import org.jetbrains.annotations.NotNull; 11 | 12 | public class DisguisedChat extends BaseServerComponentsPacketListener { 13 | 14 | public DisguisedChat() { 15 | super(PacketType.Play.Server.DISGUISED_CHAT, ListenType.CHAT); 16 | } 17 | 18 | @Override 19 | protected void process(@NotNull PacketEvent packetEvent) { 20 | PsrUser user = getEventUser(packetEvent); 21 | if (user == null) { 22 | return; 23 | } 24 | 25 | StructureModifier wrappedChatComponentStructureModifier = packetEvent.getPacket().getChatComponents(); 26 | WrappedChatComponent wrappedChatComponent = wrappedChatComponentStructureModifier.read(0); 27 | String replaced = getReplacedJson(packetEvent, user, listenType, wrappedChatComponent.getJson(), filter); 28 | 29 | if (replaced != null) { 30 | wrappedChatComponentStructureModifier.write(0, WrappedChatComponent.fromJson(replaced)); 31 | } 32 | 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/chat/SystemChat.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.chat; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketContainer; 5 | import com.comphenix.protocol.events.PacketEvent; 6 | import com.comphenix.protocol.reflect.StructureModifier; 7 | import com.comphenix.protocol.wrappers.EnumWrappers; 8 | import com.comphenix.protocol.wrappers.WrappedChatComponent; 9 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 10 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerComponentsPacketListener; 11 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 12 | import org.jetbrains.annotations.NotNull; 13 | 14 | import java.util.Optional; 15 | 16 | public class SystemChat extends BaseServerComponentsPacketListener { 17 | 18 | public SystemChat() { 19 | super(PacketType.Play.Server.SYSTEM_CHAT, ListenType.CHAT); 20 | } 21 | 22 | @Override 23 | protected void process(@NotNull PacketEvent packetEvent) { 24 | PacketContainer packet = packetEvent.getPacket(); 25 | Optional isFiltered = packet.getMeta("psr_filtered_packet"); 26 | if (!(isFiltered.isPresent() && isFiltered.get())) { 27 | 28 | StructureModifier booleans = packet.getBooleans(); 29 | if (booleans.size() == 1) { 30 | if (booleans.read(0)) { 31 | return; 32 | } 33 | } else if (packet.getIntegers().read(0) == EnumWrappers.ChatType.GAME_INFO.getId()) { 34 | return; 35 | } 36 | 37 | PsrUser user = getEventUser(packetEvent); 38 | if (user == null) { 39 | return; 40 | } 41 | 42 | StructureModifier stringModifier = packet.getStrings(); 43 | if (stringModifier.size() == 0) { 44 | // Since 1.20.3 45 | StructureModifier components = packet.getChatComponents(); 46 | WrappedChatComponent replaced = getReplacedJsonWrappedComponent(packetEvent, user, listenType, components.read(0).getJson(), filter); 47 | if (replaced == null) { 48 | return; 49 | } 50 | components.write(0, replaced); 51 | } else { 52 | String replaced; 53 | String read = stringModifier.read(0); 54 | if (read != null) { 55 | replaced = getReplacedJson(packetEvent, user, listenType, read, filter); 56 | } else { 57 | replaced = processPaperComponent(packet.getModifier(), packetEvent, user); 58 | } 59 | 60 | if (replaced != null) { 61 | stringModifier.write(0, replaced); 62 | } 63 | } 64 | } 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/chat/TabComplete.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.chat; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketContainer; 5 | import com.comphenix.protocol.events.PacketEvent; 6 | import com.comphenix.protocol.reflect.StructureModifier; 7 | import com.mojang.brigadier.suggestion.Suggestion; 8 | import com.mojang.brigadier.suggestion.Suggestions; 9 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer; 10 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 11 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerPacketListener; 12 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 13 | import org.jetbrains.annotations.NotNull; 14 | 15 | import java.util.List; 16 | 17 | public class TabComplete extends BaseServerPacketListener { 18 | 19 | public TabComplete() { 20 | super(PacketType.Play.Server.TAB_COMPLETE, ListenType.TAB_COMPLETE); 21 | } 22 | 23 | @Override 24 | protected void process(@NotNull PacketEvent packetEvent) { 25 | PacketContainer packet = packetEvent.getPacket(); 26 | PsrUser user = getEventUser(packetEvent); 27 | if (user == null) { 28 | return; 29 | } 30 | 31 | if (ProtocolStringReplacer.getInstance().getServerMajorVersion() >= 13) { 32 | // 1.13+ 33 | StructureModifier modifier = packet.getModifier().withType(Suggestions.class); 34 | Suggestions suggestions = modifier.read(0); 35 | 36 | List list = suggestions.getList(); 37 | Suggestion suggestion; 38 | for (int i = 0; i < list.size(); i++) { 39 | suggestion = list.get(i); 40 | list.set(i, new Suggestion(suggestion.getRange(), 41 | getReplacedText(packetEvent, user, listenType, suggestion.getText(), filter), 42 | suggestion.getTooltip())); 43 | } 44 | } else { 45 | // 1.8 - 1.12 46 | StructureModifier stringArrays = packet.getStringArrays(); 47 | if (stringArrays.size() != 0) { 48 | String[] read = stringArrays.read(0); 49 | for (int i = 0; i < read.length; i++) { 50 | read[i] = getReplacedText(packetEvent, user, listenType, read[i], filter); 51 | } 52 | } 53 | } 54 | 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/combat/CombatEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.combat; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketContainer; 5 | import com.comphenix.protocol.events.PacketEvent; 6 | import com.comphenix.protocol.reflect.StructureModifier; 7 | import com.comphenix.protocol.wrappers.EnumWrappers; 8 | import com.comphenix.protocol.wrappers.WrappedChatComponent; 9 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 10 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerPacketListener; 11 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 12 | import org.jetbrains.annotations.NotNull; 13 | 14 | public class CombatEvent extends BaseServerPacketListener { 15 | 16 | public CombatEvent() { 17 | super(PacketType.Play.Server.COMBAT_EVENT, ListenType.COMBAT_KILL); 18 | } 19 | 20 | @Override 21 | protected void process(@NotNull PacketEvent packetEvent) { 22 | PsrUser user = getEventUser(packetEvent); 23 | if (user == null) { 24 | return; 25 | } 26 | PacketContainer packet = packetEvent.getPacket(); 27 | StructureModifier chatComponents = packet.getChatComponents(); 28 | if (packet.getCombatEvents().read(0) != EnumWrappers.CombatEventType.ENTITY_DIED) { 29 | return; 30 | } 31 | 32 | if (chatComponents.size() != 1) { 33 | // On 1.8 this is a String. 34 | StructureModifier strings = packet.getStrings(); 35 | strings.write(0, 36 | getReplacedText(packetEvent, user, listenType, strings.read(0), filter)); 37 | return; 38 | } 39 | String json = chatComponents.read(0).getJson(); 40 | WrappedChatComponent replaced = getReplacedJsonWrappedComponent(packetEvent, user, listenType, json, filter); 41 | if (replaced != null) { 42 | chatComponents.write(0, replaced); 43 | } 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/combat/PlayerCombatKill.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.combat; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketContainer; 5 | import com.comphenix.protocol.events.PacketEvent; 6 | import com.comphenix.protocol.reflect.StructureModifier; 7 | import com.comphenix.protocol.wrappers.WrappedChatComponent; 8 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 9 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerPacketListener; 10 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 11 | import org.jetbrains.annotations.NotNull; 12 | 13 | public class PlayerCombatKill extends BaseServerPacketListener { 14 | 15 | public PlayerCombatKill() { 16 | super(PacketType.Play.Server.PLAYER_COMBAT_KILL, ListenType.COMBAT_KILL); 17 | } 18 | 19 | @Override 20 | protected void process(@NotNull PacketEvent packetEvent) { 21 | PsrUser user = getEventUser(packetEvent); 22 | if (user == null) { 23 | return; 24 | } 25 | PacketContainer packet = packetEvent.getPacket(); 26 | StructureModifier chatComponents = packet.getChatComponents(); 27 | String json = chatComponents.read(0).getJson(); 28 | WrappedChatComponent replaced = getReplacedJsonWrappedComponent(packetEvent, user, listenType, json, filter); 29 | if (replaced != null) { 30 | chatComponents.write(0, replaced); 31 | } 32 | 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/itemstack/BaseServerItemPacketListener.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.itemstack; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import io.github.rothes.protocolstringreplacer.api.replacer.ReplacerConfig; 5 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 6 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerPacketListener; 7 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 8 | 9 | import java.util.function.BiPredicate; 10 | 11 | public abstract class BaseServerItemPacketListener extends BaseServerPacketListener { 12 | 13 | protected final BiPredicate itemNbtFilter = 14 | (replacerConfig, user) -> containType(replacerConfig) 15 | && replacerConfig.handleItemStackNbt() && checkFilter(user, replacerConfig) && checkWindowTitle(user, replacerConfig); 16 | protected final BiPredicate itemLoreFilter = 17 | (replacerConfig, user) -> containType(replacerConfig) 18 | && replacerConfig.handleItemStackLore() && checkFilter(user, replacerConfig) && checkWindowTitle(user, replacerConfig); 19 | protected final BiPredicate itemEntriesFilter = (replacerConfig, user) -> containType(replacerConfig) 20 | && replacerConfig.handleItemStackDisplayEntries() && checkFilter(user, replacerConfig) && checkWindowTitle(user, replacerConfig); 21 | 22 | protected BaseServerItemPacketListener(PacketType packetType) { 23 | super(packetType, ListenType.ITEMSTACK); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/itemstack/SetSlot.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.itemstack; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketEvent; 5 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer; 6 | import io.github.rothes.protocolstringreplacer.api.replacer.ReplacerConfig; 7 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 8 | import io.github.rothes.protocolstringreplacer.replacer.ReplacerManager; 9 | import org.bukkit.inventory.ItemStack; 10 | import org.jetbrains.annotations.NotNull; 11 | 12 | import java.util.List; 13 | 14 | public final class SetSlot extends BaseServerItemPacketListener { 15 | 16 | public SetSlot() { 17 | super(PacketType.Play.Server.SET_SLOT); 18 | } 19 | 20 | protected void process(@NotNull PacketEvent packetEvent) { 21 | PsrUser user = getEventUser(packetEvent); 22 | if (user == null) { 23 | return; 24 | } 25 | ReplacerManager replacerManager = ProtocolStringReplacer.getInstance().getReplacerManager(); 26 | List nbt = replacerManager.getAcceptedReplacers(user, itemNbtFilter); 27 | List lore = replacerManager.getAcceptedReplacers(user, itemLoreFilter); 28 | List entries = replacerManager.getAcceptedReplacers(user, itemEntriesFilter); 29 | 30 | ItemStack itemStack = packetEvent.getPacket().getItemModifier().read(0); 31 | ItemStack replaced = replaceItemStack(packetEvent, user, listenType, itemStack, nbt, lore, entries, true); 32 | packetEvent.getPacket().getItemModifier().write(0, replaced); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/scoreboard/BaseScoreBoardListener.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.scoreboard; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import io.github.rothes.protocolstringreplacer.api.replacer.ReplacerConfig; 5 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 6 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerPacketListener; 7 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 8 | 9 | import java.util.function.BiPredicate; 10 | 11 | public abstract class BaseScoreBoardListener extends BaseServerPacketListener { 12 | 13 | protected final BiPredicate titleFilter; 14 | protected final BiPredicate entityNameFilter; 15 | 16 | protected BaseScoreBoardListener(PacketType packetType, ListenType listenType) { 17 | super(packetType, listenType); 18 | titleFilter = (replacerConfig, user) -> { 19 | if (containType(replacerConfig) && checkFilter(user, replacerConfig)) { 20 | return replacerConfig.handleScoreboardTitle(); 21 | } 22 | return false; 23 | }; 24 | entityNameFilter = (replacerConfig, user) -> { 25 | if (containType(replacerConfig) && checkFilter(user, replacerConfig)) { 26 | return replacerConfig.handleScoreboardEntityName(); 27 | } 28 | return false; 29 | }; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/scoreboard/BaseUpdateTeamListener.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.scoreboard; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import io.github.rothes.protocolstringreplacer.api.replacer.ReplacerConfig; 5 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 6 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerPacketListener; 7 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 8 | 9 | import java.util.function.BiPredicate; 10 | 11 | public abstract class BaseUpdateTeamListener extends BaseServerPacketListener { 12 | 13 | protected final BiPredicate teamDNameFilter = (replacerConfig, user) -> 14 | containType(replacerConfig) && checkFilter(user, replacerConfig) && replacerConfig.handleScoreboardTeamDisplayName(); 15 | protected final BiPredicate teamPrefixFilter = (replacerConfig, user) -> 16 | containType(replacerConfig) && checkFilter(user, replacerConfig) && replacerConfig.handleScoreboardTeamPrefix(); 17 | protected final BiPredicate teamSuffixFilter = (replacerConfig, user) -> 18 | containType(replacerConfig) && checkFilter(user, replacerConfig) && replacerConfig.handleScoreboardTeamSuffix(); 19 | 20 | protected BaseUpdateTeamListener() { 21 | super(PacketType.Play.Server.SCOREBOARD_TEAM, ListenType.SCOREBOARD); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/scoreboard/ScoreBoardObjective.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.scoreboard; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketContainer; 5 | import com.comphenix.protocol.events.PacketEvent; 6 | import com.comphenix.protocol.reflect.StructureModifier; 7 | import com.comphenix.protocol.wrappers.WrappedChatComponent; 8 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer; 9 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 10 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerPacketListener; 11 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 12 | import org.jetbrains.annotations.NotNull; 13 | 14 | public class ScoreBoardObjective extends BaseScoreBoardListener { 15 | 16 | public ScoreBoardObjective() { 17 | super(PacketType.Play.Server.SCOREBOARD_OBJECTIVE, ListenType.SCOREBOARD); 18 | } 19 | 20 | protected void process(@NotNull PacketEvent packetEvent) { 21 | PsrUser user = getEventUser(packetEvent); 22 | if (user == null) { 23 | return; 24 | } 25 | PacketContainer packet = packetEvent.getPacket(); 26 | 27 | if (packet.getIntegers().read(0) != 1) { 28 | if (ProtocolStringReplacer.getInstance().getServerMajorVersion() >= 13) { 29 | StructureModifier wrappedChatComponentStructureModifier = packet.getChatComponents(); 30 | WrappedChatComponent wrappedChatComponent = wrappedChatComponentStructureModifier.read(0); 31 | String replaced = BaseServerPacketListener.getReplacedJson(packetEvent, user, listenType, wrappedChatComponent.getJson(), titleFilter); 32 | if (replaced != null) { 33 | wrappedChatComponentStructureModifier.write(0, WrappedChatComponent.fromJson(replaced)); 34 | } 35 | } else { 36 | StructureModifier strings = packet.getStrings(); 37 | String replaced = BaseServerPacketListener.getReplacedText(packetEvent, user, listenType, strings.read(1), titleFilter); 38 | if (replaced != null) 39 | strings.write(1, replaced); 40 | } 41 | } 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/scoreboard/UpdateScore.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.scoreboard; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketContainer; 5 | import com.comphenix.protocol.events.PacketEvent; 6 | import com.comphenix.protocol.reflect.StructureModifier; 7 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 8 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerPacketListener; 9 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 10 | 11 | public class UpdateScore extends BaseScoreBoardListener { 12 | 13 | public UpdateScore() { 14 | super(PacketType.Play.Server.SCOREBOARD_SCORE, ListenType.SCOREBOARD); 15 | } 16 | 17 | protected void process(PacketEvent packetEvent) { 18 | PsrUser user = getEventUser(packetEvent); 19 | if (user == null) { 20 | return; 21 | } 22 | PacketContainer packet = packetEvent.getPacket(); 23 | StructureModifier strings = packet.getStrings(); 24 | 25 | String replaced = BaseServerPacketListener.getReplacedText(packetEvent, user, listenType, strings.read(0), entityNameFilter); 26 | if (replaced != null) { 27 | strings.write(0, replaced); 28 | } 29 | // TODO: Edit the score (Integer) maybe? But §klazy to do. 30 | /*if (packet.getScoreboardActions().read(0) != EnumWrappers.ScoreboardAction.REMOVE) { 31 | int score = packet.getIntegers().read(0); 32 | }*/ 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/scoreboard/UpdateTeam.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.scoreboard; 2 | 3 | import com.comphenix.protocol.events.PacketContainer; 4 | import com.comphenix.protocol.events.PacketEvent; 5 | import com.comphenix.protocol.reflect.StructureModifier; 6 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 7 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerPacketListener; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | public final class UpdateTeam extends BaseUpdateTeamListener { 11 | 12 | @Override 13 | protected void process(@NotNull PacketEvent packetEvent) { 14 | PsrUser user = getEventUser(packetEvent); 15 | if (user == null) { 16 | return; 17 | } 18 | PacketContainer packet = packetEvent.getPacket(); 19 | StructureModifier strings = packet.getStrings(); 20 | String read = strings.read(1); 21 | if (read == null) { 22 | return; 23 | } 24 | String replacedText = BaseServerPacketListener.getReplacedText(packetEvent, user, listenType, read, teamDNameFilter); 25 | if (replacedText == null) { 26 | return; 27 | } 28 | strings.write(1, replacedText); 29 | 30 | replacedText = BaseServerPacketListener.getReplacedText(packetEvent, user, listenType, strings.read(2), teamPrefixFilter); 31 | if (replacedText == null) { 32 | return; 33 | } 34 | strings.write(2, replacedText); 35 | 36 | replacedText = BaseServerPacketListener.getReplacedText(packetEvent, user, listenType, strings.read(3), teamSuffixFilter); 37 | if (replacedText == null) { 38 | return; 39 | } 40 | strings.write(3, replacedText); 41 | 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/scoreboard/UpdateTeamPost13.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.scoreboard; 2 | 3 | import com.comphenix.protocol.events.PacketContainer; 4 | import com.comphenix.protocol.events.PacketEvent; 5 | import com.comphenix.protocol.reflect.StructureModifier; 6 | import com.comphenix.protocol.wrappers.WrappedChatComponent; 7 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | public final class UpdateTeamPost13 extends BaseUpdateTeamListener { 11 | 12 | @Override 13 | protected void process(@NotNull PacketEvent packetEvent) { 14 | PsrUser user = getEventUser(packetEvent); 15 | if (user == null) { 16 | return; 17 | } 18 | PacketContainer packet = packetEvent.getPacket(); 19 | StructureModifier chatComponents = packet.getChatComponents(); 20 | WrappedChatComponent wrappedChatComponent = chatComponents.read(0); 21 | if (wrappedChatComponent == null) { 22 | return; 23 | } 24 | String json = wrappedChatComponent.getJson(); 25 | WrappedChatComponent replaced = getReplacedJsonWrappedComponent(packetEvent, user, listenType, json, teamDNameFilter); 26 | if (replaced == null) { 27 | return; 28 | } 29 | chatComponents.write(0, replaced); 30 | 31 | wrappedChatComponent = chatComponents.read(1); 32 | json = wrappedChatComponent.getJson(); 33 | replaced = getReplacedJsonWrappedComponent(packetEvent, user, listenType, json, teamPrefixFilter); 34 | if (replaced == null) { 35 | return; 36 | } 37 | chatComponents.write(1, replaced); 38 | 39 | wrappedChatComponent = chatComponents.read(2); 40 | json = wrappedChatComponent.getJson(); 41 | replaced = getReplacedJsonWrappedComponent(packetEvent, user, listenType, json, teamSuffixFilter); 42 | if (replaced == null) { 43 | return; 44 | } 45 | chatComponents.write(2, replaced); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/sign/MapChunk.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.sign; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketContainer; 5 | import com.comphenix.protocol.events.PacketEvent; 6 | import de.tr7zw.changeme.nbtapi.NBTContainer; 7 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 8 | 9 | import java.util.Collection; 10 | import java.util.List; 11 | 12 | public final class MapChunk extends BaseServerSignPacketListener { 13 | 14 | public MapChunk() { 15 | super(PacketType.Play.Server.MAP_CHUNK); 16 | } 17 | 18 | protected void process(PacketEvent packetEvent) { 19 | PsrUser user = getEventUser(packetEvent); 20 | if (user == null) { 21 | return; 22 | } 23 | PacketContainer packet = packetEvent.getPacket(); 24 | List read = (List) packet.getModifier().withType(Collection.class).read(0); 25 | for (Object nbt : read) { 26 | NBTContainer nbtContainer = new NBTContainer(nbt); 27 | if (!nbtContainer.hasTag("id")) { 28 | continue; 29 | } 30 | if ("minecraft:sign".equals(nbtContainer.getString("id"))) { 31 | replaceSign(packetEvent, nbtContainer, user, filter); 32 | } 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/sign/TileEntityData.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.sign; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketContainer; 5 | import com.comphenix.protocol.events.PacketEvent; 6 | import com.comphenix.protocol.utility.MinecraftReflection; 7 | import de.tr7zw.changeme.nbtapi.NBTContainer; 8 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 9 | 10 | public final class TileEntityData extends BaseServerSignPacketListener { 11 | 12 | public TileEntityData() { 13 | super(PacketType.Play.Server.TILE_ENTITY_DATA); 14 | } 15 | 16 | protected void process(PacketEvent packetEvent) { 17 | PsrUser user = getEventUser(packetEvent); 18 | if (user == null) { 19 | return; 20 | } 21 | PacketContainer packet = packetEvent.getPacket(); 22 | // 9: Set the text on a sign 23 | if (packet.getIntegers().read(0) == 9) { 24 | // Have to clone, to make sure the result of the player doesn't affect other players and may kick random players. 25 | PacketContainer clone = packet.deepClone(); 26 | Object read = clone.getModifier().withType(MinecraftReflection.getNBTBaseClass()).read(0); 27 | replaceSign(packetEvent, new NBTContainer(read), user, filter); 28 | packetEvent.setPacket(clone); 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/sign/TileEntityDataPost18.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.sign; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketContainer; 5 | import com.comphenix.protocol.events.PacketEvent; 6 | import com.comphenix.protocol.utility.MinecraftReflection; 7 | import de.tr7zw.changeme.nbtapi.NBTContainer; 8 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | public class TileEntityDataPost18 extends BaseServerSignPacketListener { 12 | 13 | public TileEntityDataPost18() { 14 | super(PacketType.Play.Server.TILE_ENTITY_DATA); 15 | } 16 | 17 | protected void process(@NotNull PacketEvent packetEvent) { 18 | PsrUser user = getEventUser(packetEvent); 19 | if (user == null) { 20 | return; 21 | } 22 | PacketContainer packet = packetEvent.getPacket(); 23 | if (TileTypeHelper.isSignType(packet.getModifier().read(1))) { 24 | // Have to clone, to make sure the result of the player doesn't affect other players and may kick random players. 25 | PacketContainer clone = packet.deepClone(); 26 | Object read = clone.getModifier().withType(MinecraftReflection.getNBTBaseClass()).read(0); 27 | replaceSign(packetEvent, new NBTContainer(read), user, filter); 28 | packetEvent.setPacket(clone); 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/sign/UpdateSign.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.sign; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketContainer; 5 | import com.comphenix.protocol.events.PacketEvent; 6 | import com.comphenix.protocol.wrappers.BukkitConverters; 7 | import com.comphenix.protocol.wrappers.WrappedChatComponent; 8 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 9 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerPacketListener; 10 | 11 | public class UpdateSign extends BaseServerSignPacketListener { 12 | 13 | public UpdateSign() { 14 | super(PacketType.Play.Server.UPDATE_SIGN); 15 | } 16 | 17 | protected void process(PacketEvent packetEvent) { 18 | PsrUser user = getEventUser(packetEvent); 19 | if (user == null) { 20 | return; 21 | } 22 | PacketContainer packet = packetEvent.getPacket(); 23 | Object[] read = (Object[]) packet.getModifier().read(2); 24 | for (int i = 0; i < read.length; i++) { 25 | String replaced = BaseServerPacketListener.getReplacedJson(packetEvent, user, listenType, 26 | BukkitConverters.getWrappedChatComponentConverter().getSpecific(read[i]).getJson(), filter); 27 | if (replaced != null) { 28 | read[i] = BukkitConverters.getWrappedChatComponentConverter().getGeneric( 29 | WrappedChatComponent.fromJson(replaced)); 30 | } else { 31 | return; 32 | } 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/title/BaseTitleListener.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.title; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketContainer; 5 | import com.comphenix.protocol.events.PacketEvent; 6 | import com.comphenix.protocol.reflect.StructureModifier; 7 | import com.comphenix.protocol.wrappers.WrappedChatComponent; 8 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerComponentsPacketListener; 9 | import io.github.rothes.protocolstringreplacer.replacer.ListenType; 10 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser; 11 | 12 | public abstract class BaseTitleListener extends BaseServerComponentsPacketListener { 13 | 14 | protected BaseTitleListener(PacketType packetType) { 15 | this(packetType, ListenType.TITLE); 16 | } 17 | 18 | protected BaseTitleListener(PacketType packetType, ListenType listenType) { 19 | super(packetType, listenType); 20 | } 21 | 22 | protected void process(PacketEvent packetEvent) { 23 | PsrUser user = getEventUser(packetEvent); 24 | if (user == null) { 25 | return; 26 | } 27 | PacketContainer packet = packetEvent.getPacket(); 28 | 29 | String replaced; 30 | StructureModifier wrappedChatComponentStructureModifier = packet.getChatComponents(); 31 | WrappedChatComponent wrappedChatComponent = wrappedChatComponentStructureModifier.read(0); 32 | if (wrappedChatComponent != null) { 33 | String json = wrappedChatComponent.getJson(); 34 | replaced = getReplacedJson(packetEvent, user, listenType, json, filter); 35 | } else { 36 | replaced = processSpigotComponent(packet.getModifier(), packetEvent, user); 37 | if (replaced == null) { 38 | replaced = processPaperComponent(packet.getModifier(), packetEvent, user); 39 | } 40 | } 41 | 42 | if (replaced != null) { 43 | wrappedChatComponentStructureModifier.write(0, WrappedChatComponent.fromJson(replaced)); 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/title/SetSubtitleText.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.title; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | 5 | public class SetSubtitleText extends BaseTitleListener { 6 | 7 | public SetSubtitleText() { 8 | super(PacketType.Play.Server.SET_SUBTITLE_TEXT); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/title/SetTitleText.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.title; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | 5 | public class SetTitleText extends BaseTitleListener { 6 | 7 | public SetTitleText() { 8 | super(PacketType.Play.Server.SET_TITLE_TEXT); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/packetlistener/server/title/Title.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.title; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.events.PacketEvent; 5 | import com.comphenix.protocol.wrappers.EnumWrappers; 6 | 7 | public final class Title extends BaseTitleListener { 8 | 9 | public Title() { 10 | super(PacketType.Play.Server.TITLE); 11 | } 12 | 13 | @Override 14 | protected void process(PacketEvent packetEvent) { 15 | if (packetEvent.getPacket().getTitleActions().read(0) == EnumWrappers.TitleAction.ACTIONBAR) { 16 | return; 17 | } 18 | super.process(packetEvent); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/replacer/ListenType.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.replacer; 2 | 3 | public enum ListenType { 4 | 5 | CHAT("Chat", true), 6 | CHAT_PREVIEW("Chat-Preview", true), 7 | TAB_COMPLETE("Tab-Complete", true), 8 | SIGN("Sign", true), 9 | TITLE("Title", true), 10 | ENTITY("Entity", true), 11 | BOSS_BAR("Boss-Bar", true), 12 | ITEMSTACK("ItemStack", true), 13 | WINDOW_TITLE("Window-Title", true), 14 | SCOREBOARD("ScoreBoard", true), 15 | CONSOLE("Console", false), 16 | KICK_DISCONNECT("Kick-Disconnect", true), // Is it important capture-able now? lol 17 | COMBAT_KILL("Combat-Kill", true), 18 | ACTIONBAR("ActionBar", true); 19 | 20 | private String name; 21 | private boolean capturable; 22 | 23 | ListenType(String name, boolean capturable) { 24 | this.name = name; 25 | this.capturable = capturable; 26 | } 27 | 28 | public static ListenType getType(String typeName) { 29 | for (ListenType type : ListenType.values()) { 30 | if (type.getName().equalsIgnoreCase(typeName)) { 31 | return type; 32 | } 33 | } 34 | return null; 35 | } 36 | 37 | public String getName() { 38 | return name; 39 | } 40 | 41 | public boolean isCapturable() { 42 | return capturable; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/replacer/MatchMode.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.replacer; 2 | 3 | public enum MatchMode { 4 | 5 | CONTAIN("Contain", "Variables.Match-Mode.Enums.Contain"), 6 | EQUAL("Equal", "Variables.Match-Mode.Enums.Equal"), 7 | REGEX("Regex", "Variables.Match-Mode.Enums.Regex"); 8 | 9 | private String name; 10 | private String localeKey; 11 | 12 | MatchMode(String name, String localeKey) { 13 | this.name = name; 14 | this.localeKey = localeKey; 15 | } 16 | 17 | public String getName() { 18 | return name; 19 | } 20 | 21 | public String getLocaleKey() { 22 | return localeKey; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/replacer/ReplaceMode.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.replacer; 2 | 3 | public enum ReplaceMode { 4 | 5 | COMMON("Common", "Variables.Replacers-Mode.Enums.Common"), 6 | JSON("Json", "Variables.Replacers-Mode.Enums.Json"), 7 | DIRECT("Direct", "Variables.Replacers-Mode.Enums.Direct"); 8 | 9 | private String node; 10 | private String localeKey; 11 | 12 | ReplaceMode(String node, String localeKey) { 13 | this.node = node; 14 | this.localeKey = localeKey; 15 | } 16 | 17 | public String getNode() { 18 | return node; 19 | } 20 | 21 | public String getLocaleKey() { 22 | return localeKey; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/replacer/containers/ChatJsonContainer.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.replacer.containers; 2 | 3 | import io.github.rothes.protocolstringreplacer.api.exceptions.JsonSyntaxException; 4 | import io.github.rothes.protocolstringreplacer.util.SpigotUtils; 5 | import net.md_5.bungee.chat.ComponentSerializer; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | public class ChatJsonContainer extends AbstractContainer { 9 | 10 | private boolean createComponents = false; 11 | private ComponentsContainer componentsContainer = null; 12 | 13 | public ChatJsonContainer(@NotNull String json) { 14 | super(json); 15 | } 16 | 17 | public ChatJsonContainer(@NotNull String json, boolean createComponents) { 18 | super(json); 19 | this.createComponents = createComponents; 20 | } 21 | 22 | public ChatJsonContainer(@NotNull String json, @NotNull Container root) { 23 | super(json, root); 24 | } 25 | 26 | public ChatJsonContainer(@NotNull String json, @NotNull Container root, boolean createComponents) { 27 | super(json, root); 28 | this.createComponents = createComponents; 29 | } 30 | 31 | @Override 32 | public void createDefaultChildren() { 33 | if (createComponents) { 34 | try { 35 | componentsContainer = new ComponentsContainer(ComponentSerializer.parse(content), root); 36 | } catch (Throwable t) { 37 | throw new JsonSyntaxException("Serializer can't parse Json: " + content, t); 38 | } 39 | children.add(componentsContainer); 40 | } 41 | super.createDefaultChildren(); 42 | } 43 | 44 | @Override 45 | public void createJsons(@NotNull Container container) { 46 | super.createJsons(container); 47 | root.addJson(new ReplaceableImpl()); 48 | } 49 | 50 | @Override 51 | public String getResult() { 52 | if (componentsContainer != null) { 53 | return SpigotUtils.serializeComponents(componentsContainer.getResult()); 54 | } else { 55 | return super.getResult(); 56 | } 57 | } 58 | 59 | public ComponentsContainer getComponentsContainer() { 60 | return componentsContainer; 61 | } 62 | 63 | private class ReplaceableImpl implements Replaceable { 64 | 65 | @Override 66 | public String getText() { 67 | return content; 68 | } 69 | 70 | @Override 71 | public void setText(String text) { 72 | content = text; 73 | } 74 | 75 | @Override 76 | public String toString() { 77 | return content; 78 | } 79 | 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/replacer/containers/ComponentsContainer.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.replacer.containers; 2 | 3 | import net.md_5.bungee.api.chat.BaseComponent; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class ComponentsContainer extends AbstractContainer { 7 | 8 | public ComponentsContainer(@NotNull BaseComponent[] components) { 9 | super(components); 10 | } 11 | 12 | public ComponentsContainer(@NotNull BaseComponent[] components, @NotNull Container root) { 13 | super(components, root); 14 | } 15 | 16 | @Override 17 | public void createDefaultChildren() { 18 | // content = ComponentsUtils.mergeTexts(content); 19 | for (int i = 0; i < content.length; i++) { 20 | BaseComponent component = content[i]; 21 | int finalI = i; 22 | children.add(new ComponentContainer(component, root) { 23 | @Override 24 | public BaseComponent getResult() { 25 | BaseComponent result = super.getResult(); 26 | ComponentsContainer.this.content[finalI] = result; 27 | return result; 28 | } 29 | }); 30 | } 31 | super.createDefaultChildren(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/replacer/containers/Container.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.replacer.containers; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | import java.util.List; 6 | 7 | public interface Container { 8 | 9 | List getJsons(); 10 | 11 | List getTexts(); 12 | 13 | void createDefaultChildren(); 14 | 15 | void createJsons(@NotNull Container container); 16 | 17 | void createTexts(@NotNull Container container); 18 | 19 | void addJson(@NotNull Replaceable replaceable); 20 | 21 | void addText(@NotNull Replaceable replaceable); 22 | 23 | void reset(); 24 | 25 | @NotNull 26 | Container getRoot(); 27 | 28 | @NotNull 29 | List> getChildren(); 30 | 31 | @NotNull 32 | T getResult(); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/replacer/containers/EntityContentContainer.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.replacer.containers; 2 | 3 | import net.md_5.bungee.api.chat.BaseComponent; 4 | import net.md_5.bungee.api.chat.hover.content.Entity; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | public class EntityContentContainer extends AbstractContainer { 8 | 9 | public EntityContentContainer(@NotNull Entity entity) { 10 | super(entity); 11 | } 12 | 13 | public EntityContentContainer(@NotNull Entity entity, @NotNull Container root) { 14 | super(entity, root); 15 | } 16 | 17 | @Override 18 | public void createDefaultChildren() { 19 | children.add(new ComponentContainer(content.getName(), root) { 20 | @Override 21 | public BaseComponent getResult() { 22 | BaseComponent result = super.getResult(); 23 | EntityContentContainer.this.content.setName(result); 24 | return result; 25 | } 26 | }); 27 | super.createDefaultChildren(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/replacer/containers/HoverContentContainer.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.replacer.containers; 2 | 3 | import net.md_5.bungee.api.chat.hover.content.Content; 4 | import net.md_5.bungee.api.chat.hover.content.Entity; 5 | import net.md_5.bungee.api.chat.hover.content.Item; 6 | import net.md_5.bungee.api.chat.hover.content.Text; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | public class HoverContentContainer extends AbstractContainer { 10 | 11 | public HoverContentContainer(@NotNull Content content) { 12 | super(content); 13 | } 14 | 15 | public HoverContentContainer(@NotNull Content content, @NotNull Container root) { 16 | super(content, root); 17 | } 18 | 19 | @Override 20 | public void createDefaultChildren() { 21 | if (content instanceof Text) { 22 | children.add(new TextContentContainer((Text) content, root) { 23 | @Override 24 | public Text getResult() { 25 | Text result = super.getResult(); 26 | content = result; 27 | return result; 28 | } 29 | }); 30 | } else if (content instanceof Item) { 31 | children.add(new ItemContentContainer((Item) content, root) { 32 | @Override 33 | public Item getResult() { 34 | Item result = super.getResult(); 35 | content = result; 36 | return result; 37 | } 38 | }); 39 | } else if (content instanceof Entity) { 40 | children.add(new EntityContentContainer((Entity) content, root) { 41 | @Override 42 | public Entity getResult() { 43 | Entity result = super.getResult(); 44 | content = result; 45 | return result; 46 | } 47 | }); 48 | } 49 | super.createDefaultChildren(); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/replacer/containers/HoverEventContainer.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.replacer.containers; 2 | 3 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer; 4 | import net.md_5.bungee.api.chat.HoverEvent; 5 | import net.md_5.bungee.api.chat.hover.content.Content; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.util.List; 9 | 10 | public class HoverEventContainer extends AbstractContainer { 11 | 12 | public HoverEventContainer(@NotNull HoverEvent hoverEvent) { 13 | super(hoverEvent); 14 | } 15 | 16 | public HoverEventContainer(@NotNull HoverEvent hoverEvent, @NotNull Container root) { 17 | super(hoverEvent, root); 18 | } 19 | 20 | @Override 21 | public void createDefaultChildren() { 22 | if (ProtocolStringReplacer.getInstance().getServerMajorVersion() > 15 && !content.isLegacy()) { 23 | List contents = content.getContents(); 24 | for (int i = 0; i < contents.size(); i++) { 25 | int finalI = i; 26 | children.add(new HoverContentContainer(contents.get(finalI), root) { 27 | @Override 28 | public Content getResult() { 29 | Content result = super.getResult(); 30 | contents.set(finalI, result); 31 | return result; 32 | } 33 | }); 34 | } 35 | } else { 36 | children.add(new ComponentsContainer(content.getValue(), root)); 37 | } 38 | super.createDefaultChildren(); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/replacer/containers/ItemContentContainer.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.replacer.containers; 2 | 3 | import io.github.rothes.protocolstringreplacer.replacer.helpers.ItemHelper; 4 | import net.md_5.bungee.api.chat.BaseComponent; 5 | import net.md_5.bungee.api.chat.hover.content.Item; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | public class ItemContentContainer extends AbstractContainer { 9 | 10 | protected ItemHelper helper; 11 | 12 | public ItemContentContainer(@NotNull Item item) { 13 | super(item); 14 | } 15 | 16 | public ItemContentContainer(@NotNull Item item, @NotNull Container root) { 17 | super(item, root); 18 | } 19 | 20 | @Override 21 | public void createDefaultChildren() { 22 | helper = ItemHelper.parse(content); 23 | if (helper.hasName()) { 24 | children.add(new ComponentsContainer(helper.getName(), root) { 25 | @Override 26 | public BaseComponent[] getResult() { 27 | BaseComponent[] result = super.getResult(); 28 | helper.setName(result); 29 | return result; 30 | } 31 | }); 32 | } 33 | if (helper.hasLore()) { 34 | int size = helper.getLoreSize(); 35 | for (int line = 0; line < size; line++) { 36 | int finalLine = line; 37 | children.add(new ComponentsContainer(helper.getLore(line), root) { 38 | @Override 39 | public BaseComponent[] getResult() { 40 | BaseComponent[] result = super.getResult(); 41 | helper.setLore(finalLine, result); 42 | return result; 43 | } 44 | }); 45 | } 46 | } 47 | super.createDefaultChildren(); 48 | } 49 | 50 | @Override 51 | public Item getResult() { 52 | Item result = super.getResult(); 53 | helper.saveChanges(); 54 | return result; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/replacer/containers/Replaceable.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.replacer.containers; 2 | 3 | public interface Replaceable { 4 | 5 | String getText(); 6 | 7 | void setText(String text); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/replacer/containers/SimpleTextContainer.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.replacer.containers; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | public class SimpleTextContainer extends AbstractContainer { 6 | 7 | public SimpleTextContainer(@NotNull String string) { 8 | super(string); 9 | } 10 | 11 | public SimpleTextContainer(@NotNull String string, @NotNull Container root) { 12 | super(string, root); 13 | } 14 | 15 | @Override 16 | public void createDefaultChildren() { 17 | // Nothing more to create here. 18 | } 19 | 20 | @Override 21 | public void createTexts(@NotNull Container container) { 22 | super.createTexts(container); 23 | if (!content.isEmpty()) { 24 | root.addText(new ReplaceableImpl()); 25 | } 26 | } 27 | 28 | @Override 29 | public String getResult() { 30 | return super.getResult(); 31 | } 32 | 33 | private class ReplaceableImpl implements Replaceable { 34 | 35 | @Override 36 | public String getText() { 37 | return content; 38 | } 39 | 40 | @Override 41 | public void setText(String newText) { 42 | content = newText; 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return content; 48 | } 49 | 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/replacer/containers/TextContentContainer.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.replacer.containers; 2 | 3 | import net.md_5.bungee.api.chat.BaseComponent; 4 | import net.md_5.bungee.api.chat.hover.content.Text; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | public class TextContentContainer extends AbstractContainer { 8 | 9 | public TextContentContainer(@NotNull Text text) { 10 | super(text); 11 | } 12 | 13 | public TextContentContainer(@NotNull Text text, @NotNull Container root) { 14 | super(text, root); 15 | } 16 | 17 | @Override 18 | public void createDefaultChildren() { 19 | Object object = content.getValue(); 20 | if (object instanceof BaseComponent[]) { 21 | children.add(new ComponentsContainer((BaseComponent[]) object, root) { 22 | @Override 23 | public BaseComponent[] getResult() { 24 | BaseComponent[] result = super.getResult(); 25 | TextContentContainer.this.content = new Text(result); 26 | return result; 27 | } 28 | }); 29 | } else { 30 | children.add(new SimpleTextContainer((String) object, root) { 31 | @Override 32 | public String getResult() { 33 | String result = super.getResult(); 34 | TextContentContainer.this.content = new Text(result); 35 | return result; 36 | } 37 | }); 38 | } 39 | super.createDefaultChildren(); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/replacer/helpers/ItemHelper.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.replacer.helpers; 2 | 3 | import de.tr7zw.changeme.nbtapi.NBTCompound; 4 | import de.tr7zw.changeme.nbtapi.NBTContainer; 5 | import de.tr7zw.changeme.nbtapi.NBTList; 6 | import io.github.rothes.protocolstringreplacer.util.SpigotUtils; 7 | import net.md_5.bungee.api.chat.BaseComponent; 8 | import net.md_5.bungee.api.chat.ItemTag; 9 | import net.md_5.bungee.api.chat.hover.content.Item; 10 | import net.md_5.bungee.chat.ComponentSerializer; 11 | import org.apache.commons.lang.Validate; 12 | import org.jetbrains.annotations.NotNull; 13 | 14 | import javax.annotation.Nonnull; 15 | import javax.annotation.Nullable; 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | 19 | public class ItemHelper { 20 | 21 | private Item item; 22 | 23 | private NBTContainer nbt; 24 | private NBTCompound display; 25 | private NBTList loreNbt; 26 | 27 | private BaseComponent[] name = null; 28 | private List lore = null; 29 | 30 | private ItemHelper() { 31 | 32 | } 33 | 34 | @NotNull 35 | public static ItemHelper parse(@Nonnull Item item) { 36 | Validate.notNull(item, "Item cannot be null"); 37 | ItemHelper helper = new ItemHelper(); 38 | 39 | helper.item = item; 40 | ItemTag tag = item.getTag(); 41 | if (tag != null) { 42 | helper.nbt = new NBTContainer(tag.getNbt()); 43 | helper.display = helper.nbt.getCompound("display"); 44 | if (helper.display != null) { 45 | if (helper.display.hasTag("Name")) { 46 | helper.name = ComponentSerializer.parse(helper.display.getString("Name")); 47 | } 48 | if (helper.display.hasTag("Lore")) { 49 | helper.loreNbt = helper.display.getStringList("Lore"); 50 | helper.lore = new ArrayList<>(helper.loreNbt.size()); 51 | for (String line : helper.loreNbt) { 52 | helper.lore.add(ComponentSerializer.parse(line)); 53 | } 54 | } 55 | } 56 | } 57 | return helper; 58 | } 59 | 60 | public boolean hasName() { 61 | return name != null; 62 | } 63 | 64 | @Nullable 65 | public BaseComponent[] getName() { 66 | return name; 67 | } 68 | 69 | public void setName(BaseComponent[] name) { 70 | this.name = name; 71 | if (name != null) { 72 | String result = SpigotUtils.serializeComponents(name); 73 | display.setString("Name", result); 74 | } else { 75 | display.removeKey("Name"); 76 | } 77 | } 78 | 79 | public boolean hasLore() { 80 | return lore != null; 81 | } 82 | 83 | public int getLoreSize() { 84 | return this.lore.size(); 85 | } 86 | 87 | public BaseComponent[] getLore(int line) { 88 | return this.lore.get(line); 89 | } 90 | 91 | public void setLore(int line, BaseComponent[] loreLine) { 92 | this.lore.set(line, loreLine); 93 | String result = SpigotUtils.serializeComponents(loreLine); 94 | loreNbt.set(line, result); 95 | } 96 | 97 | public void saveChanges() { 98 | if (display == null) { 99 | return; 100 | } 101 | item.setTag(ItemTag.ofNbt(nbt.toString())); 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/upgrade/AbstractUpgradeHandler.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.upgrade; 2 | 3 | import io.github.rothes.protocolstringreplacer.api.configuration.CommentYamlConfiguration; 4 | import io.github.rothes.protocolstringreplacer.util.FileUtils; 5 | import org.bukkit.configuration.file.YamlConfiguration; 6 | 7 | import javax.annotation.Nonnull; 8 | import java.io.File; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | public abstract class AbstractUpgradeHandler { 14 | 15 | public abstract void upgrade(); 16 | 17 | protected abstract void upgradeReplacerConfig(@Nonnull File file, @Nonnull YamlConfiguration config); 18 | 19 | protected void upgradeAllReplacerConfigs(@Nonnull File folder) { 20 | HashMap loaded = new HashMap<>(); 21 | List files = FileUtils.getFolderFiles(folder, true, ".yml"); 22 | for (File file : files) { 23 | loaded.put(file, CommentYamlConfiguration.loadConfiguration(file)); 24 | } 25 | for (Map.Entry entry : loaded.entrySet()) { 26 | upgradeReplacerConfig(entry.getKey(), entry.getValue()); 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/upgrade/DotConfigUpgradeHandler.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.upgrade; 2 | 3 | import io.github.rothes.protocolstringreplacer.api.configuration.DotYamlConfiguration; 4 | import io.github.rothes.protocolstringreplacer.util.FileUtils; 5 | 6 | import javax.annotation.Nonnull; 7 | import java.io.File; 8 | import java.util.HashMap; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | public abstract class DotConfigUpgradeHandler extends AbstractUpgradeHandler { 13 | 14 | protected void upgradeAllReplacerConfigs(@Nonnull File folder) { 15 | HashMap loaded = new HashMap<>(); 16 | List files = FileUtils.getFolderFiles(folder, true, ".yml"); 17 | for (File file : files) { 18 | loaded.put(file, DotYamlConfiguration.loadConfiguration(file)); 19 | } 20 | for (Map.Entry entry : loaded.entrySet()) { 21 | upgradeReplacerConfig(entry.getKey(), entry.getValue()); 22 | } 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/upgrade/UpgradeEnum.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.upgrade; 2 | 3 | public enum UpgradeEnum { 4 | 5 | FROM_1_TO_2((short) 1, UpgradeHandler1To2.class), 6 | FROM_2_TO_3((short) 2, UpgradeHandler2To3.class), 7 | FROM_3_TO_4((short) 3, UpgradeHandler3To4.class), 8 | FROM_4_TO_5((short) 4, UpgradeHandler4To5.class), 9 | FROM_5_TO_6((short) 5, UpgradeHandler5To6.class); 10 | 11 | private short currentVersion; 12 | private Class upgradeHandler; 13 | 14 | UpgradeEnum(short currentVersion, Class upgradeHandler) { 15 | this.currentVersion = currentVersion; 16 | this.upgradeHandler = upgradeHandler; 17 | } 18 | 19 | public short getCurrentVersion() { 20 | return currentVersion; 21 | } 22 | 23 | public Class getUpgradeHandler() { 24 | return upgradeHandler; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/upgrade/UpgradeHandler2To3.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.upgrade; 2 | 3 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer; 4 | import io.github.rothes.protocolstringreplacer.api.configuration.CommentYamlConfiguration; 5 | import org.apache.commons.collections.map.ListOrderedMap; 6 | import org.bukkit.configuration.ConfigurationSection; 7 | import org.bukkit.configuration.file.YamlConfiguration; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | import java.io.File; 11 | import java.io.IOException; 12 | import java.util.Map; 13 | import java.util.Set; 14 | import java.util.regex.Pattern; 15 | 16 | public final class UpgradeHandler2To3 extends DotConfigUpgradeHandler { 17 | 18 | @Override 19 | public void upgrade() { 20 | upgradeAllReplacerConfigs(new File(ProtocolStringReplacer.getInstance().getDataFolder() + "/Replacers")); 21 | 22 | CommentYamlConfiguration config = ProtocolStringReplacer.getInstance().getConfig(); 23 | config.set("Configs-Version", 3); 24 | try { 25 | config.save(ProtocolStringReplacer.getInstance().getConfigFile()); 26 | } catch (IOException exception) { 27 | exception.printStackTrace(); 28 | } 29 | } 30 | 31 | @SuppressWarnings("unchecked") 32 | @Override 33 | protected void upgradeReplacerConfig(@NotNull File file, @NotNull YamlConfiguration config) { 34 | ConfigurationSection section = config.getConfigurationSection("Replaces"); 35 | if (section != null) { 36 | final ListOrderedMap keyValueHashMap = new ListOrderedMap(); 37 | final Pattern commentKeyPattern = CommentYamlConfiguration.getCommentKeyPattern(); 38 | final Pattern splitPattern = Pattern.compile("\\| "); 39 | for (String key : section.getKeys(false)) { 40 | Object value = section.get(key); 41 | if (value instanceof String) { 42 | String valueString = (String) value; 43 | if (commentKeyPattern.matcher(key).find()) { 44 | String[] split = splitPattern.split(valueString); 45 | value = split[0] + "| " + split[1]; 46 | } 47 | keyValueHashMap.put(key, value); 48 | section.set(key, null); 49 | } 50 | } 51 | section.set("23307㩵遌㚳这是注释是", "0| # 常规文本替换模式."); 52 | Set> set = (Set>) keyValueHashMap.entrySet(); 53 | for (Map.Entry entry : set) { 54 | section.set("Common鰠" + entry.getKey(), entry.getValue()); 55 | } 56 | try { 57 | config.save(file); 58 | } catch (IOException exception) { 59 | exception.printStackTrace(); 60 | } 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/upgrade/UpgradeHandler4To5.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.upgrade; 2 | 3 | import io.github.rothes.protocolstringreplacer.PsrLocalization; 4 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer; 5 | import io.github.rothes.protocolstringreplacer.api.configuration.CommentYamlConfiguration; 6 | import org.bukkit.configuration.file.YamlConfiguration; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | import java.io.File; 10 | import java.io.IOException; 11 | import java.util.ArrayList; 12 | import java.util.regex.Pattern; 13 | 14 | public final class UpgradeHandler4To5 extends AbstractUpgradeHandler { 15 | 16 | @Override 17 | public void upgrade() { 18 | CommentYamlConfiguration config = ProtocolStringReplacer.getInstance().getConfig(); 19 | Pattern commentPattern = CommentYamlConfiguration.getCommentKeyPattern(); 20 | ArrayList comments = new ArrayList<>(); 21 | String locale = null; 22 | for (String key : config.getKeys(true)) { 23 | if (commentPattern.matcher(key).find()) { 24 | comments.add(key); 25 | } else if (key.equals("Options.Localization")){ 26 | locale = config.getString(key); 27 | for (String comment : comments) { 28 | config.set(comment, null); 29 | } 30 | config.set(key, null); 31 | } else { 32 | comments.clear(); 33 | } 34 | } 35 | config.set("Configs-Version", 5); 36 | try { 37 | config.save(ProtocolStringReplacer.getInstance().getConfigFile()); 38 | ProtocolStringReplacer.getInstance().checkConfigKeys(); 39 | config.set("Options.Locale", locale); 40 | config.save(ProtocolStringReplacer.getInstance().getConfigFile()); 41 | PsrLocalization.initialize(ProtocolStringReplacer.getInstance()); 42 | } catch (IOException e) { 43 | e.printStackTrace(); 44 | } 45 | } 46 | 47 | @Override 48 | protected void upgradeReplacerConfig(@NotNull File file, @NotNull YamlConfiguration config) { 49 | // Empty method. 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/upgrade/UpgradeHandler5To6.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.upgrade; 2 | 3 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer; 4 | import io.github.rothes.protocolstringreplacer.api.configuration.CommentYamlConfiguration; 5 | import org.bukkit.configuration.file.YamlConfiguration; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | 11 | public final class UpgradeHandler5To6 extends AbstractUpgradeHandler { 12 | 13 | @Override 14 | public void upgrade() { 15 | CommentYamlConfiguration config = ProtocolStringReplacer.getInstance().getConfig(); 16 | config.set("Configs-Version", 6); 17 | try { 18 | config.save(ProtocolStringReplacer.getInstance().getConfigFile()); 19 | } catch (IOException e) { 20 | e.printStackTrace(); 21 | } 22 | upgradeAllReplacerConfigs(new File(ProtocolStringReplacer.getInstance().getDataFolder(), "/Replacers")); 23 | } 24 | 25 | @Override 26 | protected void upgradeReplacerConfig(@NotNull File file, @NotNull YamlConfiguration config) { 27 | renameNode(config, "Options.Enable", "Options.Enabled"); 28 | renameNode(config, "Options.Filter.ScoreBoard.Replace-Title", "Options.Filter.ScoreBoard.Handle-Title"); 29 | renameNode(config, "Options.Filter.ScoreBoard.Replace-Entity-Name", "Options.Filter.ScoreBoard.Handle-Entity-Name"); 30 | renameNode(config, "Options.Filter.ScoreBoard.Replace-Team-Display-Name", "Options.Filter.ScoreBoard.Handle-Team-Display-Name"); 31 | renameNode(config, "Options.Filter.ScoreBoard.Replace-Team-Prefix", "Options.Filter.ScoreBoard.Handle-Team-Prefix"); 32 | renameNode(config, "Options.Filter.ScoreBoard.Replace-Team-Suffix", "Options.Filter.ScoreBoard.Handle-Team-Suffix"); 33 | config.set("Options.Filter.ItemStack.Handle-Nbt-Compound", false); 34 | config.set("Options.Filter.ItemStack.Handle-Nbt-Lore-List", false); 35 | config.set("Options.Filter.ItemStack.Handle-Nbt-Display-Entries", true); 36 | try { 37 | config.save(file); 38 | } catch (IOException exception) { 39 | exception.printStackTrace(); 40 | } 41 | } 42 | 43 | private void renameNode(@NotNull YamlConfiguration config, @NotNull String o, @NotNull String n) { 44 | Object old = config.get(o); 45 | if (old == null) { 46 | return; 47 | } 48 | config.set(n, old); 49 | config.set(o, null); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/util/FileUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.util; 2 | 3 | import org.apache.commons.lang.Validate; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.nio.file.Files; 9 | import java.nio.file.StandardCopyOption; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | public class FileUtils { 14 | 15 | public static boolean createFile(@NotNull File file) { 16 | File fileParent = file.getParentFile(); 17 | if(!fileParent.exists() && !fileParent.mkdirs()){ 18 | return false; 19 | } 20 | try { 21 | return file.createNewFile(); 22 | } catch (IOException e) { 23 | e.printStackTrace(); 24 | return false; 25 | } 26 | } 27 | 28 | public static void copyDirectoryOrFile(@NotNull File source, @NotNull File destination) throws IOException { 29 | if (!source.exists()) { 30 | return; 31 | } 32 | if (source.isDirectory()) { 33 | copyDirectory(source, destination); 34 | } else { 35 | copyFile(source, destination); 36 | } 37 | } 38 | 39 | public static void copyDirectory(@NotNull File sourceDirectory, @NotNull File destinationDirectory) throws IOException { 40 | if (!destinationDirectory.exists()) { 41 | destinationDirectory.mkdir(); 42 | } 43 | for (String p : sourceDirectory.list()) { 44 | copyDirectoryOrFile(new File(sourceDirectory, p), new File(destinationDirectory, p)); 45 | } 46 | } 47 | 48 | public static void copyFile(@NotNull File sourceFile, @NotNull File destinationFile) throws IOException { 49 | Files.copy(sourceFile.toPath(), destinationFile.toPath(), StandardCopyOption.REPLACE_EXISTING); 50 | } 51 | 52 | @NotNull 53 | public static List getFolderFiles(@NotNull File folder, boolean deep, String suffix) { 54 | List result = new ArrayList<>(); 55 | if (folder.exists()) { 56 | File[] files = folder.listFiles(); 57 | for (File file : files) { 58 | if (file.isFile() && (suffix == null || checkFileSuffix(file, suffix))) { 59 | result.add(file); 60 | } else if (deep && file.isDirectory()) { 61 | result.addAll(getFolderFiles(file, deep, suffix)); 62 | } 63 | } 64 | } 65 | return result; 66 | } 67 | 68 | public static boolean checkFileSuffix(@NotNull File file, @NotNull String suffix) { 69 | Validate.notNull(file, "File cannot be null"); 70 | return checkFileSuffix(file.getName(), suffix); 71 | } 72 | 73 | public static boolean checkFileSuffix(@NotNull String fileName, @NotNull String suffix) { 74 | Validate.notNull(fileName, "FileName cannot be null"); 75 | int length = fileName.length(); 76 | int suffixLength = suffix.length(); 77 | if (length > suffixLength) { 78 | String sub = fileName.substring(length - suffixLength, length); 79 | return sub.equalsIgnoreCase(suffix); 80 | } 81 | return false; 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/util/PaperUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.util; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.GsonBuilder; 5 | import io.papermc.paper.text.PaperComponents; 6 | import net.kyori.adventure.text.Component; 7 | import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; 8 | 9 | public class PaperUtils { 10 | 11 | private static final GsonComponentSerializer paperGsonComponentSerializer = PaperComponents.gsonSerializer(); 12 | private static final Gson psrSerializer = paperGsonComponentSerializer.populator().apply(new GsonBuilder().disableHtmlEscaping()).create(); 13 | 14 | public static GsonComponentSerializer getPaperGsonComponentSerializer() { 15 | return paperGsonComponentSerializer; 16 | } 17 | 18 | public static String serializeComponent(Component component) { 19 | return psrSerializer.toJson(component); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/util/scheduler/PsrScheduler.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.util.scheduler; 2 | 3 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer; 4 | import org.bukkit.Bukkit; 5 | import org.bukkit.Location; 6 | 7 | import java.util.concurrent.TimeUnit; 8 | 9 | public class PsrScheduler { 10 | 11 | private static final ProtocolStringReplacer PLUGIN = ProtocolStringReplacer.getInstance(); 12 | private static final boolean FOLIA = PLUGIN.isFolia(); 13 | 14 | private PsrScheduler() { 15 | 16 | } 17 | 18 | public static PsrTask runTaskTimerAsynchronously(Runnable runnable, long delay, long period) { 19 | if (FOLIA) { 20 | return new PsrTask(Bukkit.getServer().getAsyncScheduler().runAtFixedRate(PLUGIN, val -> runnable.run(), delay * 50, period * 50, TimeUnit.MILLISECONDS)); 21 | } else { 22 | return new PsrTask(Bukkit.getScheduler().runTaskTimerAsynchronously(PLUGIN, runnable, delay, period)); 23 | } 24 | } 25 | public static PsrTask runTaskLaterAsynchronously(Runnable runnable, long delay) { 26 | if (FOLIA) { 27 | return new PsrTask(Bukkit.getServer().getAsyncScheduler().runDelayed(PLUGIN, val -> runnable.run(), delay * 50, TimeUnit.MILLISECONDS)); 28 | } else { 29 | return new PsrTask(Bukkit.getScheduler().runTaskLaterAsynchronously(PLUGIN, runnable, delay)); 30 | } 31 | } 32 | 33 | public static PsrTask runTaskAsynchronously(Runnable runnable) { 34 | if (FOLIA) { 35 | return new PsrTask(Bukkit.getServer().getAsyncScheduler().runNow(PLUGIN, val -> runnable.run())); 36 | } else { 37 | return new PsrTask(Bukkit.getScheduler().runTaskAsynchronously(PLUGIN, runnable)); 38 | } 39 | } 40 | 41 | public static void runTask(Runnable runnable) { 42 | if (FOLIA) { 43 | Bukkit.getServer().getGlobalRegionScheduler().run(PLUGIN, val -> runnable.run()); 44 | } else { 45 | Bukkit.getScheduler().runTask(PLUGIN, runnable); 46 | } 47 | } 48 | 49 | public static void run(Runnable runnable, Location location) { 50 | if (FOLIA) { 51 | Bukkit.getServer().getRegionScheduler().execute(PLUGIN, location, runnable); 52 | } else { 53 | runnable.run(); 54 | } 55 | } 56 | 57 | public static void runTaskLater(Runnable runnable, long delay) { 58 | if (FOLIA) { 59 | Bukkit.getServer().getGlobalRegionScheduler().runDelayed(PLUGIN, val -> runnable.run(), delay); 60 | } else { 61 | Bukkit.getScheduler().runTaskLater(PLUGIN, runnable, delay); 62 | } 63 | } 64 | 65 | public static void runTaskLater(Runnable runnable, Location location, long delay) { 66 | if (FOLIA) { 67 | Bukkit.getServer().getRegionScheduler().runDelayed(PLUGIN, location, val -> runnable.run(), delay); 68 | } else { 69 | Bukkit.getScheduler().runTaskLater(PLUGIN, runnable, delay); 70 | } 71 | } 72 | 73 | public static void cancelTasks() { 74 | if (FOLIA) { 75 | Bukkit.getServer().getGlobalRegionScheduler().cancelTasks(PLUGIN); 76 | Bukkit.getServer().getAsyncScheduler().cancelTasks(PLUGIN); 77 | } else { 78 | Bukkit.getScheduler().cancelTasks(PLUGIN); 79 | } 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /bukkit/src/main/java/io/github/rothes/protocolstringreplacer/util/scheduler/PsrTask.java: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.util.scheduler; 2 | 3 | import io.papermc.paper.threadedregions.scheduler.ScheduledTask; 4 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer; 5 | import org.bukkit.Bukkit; 6 | import org.bukkit.scheduler.BukkitScheduler; 7 | import org.bukkit.scheduler.BukkitTask; 8 | 9 | public final class PsrTask { 10 | 11 | private static final boolean FOLIA = ProtocolStringReplacer.getInstance().isFolia(); 12 | 13 | private final Object task; 14 | private final int taskId; 15 | 16 | public PsrTask(ScheduledTask task) { 17 | this.task = task; 18 | this.taskId = -1; 19 | } 20 | 21 | public PsrTask(BukkitTask task) { 22 | this.task = task; 23 | this.taskId = task.getTaskId(); 24 | } 25 | 26 | public PsrTask(int taskId) { 27 | this.task = null; 28 | this.taskId = taskId; 29 | } 30 | 31 | public void cancel() { 32 | if (FOLIA) { 33 | ((ScheduledTask) task).cancel(); 34 | } else { 35 | if (task != null) { 36 | ((BukkitTask) task).cancel(); 37 | } else { 38 | Bukkit.getScheduler().cancelTask(taskId); 39 | } 40 | } 41 | } 42 | 43 | public boolean isCancelled() { 44 | if (task == null) { 45 | throw new IllegalStateException("Task is created by id"); 46 | } 47 | if (FOLIA) { 48 | return ((ScheduledTask) task).isCancelled(); 49 | } else { 50 | return ((BukkitTask) task).isCancelled(); 51 | } 52 | } 53 | 54 | public boolean isActive() { 55 | if (task == null) { 56 | throw new IllegalStateException("Task is created by id"); 57 | } 58 | if (FOLIA) { 59 | final ScheduledTask.ExecutionState state = ((ScheduledTask) task).getExecutionState(); 60 | return state != ScheduledTask.ExecutionState.FINISHED && state != ScheduledTask.ExecutionState.CANCELLED; 61 | } else { 62 | final int taskId = ((BukkitTask) task).getTaskId(); 63 | final BukkitScheduler scheduler = Bukkit.getScheduler(); 64 | return scheduler.isCurrentlyRunning(taskId) || scheduler.isQueued(taskId); 65 | } 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /bukkit/src/main/kotlin/io/github/rothes/protocolstringreplacer/InternalExtensions.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer 2 | 3 | import com.comphenix.protocol.events.PacketContainer 4 | import com.comphenix.protocol.reflect.StructureModifier 5 | 6 | internal inline fun PacketContainer.modifier() = this.modifier.withType(T::class.java) 7 | 8 | internal inline operator fun StructureModifier.get(field: Int) = this.read(field) 9 | 10 | internal inline operator fun StructureModifier.set(field: Int, value: T) = this.write(field, value) -------------------------------------------------------------------------------- /bukkit/src/main/kotlin/io/github/rothes/protocolstringreplacer/InternalFunctions.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer 2 | 3 | import com.comphenix.protocol.wrappers.WrappedChatComponent 4 | 5 | internal val plugin = ProtocolStringReplacer.getInstance() 6 | internal fun componentToJson(any: Any) = WrappedChatComponent.fromHandle(any).json 7 | internal fun jsonToComponent(json: String) = WrappedChatComponent.fromJson(json).handle -------------------------------------------------------------------------------- /bukkit/src/main/kotlin/io/github/rothes/protocolstringreplacer/command/subcommands/About.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.command.subcommands 2 | 3 | import io.github.rothes.protocolstringreplacer.PsrLocalization 4 | import io.github.rothes.protocolstringreplacer.api.user.PsrUser 5 | import io.github.rothes.protocolstringreplacer.command.SubCommand 6 | import io.github.rothes.protocolstringreplacer.plugin 7 | 8 | class About: SubCommand("about", "protocolstringreplacer.command.about", PsrLocalization.getLocaledMessage("Sender.Commands.About.Description")) { 9 | 10 | override fun onExecute(user: PsrUser, args: Array) { 11 | user.msg("Header") 12 | user.msg("Plugin") 13 | user.msg("Version", plugin.description.version) 14 | user.msg("Author", "Rothes") 15 | user.msg("Donate", "https://ko-fi.com/rothes") 16 | user.msg("GitHub", "https://github.com/Rothes/ProtocolStringReplacer") 17 | user.msg("To-Say") 18 | user.msg("Footer") 19 | } 20 | 21 | override fun onTab(user: PsrUser, args: Array): MutableList { 22 | return mutableListOf() 23 | } 24 | 25 | override fun sendHelp(user: PsrUser) { 26 | } 27 | 28 | private fun PsrUser.msg(key: String, append: String = "", vararg rep: String) { 29 | this.sendFilteredText(PsrLocalization.getLocaledMessage("Sender.Commands.About.$key", *rep) + append) 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /bukkit/src/main/kotlin/io/github/rothes/protocolstringreplacer/packetlistener/server/chat/DisguisedChatPost21.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.chat 2 | 3 | import com.comphenix.protocol.PacketType 4 | import com.comphenix.protocol.events.PacketEvent 5 | import com.comphenix.protocol.reflect.accessors.Accessors 6 | import com.comphenix.protocol.wrappers.WrappedChatComponent 7 | import io.github.rothes.protocolstringreplacer.componentToJson 8 | import io.github.rothes.protocolstringreplacer.jsonToComponent 9 | import io.github.rothes.protocolstringreplacer.nms.NmsManager 10 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerComponentsPacketListener 11 | import io.github.rothes.protocolstringreplacer.replacer.ListenType 12 | import net.minecraft.network.protocol.game.ClientboundDisguisedChatPacket 13 | import java.util.* 14 | 15 | class DisguisedChatPost21 : BaseServerComponentsPacketListener(PacketType.Play.Server.DISGUISED_CHAT, ListenType.CHAT) { 16 | 17 | private val display = Accessors.getFieldAccessor(NmsManager.disguisedPacketHandler.displayNameField) 18 | private val target = Accessors.getFieldAccessor(NmsManager.disguisedPacketHandler.targetField) 19 | 20 | override fun process(packetEvent: PacketEvent) { 21 | val user = getEventUser(packetEvent) ?: return 22 | 23 | val handle = packetEvent.packet.handle as ClientboundDisguisedChatPacket 24 | val boundRecord = NmsManager.disguisedPacketHandler.boundRecord(handle) 25 | getReplacedJson(packetEvent, user, listenType, 26 | WrappedChatComponent.fromHandle(display[boundRecord]).json, filter).let { 27 | if (it != null) { 28 | display[boundRecord] = WrappedChatComponent.fromJson(it).handle 29 | } else { 30 | return 31 | } 32 | } 33 | val optional = target[boundRecord] as Optional<*> 34 | if (optional.isPresent) { 35 | getReplacedJson(packetEvent, user, listenType, 36 | componentToJson(optional.get()), filter).let { replaced -> 37 | if (replaced != null) { 38 | target[boundRecord] = Optional.of(jsonToComponent(replaced)) 39 | } else { 40 | return 41 | } 42 | } 43 | } 44 | 45 | val wrappedChatComponentStructureModifier = packetEvent.packet.chatComponents 46 | val wrappedChatComponent = wrappedChatComponentStructureModifier.read(0) 47 | val replaced = getReplacedJson(packetEvent, user, listenType, wrappedChatComponent.json, filter) 48 | 49 | if (replaced != null) { 50 | wrappedChatComponentStructureModifier.write(0, WrappedChatComponent.fromJson(replaced)) 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /bukkit/src/main/kotlin/io/github/rothes/protocolstringreplacer/packetlistener/server/chat/TabCompletePost20_5.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.chat 2 | 3 | import com.comphenix.protocol.PacketType 4 | import com.comphenix.protocol.events.PacketEvent 5 | import com.comphenix.protocol.reflect.accessors.Accessors 6 | import io.github.rothes.protocolstringreplacer.componentToJson 7 | import io.github.rothes.protocolstringreplacer.get 8 | import io.github.rothes.protocolstringreplacer.jsonToComponent 9 | import io.github.rothes.protocolstringreplacer.modifier 10 | import io.github.rothes.protocolstringreplacer.packetlistener.server.BaseServerPacketListener 11 | import io.github.rothes.protocolstringreplacer.replacer.ListenType 12 | import net.minecraft.network.protocol.game.ClientboundCommandSuggestionsPacket 13 | import java.util.Optional 14 | 15 | class TabCompletePost20_5: BaseServerPacketListener(PacketType.Play.Server.TAB_COMPLETE, ListenType.TAB_COMPLETE) { 16 | 17 | private val text = Accessors.getFieldAccessor(ClientboundCommandSuggestionsPacket.Entry::class.java.declaredFields.first { it.type == String::class.java })!! 18 | private val tooltip = Accessors.getFieldAccessor(ClientboundCommandSuggestionsPacket.Entry::class.java.declaredFields.first { it.type == Optional::class.java })!! 19 | 20 | override fun process(packetEvent: PacketEvent) { 21 | val packet = packetEvent.packet 22 | val user = getEventUser(packetEvent) ?: return 23 | 24 | val entries = packet.modifier>()[0] 25 | entries.forEach { entry -> 26 | getReplacedText(packetEvent, user, listenType, text[entry] as String, filter).let { replaced -> 27 | if (replaced == null) { 28 | return 29 | } 30 | text[entry] = replaced 31 | } 32 | val optional = tooltip[entry] as Optional<*> 33 | if (optional.isPresent) { 34 | getReplacedJson(packetEvent, user, listenType, componentToJson(optional.get()), filter).let { replaced -> 35 | if (replaced == null) { 36 | return 37 | } 38 | tooltip[entry] = Optional.of(jsonToComponent(replaced)) 39 | } 40 | } 41 | } 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /bukkit/src/main/kotlin/io/github/rothes/protocolstringreplacer/packetlistener/server/itemstack/WindowItems.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.itemstack 2 | 3 | import com.comphenix.protocol.PacketType 4 | import com.comphenix.protocol.events.PacketEvent 5 | import com.comphenix.protocol.wrappers.BukkitConverters 6 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer 7 | import io.github.rothes.protocolstringreplacer.get 8 | import io.github.rothes.protocolstringreplacer.set 9 | import org.bukkit.Material 10 | 11 | class WindowItems : BaseServerItemPacketListener(PacketType.Play.Server.WINDOW_ITEMS) { 12 | 13 | override fun process(packetEvent: PacketEvent) { 14 | val user = getEventUser(packetEvent) ?: return 15 | user.clearUserItemRestoreCache() 16 | val replacerManager = ProtocolStringReplacer.getInstance().replacerManager 17 | val nbt = replacerManager.getAcceptedReplacers(user, itemNbtFilter) 18 | val lore = replacerManager.getAcceptedReplacers(user, itemLoreFilter) 19 | val entries = replacerManager.getAcceptedReplacers(user, itemEntriesFilter) 20 | 21 | var saveMeta = !user.isInAnvil 22 | packetEvent.packet.modifier[1] = (packetEvent.packet.modifier[1] as Array<*>).map { 23 | BukkitConverters.getItemStackConverter().getSpecific(it) 24 | }.map { itemStack -> 25 | if (itemStack.type == Material.AIR) { 26 | saveMeta = true 27 | return@map itemStack 28 | } 29 | replaceItemStack(packetEvent, user, listenType, itemStack, nbt, lore, entries, saveMeta).also { 30 | saveMeta = true 31 | } ?: return 32 | }.map { 33 | BukkitConverters.getItemStackConverter().getGeneric(it) 34 | }.toTypedArray() 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /bukkit/src/main/kotlin/io/github/rothes/protocolstringreplacer/packetlistener/server/itemstack/WindowItemsPost11.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.itemstack 2 | 3 | import com.comphenix.protocol.PacketType 4 | import com.comphenix.protocol.events.PacketEvent 5 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer 6 | import io.github.rothes.protocolstringreplacer.get 7 | import io.github.rothes.protocolstringreplacer.set 8 | import org.bukkit.Material 9 | 10 | class WindowItemsPost11 : BaseServerItemPacketListener(PacketType.Play.Server.WINDOW_ITEMS) { 11 | 12 | override fun process(packetEvent: PacketEvent) { 13 | val user = getEventUser(packetEvent) ?: return 14 | user.clearUserItemRestoreCache() 15 | val replacerManager = ProtocolStringReplacer.getInstance().replacerManager 16 | val nbt = replacerManager.getAcceptedReplacers(user, itemNbtFilter) 17 | val lore = replacerManager.getAcceptedReplacers(user, itemLoreFilter) 18 | val entries = replacerManager.getAcceptedReplacers(user, itemEntriesFilter) 19 | 20 | val itemListModifier = packetEvent.packet.itemListModifier 21 | var saveMeta = !user.isInAnvil 22 | itemListModifier[0] = itemListModifier[0].map { itemStack -> 23 | if (itemStack.type == Material.AIR) { 24 | saveMeta = true 25 | return@map itemStack 26 | } 27 | replaceItemStack(packetEvent, user, listenType, itemStack, nbt, lore, entries, saveMeta).also { 28 | saveMeta = true 29 | } ?: return 30 | } 31 | val itemModifier = packetEvent.packet.itemModifier 32 | if (itemModifier.size() != 0) { 33 | // Since 1.17.1 34 | val itemStack = itemModifier[0] 35 | if (itemStack.type == Material.AIR) { 36 | return 37 | } 38 | itemModifier[0] = replaceItemStack(packetEvent, user, listenType, itemStack, nbt, lore, entries, true) ?: return 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /bukkit/src/main/kotlin/io/github/rothes/protocolstringreplacer/packetlistener/server/sign/MapChunkPost18.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.sign 2 | 3 | import com.comphenix.protocol.PacketType 4 | import com.comphenix.protocol.events.PacketEvent 5 | import de.tr7zw.changeme.nbtapi.NBTContainer 6 | import net.minecraft.nbt.CompoundTag 7 | import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData 8 | import net.minecraft.world.level.block.entity.BlockEntityType 9 | import java.lang.reflect.Field 10 | import java.lang.reflect.Modifier 11 | 12 | class MapChunkPost18 : BaseServerSignPacketListener(PacketType.Play.Server.MAP_CHUNK) { 13 | 14 | private val chunkData: Field 15 | private val blockEntitiesData: Field 16 | private val type: Field 17 | private val tag: Field 18 | 19 | init { 20 | val clazz = ClientboundLevelChunkPacketData::class.java 21 | chunkData = PacketType.Play.Server.MAP_CHUNK.packetClass.declaredFields.firstOrThrow("chunkData") { it.type == clazz } 22 | with(clazz) { 23 | blockEntitiesData = declaredFields.firstOrThrow("blockEntitiesData") { it.type.isAssignableFrom(List::class.java) } 24 | val blockEntityInfo = declaredClasses.firstOrThrow("blockEntityInfo") { !it.isInterface && it.modifiers == Modifier.STATIC } 25 | type = blockEntityInfo.declaredFields.firstOrThrow("type") { it.type == BlockEntityType::class.java } 26 | tag = blockEntityInfo.declaredFields.firstOrThrow("tag") { it.type == CompoundTag::class.java } 27 | } 28 | chunkData.isAccessible = true 29 | blockEntitiesData.isAccessible = true 30 | type.isAccessible = true 31 | tag.isAccessible = true 32 | } 33 | 34 | override fun process(packetEvent: PacketEvent) { 35 | val user = getEventUser(packetEvent) ?: return 36 | val packet = packetEvent.packet 37 | for (blockEntityInfo in blockEntitiesData[chunkData[packet.handle]] as List<*>) { 38 | if (TileTypeHelper.isSignType(type[blockEntityInfo])) { 39 | replaceSign(packetEvent, NBTContainer(tag[blockEntityInfo] ?: continue), user, filter) 40 | } 41 | } 42 | } 43 | 44 | private inline fun Array.firstOrThrow(msg: String, predicate: (T) -> Boolean): T { 45 | for (element in this) if (predicate(element)) return element 46 | throw NoSuchElementException(msg) 47 | } 48 | } -------------------------------------------------------------------------------- /bukkit/src/main/kotlin/io/github/rothes/protocolstringreplacer/packetlistener/server/sign/TileTypeHelper.kt: -------------------------------------------------------------------------------- 1 | package io.github.rothes.protocolstringreplacer.packetlistener.server.sign 2 | 3 | import io.github.rothes.protocolstringreplacer.ProtocolStringReplacer 4 | import io.github.rothes.protocolstringreplacer.nms.NmsManager 5 | 6 | object TileTypeHelper { 7 | 8 | private val signType: Any 9 | private val hangingSignType: Any 10 | 11 | init { 12 | if (ProtocolStringReplacer.getInstance().serverMajorVersion < 19 13 | || (ProtocolStringReplacer.getInstance().serverMajorVersion.toInt() == 19 && ProtocolStringReplacer.getInstance().serverMinorVersion <= 2)) { 14 | signType = Class.forName("net.minecraft.world.level.block.entity.TileEntityTypes").getField("h")[null] 15 | hangingSignType = Any() 16 | } else { 17 | signType = NmsManager.blockEntityTypeGetter.signType 18 | hangingSignType = NmsManager.blockEntityTypeGetter.hangingSignType 19 | } 20 | } 21 | 22 | @JvmStatic 23 | fun isSignType(type: Any?): Boolean { 24 | return type != null && (type === signType || type === hangingSignType) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /bukkit/src/main/resources/Languages/Global/ExampleReplacers/Slimefun/Translation_CN/Chat/Text_Contain.yml: -------------------------------------------------------------------------------- 1 | Options: 2 | Enabled: true 3 | Priority: 30 4 | Version: '230208' 5 | Author: Rothes 6 | Filter: 7 | Listen-Types: 8 | - Chat 9 | Match-Mode: Contain 10 | Replaces: 11 | Common: 12 | - Original: This item has been deprecated 13 | Replacement: 此物品已弃用 14 | - Original: It will be removed soon! 15 | Replacement: 它将会在不久后的版本中被移除! 16 | - Original: Missing chest\! Auto-Crafters need to be placed above a chest 17 | Replacement: 缺少箱子! 自动合成器必须放在一个箱子的上面 18 | - Original: Crouch and Right-Click 19 | Replacement: 潜行 + 右键 20 | - Original: this block with the item you want it to craft 21 | Replacement: 此方块以设定你想要合成的物品 22 | - Original: We could not find any valid recipes for the item you are holding 23 | Replacement: 没有任何适用于合成你手上拿着的物品的配方 24 | -------------------------------------------------------------------------------- /bukkit/src/main/resources/Languages/Global/ExampleReplacers/Slimefun/Translation_CN/Console/Regex.yml: -------------------------------------------------------------------------------- 1 | Options: 2 | Enabled: true 3 | Priority: 30 4 | Version: '230208' 5 | Author: Rothes 6 | Filter: 7 | Listen-Types: 8 | - Console 9 | Match-Mode: Regex 10 | Replaces: 11 | Common: 12 | - Original: 'Auto-saving block data... \(Next auto-save: ([0-9]+)m\)' 13 | Replacement: '正在自动保存方块数据... (下次自动保存: $1分钟)' 14 | - Original: Saving block data for world "([\W|\w]+)" \(([0-9]+) change\(s\) queued\) 15 | Replacement: 正在为世界 "$1" 保存方块数据... (已队列 $2 个变化) 16 | - Original: Successfully loaded ([0-9]+) Items and ([0-9]+) Researches 17 | Replacement: 成功载入 $1 个物品 和 $2 个研究 18 | - Original: \( ([0-9]+) Items from Slimefun, ([0-9]+) Items from ([0-9]+) Addons \) 19 | Replacement: ( $1 物品来自粘液科技, $2 物品来自 $3 个扩展之中) 20 | -------------------------------------------------------------------------------- /bukkit/src/main/resources/Languages/Global/ExampleReplacers/Slimefun/Translation_CN/Console/Text_Contain.yml: -------------------------------------------------------------------------------- 1 | Options: 2 | Enabled: true 3 | Priority: 30 4 | Version: '230208' 5 | Author: Rothes 6 | Filter: 7 | Listen-Types: 8 | - Console 9 | Match-Mode: Contain 10 | Replaces: 11 | Common: 12 | - Original: '######################### - Slimefun v' 13 | Replacement: '######################### - 粘液科技 v' 14 | - Original: Slimefun is an Open-Source project that is kept alive by a large community. 15 | Replacement: 粘液科技是一个开源的项目, 由其巨大的玩家社区来其保持活力. 16 | - Original: Consider helping us maintain this project by contributing on GitHub! 17 | Replacement: 请考虑通过在 GitHub 中贡献来帮助我们维护这个项目! 18 | - Original: ' - Source Code: https://github.com/Slimefun/Slimefun4' 19 | Replacement: ' - 源代码: https://github.com/Slimefun/Slimefun4' 20 | - Original: ' - Wiki: https://github.com/Slimefun/Slimefun4/wiki' 21 | Replacement: ' - 维基: https://github.com/Slimefun/Slimefun4/wiki' 22 | - Original: ' - Addons: https://github.com/Slimefun/Slimefun4/wiki/Addons' 23 | Replacement: ' - 扩展: https://github.com/Slimefun/Slimefun4/wiki/Addons' 24 | - Original: ' - Bug Reports: https://github.com/Slimefun/Slimefun4/issues' 25 | Replacement: ' - 反馈漏洞: https://github.com/Slimefun/Slimefun4/issues' 26 | - Original: ' - Discord: https://discord.gg/slimefun' 27 | Replacement: ' - Discord: https://discord.gg/slimefun' 28 | -------------------------------------------------------------------------------- /bukkit/src/main/resources/Languages/Global/ExampleReplacers/Slimefun/Translation_CN/Entity/Cargo 货运.yml: -------------------------------------------------------------------------------- 1 | Options: 2 | Enabled: true 3 | Priority: 30 4 | Version: '230208' 5 | Author: Rothes 6 | Filter: 7 | Listen-Types: 8 | - Entity 9 | Match-Mode: Contain 10 | Replaces: 11 | Common: 12 | - Original: §cNo Cargo Nodes found 13 | Replacement: §c未找到货运网络节点 14 | - Original: §4Multiple Cargo Regulators connected 15 | Replacement: §4连接多个货运网络管理器 16 | - Original: '§7Status:' 17 | Replacement: '§7状态:' 18 | - Original: §a§lONLINE 19 | Replacement: §a§l在线 20 | -------------------------------------------------------------------------------- /bukkit/src/main/resources/Languages/Global/ExampleReplacers/Slimefun/Translation_CN/Interfaces/Machine Interfaces/Android 可编程式机器人.yml: -------------------------------------------------------------------------------- 1 | Options: 2 | Enabled: true 3 | Priority: 30 4 | Version: '230208' 5 | Author: Rothes 6 | Filter: 7 | Listen-Types: 8 | - ItemStack 9 | Match-Mode: Contain 10 | Replaces: 11 | Direct: 12 | - Original: §aStart/Continue 13 | Replacement: §a开始/继续运行 14 | - Original: §bMemory Core 15 | Replacement: §b内存核心 16 | - Original: §8⇨ §7Click to open the Script Editor 17 | Replacement: §8⇨ §7点击打开脚本编辑器 18 | - Original: §4Pause 19 | Replacement: §4暂停运行 20 | - Original: §8⇩ §cFuel Input §8⇩ 21 | Replacement: §8⇩ §c燃料槽 §8⇩ 22 | - Original: This Android runs on solid Fuel 23 | Replacement: 这个安卓机器人基于固体燃料运行 24 | - Original: 'e.g. Coal, Wood, ' 25 | Replacement: '例如: 煤炭, 木材, ' 26 | - Original: This Android runs on liquid Fuel 27 | Replacement: 这个安卓机器人基于液体燃料运行 28 | - Original: 'e.g. Lava, Oil, Fuel, ' 29 | Replacement: '例如: 熔岩, 原油, 燃油, ' 30 | - Original: This Android runs on radioactive Fuel 31 | Replacement: 这个安卓机器人基于放射性燃料运行 32 | - Original: e.g. Uranium, Neptunium or Boosted Uranium 33 | Replacement: '例如: 铀块, 镎块 和 强化铀块' 34 | - Original: §2> Edit Script 35 | Replacement: §2> 编辑脚本 36 | - Original: §aEdits your current Script 37 | Replacement: §a编辑现在使用中的脚本 38 | - Original: §7⇨ §eLeft Click §7to return to the Android's interface 39 | Replacement: §7⇨ §e左键 §7回到安卓机器人主界面 40 | - Original: §7⇨ §eLeft Click §7to edit 41 | Replacement: §7⇨ §e左键 §7编辑此指令 42 | - Original: §7⇨ §eRight Click §7to delete 43 | Replacement: §7⇨ §e右键 §7移除此指令 44 | - Original: Right Click §7to duplicate 45 | Replacement: 右键 §7重复运行一次此指令 46 | - Original: §7> Add new Command 47 | Replacement: §7> 添加一个指令 48 | - Original: §4> Create new Script 49 | Replacement: §4> 创建新脚本 50 | - Original: §cDeletes your current Script 51 | Replacement: §c删除现在使用中的脚本 52 | - Original: §cand creates a blank one 53 | Replacement: §c然后新建一个空白的脚本 54 | - Original: §6> Download a Script 55 | Replacement: §6> 下载脚本 56 | - Original: §eDownload a Script from the Server 57 | Replacement: §e从服务器中下载脚本 58 | - Original: §eYou can edit or simply use it 59 | Replacement: §e你可以编辑或直接使用它 60 | - Original: §eUpload a Script 61 | Replacement: §e上传脚本 62 | - Original: §6Click §7to upload your Android's Script 63 | Replacement: §6单击 §7上传现在使用中的脚本 64 | - Original: §7to the Server's database 65 | Replacement: §7到服务器的数据库 66 | - Original: This will override your current Script 67 | Replacement: 此操作会覆盖你现在使用中的脚本 68 | - Original: §eLeft Click §fto download this Script 69 | Replacement: §e单击 §f下载此脚本 70 | - Original: '§7Downloads: §f' 71 | Replacement: '§7下载数: §f' 72 | - Original: '§7Rating: §' 73 | Replacement: '§7评分: §' 74 | - Original: §6> Back 75 | Replacement: §6> 返回 76 | - Original: §7Return to the Android's interface 77 | Replacement: §7返回到安卓机器人主界面 78 | -------------------------------------------------------------------------------- /bukkit/src/main/resources/Languages/Global/ExampleReplacers/Slimefun/Translation_CN/Interfaces/Machine Interfaces/Auto-Crafter 自动合成器.yml: -------------------------------------------------------------------------------- 1 | Options: 2 | Enabled: true 3 | Priority: 30 4 | Version: '230208' 5 | Author: Rothes 6 | Filter: 7 | Listen-Types: 8 | - ItemStack 9 | ItemStack: 10 | Window-Title: 11 | - '{"extra":[{"color":"dark_green","text":"Auto-Crafter "},{"color":"dark_gray","text":"(Vanilla)"}],"text":""}' 12 | - '{"extra":[{"color":"dark_green","text":"Auto-Crafter "},{"color":"dark_gray","text":"(Enhanced)"}],"text":""}' 13 | - '{"extra":[{"color":"dark_green","text":"Auto-Crafter "},{"color":"dark_gray","text":"(Armor Forge)"}],"text":""}' 14 | Match-Mode: Contain 15 | Replaces: 16 | Direct: 17 | - Original: §aSelect this recipe 18 | Replacement: §a选择这个配方 19 | - Original: §aThis recipe is currently enabled 20 | Replacement: §a此配方目前已启用 21 | - Original: §eLeft Click §7to temporarily disable the recipe 22 | Replacement: §e左键单击 §7暂时禁用配方 23 | - Original: §eRight Click §7to remove this recipe 24 | Replacement: §e右键单击 §7移除这个配方 25 | - Original: §cThis recipe is currently disabled 26 | Replacement: §c此配方目前已禁用 27 | - Original: §eLeft Click §7to re-enable this recipe 28 | Replacement: §e左键单击 §7重新启用此配方 29 | -------------------------------------------------------------------------------- /bukkit/src/main/resources/Languages/Global/ExampleReplacers/Slimefun/Translation_CN/Interfaces/Machine Interfaces/Cargo 货运.yml: -------------------------------------------------------------------------------- 1 | Options: 2 | Enabled: true 3 | Priority: 30 4 | Version: '230208' 5 | Author: Rothes 6 | Filter: 7 | Listen-Types: 8 | - ItemStack 9 | ItemStack: 10 | Window-Title: 11 | - '{"text":"Cargo Node (Input)"}' 12 | - '{"text":"Cargo Node (Output)"}' 13 | - '{"text":"Advanced Cargo Node (Output)"}' 14 | Match-Mode: Contain 15 | Replaces: 16 | Direct: 17 | - Original: §3Items 18 | Replacement: §3物品管理 19 | - Original: §bPut in all Items you want to 20 | Replacement: §b在此处放入你想要添加 21 | - Original: §bblacklist/whitelist 22 | Replacement: §b白名单或黑名单的物品 23 | - Original: '§7Type: §fWhitelist' 24 | Replacement: '§7过滤模式: §r白名单' 25 | - Original: §e> Click to change it to Blacklist 26 | Replacement: §e> 点击切换为黑名单模式 27 | - Original: '§7Type: §8Blacklist' 28 | Replacement: '§7过滤模式: §8黑名单' 29 | - Original: §e> Click to change it to Whitelist 30 | Replacement: §e> 点击切换为白名单模式 31 | - Original: '§7Include Lore: §' 32 | Replacement: '§7检查物品Lore: §' 33 | - Original: §e> Click to toggle whether the Lore has to match 34 | Replacement: §e> 点击切换是否检测物品Lore数据 35 | - Original: '§bChannel ID: §' 36 | Replacement: '§b信道 ID: §' 37 | - Original: §bPrevious Channel 38 | Replacement: §b上一信道 39 | - Original: §e> Click to decrease the Channel ID by 1 40 | Replacement: §e> 点击切换到上一个信道 41 | - Original: §bNext Channel 42 | Replacement: §b下一信道 43 | - Original: §e> Click to increase the Channel ID by 1 44 | Replacement: §e> 点击切换到下一个信道 45 | - Original: '§7Round-Robin Mode: §' 46 | Replacement: '§7循环模式: §' 47 | - Original: §e> Click to enable Round Robin Mode 48 | Replacement: §e> 点击启用循环模式 49 | - Original: §e> Click to disable Round Robin Mode 50 | Replacement: §e> 点击禁用循环模式 51 | - Original: Items will be equally distributed on the Channel 52 | Replacement: 用于让物品在不同信道中均匀发放 53 | - Original: '§7"Smart-Filling" Mode:' 54 | Replacement: '§7"智能填充" 模式:' 55 | - Original: §e> Click to enable "Smart-Filling" Mode 56 | Replacement: §e> 单击 启用 "智能填充" 模式 57 | - Original: §e> Click to disable "Smart-Filling" Mode 58 | Replacement: §e> 单击 禁用 "智能填充" 模式 59 | - Original: §fIn this mode, the Cargo node will attempt 60 | Replacement: §f在此模式中, 货运节点将会尝试 61 | - Original: §fto keep a constant amount of items 62 | Replacement: §f在容器中保持恒定的物品数量. 63 | - Original: §fin the inventory. This is not perfect 64 | Replacement: §f此模式运行地不是非常完美, 并且 65 | - Original: §fand will still fill in empty slots that 66 | Replacement: §f仍然会向在已配置的堆叠物 67 | - Original: §fcome before a stack of a configured item 68 | Replacement: §f之前的空槽位中填充 69 | -------------------------------------------------------------------------------- /bukkit/src/main/resources/Languages/Global/ExampleReplacers/Slimefun/Translation_CN/Interfaces/Window-Title.yml: -------------------------------------------------------------------------------- 1 | Options: 2 | Enabled: true 3 | Priority: 30 4 | Version: '230208' 5 | Author: Rothes 6 | Filter: 7 | Listen-Types: 8 | - Window-Title 9 | Match-Mode: Contain 10 | Replaces: 11 | Direct: 12 | - Original: Slimefun 指南 13 | Replacement: §8粘液科技指南 14 | - Original: Enhanced Furnace 15 | Replacement: §8增强型熔炉 16 | - Original: Reinforced Furnace 17 | Replacement: §8强化熔炉 18 | - Original: Carbonado Edged Furnace 19 | Replacement: §8黑金刚石镶边熔炉 20 | - Original: Block Placer 21 | Replacement: §8方块放置机 22 | - Original: Android Interface §9(Items) 23 | Replacement: §8安卓机器人容器 §9(物品) 24 | - Original: Android Interface §c(Fuel) 25 | Replacement: §8安卓机器人容器 §c(燃料) 26 | - Original: Programmable Android 27 | Replacement: §8可编程式机器人 28 | - Original: Advanced Programmable Android 29 | Replacement: §8高级可编程式机器人 30 | - Original: Empowered Programmable Android 31 | Replacement: §8可授权编程式机器人 32 | - Original: Android Scripts 33 | Replacement: §8机器人脚本 34 | - Original: Advanced Cargo Node (Output) 35 | Replacement: §8高级货运节点 (输出) 36 | - Original: Cargo Node (Input) 37 | Replacement: §8货运网络节点 (输入) 38 | - Original: Cargo Node (Output) 39 | Replacement: §8货运网络节点 (输出) 40 | - Original: §2Auto-Crafter §8(Vanilla) 41 | Replacement: §2自动合成器§8 (原版) 42 | - Original: §2Auto-Crafter §8(Enhanced) 43 | Replacement: §2自动合成器§8 (增强) 44 | - Original: §2Auto-Crafter §8(Armor Forge) 45 | Replacement: §2自动合成器§8 (盔甲锻造台) 46 | -------------------------------------------------------------------------------- /bukkit/src/main/resources/Languages/Global/ExampleReplacers/Slimefun/Translation_CN/ItemStack/Regex.yml: -------------------------------------------------------------------------------- 1 | Options: 2 | Enabled: true 3 | Priority: 30 4 | Version: '230208' 5 | Author: Rothes 6 | Filter: 7 | Listen-Types: 8 | - ItemStack 9 | Match-Mode: Regex 10 | Replaces: 11 | Direct: 12 | - Original: (\d) J/s 13 | Replacement: $1 J/秒 14 | - Original: '§8⇨ §7Speed: §a(\d)/time' 15 | Replacement: '§8⇨ §7效率: §a$1/次' 16 | - Original: §8⇨ §7Lasts (\d+)m (\d+)s 17 | Replacement: §8⇨ §7持续发电 $1分钟 $2秒 18 | - Original: §e⚡ §7(\d+)K J in total 19 | Replacement: §e⚡ §7共可发电 $1 KJ 20 | - Original: §([a7])Survival Mode 21 | Replacement: §$1生存模式 22 | - Original: §([a7])Cheat Sheet 23 | Replacement: §$1作弊模式 24 | - Original: Level (I+) - Medical Supply 25 | Replacement: 等级 $1 - 医疗用品 26 | - Original: Restores (\d) Hearts 27 | Replacement: 回复 $1♥ 血量 28 | - Original: '§7Size: §e(\d)' 29 | Replacement: '§7容量: §e$1' 30 | - Original: ' §7\((\d+)\-Carat\)' 31 | Replacement: ' §7($1-克拉)' 32 | - Original: anything that can be crafted using a(n)? 33 | Replacement: 所有你想合成的物品. 相当于一个 34 | -------------------------------------------------------------------------------- /bukkit/src/main/resources/Languages/en-US/ExampleReplacers/ReadMe.md: -------------------------------------------------------------------------------- 1 | Configs in this directory is only for example uses, for helping you learn the plugin. 2 | 3 | They will not take effect unless they are moved to the Replacers directory. -------------------------------------------------------------------------------- /bukkit/src/main/resources/Languages/en-US/ExampleReplacers/Slimefun/Translation_CN/ReadMe.md: -------------------------------------------------------------------------------- 1 | These replacer configs are used to translate Slimefun into Simplified Chinese. 2 | 3 | It shows how to use Regex, how to specify the Filter properly, etc. -------------------------------------------------------------------------------- /bukkit/src/main/resources/Languages/en-US/Example_Replacers.txt: -------------------------------------------------------------------------------- 1 | $Locale/Replacers/Example.yml 2 | $Locale/Replacers/ConsoleColor.yml 3 | 4 | $Locale/ExampleReplacers/ReadMe.md 5 | $Locale/ExampleReplacers/Slimefun/Translation_CN/ReadMe.md 6 | Global/ExampleReplacers/Slimefun/Translation_CN/Chat/Text_Contain.yml 7 | Global/ExampleReplacers/Slimefun/Translation_CN/Console/Regex.yml 8 | Global/ExampleReplacers/Slimefun/Translation_CN/Console/Text_Contain.yml 9 | Global/ExampleReplacers/Slimefun/Translation_CN/Entity/Cargo 货运.yml 10 | Global/ExampleReplacers/Slimefun/Translation_CN/Interfaces/Window-Title.yml 11 | Global/ExampleReplacers/Slimefun/Translation_CN/Interfaces/Machine Interfaces/Android 可编程式机器人.yml 12 | Global/ExampleReplacers/Slimefun/Translation_CN/Interfaces/Machine Interfaces/Auto-Crafter 自动合成器.yml 13 | Global/ExampleReplacers/Slimefun/Translation_CN/Interfaces/Machine Interfaces/Cargo 货运.yml 14 | Global/ExampleReplacers/Slimefun/Translation_CN/ItemStack/Regex.yml 15 | Global/ExampleReplacers/Slimefun/Translation_CN/ItemStack/Text_Contain.yml -------------------------------------------------------------------------------- /bukkit/src/main/resources/Languages/zh-CN/Configs/Config.yml: -------------------------------------------------------------------------------- 1 | # 请勿手动修改Configs-Version值! 2 | Configs-Version: 6 3 | 4 | Options: 5 | # 本地语言. 将在 ProtocolStringReplacer/Locales 中寻找对应 yml 文件. 6 | # 此设定也涉及一些内部操作, 建议按照规范 语言缩写(小写)-地区缩写(大写) 来填写. 7 | Locale: zh-CN 8 | 9 | # 设置检测更新服务器的域名. 默认为 'raw.githubusercontent.com'. 10 | # 若连接不上此加速线路, 应自行选择其它加速线路. 11 | Git-Raw-Host: 'mirror.ghproxy.com/https://raw.githubusercontent.com' 12 | 13 | # 设置 PSR 加载配置的时期. 可选 INIT (最早), LOAD (中), ENABLE (最晚, 默认值). 14 | # 主要用于控制台消息的修改. 15 | Config-Load-LifeCycle: 'ENABLE' 16 | 17 | # PSR 会显示多少次由 ProtocolLib 导致的报错? 设置为 0 为永久禁止. 18 | ProtocolLib-Side-Stack-Print-Count: 3 19 | 20 | # 设置 /psr capture list 最多储存多少条捕获记录. 21 | Max-Capture-Records: 100 22 | 23 | Features: 24 | # 启用游戏内指令输入音效. 25 | Command-Typing-Sound-Enabled: true 26 | 27 | # 控制台相关设定. 28 | Console: 29 | # 在控制台内显示加载的替换配置文件. 30 | Print-Replacer-Config-When-Loaded: true 31 | # 在记录结束后重置控制台颜色. 32 | # 如果您的配置对色彩进行了修改, 您可能需要开启此设定. 33 | Reset-Console-Color-At-End: true 34 | 35 | # 自定义插件占位符的使用格式. 建议使用玩家想不到的格式 36 | # 以防止玩家通过占位符获取到不该获取的信息. 37 | # 在默认值下, 使用如{player_name}的格式来获取占位符的变量. 38 | Placeholder: 39 | # 启用 PlaceholderAPI 功能. 如果您不需要解析占位符, 可以关闭此功能. 40 | Placeholder-Enabled: true 41 | # 使用占位符的前缀. 仅允许一个字符. 42 | Placeholder-Head: { 43 | # 使用占位符的后缀. 仅允许一个字符. 44 | Placeholder-Tail: } 45 | # 是否为显示在控制台的文本解析占位符. 46 | Parse-For-Console: true 47 | 48 | # 关于已替换物品缓存表的相关设定. 49 | ItemMetaCache: 50 | # 每多少秒执行一次清理缓存的任务. 51 | Purge-Task-Interval: 600 52 | # 只清理多少秒未读取过的缓存条目. 53 | Purge-Access-Interval: 300 54 | # 在与村民/流浪商人交易时移除物品上的NBT缓存 55 | # 以解决部分小故障. 56 | Remove-Cache-When-Merchant-Trade: false 57 | 58 | # 关于网络数据包监听器的相关设定. 59 | Packet-Listener: 60 | # 定义 ProtocolStringReplacer 监听数据包全局优先度. 61 | # 如果与其他发包插件产生冲突, 请修改该值. 62 | Listener-Priority: HIGHEST 63 | # 是否强行修改不允许修改的数据包. 64 | Force-Replace: false 65 | # 设定启用哪些类型的监听. 若某种类型中的文本不需要修改, 可设为 false 以优化性能. 66 | Listen-Type-Enabled: 67 | ActionBar: true 68 | Boss-Bar: true 69 | Chat: true 70 | Chat-Preview: true 71 | Combat-Kill: true 72 | Entity: true 73 | ItemStack: true 74 | Kick-Disconnect: true 75 | ScoreBoard: true 76 | Sign: true 77 | Tab-Complete: true 78 | Title: true 79 | Window-Title: true 80 | 81 | # 聊天数据包的相关设定. 82 | Chat-Packet: 83 | # 仅适用于 1.19+ . 必须启用此功能 PSR 才能处理玩家发送的消息. 84 | # 启用后, PSR 会转换所有 PLAYER_CHAT 数据包为 SYSTEM_CHAT, 85 | # 以解决服务端/客户端开启“仅显示安全的聊天”后消息无法显示的问题. 86 | # 注意: 这会影响到客户端对玩家聊天的检测. 例如, 您将无法通过聊天来举报其他玩家. 87 | Convert-Player-Chat: true 88 | 89 | # 有关替换模式优化的相关设定. 90 | Replace-Mode: 91 | # 在直观(Direct)替换模式成功替换后, 跳过对这个数据包所有的处理. 92 | Skip-When-Direct-Replaced: true 93 | -------------------------------------------------------------------------------- /bukkit/src/main/resources/Languages/zh-CN/ExampleReplacers/ReadMe.md: -------------------------------------------------------------------------------- 1 | 本文件夹中的配置文件作为示例使用, 以便您更好地了解插件. 2 | 3 | 除非将其移至 Replacers 文件夹, 否则它们不会生效. -------------------------------------------------------------------------------- /bukkit/src/main/resources/Languages/zh-CN/ExampleReplacers/Slimefun/Translation_CN/ReadMe.md: -------------------------------------------------------------------------------- 1 | 这些替换配置用于将粘液科技翻译为简体中文. 2 | 3 | 它展示了如何使用正则表达式替换模式、 4 | 如何正确指定过滤器等. -------------------------------------------------------------------------------- /bukkit/src/main/resources/Languages/zh-CN/Example_Replacers.txt: -------------------------------------------------------------------------------- 1 | $Locale/Replacers/Example.yml 2 | $Locale/Replacers/ConsoleColor.yml 3 | 4 | $Locale/ExampleReplacers/ReadMe.md 5 | $Locale/ExampleReplacers/Slimefun/Translation_CN/ReadMe.md 6 | Global/ExampleReplacers/Slimefun/Translation_CN/Chat/Text_Contain.yml 7 | Global/ExampleReplacers/Slimefun/Translation_CN/Console/Regex.yml 8 | Global/ExampleReplacers/Slimefun/Translation_CN/Console/Text_Contain.yml 9 | Global/ExampleReplacers/Slimefun/Translation_CN/Entity/Cargo 货运.yml 10 | Global/ExampleReplacers/Slimefun/Translation_CN/Interfaces/Window-Title.yml 11 | Global/ExampleReplacers/Slimefun/Translation_CN/Interfaces/Machine Interfaces/Android 可编程式机器人.yml 12 | Global/ExampleReplacers/Slimefun/Translation_CN/Interfaces/Machine Interfaces/Auto-Crafter 自动合成器.yml 13 | Global/ExampleReplacers/Slimefun/Translation_CN/Interfaces/Machine Interfaces/Cargo 货运.yml 14 | Global/ExampleReplacers/Slimefun/Translation_CN/ItemStack/Regex.yml 15 | Global/ExampleReplacers/Slimefun/Translation_CN/ItemStack/Text_Contain.yml -------------------------------------------------------------------------------- /bukkit/src/main/resources/Languages/zh-CN/Replacers/ConsoleColor.yml: -------------------------------------------------------------------------------- 1 | # 这是一个设定控制台色彩的示例配置文件. 2 | # 如果您的服务端不在控制台内转换色彩, 您可以使用此配置作为替代. 3 | # 如果使用旧版 Paper/ Purpur 服务端, 可能不需要此配置. 4 | Options: 5 | Enabled: true 6 | Priority: 1 7 | Version: '2.17.4' 8 | Author: Rothes 9 | Filter: 10 | Listen-Types: 11 | - Console 12 | Match-Mode: Contain 13 | 14 | ### 使用 RGB 色彩 - 如果与您的控制台/终端兼容. 15 | Replaces: 16 | Common: 17 | - Original: '§0' 18 | Replacement: "\u001B[38;2;0;0;0m" # ANSI 转义码色彩 19 | - Original: '§1' 20 | Replacement: "\u001B[38;2;0;0;170m" 21 | - Original: '§2' 22 | Replacement: "\u001B[38;2;0;170;0m" 23 | - Original: '§3' 24 | Replacement: "\u001B[38;2;0;170;170m" 25 | - Original: '§4' 26 | Replacement: "\u001B[38;2;170;0;0m" 27 | - Original: '§5' 28 | Replacement: "\u001B[38;2;170;0;170m" 29 | - Original: '§6' 30 | Replacement: "\u001B[38;2;255;170;0m" 31 | - Original: '§7' 32 | Replacement: "\u001B[38;2;170;170;170m" 33 | - Original: '§8' 34 | Replacement: "\u001B[38;2;85;85;85m" 35 | - Original: '§9' 36 | Replacement: "\u001B[38;2;85;85;255m" 37 | - Original: '§a' 38 | Replacement: "\u001B[38;2;85;255;85m" 39 | - Original: '§b' 40 | Replacement: "\u001B[38;2;85;255;255m" 41 | - Original: '§c' 42 | Replacement: "\u001B[38;2;255;85;85m" 43 | - Original: '§d' 44 | Replacement: "\u001B[38;2;255;85;255m" 45 | - Original: '§e' 46 | Replacement: "\u001B[38;2;255;255;85m" 47 | - Original: '§f' 48 | Replacement: "\u001B[38;2;255;255;255m" 49 | - Original: '§k' 50 | Replacement: "\u001B[5m" 51 | - Original: '§l' 52 | Replacement: "\u001B[1m" 53 | # Replacement: "\u001B[21m" # 原版定义的样式 54 | - Original: '§m' 55 | Replacement: "\u001B[9m" 56 | - Original: '§n' 57 | Replacement: "\u001B[4m" 58 | - Original: '§o' 59 | Replacement: "\u001B[3m" 60 | - Original: '§r' 61 | Replacement: "\u001B[m" 62 | 63 | 64 | ### 下面是原版定义的色彩. 65 | 66 | # Replaces: 67 | # Common: 68 | # - Original: '§0' 69 | # Replacement: "\u001B[0;30m" # ANSI 转义码色彩 70 | # - Original: '§1' 71 | # Replacement: "\u001B[0;34m" 72 | # - Original: '§2' 73 | # Replacement: "\u001B[0;32m" 74 | # - Original: '§3' 75 | # Replacement: "\u001B[0;36m" 76 | # - Original: '§4' 77 | # Replacement: "\u001B[0;31m" 78 | # - Original: '§5' 79 | # Replacement: "\u001B[0;35m" 80 | # - Original: '§6' 81 | # Replacement: "\u001B[0;33m" 82 | # - Original: '§7' 83 | # Replacement: "\u001B[0;37m" 84 | # - Original: '§8' 85 | # Replacement: "\u001B[0;30;1m" 86 | # - Original: '§9' 87 | # Replacement: "\u001B[0;34;1m" 88 | # - Original: '§a' 89 | # Replacement: "\u001B[0;32;1m" 90 | # - Original: '§b' 91 | # Replacement: "\u001B[0;36;1m" 92 | # - Original: '§c' 93 | # Replacement: "\u001B[0;31;1m" 94 | # - Original: '§d' 95 | # Replacement: "\u001B[0;35;1m" 96 | # - Original: '§e' 97 | # Replacement: "\u001B[0;33;1m" 98 | # - Original: '§f' 99 | # Replacement: "\u001B[0;37;1m" 100 | # - Original: '§k' 101 | # Replacement: "\u001B[5m" 102 | # - Original: '§l' 103 | # Replacement: "\u001B[21m" 104 | # - Original: '§m' 105 | # Replacement: "\u001B[9m" 106 | # - Original: '§n' 107 | # Replacement: "\u001B[4m" 108 | # - Original: '§o' 109 | # Replacement: "\u001B[3m" 110 | # - Original: '§r' 111 | # Replacement: "\u001B[m" -------------------------------------------------------------------------------- /bukkit/src/main/resources/metadata.yml: -------------------------------------------------------------------------------- 1 | version-channel: @versionChannel@ 2 | version-id: @versionId@ -------------------------------------------------------------------------------- /bukkit/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: ProtocolStringReplacer 2 | version: @versionName@ 3 | main: io.github.rothes.protocolstringreplacer.ProtocolStringReplacer 4 | author: Rothes 5 | api-version: 1.13 6 | folia-supported: true 7 | softdepend: 8 | - ProtocolLib 9 | - PlaceholderAPI 10 | commands: 11 | protocolstringreplacer: 12 | aliases: [psr] 13 | description: ProtocolStringReplacer commands. 14 | permission: 'protocolstringreplacer.command' 15 | permissions: 16 | 'protocolstringreplacer.command': 17 | description: ProtocolStringReplacer commands global permission. 18 | default: true 19 | protocolstringreplacer.command.about: 20 | description: See plugin info. 21 | default: true 22 | protocolstringreplacer.command.capture: 23 | description: allow you to capture the packet contents. 24 | default: op 25 | protocolstringreplacer.command.edit: 26 | description: allow you to edit the replacer configs. 27 | default: op 28 | protocolstringreplacer.command.parse: 29 | description: allow you to parse a String. 30 | default: op 31 | protocolstringreplacer.command.reload: 32 | description: allow you to reload the configs. 33 | default: op 34 | protocolstringreplacer.feature.usermetacache: 35 | description: save the itemmeta when editing, and restore the original one when the player in creative interacts it. 36 | default: op 37 | protocolstringreplacer.feature.usermetacache.noncreative: 38 | description: with protocolstringreplacer.feature.usermetacache, allow to restore the original one when the player in other gamemodes interacts it. 39 | default: false 40 | protocolstringreplacer.feature.parsepapi: 41 | description: Parse placeholders from PlaceholderAPI for player. Set to false will prevent any papi parse. 42 | default: true 43 | protocolstringreplacer.updater.notify: 44 | description: allow you to receive updater info. 45 | default: op 46 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | versionName = 3.1.2 2 | versionChannel = Stable 3 | versionId = 126 4 | targetMinecraftVersion = 1.21.4 -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rothes/ProtocolStringReplacer/8ede896025ee89eff5ecc263ae836e34cc6a8da7/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /jitpack.yml: -------------------------------------------------------------------------------- 1 | before_install: 2 | - wget https://github.com/sormuras/bach/raw/master/install-jdk.sh 3 | - source ./install-jdk.sh --feature 17 --license GPL 4 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "ProtocolStringReplacer" 2 | include("bukkit") 3 | include("bukkit:nms") 4 | include("bukkit:nms:common") 5 | include("bukkit:nms:common:generic_v1_19_3") 6 | include("bukkit:nms:common:generic_v1_21") 7 | include("bukkit:nms:common:generic_v1_21_3") 8 | include("bukkit:nms:v1_19_1") 9 | include("bukkit:nms:v1_19_2") 10 | include("bukkit:nms:v1_19_3") 11 | include("bukkit:nms:v1_19_4") 12 | include("bukkit:nms:v1_20_1") 13 | include("bukkit:nms:v1_20_2") 14 | include("bukkit:nms:v1_20_4") 15 | include("bukkit:nms:v1_20_6") 16 | include("bukkit:nms:v1_21_1") 17 | include("bukkit:nms:v1_21_3") 18 | include("bukkit:nms:v1_21_4") 19 | include("bukkit:nms:v1_21_5") 20 | findProject(":bukkit:nms:v1_21_5")?.name = "v1_21_5" 21 | --------------------------------------------------------------------------------