├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── PULL_REQUEST_TEMPLATE
│ └── documentation.md
└── workflows
│ ├── discord_publish.yml
│ └── publish.yml
├── .gitignore
├── HEADER.txt
├── LICENSE.txt
├── README.md
├── build.gradle
├── docs
├── _config.yml
├── chatBox
│ ├── assets
│ │ └── images
│ │ │ ├── ACC-ChatBox_Icon.png
│ │ │ ├── calculatorMASS.png
│ │ │ ├── colorCode.png
│ │ │ ├── colorShowcaseMASS.png
│ │ │ ├── shortcutMASS.png
│ │ │ └── spellCheck.png
│ └── chatBox.md
├── chatHUD
│ ├── ChatHUD.md
│ └── assets
│ │ └── images
│ │ ├── ACC-ChatHUD_Icon.png
│ │ ├── ChatButtons.png
│ │ ├── ChatColoring.png
│ │ ├── ChatHUDTab.png
│ │ ├── ChatHeadsDisplay.png
│ │ ├── ChatHxW.png
│ │ ├── ChatLineStyle.png
│ │ ├── ChatPaddingUI.png
│ │ ├── ChatRightSideTabBtn.png
│ │ ├── ChatStrippedMsg.png
│ │ ├── ChatTabsTab.png
│ │ ├── ChatUnreadMsg.png
│ │ └── RightClickContextMenu.png
├── chatLog
│ ├── assets
│ │ └── images
│ │ │ ├── ACC-ChatLog_Icon.png
│ │ │ ├── LogTAB.png
│ │ │ ├── logGUI.png
│ │ │ └── logView.png
│ └── chatLog.md
├── commonKnowledge
│ ├── commonKnowledgeCOLOR.md
│ ├── commonKnowledgeMATH.md
│ ├── commonKnowledgeREGEX.md
│ └── index.md
├── core
│ ├── core_configuration.md
│ └── index.md
├── filters
│ ├── common_filters.md
│ ├── images
│ │ └── filterconfig.png
│ ├── index.md
│ └── tutorial.md
├── index.md
└── modules
│ ├── assets
│ └── images
│ │ ├── ACC-ChatBox_Icon.png
│ │ ├── ACC-ChatFilters_Icon.png
│ │ ├── ACC-ChatHUD_Icon.png
│ │ ├── ACC-ChatLog_Icon.png
│ │ ├── ACC-ChatMacros_Icon.png
│ │ └── AdvancedChatCore_Icon.png
│ └── modulesOverview.md
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── icon - original.png
├── jitpack.yml
├── settings.gradle
└── src
└── main
├── java
└── io
│ └── github
│ └── darkkronicle
│ └── advancedchatcore
│ ├── AdvancedChatCore.java
│ ├── InitHandler.java
│ ├── Module.java
│ ├── ModuleHandler.java
│ ├── chat
│ ├── AdvancedChatScreen.java
│ ├── AdvancedSleepingChatScreen.java
│ ├── AdvancedTextField.java
│ ├── ChatHistory.java
│ ├── ChatHistoryProcessor.java
│ ├── ChatMessage.java
│ ├── ChatScreenSectionHolder.java
│ ├── DefaultChatSuggestor.java
│ ├── MessageDispatcher.java
│ ├── MessageOwner.java
│ └── MessageSender.java
│ ├── config
│ ├── ConfigStorage.java
│ ├── SaveableConfig.java
│ ├── gui
│ │ ├── GuiConfig.java
│ │ ├── GuiConfigHandler.java
│ │ ├── ModMenuImpl.java
│ │ ├── OnOffListListener.java
│ │ ├── TabSupplier.java
│ │ └── widgets
│ │ │ ├── WidgetColor.java
│ │ │ ├── WidgetIntBox.java
│ │ │ ├── WidgetLabelHoverable.java
│ │ │ ├── WidgetListRegistryOption.java
│ │ │ ├── WidgetRegistryOptionEntry.java
│ │ │ └── WidgetToggle.java
│ └── options
│ │ └── ConfigColor.java
│ ├── finder
│ ├── CustomFinder.java
│ ├── LiteralFinder.java
│ ├── PatternFinder.java
│ ├── RegexFinder.java
│ ├── UpperLowerFinder.java
│ └── custom
│ │ └── ProfanityFinder.java
│ ├── gui
│ ├── CleanButton.java
│ ├── ConfigGuiListBase.java
│ ├── ContextMenu.java
│ ├── CoreGuiListBase.java
│ ├── IconButton.java
│ ├── WidgetConfigList.java
│ ├── WidgetConfigListEntry.java
│ └── buttons
│ │ ├── BackButtonListener.java
│ │ ├── Buttons.java
│ │ ├── ConfigTabsButtonListener.java
│ │ └── NamedSimpleButton.java
│ ├── hotkeys
│ └── InputHandler.java
│ ├── interfaces
│ ├── AdvancedChatScreenSection.java
│ ├── ConfigRegistryOption.java
│ ├── IChatMessageProcessor.java
│ ├── IClosable.java
│ ├── IFinder.java
│ ├── IJsonApplier.java
│ ├── IJsonSave.java
│ ├── IMatchProcessor.java
│ ├── IMessageFilter.java
│ ├── IMessageProcessor.java
│ ├── IScreenSupplier.java
│ ├── IStringFilter.java
│ ├── RegistryOption.java
│ └── Translatable.java
│ ├── konstruct
│ ├── AdvancedChatKonstruct.java
│ └── StringMatchObject.java
│ ├── mixin
│ ├── MixinChatHud.java
│ ├── MixinChatHudInvoker.java
│ ├── MixinChatScreen.java
│ ├── MixinClientPlayerEntity.java
│ ├── MixinKeyboard.java
│ ├── MixinMessageIndicator.java
│ ├── MixinMinecraftClient.java
│ └── MixinSleepingChatScreen.java
│ └── util
│ ├── AbstractRegistry.java
│ ├── Color.java
│ ├── ColorUtil.java
│ ├── Colors.java
│ ├── EasingMethod.java
│ ├── FindPair.java
│ ├── FindType.java
│ ├── LimitedInteger.java
│ ├── ProfanityUtil.java
│ ├── RawText.java
│ ├── RowList.java
│ ├── SearchResult.java
│ ├── SearchUtils.java
│ ├── StringInsert.java
│ ├── StringMatch.java
│ ├── StyleFormatter.java
│ ├── SyncTaskQueue.java
│ ├── TextBuilder.java
│ ├── TextUtil.java
│ └── TomlUtil.java
└── resources
├── advancedchatcore.mixins.json
├── assets
└── advancedchatcore
│ ├── icon.png
│ ├── lang
│ ├── en_us.json
│ └── zh_cn.json
│ └── textures
│ └── gui
│ └── settings.png
├── colors.toml
└── fabric.mod.json
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: "[BUG]"
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **Minecraft Info**
14 | Minecraft information:
15 | - AdvancedChat version [e.g. AdvancedChat-2.0.0-beta]
16 |
17 | **To Reproduce**
18 | Steps to reproduce the behavior:
19 | 1. Go to '...'
20 | 2. Click on '....'
21 | 3. Scroll down to '....'
22 | 4. See error
23 |
24 | **Expected behavior**
25 | A clear and concise description of what you expected to happen.
26 |
27 | **Screenshots**
28 | If applicable, add screenshots to help explain your problem.
29 |
30 | **Additional context**
31 | Add any other context about the problem here. This could be a mods list, server, etc.
32 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: "[FEATURE]"
5 | labels: feature
6 | assignees: ''
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.
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Additional context**
17 | Add any other context or screenshots about the feature request here.
18 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE/documentation.md:
--------------------------------------------------------------------------------
1 | ## Key Topics
2 |
3 | What key topics did you update/add?
--------------------------------------------------------------------------------
/.github/workflows/discord_publish.yml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | branches:
4 | - main
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: actions/checkout@main
10 | - name: Set up JDK 17
11 | uses: actions/setup-java@v1
12 | with:
13 | java-version: 17
14 | - name: Upload to Discord
15 | run: ./gradlew discord --stacktrace
16 | if: |
17 | !contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.pull_request.title, '[ci skip]')
18 | env:
19 | discord_webhook: ${{ secrets.DISCORD_WEBHOOK }}
20 | action_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
21 | - name: Capture build artifacts
22 | uses: actions/upload-artifact@v2
23 | with:
24 | name: Artifacts
25 | path: build/libs/
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | on:
2 | workflow_dispatch:
3 | inputs:
4 | previousVersion:
5 | description: 'Previous Version (Do not include v prefix, must be same as the last version tag! Example: 1.4.1)'
6 | required: true
7 | version:
8 | description: 'Version (Do not include v prefix! Example: 1.4.2)'
9 | required: true
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@main
15 | - name: Fetch tags
16 | run: git fetch --tags
17 | - name: Set up JDK 17
18 | uses: actions/setup-java@v1
19 | with:
20 | java-version: 17
21 | - name: Upload to websites
22 | run: ./gradlew publishThirdParty --stacktrace -PlastTag="v${{ github.event.inputs.previousVersion }}" -PcurrentTag="v${{ github.event.inputs.version }}"
23 | if: |
24 | !contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.pull_request.title, '[ci skip]')
25 | env:
26 | modrinth_token: ${{ secrets.MODRINTH_TOKEN }}
27 | curseforge_token: ${{ secrets.CURSEFORGE_TOKEN }}
28 | github_token: ${{ secrets.GH_API_KEY }}
29 | discord_release_webhook: ${{ secrets.DISCORD_RELEASE_WEBHOOK }}
30 | - name: Capture build artifacts
31 | uses: actions/upload-artifact@v2
32 | with:
33 | name: Artifacts
34 | path: build/libs/
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | *.iml
3 | *.ipr
4 | *.iws
5 | lib/
6 | run/
7 | out/
8 | bin/
9 | build/
10 | .gradle/
11 | classes/
12 | lombok.config
13 | extra.properties
14 | swear_words.csv
--------------------------------------------------------------------------------
/HEADER.txt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) $YEAR DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AdvancedChatCore
2 |
3 | This is the base mod of all AdvancedChat modules and features. This mod provides the necessary foundation and framework for AdvancedChat mod's to work.
4 |
5 | This mod primarily adds internal features used by other modules, as well as the ability to display the time that a message was sent.
6 |
7 | ## Dependencies
8 | [MaLiLib](https://www.curseforge.com/minecraft/mc-mods/malilib) and [Fabric API](https://www.curseforge.com/minecraft/mc-mods/fabric-api/) are **required** for this mod to run
9 |
10 | [Mod Menu](https://www.curseforge.com/minecraft/mc-mods/modmenu) is strongly recommended, as it allows you to easily edit the config
11 |
12 |
13 | ## Configuration
14 |
15 | You can either manually edit the config file, located in `~.minecraft/config/advancedchat/advancedchatcore.json`, or you can open the configuration screen using mod menu (see **Dependencies**)
16 |
17 |
18 | ## About AdvancedChat Modules
19 |
20 | AdvancedChat Modules splits the features of [AdvancedChat](https://www.curseforge.com/minecraft/mc-mods/advancedchat/) into several different mods, all of which depend on AdvancedChatCore. This simplifies development, and also allows for the user to pick-and-choose what features of AdvancedChat they want or don't want. The main AdvancedChat mod will eventually serve as a bundle of all AdvancedChat modules. [Full list](https://github.com/DarkKronicle/AdvancedChatCore/wiki/Modules-List)
21 |
22 | ## Developers
23 |
24 | To use AdvancedChatCore within your own mod you can use [jitpack](https://jitpack.io/) with maven to download and implement it.
25 |
26 | ```
27 | allprojects {
28 | repositories {
29 | ...
30 | maven { url 'https://jitpack.io' }
31 | }
32 | }
33 | ```
34 |
35 | ```
36 | dependencies {
37 | modImplementation 'com.github.DarkKronicle:AdvancedChatCore:VERSION'
38 | }
39 | ```
40 |
41 | To have the core reference the mod as a module, int `fabric.mod.json` in `custom` put `"acmodule: true"`
42 |
43 | ```JSON
44 | {
45 | ...
46 | "custom": {
47 | "acmodule": true
48 | }
49 | }
50 | ```
51 |
52 | Reference the [example mod](https://github.com/DarkKronicle/AdvancedChatModuleTemplate) for individual use cases.
53 |
54 | ## Development
55 |
56 | To develop, all dependencies should automatically be processed through gradle.
57 |
58 | ## Credits n' more
59 |
60 | Code & Mastermind: DarkKronicle
61 |
62 | Update to 1.16.3: lmichaelis
63 |
64 | Logo & Proofreading: Chronos22
65 |
66 | Libraries:
67 | - [MathParser](http://mathparser.org/)
68 | - [OwO](https://github.com/maowcraft/owo)
69 |
70 | For more help join the [Discord](https://discord.gg/WnaE3uZxDA)
71 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'fabric-loom' version '1.0-SNAPSHOT'
3 | id 'maven-publish'
4 | id "io.freefair.lombok" version "6.0.0-m2"
5 | }
6 |
7 | apply from: 'https://raw.githubusercontent.com/DarkKronicle/GradleScripts/main/gradle/publish.gradle'
8 |
9 | sourceCompatibility = JavaVersion.VERSION_17
10 | targetCompatibility = JavaVersion.VERSION_17
11 |
12 | archivesBaseName = project.archives_base_name
13 | version = "${project.minecraft_version}-${project.mod_version}"
14 | group = project.maven_group
15 |
16 | Properties additionalProperties = new Properties()
17 | if (file("extra.properties").exists()) {
18 | additionalProperties.load(file("extra.properties").newReader())
19 | }
20 |
21 | repositories {
22 | mavenCentral()
23 | maven { url 'https://masa.dy.fi/maven' }
24 | maven { url 'https://maven.terraformersmc.com/releases/' }
25 | maven { url 'https://jitpack.io' }
26 | maven { url 'https://maven.wispforest.io' }
27 | }
28 |
29 | dependencies {
30 | minecraft "com.mojang:minecraft:${project.minecraft_version}"
31 | mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
32 | modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
33 | modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
34 | modImplementation "fi.dy.masa.malilib:malilib-fabric-1.20.2:${project.malilib_version}"
35 | modCompileOnly "com.terraformersmc:modmenu:${project.modmenu_version}"
36 |
37 | implementation "com.github.DarkKronicle.Konstruct:addons:${project.konstruct_version}"
38 | implementation "com.github.DarkKronicle.Konstruct:core:${project.konstruct_version}"
39 |
40 | implementation 'com.electronwill.night-config:toml:3.6.5'
41 | // Transitive
42 | include 'com.electronwill.night-config:toml:3.6.5'
43 | include 'com.electronwill.night-config:core:3.6.5'
44 |
45 |
46 | include "com.github.DarkKronicle.Konstruct:addons:${project.konstruct_version}"
47 | include "com.github.DarkKronicle.Konstruct:core:${project.konstruct_version}"
48 |
49 | implementation "org.mariuszgromada.math:MathParser.org-mXparser:${project.mxparser_version}"
50 | include "org.mariuszgromada.math:MathParser.org-mXparser:${project.mxparser_version}"
51 |
52 | implementation "io.github.maowimpl:owo:${project.owo_version}"
53 | include "io.github.maowimpl:owo:${project.owo_version}"
54 |
55 | implementation 'org.apache.commons:commons-csv:1.8'
56 | include 'org.apache.commons:commons-csv:1.8'
57 |
58 | }
59 |
60 | processResources {
61 | inputs.property "version", project.version
62 |
63 | filesMatching("fabric.mod.json") {
64 | expand "version": project.version
65 | }
66 | }
67 |
68 | tasks.withType(JavaCompile).configureEach {
69 | it.options.encoding = "UTF-8"
70 | it.options.release = 17
71 | }
72 |
73 | task sourcesJar(type: Jar, dependsOn: classes) {
74 | classifier = "sources"
75 | from sourceSets.main.allSource
76 | }
77 |
78 | jar {
79 | from "LICENSE.txt"
80 | }
81 |
82 | tasks.register('downloadExtra') {
83 | def f = new File('./src/main/resources/swear_words.csv')
84 | if (!f.exists()) {
85 | new URL('https://raw.githubusercontent.com/surge-ai/profanity/main/profanity_en.csv').withInputStream{ i -> f.withOutputStream{ it << i }}
86 | }
87 | }
88 |
89 | assemble {
90 | dependsOn 'downloadExtra'
91 | }
92 |
93 | // configure the maven publication
94 | publishing {
95 | publications {
96 | mavenJava(MavenPublication) {
97 | // add all the jars that should be included when publishing to maven
98 | artifact(remapJar) {
99 | builtBy remapJar
100 | }
101 | artifact(sourcesJar) {
102 | builtBy remapSourcesJar
103 | }
104 | }
105 | }
106 |
107 | // select the repositories you want to publish to
108 | repositories {
109 | // uncomment to publish to the local maven
110 | // mavenLocal()
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/docs/_config.yml:
--------------------------------------------------------------------------------
1 | remote_theme: pmarsceill/just-the-docs
2 | color_scheme: dark
3 | title: AdvancedChat
4 | description: Documentation for AdvancedChat
5 | aux_links:
6 | "AdvancedChat on GitHub":
7 | - "https://github.com/DarkKronicle/AdvancedChatCore"
8 | gh_edit_link: true
9 | gh_edit_link_text: "Edit this page on GitHub"
10 | gh_edit_repository: "https://github.com/DarkKronicle/AdvancedChatCore"
11 | gh_edit_branch: "main"
12 | gh_edit_source: docs
13 | gh_edit_view_mode: "tree"
14 |
15 | search_enabled: true
16 | search:
17 | heading_level: 2
18 | previews: 2
19 | preview_words_before: 5
20 | preview_words_after: 5
21 | tokenizer_separator: /[\s\-/]+/
22 | rel_url: true
23 | button: true
--------------------------------------------------------------------------------
/docs/chatBox/assets/images/ACC-ChatBox_Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatBox/assets/images/ACC-ChatBox_Icon.png
--------------------------------------------------------------------------------
/docs/chatBox/assets/images/calculatorMASS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatBox/assets/images/calculatorMASS.png
--------------------------------------------------------------------------------
/docs/chatBox/assets/images/colorCode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatBox/assets/images/colorCode.png
--------------------------------------------------------------------------------
/docs/chatBox/assets/images/colorShowcaseMASS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatBox/assets/images/colorShowcaseMASS.png
--------------------------------------------------------------------------------
/docs/chatBox/assets/images/shortcutMASS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatBox/assets/images/shortcutMASS.png
--------------------------------------------------------------------------------
/docs/chatBox/assets/images/spellCheck.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatBox/assets/images/spellCheck.png
--------------------------------------------------------------------------------
/docs/chatHUD/assets/images/ACC-ChatHUD_Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatHUD/assets/images/ACC-ChatHUD_Icon.png
--------------------------------------------------------------------------------
/docs/chatHUD/assets/images/ChatButtons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatHUD/assets/images/ChatButtons.png
--------------------------------------------------------------------------------
/docs/chatHUD/assets/images/ChatColoring.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatHUD/assets/images/ChatColoring.png
--------------------------------------------------------------------------------
/docs/chatHUD/assets/images/ChatHUDTab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatHUD/assets/images/ChatHUDTab.png
--------------------------------------------------------------------------------
/docs/chatHUD/assets/images/ChatHeadsDisplay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatHUD/assets/images/ChatHeadsDisplay.png
--------------------------------------------------------------------------------
/docs/chatHUD/assets/images/ChatHxW.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatHUD/assets/images/ChatHxW.png
--------------------------------------------------------------------------------
/docs/chatHUD/assets/images/ChatLineStyle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatHUD/assets/images/ChatLineStyle.png
--------------------------------------------------------------------------------
/docs/chatHUD/assets/images/ChatPaddingUI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatHUD/assets/images/ChatPaddingUI.png
--------------------------------------------------------------------------------
/docs/chatHUD/assets/images/ChatRightSideTabBtn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatHUD/assets/images/ChatRightSideTabBtn.png
--------------------------------------------------------------------------------
/docs/chatHUD/assets/images/ChatStrippedMsg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatHUD/assets/images/ChatStrippedMsg.png
--------------------------------------------------------------------------------
/docs/chatHUD/assets/images/ChatTabsTab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatHUD/assets/images/ChatTabsTab.png
--------------------------------------------------------------------------------
/docs/chatHUD/assets/images/ChatUnreadMsg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatHUD/assets/images/ChatUnreadMsg.png
--------------------------------------------------------------------------------
/docs/chatHUD/assets/images/RightClickContextMenu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatHUD/assets/images/RightClickContextMenu.png
--------------------------------------------------------------------------------
/docs/chatLog/assets/images/ACC-ChatLog_Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatLog/assets/images/ACC-ChatLog_Icon.png
--------------------------------------------------------------------------------
/docs/chatLog/assets/images/LogTAB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatLog/assets/images/LogTAB.png
--------------------------------------------------------------------------------
/docs/chatLog/assets/images/logGUI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatLog/assets/images/logGUI.png
--------------------------------------------------------------------------------
/docs/chatLog/assets/images/logView.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/chatLog/assets/images/logView.png
--------------------------------------------------------------------------------
/docs/chatLog/chatLog.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: Log
4 | nav_order: 5
5 | has_children: false
6 | ---
7 |
8 | # AdvancedChat ChatLog Overview
9 |
10 |
11 | Table of contents
12 |
13 | {: .text-delta }
14 | 1. TOC
15 | {:toc}
16 |
17 |
18 | ---
19 | 
20 | ### AdvancedChatLog
21 | - View, store and sort through mass amounts of previous messages.
22 |
23 | ---
24 | ### Overview
25 | {:toc}
26 | The information on this page is for the features of the **ChatLog** module of AdvancedChat.
27 | Once the mod is installed a **Chat Log** tab will be added to the AdvancedChat Config Menu, as well as a button in the chat GUI that looks like 3 stacked bars.
28 |
29 | **A bit of information**
30 | This mod allows you to not only store messages typed in game to a local file, but also allows the ability to leave the game either to the menu or to the desktop, and come back to your world with your previously sent messages.
31 | You can configure how many lines of chat are stored, as well as how many of those stored lines will be saved in order to be loaded the next time you play. Plus you can also search those saved lines in game via a chat GUI button.
32 |
33 | ---
34 | ### Available Tabs and Settings
35 | {:toc}
36 | The following section will go over all the available tabs and settings in each tab that you can modify. This information can also be found [here](https://darkkronicle.github.io/AdvancedChatCore/modules/modulesOverview.html), in the Modules Overview section. As well as overviews for all other modules available as of January 31st 2022.
37 |
38 | **In Game Buttons**
39 | - The Chatlog module adds an additional button to the right of the UI that looks like 3 stacked bars once the chat is opened. That is used to view and search chat. The search options use the **Filter Type** button that cycles the options;
40 | - **Literal**, exact match.
41 | - **Upper-Lower**, literal but not case-sensitive.
42 | - **RegEx**, Parses the strings as Regular Expression.
43 | - **Custom**, Allows for custom search parameters.
44 |
45 | 
46 |
47 | ***Chat Log Tab***
48 | - Stored Lines - This value dictates how many lines of information are saved to the log file. Fair warning, large numbers may result in out of memory errors.
49 | - Saved - Lines - The amount of stored lines that are loaded when the game starts.
50 | - Clean Saved Lines - When true this will make it so that the log doesn't save things like mouse clicks and movements to help reduce the logs file size.
51 |
52 | 
53 |
54 | **Output File**
55 | - It should be noted that the location of the log output file is in your .minecraft folder, either in the directory in the 'chatlogs' folder or in your profiles 'chatlogs' folder. (*~/.minecraft/chatlogs/ -OR- ~/.minecraft/MC_Profile_Name/chatlogs/*)
56 |
57 | 
58 |
59 |
60 |
--------------------------------------------------------------------------------
/docs/commonKnowledge/commonKnowledgeCOLOR.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: Color
4 | nav_order: 2
5 | parent: Common Knowledge
6 | ---
7 |
8 | # Common Knowledge - Color
9 |
10 |
11 | Table of contents
12 |
13 | {: .text-delta }
14 | 1. TOC
15 | {:toc}
16 |
17 |
18 | ---
19 | ## Color in AdvancedChat
20 | {:toc}
21 | AdvancedChat Project, the name given to encompass all of the AdvancedChat mods(Core, HUD, Box, Log, and Filters), has the option to change the color of certain things. Anytime you encounter the option to change the color of a setting it will use HEX values. Some will only use the 6 character format and others may use the 8 character format. The difference between these two is the alpha channel aka the opacity of your color.
22 |
23 | A normal HEX code looks something like this #FF0000, which is bright red. The FF indicates the hue of the the RGB channels which are represented by the four zeros. But when using an 8 character HEX suddenly you unlock an additional two characters at the front of the string that represent opacity also called transparency.
24 |
25 | The proper format is #AARRGGBB where the A is alpha channels, R is red, G is green and B is blue. Which is why HEX+Alpha is sometimes referred to ARGB but has fallen out of style a bit due to ARGB referring to Addressable RGB lights.
26 |
27 | So knowing all that; #CCFF0000 would be an 80% opacity to our bright red mentioned earlier making it a slightly lighter red. As 100% opacity would be our default value of bright red.
28 |
29 | ---
30 | ## Resources
31 | {:toc}
32 | Here is a dumb of useful links to help get you on your way;
33 | - Learning
34 | - Incase you would like to learn more [here](https://learn.sparkfun.com/tutorials/hexadecimal/all) is a link to an article on HEX itself
35 | - As well as [this](https://www.codeconquest.com/hex-color-codes/) one for HEX color specifically.
36 | - Coloring
37 | - Color pallet [picker](https://coolors.co/c6c5b9-62929e-4a6d7c-393a10-475657) randomizer that has a fair few customization options. Just load the page and if you don't like the choices hit SPACE.
38 | - Have a specific color you like in an image? [This](https://imagecolorpicker.com/en) site allows you to figure out what it is.
39 | - Looking for something popular? We got you covered with [this](https://www.color-hex.com/popular-colors.php) site.
40 | - What's that you want a palette and to be popular? Well alright [here](https://www.color-hex.com/color-palettes/popular.php) you go.
41 | - If you don't want to google around for a decent HEX color picker [here](https://htmlcolorcodes.com/color-picker/) is my go to that offers HSL, CYMYK, RGB, and our needed HEX.
42 | It also has some information on things like color theory and shading. Pick your color and then just use the section below to add opacity if you'd like.
43 |
44 | ---
45 | ## HEX Opacity Table
46 | {:toc}
47 | Here is a complete table from 0% opacity all the way up to 100% opacity at single percent increments...It should be noted that you wont see much of a difference from say 1% to 3%. You more than likely will see the best result when working at 5% increments. I included 1% increments incase you want to dial it in after getting in the ball park of where youd like it. Remember! The **closer** to 100% the value is the **less** transparent it is.
48 |
49 |
50 | Click here to show the Opacity Table
51 |
52 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
53 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
54 | |Opacity% | 0% | 1% | 2% | 3% | 4% | 5% | 6% | 7% | 8% | 9% | 10% | 11% | 12% | 13% | 14% | 15% | 16% | 17% | 18% | 19% | 20% | 21% | 22% | 23% | 24% | 25% | 26% | 27% | 28% | 29% | 30% | 31% | 32% | 33% | 34% | 35% | 36% | 37% | 38% | 39% | 40% | 41% | 42% | 43% | 44% | 45% | 46% | 47% | 48% | 49% | 50% | 51% | 52% | 53% | 54% | 55% | 56% | 57% | 58% | 59% | 60% | 61% | 62% | 63% | 64% | 65% | 66% | 67% | 68% | 69% | 70% | 71% | 72% | 73% | 74% | 75% | 76% | 77% | 78% | 79% | 80% | 81% | 82% | 83% | 84% | 85% | 86% | 87% | 88% | 89% | 90% | 91% | 92% | 93% | 94% | 95% | 96% | 97% | 98% | 99% | 100% |
55 | |Hex# | 00 | 02 | 05 | 07 | 0C | 0C | 0F | 11 | 14 | 16 | 19 | 1C | 1E | 21 | 23 | 26 | 28 | 2B | 2D | 30 | 33 | 35 | 38 | 3A | 3D | 3F | 42 | 44 | 47 | 49 | 4C | 4F | 51 | 54 | 56 | 59 | 5B | 5E | 60 | 63 | 66 | 68 | 6B | 6D | 70 | 72 | 75 | 77 | 7A | 7C | 7F | 82 | 84 | 87 | 89 | 8C | 8E | 91 | 93 | 96 | 99 | 9B | 9E | A0 | A3 | A5 | A8 | AA | AD | AF | B2 | B5 | B7 | BA | BC | 8F | C1 | C4 | C6 | C9 | CC | CE | D1 | D3 | D6 | D8 | DB | DD | E0 | E2 | E5 | E8 | EA | ED | EF | F2 | F4 | F7 | F9 | FC | FF |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/docs/commonKnowledge/commonKnowledgeMATH.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: Math
4 | nav_order: 1
5 | parent: Common Knowledge
6 | ---
7 |
8 | # Common Knowledge - Math
9 |
10 |
11 | Table of contents
12 |
13 | {: .text-delta }
14 | 1. TOC
15 | {:toc}
16 |
17 |
18 | ---
19 | ## Calculator
20 | {:toc}
21 | AdvancedChat [ChatBox]() has the available option to use an in game calculator. It uses [mXparser](https://mathparser.org/) to do its business. (*Those who are more technically inclined should probably just explore the link.*)
22 |
23 | - For those needing a basic run down.
24 | - mXparser is basically just a library of information that can be used by a programmer to create code that can dip its toes into the library for any information it may need.
25 |
26 | In this case we are using it in Minecraft as a calculator. Simply put you can put into chat something simple like `1+2` or something as complex as `int( sqrt(1-x^2), x, -1, 1)`. Though for the average user what you need to know is that you don't need to worry about parentheses for longer equations.
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/docs/commonKnowledge/commonKnowledgeREGEX.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: RegEx
4 | nav_order: 3
5 | parent: Common Knowledge
6 | ---
7 |
8 | # RegEx
9 |
10 | AdvancedChat provides a lot of support for Regular Expressions (RegEx) to allow for more complex matching, filtering, and searching.
11 |
12 | ## Overview
13 |
14 | Regular Expressions are a tool to find matches within a string. They can come off as very complex, confusing, and hard to learn. 9/10 times a simple regular expression will be easy to create and easy to understand.
15 |
16 | - RegEx parser (HIGHLY RECOMMEND) - https://regex101.com/
17 | - Interactive Tutorial - https://regexone.com/
18 | - Visualizer - https://extendsclass.com/regex-tester.html#java
19 | - Cheat Sheet - https://cheatography.com/davechild/cheat-sheets/regular-expressions/
20 | - Basics Video - https://www.youtube.com/watch?v=sXQxhojSdZM
21 |
22 | ## AdvancedChat Specific RegEx
23 |
24 | AdvancedChat (in specific situations) allows for matching for colors/links/other text properties within RegEx. This is supported in filters and is rolling out to other modules.
25 |
26 | How do you do it? RegEx group names.
27 |
28 | You can create a RegEx group name by using the syntax `(?)`. An example is `(?.)`. It creates a group named `eachCharacter that is applied to every character that it matches.
29 |
30 | AdvancedChat takes these names and checks to see if any start with `adv`. If they do you can apply filtering conditions making it so that AdvancedChat won't match unless the condition is met. This is a second layer, so the RegEx won't be reprocessed so `or` conditions can be a bit confusing.
31 |
32 | ## Color Example
33 |
34 | You can use any built in Minecraft color `0-9`, `a-f` to compare to as well as `o`, `l`, `m`, `n`. Let's say I only want to match to dark blue `DarkKronicle`. I would use the regex `(?DarkKronicle)`. The `adv0` specifies function 0 for AdvancedChat. Any character specified after that functions as an `or` condition. This one is only `9` which is the color code for dark blue. For example, if I did `9al` it would match dark blue, green, or bold. If an `and` condition is wanted there can be nested groups.
35 |
36 | Custom types:
37 |
38 | - `z` - A clickable link
39 | - `x` - Copy to clipboard
40 | - `y` - Open file
41 | - `w` - Run command
42 | - `v` - Suggest command
43 | - `h` - Hover text
44 |
--------------------------------------------------------------------------------
/docs/commonKnowledge/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: Common Knowledge
4 | nav_order: 2
5 | has_children: true
6 | ---
7 |
8 | ---
9 | # Common Knowledge
10 |
11 | These series of pages are dedicated to the aspects of the AdvancedChat project that to some are common knowledge or should be known to those using the mod(s) to some degree.
12 |
13 |
14 |
15 | Table of contents
16 |
17 | {: .text-delta }
18 | 1. TOC
19 | {:toc}
20 |
--------------------------------------------------------------------------------
/docs/core/core_configuration.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: Core Configuration
4 | parent: AdvancedChatCore
5 | nav_order: 0
6 | ---
7 |
8 | # AdvancedChatCore
--------------------------------------------------------------------------------
/docs/core/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: Core
4 | nav_order: 1
5 | has_children: true
6 | ---
7 |
8 | # AdvancedChatCore
9 |
10 |
11 |
12 | Table of contents
13 |
14 | {: .text-delta }
15 | 1. TOC
16 | {:toc}
17 |
--------------------------------------------------------------------------------
/docs/filters/common_filters.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: Common Filters
4 | nav_order: 1
5 | parent: AdvancedChatFilters
6 | ---
7 |
8 | # Common Filters
9 |
10 | To import these go to filters then click import and paste in the JSON data from this page.
11 |
12 | ## Underline Links
13 |
14 | Underline links in chat
15 |
16 | ```
17 | {"name":"Underline Links","active":true,"stripColors":true,"findString":"(?\u003cadv0z\u003e.)","findType":"regex","replaceType":"onlymatch","replaceTo":"\u0026n$1\u0026r","replaceTextColor":false,"textColor":"#FFFFFFFF","replaceBackgroundColor":false,"backgroundColor":"#FFFFFFFF","processors":{"forward":{"active":true},"actionbar":{"active":false},"sound":{"active":false,"notifySound":"none","soundPitch":1.0,"soundVolume":1.0},"narrator":{"active":false,"message":"$1"},"konstruct":{"active":false,"nodeData":""}},"order":0}
18 | ```
19 |
20 | ## Markdown Formatting
21 |
22 | Provides support for discord-like formatting within chat. All 5 need to be imported.
23 |
24 | 1
25 | ```
26 | {"name":"Markdown Underline","active":true,"stripColors":true,"findString":"__([^_]*?)__","findType":"regex","replaceType":"onlymatch","replaceTo":"\u0026n$1","replaceTextColor":false,"textColor":"#FFFFFFFF","replaceBackgroundColor":false,"backgroundColor":"#FFFFFFFF","processors":{"forward":{"active":true},"actionbar":{"active":false},"sound":{"active":false,"notifySound":"none","soundPitch":1.0,"soundVolume":1.0},"narrator":{"active":false,"message":"$1"},"konstruct":{"active":false,"nodeData":""}},"order":1}
27 | ```
28 | 2
29 | ```
30 | {"name":"Markdown Strikethrough","active":true,"stripColors":true,"findString":"~~([^\\*]*?)~~","findType":"regex","replaceType":"onlymatch","replaceTo":"\u0026m$1","replaceTextColor":false,"textColor":"#FFFFFFFF","replaceBackgroundColor":false,"backgroundColor":"#FFFFFFFF","processors":{"forward":{"active":true},"actionbar":{"active":false},"sound":{"active":false,"notifySound":"none","soundPitch":1.0,"soundVolume":1.0},"narrator":{"active":false,"message":"$1"},"konstruct":{"active":false,"nodeData":""}},"order":2}
31 | ```
32 | 3
33 | ```
34 | {"name":"Markdown Bold Italic","active":true,"stripColors":true,"findString":"\\*\\*\\*([^\\*]*?)\\*\\*\\*","findType":"regex","replaceType":"onlymatch","replaceTo":"\u0026o\u0026l$1","replaceTextColor":false,"textColor":"#FFFFFFFF","replaceBackgroundColor":false,"backgroundColor":"#FFFFFFFF","processors":{"forward":{"active":true},"actionbar":{"active":false},"sound":{"active":false,"notifySound":"none","soundPitch":1.0,"soundVolume":1.0},"narrator":{"active":false,"message":"$1"},"konstruct":{"active":false,"nodeData":""}},"order":3}
35 | ```
36 | 4
37 | ```
38 | {"name":"Markdown Bold","active":true,"stripColors":true,"findString":"(?\u003c!\\*)\\*\\*([^\\*]*?)\\*\\*(?!\\*)","findType":"regex","replaceType":"onlymatch","replaceTo":"\u0026o$1","replaceTextColor":false,"textColor":"#FFFFFFFF","replaceBackgroundColor":false,"backgroundColor":"#FFFFFFFF","processors":{"forward":{"active":true},"actionbar":{"active":false},"sound":{"active":false,"notifySound":"none","soundPitch":1.0,"soundVolume":1.0},"narrator":{"active":false,"message":"$1"},"konstruct":{"active":false,"nodeData":""}},"order":4}
39 | ```
40 | 5
41 | ```
42 | {"name":"Markdown Italic","active":true,"stripColors":true,"findString":"(?\u003c!\\*)\\*([^\\*]*?)\\*(?!\\*)","findType":"regex","replaceType":"onlymatch","replaceTo":"\u0026o$1","replaceTextColor":false,"textColor":"#FFFFFFFF","replaceBackgroundColor":false,"backgroundColor":"#FFFFFFFF","processors":{"forward":{"active":true},"actionbar":{"active":false},"sound":{"active":false,"notifySound":"none","soundPitch":1.0,"soundVolume":1.0},"narrator":{"active":false,"message":"$1"},"konstruct":{"active":false,"nodeData":""}},"order":5}
43 | ```
44 |
45 | ## Pig Latin
46 |
47 | Enable Pig Latin. Not perfect, but really close.
48 |
49 | ```
50 | {"name":"Pig Latin","active":true,"stripColors":true,"findString":"(?\u003c\u003d\\W?)([aeiouy]?[^aeiouy\\W]+?)([aeiouy]\\w*)","findType":"regex","replaceType":"onlymatch","replaceTo":"$2$1ay","replaceTextColor":false,"textColor":"#FFBBFFFF","replaceBackgroundColor":false,"backgroundColor":"#FFFFFFFF","processors":{"forward":{"active":true},"actionbar":{"active":false},"sound":{"active":false,"notifySound":"none","soundPitch":1.0,"soundVolume":1.0},"narrator":{"active":false,"message":"$1"},"konstruct":{"active":false,"nodeData":""},"macro":{"active":false,"command":"po|gers","delay":68,"parseAsKonstruct":false}},"order":0}
51 | ```
52 |
--------------------------------------------------------------------------------
/docs/filters/images/filterconfig.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/filters/images/filterconfig.png
--------------------------------------------------------------------------------
/docs/filters/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: AdvancedChatFilters
4 | nav_order: 2
5 | has_children: true
6 | ---
7 |
8 | Chat, but **filtered**
9 |
--------------------------------------------------------------------------------
/docs/filters/tutorial.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: Filters Tutorial
4 | parent: AdvancedChatFilters
5 | nav_order: 0
6 | ---
7 | # Basic Filters
8 |
9 | AC Filters let you take control of your chat. Let's take a look at how to make your own filters.
10 | Recall that the String to Find box contains the string to filter for. The treatment is specified by the Filter Type property.
11 |
12 | ## Name Highlights
13 |
14 | A common use for filters is to highlight your name in chat. The easiest way to do this is to edit the `Text Color` property. Change the color value to what you want make sure to turn on `Replace Text Color`. Keep the other values at default for now.
15 | What if you wanted to make it trigger regardless of casing? You can simply change the `Filter Type` property to Upper-Lower. You can experiment with this and change different properties.
16 |
17 | ## Profanity
18 |
19 | Let's try something a little harder. What about filtering profanity? You may think you need to check for *every* single profane word, but DarkKronicle makes this easy for us. Set the `Filter Type` to Custom, and set the search string to `profanity`. You can then set the Replace String to something more friendly.
20 |
21 | We encourage you to mess around with these examples and try things on your own.
22 |
23 | # Message Processor
24 |
25 | ACF offers a lot more options with the matched chat message. The Message Processor section allows you to configure what happens to the chat message. You can control if it goes to the chat, it goes to the Action Bar, the Narrator says it, or if a sound is played. (psst... that would be great for the name highlights we mentioned before!). You can also add Konstruct filters, which are pretty advanced.
26 |
27 | # Regular Expressions
28 |
29 | Regular expressions are one of the best ways to implement find and replace searches. Fortunately, ACF contains RegEx support in `Filter Type`. We recommend a few tools to help you out.
30 | 1. [Regex Parser - Extremely useful](https://regex101.com)
31 | 2. [Interactive Tutorial](https://regexone.com/)
32 | 3. [Visualizer](https://extendsclass.com/regex-tester.html#java)
33 | 4. [Cheat Sheet](https://cheatography.com/davechild/cheat-sheets/regular-expressions/)
34 | 5. [Basics Video](https://www.youtube.com/watch?v=sXQxhojSdZM])
35 |
36 | Keep in mind that the code runs on Java 8, so make sure to select that option while testing regex.
37 | Currently, the regex does not support `/regex/flags` syntax. Use `(?flags)regex` instead.
38 |
39 | Let's go over some quick regex tips.
40 |
41 | ## Players
42 |
43 | Oftentimes with ACF we find the need for regex that matches any valid playername. `[A-Za-z0-9_§]{3,16}` matches valid playernames. You can use this for [message regex](FILE SOON) and more.
44 |
45 | Another thing we can do with regex is make more complicated name highlights. This will vary for everyone, but the regex for me is `(?i)furr?y(?:[_ ]?101)?`.
46 |
47 | ---
48 |
49 | That's all the basic tutorial has to offer. Consider looking at our [filter examples](FILES SOON) before moving onto advanced filters.
50 |
51 |
52 |
53 | Questions? Comments? Concerns? Join the discord for more help or just to hang out.
54 |
55 | Poke Fury if something is wrong with the page
56 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: Home
4 | nav_order: 0
5 | has_children: false
6 | ---
7 |
8 | # AdvancedChat
9 |
10 | Chat, but **epic**.
11 |
12 |
13 |
14 | Table of contents
15 |
16 | {: .text-delta }
17 | 1. TOC
18 | {:toc}
19 |
--------------------------------------------------------------------------------
/docs/modules/assets/images/ACC-ChatBox_Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/modules/assets/images/ACC-ChatBox_Icon.png
--------------------------------------------------------------------------------
/docs/modules/assets/images/ACC-ChatFilters_Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/modules/assets/images/ACC-ChatFilters_Icon.png
--------------------------------------------------------------------------------
/docs/modules/assets/images/ACC-ChatHUD_Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/modules/assets/images/ACC-ChatHUD_Icon.png
--------------------------------------------------------------------------------
/docs/modules/assets/images/ACC-ChatLog_Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/modules/assets/images/ACC-ChatLog_Icon.png
--------------------------------------------------------------------------------
/docs/modules/assets/images/ACC-ChatMacros_Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/modules/assets/images/ACC-ChatMacros_Icon.png
--------------------------------------------------------------------------------
/docs/modules/assets/images/AdvancedChatCore_Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/docs/modules/assets/images/AdvancedChatCore_Icon.png
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1G
2 |
3 | minecraft_version=1.20.4
4 | yarn_mappings=1.20.4+build.3
5 | loader_version=0.15.3
6 | fabric_api_version=0.92.0+1.20.4
7 |
8 | mod_version=1.5.10
9 | maven_group=io.github.darkkronicle
10 | archives_base_name=AdvancedChatCore
11 |
12 | malilib_version=0.17.0
13 | konstruct_version=2.0.3-build1
14 | mxparser_version=4.4.2
15 | owo_version=2.0.0
16 | modmenu_version=7.1.0
17 |
18 | # Uploading data
19 | curseforge_slug=advancedchatcore
20 | curseforge_id=537853
21 |
22 | modrinth_slug=advancedchatcore
23 | modrinth_id=1l6k9gvT
24 |
25 | # default_release_type can be stable, beta, or alpha
26 | default_release_type=stable
27 | project_name=AdvancedChatCore
28 | project_url=https://modrinth.com/mod/advancedchatcore
29 | project_logo=https://raw.githubusercontent.com/DarkKronicle/AdvancedChatCore/main/src/main/resources/assets/advancedchatcore/icon.png
30 | project_color=0x134bff
31 | changelog_hide_unimportant_commits=true
32 | changelog_max_commit_search=200
33 | discord_webhook_changelog_line_limit=10
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/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-7.2-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
--------------------------------------------------------------------------------
/icon - original.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medisant/AdvancedChatCore/f38f9f82de7e7ba29a5ac6f9a02b07840216416f/icon - original.png
--------------------------------------------------------------------------------
/jitpack.yml:
--------------------------------------------------------------------------------
1 | before_install:
2 | - sdk install java 17.0.2-open
3 | - sdk use java 17.0.2-open
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | maven {
4 | name = 'Fabric'
5 | url = 'https://maven.fabricmc.net/'
6 | }
7 | gradlePluginPortal()
8 | mavenCentral()
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/AdvancedChatCore.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021-2022 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore;
9 |
10 | import fi.dy.masa.malilib.event.InitializationHandler;
11 | import fi.dy.masa.malilib.gui.GuiBase;
12 | import io.github.darkkronicle.advancedchatcore.chat.AdvancedSleepingChatScreen;
13 | import io.github.darkkronicle.advancedchatcore.util.Colors;
14 | import io.github.darkkronicle.advancedchatcore.util.SyncTaskQueue;
15 | import java.io.FileInputStream;
16 | import java.io.IOException;
17 | import java.io.InputStream;
18 | import java.net.URI;
19 | import java.net.URISyntaxException;
20 | import java.nio.file.Paths;
21 | import java.util.Random;
22 | import net.fabricmc.api.ClientModInitializer;
23 | import net.fabricmc.api.EnvType;
24 | import net.fabricmc.api.Environment;
25 | import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
26 | import net.minecraft.client.MinecraftClient;
27 | import org.apache.logging.log4j.LogManager;
28 | import org.apache.logging.log4j.Logger;
29 |
30 | @Environment(EnvType.CLIENT)
31 | public class AdvancedChatCore implements ClientModInitializer {
32 |
33 | public static final String MOD_ID = "advancedchatcore";
34 |
35 | /**
36 | * Whether or not messages should be sent to the HUD. Used for other modules overwriting HUD.
37 | */
38 | public static boolean FORWARD_TO_HUD = true;
39 |
40 | /**
41 | * Whether or not the default chat suggestor should be created. Used for modules overwriting the
42 | * suggestor.
43 | */
44 | public static boolean CREATE_SUGGESTOR = true;
45 |
46 | public static final Logger LOGGER = LogManager.getLogger(MOD_ID);
47 |
48 | private static final Random RANDOM = new Random();
49 |
50 | private static final String[] RANDOM_STRINGS = {
51 | "yes", "maybe", "no", "potentially", "hello", "goodbye", "tail", "pop", "water",
52 | "headphone", "head", "scissor", "paper", "burger", "clock", "peg", "speaker",
53 | "computer", "mouse", "mat", "keyboard", "soda", "mac", "cheese", "home",
54 | "pillow", "couch", "drums", "drumstick", "math", "Euler", "Chronos", "DarkKronicle",
55 | "Kron", "pain", "suffer", "bridge", "Annevdl", "MaLiLib", "pog", "music",
56 | "pants", "glockenspiel", "marimba", "chimes", "vibraphone", "vibe", "snare",
57 | "monkeymode", "shades", "cactus", "shaker", "pit", "band", "percussion",
58 | "foot", "leg", "Kurt", "bruh", "gamer", "gaming"
59 | };
60 |
61 | @Override
62 | public void onInitializeClient() {
63 | // Important to get first since configuration options depend on colors
64 | Colors.getInstance().load();
65 | InitializationHandler.getInstance().registerInitializationHandler(new InitHandler());
66 | MinecraftClient client = MinecraftClient.getInstance();
67 | ClientTickEvents.START_CLIENT_TICK.register(
68 | s -> {
69 | // Allow for delayed tasks to be added
70 | SyncTaskQueue.getInstance().update(s.inGameHud.getTicks());
71 | // Make sure we're not in the sleeping screen while awake
72 | if (client.currentScreen instanceof AdvancedSleepingChatScreen
73 | && !client.player.isSleeping()) {
74 | GuiBase.openGui(null);
75 | }
76 | });
77 | }
78 |
79 | /**
80 | * Get's a resource from src/resources. Works in a emulated environment.
81 | *
82 | * @param path Path from the resources to get
83 | * @return Stream of the resource
84 | * @throws URISyntaxException If the resource doesn't exist
85 | * @throws IOException Can't be opened
86 | */
87 | public static InputStream getResource(String path) throws URISyntaxException, IOException {
88 | URI uri = Thread.currentThread().getContextClassLoader().getResource(path).toURI();
89 | if (!uri.getScheme().equals("file")) {
90 | // it's not a file
91 | return Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
92 | } else {
93 | // it's a file - try to access it directly!
94 | return new FileInputStream(Paths.get(uri).toFile());
95 | }
96 | }
97 |
98 | /**
99 | * Get's a random string.
100 | *
101 | * @return Random generated string.
102 | */
103 | public static String getRandomString() {
104 | return RANDOM_STRINGS[RANDOM.nextInt(RANDOM_STRINGS.length)];
105 | }
106 |
107 | /**
108 | * Returns the server address that the client is currently connected to.
109 | * @return The server address if connected, 'singleplayer' if singleplayer, 'none' if none.
110 | */
111 | public static String getServer() {
112 | MinecraftClient client = MinecraftClient.getInstance();
113 | if (client.isInSingleplayer()) {
114 | return "singleplayer";
115 | }
116 | if (client.getCurrentServerEntry() == null) {
117 | return "none";
118 | }
119 | return client.getCurrentServerEntry().address;
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/Module.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore;
9 |
10 | import java.util.Collection;
11 | import lombok.Value;
12 | import net.fabricmc.loader.api.metadata.Person;
13 |
14 | @Value
15 | public class Module {
16 |
17 | /** The Mod ID of the module */
18 | String modId;
19 |
20 | /** A {@link Collection} of {@link Person}'s */
21 | Collection authors;
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/ModuleHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore;
9 |
10 | import java.util.ArrayList;
11 | import java.util.Collections;
12 | import java.util.List;
13 | import java.util.Optional;
14 |
15 | import fi.dy.masa.malilib.interfaces.IInitializationHandler;
16 | import lombok.AllArgsConstructor;
17 | import lombok.Getter;
18 | import lombok.Value;
19 | import net.fabricmc.loader.api.FabricLoader;
20 | import net.fabricmc.loader.api.ModContainer;
21 | import net.fabricmc.loader.api.metadata.CustomValue;
22 |
23 | public class ModuleHandler {
24 |
25 | private static final ModuleHandler INSTANCE = new ModuleHandler();
26 |
27 | @Getter private final List modules = new ArrayList<>();
28 |
29 | private ModuleHandler() {}
30 |
31 | private List toLoad = new ArrayList<>();
32 |
33 | public static ModuleHandler getInstance() {
34 | return INSTANCE;
35 | }
36 |
37 | public void registerModules() {
38 | modules.clear();
39 | for (ModContainer mod : FabricLoader.getInstance().getAllMods()) {
40 | // Check if in "custom" it has "acmodule": true
41 | CustomValue acData = mod.getMetadata().getCustomValue("acmodule");
42 | if (acData == null) {
43 | continue;
44 | }
45 | if (acData.getType() == CustomValue.CvType.BOOLEAN && acData.getAsBoolean()) {
46 | // Add the module
47 | modules.add(new Module(mod.getMetadata().getId(), mod.getMetadata().getAuthors()));
48 | }
49 | }
50 | }
51 |
52 | public void registerInitHandler(String name, int priority, IInitializationHandler handler) {
53 | toLoad.add(new LoadOrder(name, priority, handler));
54 | }
55 |
56 | /** Do not call */
57 | public void load() {
58 | Collections.sort(toLoad);
59 | for (LoadOrder load : toLoad) {
60 | load.getHandler().registerModHandlers();
61 | }
62 | toLoad = null;
63 | }
64 |
65 | /**
66 | * Retrieves a {@link Module} based off of a mod ID.
67 | *
68 | *
This is useful for incompatible features or enabling others.
69 | *
70 | * @param modID Mod id of the mod
71 | * @return An optional containing the module if found.
72 | */
73 | public Optional fromId(String modID) {
74 | for (Module m : modules) {
75 | if (m.getModId().equals(modID)) {
76 | return Optional.of(m);
77 | }
78 | }
79 | return Optional.empty();
80 | }
81 |
82 | @AllArgsConstructor
83 | @Value
84 | public static class LoadOrder implements Comparable {
85 | String name;
86 | Integer order;
87 | IInitializationHandler handler;
88 |
89 | @Override
90 | public int compareTo(ModuleHandler.LoadOrder o) {
91 | int compared = order.compareTo(o.order);
92 | if (compared == 0) {
93 | return name.compareTo(o.getName());
94 | }
95 | return compared;
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/chat/AdvancedSleepingChatScreen.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021-2022 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.chat;
9 |
10 | import fi.dy.masa.malilib.gui.GuiBase;
11 | import fi.dy.masa.malilib.gui.button.ButtonGeneric;
12 | import fi.dy.masa.malilib.util.KeyCodes;
13 | import fi.dy.masa.malilib.util.StringUtils;
14 | import net.minecraft.client.network.ClientPlayNetworkHandler;
15 | import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket;
16 |
17 | public class AdvancedSleepingChatScreen extends AdvancedChatScreen {
18 |
19 | public AdvancedSleepingChatScreen() {
20 | super("");
21 | }
22 |
23 | public void initGui() {
24 | super.initGui();
25 | ButtonGeneric stopSleep =
26 | new ButtonGeneric(
27 | this.width / 2 - 100,
28 | this.height - 40,
29 | 200,
30 | 20,
31 | StringUtils.translate("multiplayer.stopSleeping"));
32 | this.addButton(stopSleep, (button, mouseButton) -> stopSleeping());
33 | }
34 |
35 | public void onClose() {
36 | this.stopSleeping();
37 | }
38 |
39 | public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
40 | if (keyCode == KeyCodes.KEY_ESCAPE) {
41 | this.stopSleeping();
42 | } else if (keyCode == KeyCodes.KEY_ENTER || keyCode == KeyCodes.KEY_KP_ENTER) {
43 | String string = this.chatField.getText().trim();
44 | if (!string.isEmpty()) {
45 | MessageSender.getInstance().sendMessage(string);
46 | }
47 |
48 | this.chatField.setText("");
49 | this.client.inGameHud.getChatHud().resetScroll();
50 | // Prevents really weird interactions with chat history
51 | resetCurrentMessage();
52 | return true;
53 | }
54 |
55 | return super.keyPressed(keyCode, scanCode, modifiers);
56 | }
57 |
58 | private void stopSleeping() {
59 | ClientPlayNetworkHandler clientPlayNetworkHandler = this.client.player.networkHandler;
60 | clientPlayNetworkHandler.sendPacket(
61 | new ClientCommandC2SPacket(
62 | this.client.player, ClientCommandC2SPacket.Mode.STOP_SLEEPING));
63 | GuiBase.openGui(null);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/chat/ChatHistory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.chat;
9 |
10 | import io.github.darkkronicle.advancedchatcore.config.ConfigStorage;
11 | import io.github.darkkronicle.advancedchatcore.interfaces.IChatMessageProcessor;
12 | import java.util.ArrayList;
13 | import java.util.List;
14 | import java.util.stream.Collectors;
15 | import lombok.Getter;
16 | import lombok.Setter;
17 | import net.fabricmc.api.EnvType;
18 | import net.fabricmc.api.Environment;
19 |
20 | /** A utility class to maintain the storage of the chat. */
21 | @Environment(EnvType.CLIENT)
22 | public class ChatHistory {
23 |
24 | private static final ChatHistory INSTANCE = new ChatHistory();
25 |
26 | /** Stored lines */
27 | @Getter private final List messages = new ArrayList<>();
28 |
29 | /** Maximum lines for storage */
30 | @Getter @Setter private int maxLines = 500;
31 |
32 | /** Runnable's to run when chat history is cleared */
33 | @Getter private final List onClear = new ArrayList<>();
34 |
35 | /** {@link IChatMessageProcessor} for when history is updated. */
36 | @Getter private final List onUpdate = new ArrayList<>();
37 |
38 | public static ChatHistory getInstance() {
39 | return INSTANCE;
40 | }
41 |
42 | private ChatHistory() {}
43 |
44 | /**
45 | * Add's a runnable that will trigger when all chat messages should be cleared.
46 | *
47 | * @param runnable Runnable to run
48 | */
49 | public void addOnClear(Runnable runnable) {
50 | onClear.add(runnable);
51 | }
52 |
53 | /**
54 | * Add's a {@link IChatMessageProcessor} that get's called on new messages, added messages,
55 | * stacked messages, or removed messages.
56 | *
57 | * @param processor Processor ot add
58 | */
59 | public void addOnUpdate(IChatMessageProcessor processor) {
60 | onUpdate.add(processor);
61 | }
62 |
63 | /** Goes through and clears all message data from everywhere. */
64 | public void clearAll() {
65 | this.messages.clear();
66 | for (Runnable r : onClear) {
67 | r.run();
68 | }
69 | }
70 |
71 | /** Clear's all the chat messages from the history */
72 | public void clear() {
73 | messages.clear();
74 | }
75 |
76 | private void sendUpdate(ChatMessage message, IChatMessageProcessor.UpdateType type) {
77 | for (IChatMessageProcessor consumer : onUpdate) {
78 | consumer.onMessageUpdate(message, type);
79 | }
80 | }
81 |
82 | /**
83 | * Add's a chat message to the history.
84 | *
85 | * @param message
86 | */
87 | public boolean add(ChatMessage message) {
88 | sendUpdate(message, IChatMessageProcessor.UpdateType.NEW);
89 | for (int i = 0;
90 | i < ConfigStorage.General.CHAT_STACK.config.getIntegerValue()
91 | && i < messages.size();
92 | i++) {
93 | // Check for stacks
94 | ChatMessage chatLine = messages.get(i);
95 | if (message.isSimilar(chatLine)) {
96 | chatLine.setStacks(chatLine.getStacks() + 1);
97 | sendUpdate(chatLine, IChatMessageProcessor.UpdateType.STACK);
98 | return false;
99 | }
100 | }
101 | sendUpdate(message, IChatMessageProcessor.UpdateType.ADDED);
102 | messages.add(0, message);
103 | while (this.messages.size() > maxLines) {
104 | sendUpdate(
105 | this.messages.remove(this.messages.size() - 1),
106 | IChatMessageProcessor.UpdateType.REMOVE);
107 | }
108 | return true;
109 | }
110 |
111 | /**
112 | * Remove's a message based off of it's messageId.
113 | *
114 | * @param messageId Message ID to find and remove
115 | */
116 | public void removeMessage(int messageId) {
117 | List toRemove =
118 | this.messages.stream()
119 | .filter(line -> line.getId() == messageId)
120 | .collect(Collectors.toList());
121 | this.messages.removeAll(toRemove);
122 | for (ChatMessage m : toRemove) {
123 | sendUpdate(m, IChatMessageProcessor.UpdateType.REMOVE);
124 | }
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/chat/ChatHistoryProcessor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021-2022 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.chat;
9 |
10 | import io.github.darkkronicle.advancedchatcore.AdvancedChatCore;
11 | import io.github.darkkronicle.advancedchatcore.config.ConfigStorage;
12 | import io.github.darkkronicle.advancedchatcore.interfaces.IMessageProcessor;
13 | import io.github.darkkronicle.advancedchatcore.mixin.MixinChatHudInvoker;
14 | import io.github.darkkronicle.advancedchatcore.util.Color;
15 | import io.github.darkkronicle.advancedchatcore.util.SearchUtils;
16 | import java.time.LocalTime;
17 | import java.time.format.DateTimeFormatter;
18 | import net.fabricmc.api.EnvType;
19 | import net.fabricmc.api.Environment;
20 | import net.minecraft.client.MinecraftClient;
21 | import net.minecraft.client.gui.hud.MessageIndicator;
22 | import net.minecraft.network.message.MessageSignatureData;
23 | import net.minecraft.text.Style;
24 | import net.minecraft.text.Text;
25 | import net.minecraft.text.TextColor;
26 | import org.jetbrains.annotations.Nullable;
27 |
28 | @Environment(EnvType.CLIENT)
29 | public class ChatHistoryProcessor implements IMessageProcessor {
30 |
31 | private static boolean sendToHud(Text text, @Nullable MessageSignatureData signature, MessageIndicator indicator) {
32 | if (AdvancedChatCore.FORWARD_TO_HUD) {
33 | ((MixinChatHudInvoker) MinecraftClient.getInstance().inGameHud.getChatHud()).invokeAddMessage(
34 | text, signature, MinecraftClient.getInstance().inGameHud.getTicks(), indicator, false);
35 | return true;
36 | }
37 | return false;
38 | }
39 |
40 | @Override
41 | public boolean process(Text text, @Nullable Text unfiltered) {
42 | return process(text, unfiltered, null, MessageIndicator.system());
43 | }
44 |
45 | @Override
46 | public boolean process(Text text, @Nullable Text unfiltered, @Nullable MessageSignatureData signature, @Nullable MessageIndicator indicator) {
47 | if (unfiltered == null) {
48 | unfiltered = text;
49 | }
50 |
51 | // Put the time in
52 | LocalTime time = LocalTime.now();
53 | boolean showtime = ConfigStorage.General.SHOW_TIME.config.getBooleanValue();
54 | // Store original so we can get stuff without the time
55 | Text original = text.copy();
56 | if (showtime) {
57 | DateTimeFormatter format =
58 | DateTimeFormatter.ofPattern(
59 | ConfigStorage.General.TIME_FORMAT.config.getStringValue());
60 | String replaceFormat =
61 | ConfigStorage.General.TIME_TEXT_FORMAT.config.getStringValue().replaceAll("&", "§");
62 | Color color = ConfigStorage.General.TIME_COLOR.config.get();
63 | Style style = Style.EMPTY;
64 | TextColor textColor = TextColor.fromRgb(color.color());
65 | style = style.withColor(textColor);
66 | text.getSiblings().add(0, Text.literal(replaceFormat.replaceAll("%TIME%", time.format(format))).fillStyle(style));
67 | }
68 |
69 | int width = 0;
70 | // Find player
71 | MessageOwner player =
72 | SearchUtils.getAuthor(
73 | MinecraftClient.getInstance().getNetworkHandler(), unfiltered.getString());
74 | ChatMessage line = ChatMessage.builder()
75 | .displayText(text)
76 | .originalText(original)
77 | .owner(player)
78 | .id(0)
79 | .width(width)
80 | .creationTick(MinecraftClient.getInstance().inGameHud.getTicks())
81 | .time(time)
82 | .backgroundColor(null)
83 | .build();
84 | if (ChatHistory.getInstance().add(line)) {
85 | sendToHud(line.getDisplayText(), line.getSignature(), line.getIndicator());
86 | }
87 | return true;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/chat/ChatScreenSectionHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.chat;
9 |
10 | import io.github.darkkronicle.advancedchatcore.interfaces.AdvancedChatScreenSection;
11 | import java.util.ArrayList;
12 | import java.util.List;
13 | import java.util.function.Function;
14 | import lombok.Getter;
15 |
16 | /**
17 | * A class to handle the construction and distribution of {@link AdvancedChatScreenSection} when
18 | * {@link AdvancedChatScreen} is created.
19 | */
20 | public class ChatScreenSectionHolder {
21 |
22 | private static final ChatScreenSectionHolder INSTANCE = new ChatScreenSectionHolder();
23 |
24 | /** All suppliers for the sections */
25 | @Getter
26 | private final List> sectionSuppliers =
27 | new ArrayList<>();
28 |
29 | public static ChatScreenSectionHolder getInstance() {
30 | return INSTANCE;
31 | }
32 |
33 | private ChatScreenSectionHolder() {}
34 |
35 | public void addSectionSupplier(
36 | Function sectionSupplier) {
37 | sectionSuppliers.add(sectionSupplier);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/chat/DefaultChatSuggestor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.chat;
9 |
10 | import io.github.darkkronicle.advancedchatcore.interfaces.AdvancedChatScreenSection;
11 | import net.fabricmc.api.EnvType;
12 | import net.fabricmc.api.Environment;
13 | import net.minecraft.client.MinecraftClient;
14 | import net.minecraft.client.gui.DrawContext;
15 | import net.minecraft.client.gui.screen.ChatInputSuggestor;
16 | import net.minecraft.client.util.math.MatrixStack;
17 |
18 | /** Handles the CommandSuggestor for the chat */
19 | @Environment(EnvType.CLIENT)
20 | public class DefaultChatSuggestor extends AdvancedChatScreenSection {
21 |
22 | private ChatInputSuggestor commandSuggestor;
23 |
24 | public DefaultChatSuggestor(AdvancedChatScreen screen) {
25 | super(screen);
26 | }
27 |
28 | @Override
29 | public void onChatFieldUpdate(String chatText, String text) {
30 | this.commandSuggestor.setWindowActive(!text.equals(getScreen().getOriginalChatText()));
31 | this.commandSuggestor.refresh();
32 | }
33 |
34 | @Override
35 | public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
36 | return this.commandSuggestor.keyPressed(keyCode, scanCode, modifiers);
37 | }
38 |
39 | @Override
40 | public void render(DrawContext context, int mouseX, int mouseY, float partialTicks) {
41 | this.commandSuggestor.render(context, mouseX, mouseY);
42 | }
43 |
44 | @Override
45 | public void setChatFromHistory(String hist) {
46 | this.commandSuggestor.setWindowActive(false);
47 | }
48 |
49 | @Override
50 | public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
51 | return this.commandSuggestor.mouseScrolled(amount);
52 | }
53 |
54 | @Override
55 | public boolean mouseClicked(double mouseX, double mouseY, int button) {
56 | return this.commandSuggestor.mouseClicked(mouseX, mouseY, button);
57 | }
58 |
59 | @Override
60 | public void resize(int width, int height) {
61 | this.commandSuggestor.refresh();
62 | }
63 |
64 | @Override
65 | public void initGui() {
66 | MinecraftClient client = MinecraftClient.getInstance();
67 | AdvancedChatScreen screen = getScreen();
68 | this.commandSuggestor =
69 | new ChatInputSuggestor(
70 | client,
71 | screen,
72 | screen.chatField,
73 | client.textRenderer,
74 | false,
75 | false,
76 | 1,
77 | 10,
78 | true,
79 | -805306368);
80 | this.commandSuggestor.refresh();
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/chat/MessageOwner.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.chat;
9 |
10 | import lombok.AllArgsConstructor;
11 | import lombok.Data;
12 | import lombok.Value;
13 | import net.fabricmc.api.EnvType;
14 | import net.fabricmc.api.Environment;
15 | import net.minecraft.client.network.PlayerListEntry;
16 | import net.minecraft.util.Identifier;
17 |
18 | /** Stores data about a message owner */
19 | @Data
20 | @Value
21 | @AllArgsConstructor
22 | @Environment(EnvType.CLIENT)
23 | public class MessageOwner {
24 |
25 | /** Player name */
26 | String name;
27 |
28 | /** Entry that has player data */
29 | PlayerListEntry entry;
30 |
31 | /**
32 | * The texture of the player's skin
33 | *
34 | * @return Identifier with texture data
35 | */
36 | public Identifier getTexture() {
37 | return entry.getSkinTextures().texture();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/chat/MessageSender.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.chat;
9 |
10 | import io.github.darkkronicle.advancedchatcore.AdvancedChatCore;
11 | import io.github.darkkronicle.advancedchatcore.interfaces.IStringFilter;
12 | import net.minecraft.client.MinecraftClient;
13 | import org.apache.logging.log4j.Level;
14 |
15 | import java.util.ArrayList;
16 | import java.util.List;
17 | import java.util.Optional;
18 |
19 | public class MessageSender {
20 |
21 | private static final MessageSender INSTANCE = new MessageSender();
22 | private final MinecraftClient client = MinecraftClient.getInstance();
23 |
24 | public static MessageSender getInstance() {
25 | return INSTANCE;
26 | }
27 |
28 | private MessageSender() {}
29 |
30 | private final List filters = new ArrayList<>();
31 |
32 | public void addFilter(IStringFilter filter) {
33 | filters.add(filter);
34 | }
35 |
36 | public void addFilter(IStringFilter filter, int index) {
37 | filters.add(index, filter);
38 | }
39 |
40 | public void sendMessage(String string) {
41 | String unfiltered = string;
42 | for (IStringFilter filter : filters) {
43 | Optional filtered = filter.filter(string);
44 | if (filtered.isPresent()) {
45 | string = filtered.get().strip();
46 | }
47 | }
48 | if (string.length() > 256) {
49 | string = string.substring(0, 256);
50 | }
51 | this.client.inGameHud.getChatHud().addToMessageHistory(unfiltered);
52 |
53 | if (string.length() == 0) {
54 | AdvancedChatCore.LOGGER.log(Level.WARN, "Blank message was attempted to be sent. " + unfiltered);
55 | return;
56 | }
57 |
58 | if (client.player != null) {
59 | if (string.startsWith("/")) {
60 | this.client.getNetworkHandler().sendChatCommand(string.substring(1));
61 | } else {
62 | this.client.getNetworkHandler().sendChatMessage(string);
63 | }
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/config/SaveableConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.config;
9 |
10 | import fi.dy.masa.malilib.config.IConfigBase;
11 |
12 | public class SaveableConfig {
13 |
14 | public final T config;
15 | public final String key;
16 |
17 | private SaveableConfig(String key, T config) {
18 | this.key = key;
19 | this.config = config;
20 | }
21 |
22 | public static SaveableConfig fromConfig(String key, C config) {
23 | return new SaveableConfig<>(key, config);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/config/gui/ModMenuImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.config.gui;
9 |
10 | import com.terraformersmc.modmenu.api.ConfigScreenFactory;
11 | import com.terraformersmc.modmenu.api.ModMenuApi;
12 | import net.fabricmc.api.EnvType;
13 | import net.fabricmc.api.Environment;
14 |
15 | @Environment(EnvType.CLIENT)
16 | public class ModMenuImpl implements ModMenuApi {
17 |
18 | @Override
19 | public ConfigScreenFactory> getModConfigScreenFactory() {
20 | return parent -> GuiConfigHandler.getInstance().getDefaultScreen();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/config/gui/OnOffListListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.config.gui;
9 |
10 | import fi.dy.masa.malilib.gui.button.ButtonBase;
11 | import fi.dy.masa.malilib.gui.button.ButtonGeneric;
12 | import fi.dy.masa.malilib.gui.button.IButtonActionListener;
13 | import io.github.darkkronicle.advancedchatcore.config.gui.widgets.WidgetToggle;
14 | import io.github.darkkronicle.advancedchatcore.interfaces.Translatable;
15 | import java.util.ArrayList;
16 | import java.util.HashMap;
17 | import java.util.List;
18 | import java.util.Map;
19 |
20 | public class OnOffListListener implements IButtonActionListener {
21 |
22 | private final ButtonGeneric button;
23 | private final WidgetToggle toggle;
24 | private T current;
25 | private HashMap onOff;
26 | private final List order;
27 |
28 | public OnOffListListener(ButtonGeneric button, WidgetToggle toggle, HashMap onOff) {
29 | this.button = button;
30 | this.toggle = toggle;
31 | this.onOff = new HashMap<>(onOff);
32 | this.order = new ArrayList<>(onOff.keySet());
33 | next();
34 | }
35 |
36 | public IButtonActionListener getButtonListener() {
37 | return (button1, mouseButton) -> {
38 | onToggled();
39 | };
40 | }
41 |
42 | private void onToggled() {
43 | onOff.put(current, toggle.isCurrentlyOn());
44 | }
45 |
46 | private void next() {
47 | int i = order.indexOf(current) + 1;
48 | if (i >= order.size()) {
49 | i = 0;
50 | }
51 | current = order.get(i);
52 | button.setDisplayString(current.translate());
53 | toggle.setOn(onOff.get(current));
54 | }
55 |
56 | public List getOn() {
57 | ArrayList list = new ArrayList<>();
58 | for (Map.Entry entry : onOff.entrySet()) {
59 | if (entry.getValue()) {
60 | list.add(entry.getKey());
61 | }
62 | }
63 | return list;
64 | }
65 |
66 | public static HashMap getOnOff(
67 | List all, List active) {
68 | HashMap map = new HashMap<>();
69 | for (T a : all) {
70 | map.put(a, active.contains(a));
71 | }
72 | return map;
73 | }
74 |
75 | @Override
76 | public void actionPerformedWithButton(ButtonBase button, int mouseButton) {
77 | next();
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/config/gui/TabSupplier.java:
--------------------------------------------------------------------------------
1 | package io.github.darkkronicle.advancedchatcore.config.gui;
2 |
3 | import fi.dy.masa.malilib.config.IConfigBase;
4 | import fi.dy.masa.malilib.util.StringUtils;
5 | import lombok.Getter;
6 | import lombok.Setter;
7 | import net.minecraft.client.gui.screen.Screen;
8 |
9 | import java.util.ArrayList;
10 | import java.util.List;
11 |
12 | public class TabSupplier {
13 |
14 | @Getter
15 | private final String name;
16 |
17 | private final String translationKey;
18 |
19 | @Getter
20 | @Setter
21 | private TabSupplier nestedSelection = null;
22 |
23 | @Getter
24 | private List children = new ArrayList<>();
25 |
26 | public TabSupplier(String name, String translationKey) {
27 | this.name = name;
28 | this.translationKey = translationKey;
29 | }
30 |
31 | public String getDisplayName() {
32 | return StringUtils.translate(translationKey);
33 | }
34 |
35 | public List getOptions() {
36 | return null;
37 | }
38 |
39 | public Screen getScreen(Screen parent) {
40 | return null;
41 | }
42 |
43 | public boolean isSelectable() {
44 | return true;
45 | }
46 |
47 | @Override
48 | public boolean equals(Object obj) {
49 | if (!(obj instanceof TabSupplier)) {
50 | return false;
51 | }
52 | return (((TabSupplier) obj).getName().equals(getName()));
53 | }
54 |
55 | public void addChild(TabSupplier supplier) {
56 | if (nestedSelection == null) {
57 | if (supplier.isSelectable()) {
58 | nestedSelection = supplier;
59 | }
60 | }
61 | this.children.add(supplier);
62 | }
63 |
64 | public TabSupplier get(String name) {
65 | for (TabSupplier child : children) {
66 | if (name.equals(child.getName())) {
67 | return child;
68 | }
69 | }
70 | return null;
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/config/gui/widgets/WidgetColor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.config.gui.widgets;
9 |
10 | import fi.dy.masa.malilib.gui.GuiTextFieldGeneric;
11 | import fi.dy.masa.malilib.render.RenderUtils;
12 | import fi.dy.masa.malilib.util.StringUtils;
13 | import io.github.darkkronicle.advancedchatcore.util.Color;
14 | import io.github.darkkronicle.advancedchatcore.util.Colors;
15 | import java.util.Optional;
16 | import net.minecraft.client.font.TextRenderer;
17 | import net.minecraft.client.gui.DrawContext;
18 | import net.minecraft.client.util.math.MatrixStack;
19 |
20 | public class WidgetColor extends GuiTextFieldGeneric {
21 |
22 | private int colorX;
23 | private Color currentColor;
24 |
25 | public WidgetColor(
26 | int x, int y, int width, int height, Color color, TextRenderer textRenderer) {
27 | super(x, y, width - 22, height, textRenderer);
28 | this.colorX = x + width - 20;
29 | this.currentColor = color;
30 | setText(String.format("#%08X", this.currentColor.color()));
31 | }
32 |
33 | @Override
34 | public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) {
35 | super.renderWidget(context, mouseX, mouseY, delta);
36 | int y = this.y;
37 | RenderUtils.drawRect(this.colorX, y, 19, 19, 0xFFFFFFFF);
38 | RenderUtils.drawRect(this.colorX + 1, y + 1, 17, 17, 0xFF000000);
39 | RenderUtils.drawRect(this.colorX + 2, y + 2, 15, 15, this.currentColor.color());
40 | }
41 |
42 | @Override
43 | public void write(String text) {
44 | super.write(text);
45 | getAndRefreshColor4f();
46 | }
47 |
48 | @Override
49 | public int getWidth() {
50 | return super.getWidth() + 22;
51 | }
52 |
53 | public Color getAndRefreshColor4f() {
54 | Optional color = Colors.getInstance().getColor(getText());
55 | if (color.isPresent()) {
56 | this.currentColor = color.get();
57 | return this.currentColor;
58 | }
59 | this.currentColor = new Color(StringUtils.getColor(getText(), 0));
60 | return this.currentColor;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/config/gui/widgets/WidgetIntBox.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.config.gui.widgets;
9 |
10 | import fi.dy.masa.malilib.gui.GuiTextFieldGeneric;
11 | import io.github.darkkronicle.advancedchatcore.util.FindType;
12 | import io.github.darkkronicle.advancedchatcore.util.SearchUtils;
13 | import io.github.darkkronicle.advancedchatcore.util.StringMatch;
14 | import java.util.List;
15 | import java.util.Optional;
16 | import lombok.Getter;
17 | import lombok.Setter;
18 | import net.minecraft.client.font.TextRenderer;
19 |
20 | public class WidgetIntBox extends GuiTextFieldGeneric {
21 |
22 | @Setter @Getter private Runnable apply = null;
23 |
24 | public WidgetIntBox(int x, int y, int width, int height, TextRenderer textRenderer) {
25 | super(x, y, width, height, textRenderer);
26 | this.setTextPredicate(
27 | text -> {
28 | if (text.equals("")) {
29 | return true;
30 | }
31 | try {
32 | // Only allow numbers!
33 | Integer.valueOf(text);
34 | } catch (NumberFormatException e) {
35 | return false;
36 | }
37 | return true;
38 | });
39 | this.setDrawsBackground(true);
40 | }
41 |
42 | public Integer getInt() {
43 | String text = this.getText();
44 | if (text == null || text.length() == 0) {
45 | return null;
46 | }
47 | try {
48 | return Integer.parseInt(text);
49 | } catch (NumberFormatException e) {
50 | // Extra catch
51 | Optional> omatches =
52 | SearchUtils.findMatches(text, "[0-9]+", FindType.REGEX);
53 | if (!omatches.isPresent()) {
54 | return null;
55 | }
56 | for (StringMatch m : omatches.get()) {
57 | try {
58 | return Integer.parseInt(m.match);
59 | } catch (NumberFormatException err) {
60 | return null;
61 | }
62 | }
63 | }
64 | return null;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/config/gui/widgets/WidgetLabelHoverable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.config.gui.widgets;
9 |
10 | import fi.dy.masa.malilib.gui.widgets.WidgetLabel;
11 | import fi.dy.masa.malilib.render.RenderUtils;
12 | import java.util.Arrays;
13 | import java.util.List;
14 |
15 | import net.minecraft.client.gui.DrawContext;
16 | import net.minecraft.client.util.math.MatrixStack;
17 |
18 | public class WidgetLabelHoverable extends WidgetLabel {
19 |
20 | private List hoverLines = null;
21 |
22 | public WidgetLabelHoverable(
23 | int x, int y, int width, int height, int textColor, List lines) {
24 | super(x, y, width, height, textColor, lines);
25 | }
26 |
27 | public WidgetLabelHoverable(
28 | int x, int y, int width, int height, int textColor, String... text) {
29 | super(x, y, width, height, textColor, text);
30 | }
31 |
32 | public void setHoverLines(String... hoverLines) {
33 | this.hoverLines = Arrays.asList(hoverLines);
34 | }
35 |
36 | @Override
37 | public void postRenderHovered(
38 | int mouseX, int mouseY, boolean selected, DrawContext context) {
39 | super.postRenderHovered(mouseX, mouseY, selected, context);
40 |
41 | if (hoverLines == null) {
42 | return;
43 | }
44 |
45 | if (mouseX >= this.x
46 | && mouseX < this.x + this.width
47 | && mouseY >= this.y
48 | && mouseY <= this.y + this.height) {
49 | RenderUtils.drawHoverText(mouseX, mouseY, this.hoverLines, context);
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/config/gui/widgets/WidgetListRegistryOption.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.config.gui.widgets;
9 |
10 | import fi.dy.masa.malilib.gui.interfaces.ISelectionListener;
11 | import fi.dy.masa.malilib.gui.widgets.WidgetListBase;
12 | import io.github.darkkronicle.advancedchatcore.interfaces.ConfigRegistryOption;
13 | import io.github.darkkronicle.advancedchatcore.util.AbstractRegistry;
14 | import java.util.Collection;
15 | import java.util.stream.Collectors;
16 | import net.minecraft.client.gui.screen.Screen;
17 | import org.jetbrains.annotations.Nullable;
18 |
19 | public class WidgetListRegistryOption>
20 | extends WidgetListBase> {
21 |
22 | private final AbstractRegistry, T> registry;
23 |
24 | public WidgetListRegistryOption(
25 | int x,
26 | int y,
27 | int width,
28 | int height,
29 | @Nullable ISelectionListener selectionListener,
30 | AbstractRegistry, T> registry,
31 | Screen parent) {
32 | super(x, y, width, height, selectionListener);
33 | this.browserEntryHeight = 22;
34 | this.setParent(parent);
35 | this.registry = registry;
36 | }
37 |
38 | @Override
39 | protected WidgetRegistryOptionEntry createListEntryWidget(
40 | int x, int y, int listIndex, boolean isOdd, T entry) {
41 | return new WidgetRegistryOptionEntry(
42 | x,
43 | y,
44 | this.browserEntryWidth,
45 | this.getBrowserEntryHeightFor(entry),
46 | isOdd,
47 | entry,
48 | listIndex,
49 | this);
50 | }
51 |
52 | @Override
53 | protected Collection getAllEntries() {
54 | return registry.getAll().stream()
55 | .filter(option -> !option.isHidden())
56 | .collect(Collectors.toList());
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/config/gui/widgets/WidgetToggle.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.config.gui.widgets;
9 |
10 | import fi.dy.masa.malilib.gui.button.ButtonOnOff;
11 | import lombok.Getter;
12 |
13 | public class WidgetToggle extends ButtonOnOff {
14 |
15 | @Getter private boolean currentlyOn;
16 |
17 | public WidgetToggle(
18 | int x,
19 | int y,
20 | int width,
21 | boolean rightAlign,
22 | String translationKey,
23 | boolean isCurrentlyOn,
24 | String... hoverStrings) {
25 | super(x, y, width, rightAlign, translationKey, isCurrentlyOn, hoverStrings);
26 | this.currentlyOn = isCurrentlyOn;
27 | }
28 |
29 | @Override
30 | protected boolean onMouseClickedImpl(int mouseX, int mouseY, int mouseButton) {
31 | this.currentlyOn = !this.currentlyOn;
32 | this.updateDisplayString(this.currentlyOn);
33 | return super.onMouseClickedImpl(mouseX, mouseY, mouseButton);
34 | }
35 |
36 | public void setOn(boolean on) {
37 | this.currentlyOn = on;
38 | this.updateDisplayString(on);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/config/options/ConfigColor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021-2022 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.config.options;
9 |
10 | import com.google.gson.JsonElement;
11 | import com.google.gson.JsonPrimitive;
12 | import fi.dy.masa.malilib.MaLiLib;
13 | import fi.dy.masa.malilib.util.StringUtils;
14 | import io.github.darkkronicle.advancedchatcore.util.Color;
15 | import io.github.darkkronicle.advancedchatcore.util.Colors;
16 | import java.util.Optional;
17 | import net.fabricmc.api.EnvType;
18 | import net.fabricmc.api.Environment;
19 |
20 | @Environment(EnvType.CLIENT)
21 | public class ConfigColor extends fi.dy.masa.malilib.config.options.ConfigColor {
22 | private Color color;
23 | private final String defaultReference;
24 | private String reference = null;
25 |
26 | public ConfigColor(String name, Color defaultValue, String comment) {
27 | super(name, defaultValue.getString(), comment);
28 | this.color = defaultValue;
29 | this.defaultReference = null;
30 | }
31 |
32 | public ConfigColor(String name, String referenceDefault, String comment) {
33 | super(name, Colors.getInstance().getColorOrWhite(referenceDefault).toString(), comment);
34 | this.color = Colors.getInstance().getColorOrWhite(referenceDefault);
35 | this.defaultReference = referenceDefault;
36 | }
37 |
38 | @Override
39 | public void resetToDefault() {
40 | if (defaultReference != null) {
41 | this.setValueFromString(defaultReference);
42 | } else {
43 | this.setValueFromString(new Color(defaultValue).getString());
44 | }
45 | onValueChanged();
46 | }
47 |
48 | @Override
49 | public String getDefaultStringValue() {
50 | if (defaultReference == null) {
51 | return super.getDefaultStringValue();
52 | }
53 | return defaultReference;
54 | }
55 |
56 | @Override
57 | public void setValueFromString(String value) {
58 | Optional color = Colors.getInstance().getColor(value);
59 | if (color.isPresent()) {
60 | this.setIntegerValue(color.get().color());
61 | this.reference = value;
62 | this.setColor();
63 | return;
64 | }
65 | this.reference = null;
66 | super.setValueFromString(value);
67 | this.setColor();
68 | }
69 |
70 | @Override
71 | public String getStringValue() {
72 | if (reference != null) {
73 | return this.reference;
74 | }
75 | return super.getStringValue();
76 | }
77 |
78 | private void setColor() {
79 | this.color = new Color(getIntegerValue());
80 | }
81 |
82 | @Override
83 | public void setValueFromJsonElement(JsonElement element) {
84 | try {
85 | if (element.isJsonPrimitive()) {
86 | String value = element.getAsString();
87 | Optional color = Colors.getInstance().getColor(value);
88 | if (color.isPresent()) {
89 | this.setIntegerValue(color.get().color());
90 | this.reference = value;
91 | this.setColor();
92 | return;
93 | }
94 | this.value = this.getClampedValue(StringUtils.getColor(value, 0));
95 | this.setIntegerValue(this.value);
96 | this.setColor();
97 | } else {
98 | MaLiLib.logger.warn(
99 | "Failed to set config value for '{}' from the JSON element '{}'",
100 | this.getName(),
101 | element);
102 | }
103 | } catch (Exception e) {
104 | MaLiLib.logger.warn(
105 | "Failed to set config value for '{}' from the JSON element '{}'",
106 | this.getName(),
107 | element,
108 | e);
109 | }
110 | }
111 |
112 | @Override
113 | public JsonElement getAsJsonElement() {
114 | return new JsonPrimitive(getStringValue());
115 | }
116 |
117 | public Color get() {
118 | return color;
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/finder/CustomFinder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.finder;
9 |
10 | import io.github.darkkronicle.advancedchatcore.AdvancedChatCore;
11 | import io.github.darkkronicle.advancedchatcore.interfaces.IFinder;
12 | import io.github.darkkronicle.advancedchatcore.interfaces.RegistryOption;
13 | import io.github.darkkronicle.advancedchatcore.util.AbstractRegistry;
14 | import io.github.darkkronicle.advancedchatcore.util.StringMatch;
15 | import java.util.ArrayList;
16 | import java.util.List;
17 | import java.util.Optional;
18 | import java.util.function.Supplier;
19 | import net.fabricmc.api.EnvType;
20 | import net.fabricmc.api.Environment;
21 | import org.apache.logging.log4j.Level;
22 |
23 | @Environment(EnvType.CLIENT)
24 | public class CustomFinder extends AbstractRegistry
25 | implements IFinder {
26 |
27 | private static final CustomFinder INSTANCE = new CustomFinder();
28 |
29 | public static CustomFinder getInstance() {
30 | return INSTANCE;
31 | }
32 |
33 | private CustomFinder() {}
34 |
35 | public static final String NAME = "customfind";
36 |
37 | @Override
38 | public boolean isMatch(String input, String toMatch) {
39 | Optional option = getFinder(toMatch);
40 | if (option.isEmpty()) {
41 | // Invalid :(
42 | AdvancedChatCore.LOGGER.log(Level.WARN, getHelp(toMatch));
43 | return false;
44 | }
45 | return option.get().isMatch(input, toMatch);
46 | }
47 |
48 | private String getHelp(String toMatch) {
49 | StringBuilder builder =
50 | new StringBuilder()
51 | .append("Custom find type was used but the match ")
52 | .append(toMatch)
53 | .append(" does not exist in the registry! Possible correct options: ");
54 | for (CustomFinderOption o : getAll()) {
55 | builder.append(o.saveString).append(", ");
56 | }
57 | return builder.substring(0, builder.length() - 2);
58 | }
59 |
60 | @Override
61 | public List getMatches(String input, String toMatch) {
62 | Optional option = getFinder(toMatch);
63 | if (option.isEmpty()) {
64 | // Invalid :(
65 | AdvancedChatCore.LOGGER.log(Level.WARN, getHelp(toMatch));
66 | return new ArrayList<>();
67 | }
68 | return option.get().getMatches(input, toMatch);
69 | }
70 |
71 | public Optional getFinder(String toMatch) {
72 | for (CustomFinderOption o : getAll()) {
73 | if (toMatch.startsWith(o.saveString)) {
74 | return Optional.of(o.getOption());
75 | }
76 | }
77 | return Optional.empty();
78 | }
79 |
80 | @Override
81 | public CustomFinder clone() {
82 | CustomFinder finder = new CustomFinder();
83 | for (CustomFinderOption o : getAll()) {
84 | finder.add(o.copy(this));
85 | }
86 | return finder;
87 | }
88 |
89 | @Override
90 | public CustomFinderOption constructOption(
91 | Supplier type,
92 | String saveString,
93 | String translation,
94 | String infoTranslation,
95 | boolean active,
96 | boolean setDefault,
97 | boolean hidden) {
98 | return new CustomFinderOption(
99 | type, saveString, translation, infoTranslation, active, hidden, this);
100 | }
101 |
102 | public static class CustomFinderOption implements RegistryOption {
103 |
104 | private final IFinder finder;
105 | private final String saveString;
106 | private final String translation;
107 | private final CustomFinder registry;
108 | private final String infoTranslation;
109 | private final boolean hidden;
110 | private final boolean active;
111 |
112 | private CustomFinderOption(
113 | Supplier finder,
114 | String saveString,
115 | String translation,
116 | String infoTranslation,
117 | boolean active,
118 | boolean hidden,
119 | CustomFinder registry) {
120 | this(finder.get(), saveString, translation, infoTranslation, active, hidden, registry);
121 | }
122 |
123 | // Only register
124 | private CustomFinderOption(
125 | IFinder finder,
126 | String saveString,
127 | String translation,
128 | String infoTranslation,
129 | boolean active,
130 | boolean hidden,
131 | CustomFinder registry) {
132 | this.finder = finder;
133 | this.saveString = saveString;
134 | this.translation = translation;
135 | this.registry = registry;
136 | this.infoTranslation = infoTranslation;
137 | this.hidden = hidden;
138 | this.active = active;
139 | }
140 |
141 | @Override
142 | public IFinder getOption() {
143 | return finder;
144 | }
145 |
146 | @Override
147 | public boolean isActive() {
148 | return active;
149 | }
150 |
151 | @Override
152 | public String getSaveString() {
153 | return saveString;
154 | }
155 |
156 | @Override
157 | public CustomFinderOption copy(AbstractRegistry registry) {
158 | return new CustomFinderOption(
159 | finder,
160 | saveString,
161 | translation,
162 | infoTranslation,
163 | isActive(),
164 | isHidden(),
165 | registry == null ? this.registry : (CustomFinder) registry);
166 | }
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/finder/LiteralFinder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.finder;
9 |
10 | import java.util.regex.Pattern;
11 |
12 | public class LiteralFinder extends PatternFinder {
13 | @Override
14 | public Pattern getPattern(String toMatch) {
15 | return Pattern.compile(Pattern.quote(toMatch));
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/finder/PatternFinder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.finder;
9 |
10 | import io.github.darkkronicle.advancedchatcore.interfaces.IFinder;
11 | import io.github.darkkronicle.advancedchatcore.util.StringMatch;
12 | import org.jetbrains.annotations.Nullable;
13 |
14 | import java.util.ArrayList;
15 | import java.util.List;
16 | import java.util.regex.Matcher;
17 | import java.util.regex.Pattern;
18 |
19 | public abstract class PatternFinder implements IFinder {
20 |
21 | @Nullable
22 | public abstract Pattern getPattern(String toMatch);
23 |
24 | @Override
25 | public boolean isMatch(String input, String toMatch) {
26 | Pattern pattern = getPattern(toMatch);
27 | if (pattern == null) {
28 | return false;
29 | }
30 | return pattern.matcher(input).find();
31 | }
32 |
33 | @Override
34 | public List getMatches(String input, String toMatch) {
35 | List matches = new ArrayList<>();
36 | Pattern pattern = getPattern(toMatch);
37 | if (pattern == null) {
38 | return matches;
39 | }
40 | Matcher matcher = pattern.matcher(input);
41 | while (matcher.find()) {
42 | matches.add(new StringMatch(matcher.group(), matcher.start(), matcher.end()));
43 | }
44 | matcher.reset();
45 | return matches;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/finder/UpperLowerFinder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.finder;
9 |
10 | import java.util.regex.Pattern;
11 |
12 | public class UpperLowerFinder extends PatternFinder {
13 | @Override
14 | public Pattern getPattern(String toMatch) {
15 | return Pattern.compile(Pattern.quote(toMatch), Pattern.CASE_INSENSITIVE);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/finder/custom/ProfanityFinder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.finder.custom;
9 |
10 | import io.github.darkkronicle.advancedchatcore.config.ConfigStorage;
11 | import io.github.darkkronicle.advancedchatcore.interfaces.IFinder;
12 | import io.github.darkkronicle.advancedchatcore.util.ProfanityUtil;
13 | import io.github.darkkronicle.advancedchatcore.util.StringMatch;
14 | import java.util.List;
15 | import net.fabricmc.api.EnvType;
16 | import net.fabricmc.api.Environment;
17 |
18 | @Environment(EnvType.CLIENT)
19 | public class ProfanityFinder implements IFinder {
20 | @Override
21 | public boolean isMatch(String input, String toMatch) {
22 | return getMatches(input, toMatch).size() != 0;
23 | }
24 |
25 | @Override
26 | public List getMatches(String input, String toMatch) {
27 | return ProfanityUtil.getInstance().getBadWords(input, (float) ConfigStorage.General.PROFANITY_ABOVE.config.getDoubleValue(), ConfigStorage.General.PROFANITY_ON_WORD_BOUNDARIES.config.getBooleanValue());
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/gui/CleanButton.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.gui;
9 |
10 | import fi.dy.masa.malilib.gui.button.ButtonBase;
11 | import fi.dy.masa.malilib.render.RenderUtils;
12 | import io.github.darkkronicle.advancedchatcore.util.Color;
13 | import io.github.darkkronicle.advancedchatcore.util.Colors;
14 | import lombok.EqualsAndHashCode;
15 | import lombok.ToString;
16 | import net.fabricmc.api.EnvType;
17 | import net.fabricmc.api.Environment;
18 | import net.minecraft.client.MinecraftClient;
19 | import net.minecraft.client.gui.DrawContext;
20 | import net.minecraft.client.util.math.MatrixStack;
21 |
22 | /** A simple button */
23 | @EqualsAndHashCode(callSuper = false)
24 | @ToString
25 | @Environment(EnvType.CLIENT)
26 | public class CleanButton extends ButtonBase {
27 |
28 | protected Color baseColor;
29 |
30 | private MinecraftClient client = MinecraftClient.getInstance();
31 |
32 | /**
33 | * Constructs a new simple clean button
34 | *
35 | * @param x X
36 | * @param y Y
37 | * @param width Width
38 | * @param height Height
39 | * @param baseColor Color that it should render when not hovered
40 | * @param text Text to render
41 | */
42 | public CleanButton(int x, int y, int width, int height, Color baseColor, String text) {
43 | super(x, y, width, height, text);
44 | this.x = x;
45 | this.y = y;
46 | this.baseColor = baseColor;
47 | }
48 |
49 | @Override
50 | public void render(int mouseX, int mouseY, boolean selected, DrawContext context) {
51 | int relMX = mouseX - x;
52 | int relMY = mouseY - y;
53 | hovered = relMX >= 0 && relMX <= width && relMY >= 0 && relMY <= height;
54 | Color color = baseColor;
55 | if (hovered) {
56 | color = Colors.getInstance().getColor("white").get().withAlpha(color.alpha());
57 | }
58 | RenderUtils.drawRect(x, y, width, height, color.color());
59 | drawCenteredString(
60 | (x + (width / 2)),
61 | (y + (height / 2) - 3),
62 | Colors.getInstance().getColorOrWhite("white").color(),
63 | displayString,
64 | context);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/gui/ConfigGuiListBase.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.gui;
9 |
10 | import fi.dy.masa.malilib.gui.widgets.WidgetListBase;
11 | import fi.dy.masa.malilib.gui.widgets.WidgetListEntryBase;
12 | import io.github.darkkronicle.advancedchatcore.config.gui.GuiConfig;
13 | import io.github.darkkronicle.advancedchatcore.config.gui.GuiConfigHandler;
14 | import java.util.List;
15 |
16 | /** GUI list base to work in a configuration screen */
17 | public abstract class ConfigGuiListBase<
18 | TYPE,
19 | WIDGET extends WidgetListEntryBase,
20 | WIDGETLIST extends WidgetListBase>
21 | extends CoreGuiListBase {
22 |
23 | public ConfigGuiListBase(List tabButtons) {
24 | this(10, 60, tabButtons);
25 | }
26 |
27 | public ConfigGuiListBase() {
28 | this(10, 60, null);
29 | }
30 |
31 | public ConfigGuiListBase(int listX, int listY, List tabButtons) {
32 | super(listX, listY);
33 | }
34 |
35 | @Override
36 | public void initGui() {
37 | super.initGui();
38 |
39 | int x = 10;
40 | int y = 26;
41 |
42 | y += (22 * GuiConfig.addTabButtons(this, 10, y));
43 | if (GuiConfig.TAB.getChildren() != null && GuiConfig.TAB.getChildren().size() > 0) {
44 | y += (22 * GuiConfig.addAllChildrenButtons(this, GuiConfig.TAB, 10, y));
45 | }
46 | this.setListPosition(this.getListX(), y);
47 | this.reCreateListWidget();
48 | this.getListWidget().refreshEntries();
49 |
50 | y += 24;
51 |
52 | initGuiConfig(x, y);
53 | }
54 |
55 | /** Method when the GUI is initialized. This one takes an X,Y that is away from the buttons */
56 | public void initGuiConfig(int x, int y) {}
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/gui/ContextMenu.java:
--------------------------------------------------------------------------------
1 | package io.github.darkkronicle.advancedchatcore.gui;
2 |
3 | import fi.dy.masa.malilib.gui.widgets.WidgetBase;
4 | import io.github.darkkronicle.advancedchatcore.util.Color;
5 | import io.github.darkkronicle.advancedchatcore.util.TextUtil;
6 | import lombok.Getter;
7 | import lombok.Setter;
8 | import net.minecraft.client.MinecraftClient;
9 | import net.minecraft.client.gui.DrawContext;
10 | import net.minecraft.text.Text;
11 |
12 | import java.util.LinkedHashMap;
13 |
14 | public class ContextMenu extends WidgetBase {
15 |
16 | private final LinkedHashMap options;
17 | private Text hoveredEntry = null;
18 |
19 | @Getter
20 | private final int contextX;
21 |
22 | @Getter
23 | private final int contextY;
24 |
25 | @Getter
26 | @Setter
27 | private Runnable close;
28 |
29 | @Setter
30 | @Getter
31 | private Color background;
32 |
33 | @Setter
34 | @Getter
35 | private Color hover;
36 |
37 | public ContextMenu(int x, int y, LinkedHashMap options, Runnable close) {
38 | this(x, y, options, close, new Color(0, 0, 0, 200), new Color(255, 255, 255, 100));
39 | }
40 |
41 | public ContextMenu(int x, int y, LinkedHashMap options, Runnable close, Color background, Color hover) {
42 | super(x, y, 10, 10);
43 | this.contextX = x;
44 | this.contextY = y;
45 | this.options = options;
46 | updateDimensions();
47 | this.close = close;
48 | this.background = background;
49 | this.hover = hover;
50 | }
51 |
52 | public void updateDimensions() {
53 | setWidth(TextUtil.getMaxLengthString(options.keySet().stream().map(Text::getString).toList()) + 4);
54 | setHeight(options.size() * (textRenderer.fontHeight + 2));
55 | int windowWidth = MinecraftClient.getInstance().getWindow().getScaledWidth();
56 | int windowHeight = MinecraftClient.getInstance().getWindow().getScaledHeight();
57 | if (x + width > windowWidth) {
58 | x = windowWidth - width;
59 | }
60 | if (y + height > windowHeight) {
61 | y = windowHeight - height;
62 | }
63 | }
64 |
65 | @Override
66 | public boolean onMouseClicked(int mouseX, int mouseY, int mouseButton) {
67 | boolean success = super.onMouseClicked(mouseX, mouseY, mouseButton);
68 | if (success) {
69 | return true;
70 | }
71 | // Didn't click on this
72 | close.run();
73 | return false;
74 | }
75 |
76 | @Override
77 | protected boolean onMouseClickedImpl(int mouseX, int mouseY, int mouseButton) {
78 | if (mouseButton != 0) {
79 | return false;
80 | }
81 | if (hoveredEntry == null) {
82 | return false;
83 | }
84 | options.get(hoveredEntry).takeAction(contextX, contextY);
85 | close.run();
86 | return true;
87 | }
88 |
89 | @Override
90 | public void render(int mouseX, int mouseY, boolean selected, DrawContext context) {
91 | drawRect(context, x, y, width, height, background.color());
92 | int rX = x + 2;
93 | int rY = y + 2;
94 | hoveredEntry = null;
95 | for (Text option : options.keySet()) {
96 | if (mouseX >= x && mouseX <= x + width && mouseY >= rY - 2 && mouseY < rY + fontHeight + 1) {
97 | hoveredEntry = option;
98 | drawRect(context, rX - 2, rY - 2, width, textRenderer.fontHeight + 2, hover.color());
99 | }
100 | context.drawTextWithShadow(textRenderer, option, rX, rY, -1);
101 | rY += textRenderer.fontHeight + 2;
102 | }
103 | }
104 |
105 | private static void drawRect(DrawContext context, int x, int y, int width, int height, int color) {
106 | context.fill(x, y, x + width, y + height, color);
107 | }
108 |
109 | public interface ContextConsumer {
110 | void takeAction(int x, int y);
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/gui/CoreGuiListBase.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.gui;
9 |
10 | import fi.dy.masa.malilib.gui.GuiListBase;
11 | import fi.dy.masa.malilib.gui.button.ButtonBase;
12 | import fi.dy.masa.malilib.gui.interfaces.ISelectionListener;
13 | import fi.dy.masa.malilib.gui.widgets.WidgetListBase;
14 | import fi.dy.masa.malilib.gui.widgets.WidgetListEntryBase;
15 | import io.github.darkkronicle.advancedchatcore.interfaces.IClosable;
16 |
17 | public abstract class CoreGuiListBase<
18 | TYPE,
19 | WIDGET extends WidgetListEntryBase,
20 | WIDGETLIST extends WidgetListBase>
21 | extends GuiListBase
22 | implements ISelectionListener, IClosable {
23 |
24 | public CoreGuiListBase(int listX, int listY) {
25 | super(listX, listY);
26 | }
27 |
28 | @Override
29 | protected WIDGETLIST createListWidget(int listX, int listY) {
30 | return null;
31 | }
32 |
33 | @Override
34 | protected int getBrowserWidth() {
35 | return this.width - 20;
36 | }
37 |
38 | @Override
39 | protected int getBrowserHeight() {
40 | return this.height - 6 - this.getListY();
41 | }
42 |
43 | @Override
44 | public void onSelectionChange(TYPE entry) {}
45 |
46 | @Override
47 | public void close(ButtonBase button) {
48 | this.closeGui(true);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/gui/IconButton.java:
--------------------------------------------------------------------------------
1 | package io.github.darkkronicle.advancedchatcore.gui;
2 |
3 | import fi.dy.masa.malilib.render.RenderUtils;
4 | import io.github.darkkronicle.advancedchatcore.util.Color;
5 | import io.github.darkkronicle.advancedchatcore.util.Colors;
6 | import lombok.Getter;
7 | import lombok.Setter;
8 | import net.minecraft.client.MinecraftClient;
9 | import net.minecraft.client.gui.DrawContext;
10 | import net.minecraft.client.sound.PositionedSoundInstance;
11 | import net.minecraft.client.util.math.MatrixStack;
12 | import net.minecraft.sound.SoundEvents;
13 | import net.minecraft.util.Identifier;
14 |
15 | import java.util.function.Consumer;
16 |
17 | public class IconButton extends CleanButton {
18 |
19 | @Setter
20 | @Getter
21 | private int padding;
22 |
23 | @Setter
24 | @Getter
25 | private Identifier icon;
26 |
27 | @Setter
28 | @Getter
29 | private int iconWidth;
30 |
31 | @Setter
32 | @Getter
33 | private int iconHeight;
34 |
35 | @Setter
36 | @Getter
37 | private Consumer onClick;
38 |
39 | @Getter
40 | @Setter
41 | private String onHover;
42 |
43 | public IconButton(int x, int y, int sideLength, int iconLength, Identifier icon, Consumer mouseClick) {
44 | this(x, y, sideLength, sideLength, iconLength, iconLength, icon, mouseClick);
45 | }
46 |
47 | public IconButton(int x, int y, int width, int height, int iconWidth, int iconHeight, Identifier icon, Consumer mouseClick) {
48 | this(x, y, width, height, 2, iconWidth, iconHeight, icon, mouseClick, null);
49 | }
50 |
51 | public IconButton(int x, int y, int width, int height, int padding, int iconWidth, int iconHeight, Identifier icon, Consumer mouseClick, String onHover) {
52 | super(x, y, width, height, null, null);
53 | this.padding = padding;
54 | this.iconWidth = iconWidth;
55 | this.iconHeight = iconHeight;
56 | this.icon = icon;
57 | this.onClick = mouseClick;
58 | this.onHover = onHover;
59 | }
60 |
61 | @Override
62 | public void render(int mouseX, int mouseY, boolean unused, DrawContext context) {
63 | int relMX = mouseX - x;
64 | int relMY = mouseY - y;
65 | hovered = relMX >= 0 && relMX <= width && relMY >= 0 && relMY <= height;
66 |
67 | Color plusBack = Colors.getInstance().getColorOrWhite("background").withAlpha(100);
68 | if (hovered) {
69 | plusBack = Colors.getInstance().getColorOrWhite("hover").withAlpha(plusBack.alpha());
70 | }
71 |
72 | RenderUtils.drawRect(x, y, width, height, plusBack.color());
73 |
74 | RenderUtils.color(1, 1, 1, 1);
75 | RenderUtils.bindTexture(icon);
76 | context.drawTexture(icon, x + padding, y + padding, width - (padding * 2), height - (padding * 2),
77 | 0, 0, iconWidth, iconHeight, iconWidth, iconHeight);
78 |
79 | if (hovered && onHover != null) {
80 | context.drawCenteredTextWithShadow(
81 | MinecraftClient.getInstance().textRenderer,
82 | onHover,
83 | mouseX + 4,
84 | mouseY - 16,
85 | Colors.getInstance().getColorOrWhite("white").color());
86 | }
87 | }
88 |
89 | @Override
90 | protected boolean onMouseClickedImpl(int mouseX, int mouseY, int mouseButton) {
91 | this.mc.getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F));
92 | onClick.accept(this);
93 | return true;
94 | }
95 |
96 | }
97 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/gui/WidgetConfigList.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.gui;
9 |
10 | import fi.dy.masa.malilib.gui.GuiTextFieldGeneric;
11 | import fi.dy.masa.malilib.gui.interfaces.ISelectionListener;
12 | import fi.dy.masa.malilib.gui.widgets.WidgetListBase;
13 | import fi.dy.masa.malilib.gui.wrappers.TextFieldWrapper;
14 | import java.util.ArrayList;
15 | import java.util.List;
16 | import net.minecraft.client.gui.screen.Screen;
17 |
18 | public abstract class WidgetConfigList>
19 | extends WidgetListBase {
20 |
21 | protected List> textFields = new ArrayList<>();
22 |
23 | public WidgetConfigList(
24 | int x,
25 | int y,
26 | int width,
27 | int height,
28 | ISelectionListener selectionListener,
29 | Screen parent) {
30 | super(x, y, width, height, selectionListener);
31 | this.browserEntryHeight = 22;
32 | this.setParent(parent);
33 | }
34 |
35 | @Override
36 | protected void reCreateListEntryWidgets() {
37 | textFields.clear();
38 | super.reCreateListEntryWidgets();
39 | }
40 |
41 | public void addTextField(TextFieldWrapper text) {
42 | textFields.add(text);
43 | }
44 |
45 | protected void clearTextFieldFocus() {
46 | for (TextFieldWrapper field : this.textFields) {
47 | GuiTextFieldGeneric textField = field.getTextField();
48 |
49 | if (textField.isFocused()) {
50 | textField.setFocused(false);
51 | break;
52 | }
53 | }
54 | }
55 |
56 | @Override
57 | public boolean onMouseClicked(int mouseX, int mouseY, int mouseButton) {
58 | clearTextFieldFocus();
59 | return super.onMouseClicked(mouseX, mouseY, mouseButton);
60 | }
61 |
62 | @Override
63 | public boolean onKeyTyped(int keyCode, int scanCode, int modifiers) {
64 | for (WidgetConfigListEntry widget : this.listWidgets) {
65 | if (widget.onKeyTyped(keyCode, scanCode, modifiers)) {
66 | return true;
67 | }
68 | }
69 | return super.onKeyTyped(keyCode, scanCode, modifiers);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/gui/buttons/BackButtonListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.gui.buttons;
9 |
10 | import fi.dy.masa.malilib.gui.button.ButtonBase;
11 | import fi.dy.masa.malilib.gui.button.IButtonActionListener;
12 | import io.github.darkkronicle.advancedchatcore.interfaces.IClosable;
13 |
14 | public class BackButtonListener implements IButtonActionListener {
15 |
16 | private final IClosable closable;
17 |
18 | public BackButtonListener(IClosable closable) {
19 | this.closable = closable;
20 | }
21 |
22 | @Override
23 | public void actionPerformedWithButton(ButtonBase button, int mouseButton) {
24 | this.closable.close(button);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/gui/buttons/Buttons.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.gui.buttons;
9 |
10 | import fi.dy.masa.malilib.util.StringUtils;
11 |
12 | public enum Buttons {
13 | BACK("advancedchat.gui.button.back");
14 |
15 | private final String translationString;
16 |
17 | Buttons(String translationString) {
18 | this.translationString = translationString;
19 | }
20 |
21 | public NamedSimpleButton createButton(int x, int y) {
22 | return new NamedSimpleButton(x, y, StringUtils.translate(translationString));
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/gui/buttons/ConfigTabsButtonListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.gui.buttons;
9 |
10 | import fi.dy.masa.malilib.gui.GuiBase;
11 | import fi.dy.masa.malilib.gui.button.ButtonBase;
12 | import fi.dy.masa.malilib.gui.button.IButtonActionListener;
13 | import io.github.darkkronicle.advancedchatcore.config.gui.GuiConfig;
14 | import io.github.darkkronicle.advancedchatcore.config.gui.GuiConfigHandler;
15 | import net.fabricmc.api.EnvType;
16 | import net.fabricmc.api.Environment;
17 |
18 | @Deprecated
19 | @Environment(EnvType.CLIENT)
20 | public class ConfigTabsButtonListener implements IButtonActionListener {
21 |
22 | private final GuiConfigHandler.TabButton tabButton;
23 |
24 | public ConfigTabsButtonListener(GuiConfigHandler.TabButton tabButton) {
25 | this.tabButton = tabButton;
26 | }
27 |
28 | @Override
29 | public void actionPerformedWithButton(ButtonBase button, int mouseButton) {
30 | GuiConfig.TAB = tabButton.getTabSupplier();
31 | GuiBase.openGui(new GuiConfig());
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/gui/buttons/NamedSimpleButton.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.gui.buttons;
9 |
10 | import fi.dy.masa.malilib.gui.button.ButtonGeneric;
11 | import fi.dy.masa.malilib.util.StringUtils;
12 |
13 | public class NamedSimpleButton extends ButtonGeneric {
14 |
15 | public NamedSimpleButton(int x, int y, String text) {
16 | this(x, y, text, true);
17 | }
18 |
19 | public NamedSimpleButton(int x, int y, String text, boolean alineLeft) {
20 | super(x, y, 5, 20, text);
21 | setWidth(StringUtils.getStringWidth(text) + 10);
22 | if (!alineLeft) {
23 | setX(this.x - this.width);
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/hotkeys/InputHandler.java:
--------------------------------------------------------------------------------
1 | package io.github.darkkronicle.advancedchatcore.hotkeys;
2 |
3 | import fi.dy.masa.malilib.config.options.ConfigHotkey;
4 | import fi.dy.masa.malilib.event.InputEventHandler;
5 | import fi.dy.masa.malilib.hotkeys.*;
6 | import lombok.Getter;
7 |
8 | import java.util.ArrayList;
9 | import java.util.HashMap;
10 | import java.util.List;
11 | import java.util.Map;
12 |
13 | public class InputHandler implements IKeybindProvider, IKeyboardInputHandler, IMouseInputHandler {
14 |
15 | private final static InputHandler INSTANCE = new InputHandler();
16 | @Getter
17 | private final Map> hotkeys = new HashMap<>();
18 | @Getter
19 | private final Map translation = new HashMap<>();
20 |
21 | public static InputHandler getInstance() {
22 | return INSTANCE;
23 | }
24 |
25 | private InputHandler() {}
26 |
27 | public void clear(String modId) {
28 | hotkeys.remove(modId);
29 | }
30 |
31 | public void addDisplayName(String modId, String displayName) {
32 | translation.put(modId, displayName);
33 | }
34 |
35 | public void add(String modId, ConfigHotkey hotkey) {
36 | if (!hotkeys.containsKey(modId)) {
37 | hotkeys.put(modId, new ArrayList<>());
38 | }
39 | hotkeys.get(modId).add(hotkey);
40 | }
41 |
42 | public void add(String modId, ConfigHotkey hotkey, IHotkeyCallback callback) {
43 | hotkey.getKeybind().setCallback(callback);
44 | add(modId, hotkey);
45 | }
46 |
47 | @Override
48 | public void addKeysToMap(IKeybindManager manager) {
49 | for (List hots : hotkeys.values()) {
50 | for (IHotkey hotkey : hots) {
51 | manager.addKeybindToMap(hotkey.getKeybind());
52 | }
53 | }
54 | }
55 |
56 | @Override
57 | public void addHotkeys(IKeybindManager manager) {
58 | for (Map.Entry> hots : hotkeys.entrySet()) {
59 | manager.addHotkeysForCategory(hots.getKey(), "hotkeys", hots.getValue());
60 | }
61 | }
62 |
63 | public void reload() {
64 | InputEventHandler.getKeybindManager().updateUsedKeys();
65 | }
66 |
67 | public String getDisplayName(String key) {
68 | return translation.getOrDefault(key, key);
69 | }
70 | }
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/interfaces/AdvancedChatScreenSection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.interfaces;
9 |
10 | import io.github.darkkronicle.advancedchatcore.chat.AdvancedChatScreen;
11 | import lombok.Getter;
12 | import net.minecraft.client.gui.Drawable;
13 | import net.minecraft.client.util.math.MatrixStack;
14 |
15 | /**
16 | * A class meant to extend onto the {@link AdvancedChatScreen}
17 | *
18 | *
This is used so that many modules can add onto the screen without problems occuring.
19 | */
20 | public abstract class AdvancedChatScreenSection implements Drawable {
21 |
22 | /** The {@link AdvancedChatScreen} that is linked to this section */
23 | @Getter private final AdvancedChatScreen screen;
24 |
25 | public AdvancedChatScreenSection(AdvancedChatScreen screen) {
26 | this.screen = screen;
27 | }
28 |
29 | /** Triggers when the gui is initiated */
30 | public void initGui() {}
31 |
32 | /**
33 | * Triggered when the window is resized
34 | *
35 | * @param width Window width
36 | * @param height Window height
37 | */
38 | public void resize(int width, int height) {}
39 |
40 | /** Triggered when the GUI is closed */
41 | public void removed() {}
42 |
43 | /**
44 | * Triggered when the chatfield text is pudated
45 | *
46 | * @param chatText Updated value (?)
47 | * @param text The text of the chatfield
48 | */
49 | public void onChatFieldUpdate(String chatText, String text) {}
50 |
51 | /**
52 | * Triggered when a key is pressed
53 | *
54 | * @param keyCode Keycode
55 | * @param scanCode Scancode
56 | * @param modifiers Modifiers
57 | * @return If it was handled and should stop.
58 | */
59 | public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
60 | return false;
61 | }
62 |
63 | /**
64 | * Triggered when the mouse is scrolled
65 | *
66 | * @param mouseX MouseX
67 | * @param mouseY MouseY
68 | * @param amount Scroll amount
69 | * @return If it was handled and should stop.
70 | */
71 | public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
72 | return false;
73 | }
74 |
75 | /**
76 | * Triggered when the mouse is clicked
77 | *
78 | * @param mouseX MouseX
79 | * @param mouseY MouseY
80 | * @param button Mouse button
81 | * @return If it was handled and should stop.
82 | */
83 | public boolean mouseClicked(double mouseX, double mouseY, int button) {
84 | return false;
85 | }
86 |
87 | /**
88 | * Triggered when the mouse click is released
89 | *
90 | * @param mouseX MouseX
91 | * @param mouseY MouseY
92 | * @param mouseButton Mouse button
93 | * @return If it was handled and should stop.
94 | */
95 | public boolean mouseReleased(double mouseX, double mouseY, int mouseButton) {
96 | return false;
97 | }
98 |
99 | /**
100 | * @param mouseX
101 | * @param mouseY
102 | * @param button
103 | * @param deltaX
104 | * @param deltaY
105 | * @return If it was handled and should stop.
106 | */
107 | public boolean mouseDragged(
108 | double mouseX, double mouseY, int button, double deltaX, double deltaY) {
109 | return false;
110 | }
111 |
112 | /**
113 | * Called when the chat field gets set due to history (up arrows)
114 | *
115 | * @param hist History set from
116 | */
117 | public void setChatFromHistory(String hist) {}
118 |
119 | /**
120 | * Called when the screen renders.
121 | *
122 | * @param matrixStack MatrixStack
123 | * @param mouseX MouseX
124 | * @param mouseY MouseY
125 | * @param partialTicks Partial tick from the last tick
126 | */
127 | public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {}
128 | }
129 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/interfaces/ConfigRegistryOption.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.interfaces;
9 |
10 | import com.google.gson.JsonElement;
11 | import com.google.gson.JsonObject;
12 | import fi.dy.masa.malilib.config.IConfigOptionListEntry;
13 | import fi.dy.masa.malilib.config.options.ConfigBoolean;
14 | import io.github.darkkronicle.advancedchatcore.config.SaveableConfig;
15 | import java.util.Map;
16 | import net.fabricmc.api.EnvType;
17 | import net.fabricmc.api.Environment;
18 |
19 | /**
20 | * A {@link RegistryOption} that can be saved and loaded from a JSON file.
21 | *
22 | * @param
23 | */
24 | @Environment(EnvType.CLIENT)
25 | public interface ConfigRegistryOption
26 | extends RegistryOption, IConfigOptionListEntry, IJsonApplier {
27 | /**
28 | * Get's a configurable boolean for whether or not the option is active.
29 | *
30 | * @return Configurable boolean
31 | */
32 | SaveableConfig getActive();
33 |
34 | /**
35 | * Get's if the option is currently active.
36 | *
37 | * @return If the option is active
38 | */
39 | @Override
40 | default boolean isActive() {
41 | return getActive().config.getBooleanValue();
42 | }
43 |
44 | /**
45 | * Save's the config option and the object that it is wrapping.
46 | *
47 | *
By default it will only save if the option is active or not, but if the {@link TYPE}
48 | * implements {@link IJsonApplier} it will also save/load that object.
49 | *
50 | * @return Serialized object
51 | */
52 | @Override
53 | default JsonObject save() {
54 | JsonObject obj = new JsonObject();
55 | obj.add(getActive().key, getActive().config.getAsJsonElement());
56 | JsonObject extra = null;
57 | if (getOption() instanceof IJsonApplier) {
58 | extra = ((IJsonApplier) getOption()).save();
59 | }
60 | if (extra != null) {
61 | for (Map.Entry e : extra.entrySet()) {
62 | obj.add(e.getKey(), e.getValue());
63 | }
64 | }
65 | return obj;
66 | }
67 |
68 | /**
69 | * Load's the config option and the object that it is wrapping.
70 | *
71 | *
By default it will only load if the option is active or not, but if the {@link TYPE}
72 | * implements {@link IJsonApplier} it will also save/load that object.
73 | */
74 | @Override
75 | default void load(JsonElement element) {
76 | if (element == null || !element.isJsonObject()) {
77 | return;
78 | }
79 | JsonObject obj = element.getAsJsonObject();
80 | getActive().config.setValueFromJsonElement(obj.get(getActive().key));
81 | if (getOption() instanceof IJsonApplier) {
82 | ((IJsonApplier) getOption()).load(obj);
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/interfaces/IChatMessageProcessor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.interfaces;
9 |
10 | import io.github.darkkronicle.advancedchatcore.chat.ChatMessage;
11 |
12 | /**
13 | * A processor that will get updated whenever an event in {@link
14 | * io.github.darkkronicle.advancedchatcore.chat.ChatHistory} happens. This gets triggered for
15 | * specific {@link ChatMessage}.
16 | */
17 | public interface IChatMessageProcessor {
18 | /** Types of chat message events that can be referenced */
19 | enum UpdateType {
20 | /** A new message is sent. This still gets triggered even if the message is stacked. */
21 | NEW,
22 |
23 | /** A message is added to the history. This does not get called on stack. */
24 | ADDED,
25 |
26 | /** A previous message has been stacked. The stack number has changed. */
27 | STACK,
28 |
29 | /**
30 | * A message is removed. This does not get called on clear, but only if a specific message
31 | * was called to remove.
32 | */
33 | REMOVE,
34 | }
35 |
36 | /**
37 | * A method to handle a {@link ChatMessage} update.
38 | *
39 | * @param message Message that was updated
40 | * @param type Type of the update
41 | */
42 | void onMessageUpdate(ChatMessage message, UpdateType type);
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/interfaces/IClosable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.interfaces;
9 |
10 | import fi.dy.masa.malilib.gui.button.ButtonBase;
11 |
12 | public interface IClosable {
13 |
14 | void close(ButtonBase button);
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/interfaces/IFinder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.interfaces;
9 |
10 | import io.github.darkkronicle.advancedchatcore.util.StringMatch;
11 | import net.minecraft.text.Text;
12 |
13 | import java.util.List;
14 |
15 | public interface IFinder {
16 |
17 | boolean isMatch(String input, String toMatch);
18 |
19 | default boolean isMatch(Text input, String toMatch) {
20 | return isMatch(input.getString(), toMatch);
21 | }
22 |
23 | List getMatches(String input, String toMatch);
24 |
25 | default List getMatches(Text input, String toMatch) {
26 | return getMatches(input.getString(), toMatch);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/interfaces/IJsonApplier.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.interfaces;
9 |
10 | import com.google.gson.JsonElement;
11 | import com.google.gson.JsonObject;
12 |
13 | /** An interface to serialize and deserialize classes into themselves. */
14 | public interface IJsonApplier {
15 | /**
16 | * Serializes the object into a JsonObject.
17 | *
18 | * @return Constructed JsonObject
19 | */
20 | JsonObject save();
21 |
22 | /**
23 | * Takes a JsonElement and loads it into the class.
24 | *
25 | * @param element Element to load
26 | */
27 | void load(JsonElement element);
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/interfaces/IJsonSave.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.interfaces;
9 |
10 | import com.google.gson.JsonObject;
11 |
12 | /**
13 | * Json serializer for other classes.
14 | *
15 | * @param Class that this class serializes.
16 | */
17 | public interface IJsonSave {
18 | /**
19 | * Returns a new object from a JsonObject to deserialize from.
20 | *
21 | * @param obj Object containing serialized data
22 | * @return Constructed object
23 | */
24 | T load(JsonObject obj);
25 |
26 | /**
27 | * Takes an object (T) and serializes it.
28 | *
29 | * @param t Object to serialize
30 | * @return Serialized {@link JsonObject}
31 | */
32 | JsonObject save(T t);
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/interfaces/IMatchProcessor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021-2022 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.interfaces;
9 |
10 | import io.github.darkkronicle.advancedchatcore.util.SearchResult;
11 | import net.minecraft.text.Text;
12 | import org.jetbrains.annotations.Nullable;
13 |
14 | /**
15 | * An interface to receive text and matches to process.
16 | *
17 | *
Similar to {@link IMessageProcessor} but it takes matches and can return a {@link Result}
18 | */
19 | public interface IMatchProcessor extends IMessageProcessor {
20 | /** Different outcome's the processor can have */
21 | enum Result {
22 | FAIL(false, true, false),
23 | PROCESSED(true, false, false),
24 | FORCE_FORWARD(true, true, true),
25 | FORCE_STOP(true, false, true);
26 |
27 | public final boolean success;
28 | public final boolean forward;
29 | public final boolean force;
30 |
31 | Result(boolean success, boolean forward, boolean force) {
32 | this.success = success;
33 | this.forward = forward;
34 | this.force = force;
35 | }
36 |
37 | public static Result getFromBool(boolean success) {
38 | if (!success) {
39 | return FAIL;
40 | }
41 | return PROCESSED;
42 | }
43 | }
44 |
45 | @Override
46 | default boolean process(Text text, Text unfiltered) {
47 | return processMatches(text, unfiltered, null).success;
48 | }
49 |
50 | /**
51 | * Process specific matches and return how the rest of the processors should be handled
52 | *
53 | * @param text Final text
54 | * @param unfiltered Unfiltered version of text. If not available null.
55 | * @param search {@link SearchResult} matches
56 | * @return The {@link Result} that the method performed
57 | */
58 | Result processMatches(
59 | Text text, @Nullable Text unfiltered, @Nullable SearchResult search);
60 |
61 | /**
62 | * Whether or not this processor should only trigger when matches are present. If false {@link
63 | * SearchResult} can be null.
64 | *
65 | * @return If this processor should only trigger when matches are present
66 | */
67 | default boolean matchesOnly() {
68 | return true;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/interfaces/IMessageFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021-2022 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.interfaces;
9 |
10 | import net.minecraft.text.Text;
11 | import java.util.Optional;
12 |
13 | /** An interface to modify text. */
14 | public interface IMessageFilter {
15 | /**
16 | * Modifies text
17 | *
18 | * @param text Text to modify
19 | * @return Modified text. If empty, the text won't be changed.
20 | */
21 | Optional filter(Text text);
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/interfaces/IMessageProcessor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021-2022 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.interfaces;
9 |
10 | import net.minecraft.client.gui.hud.MessageIndicator;
11 | import net.minecraft.network.message.MessageSignatureData;
12 | import net.minecraft.text.Text;
13 | import java.util.Optional;
14 | import org.jetbrains.annotations.Nullable;
15 |
16 | /** An interface for taking text and processing it. */
17 | public interface IMessageProcessor extends IMessageFilter {
18 | /**
19 | * Processes text without the unfiltered text.
20 | *
21 | *
Deprecated because it won't return anything. If unfiltered doesn't exist, insert null into
22 | * process.
23 | *
24 | * @param text Text to modify
25 | * @return Empty
26 | */
27 | @Deprecated
28 | @Override
29 | default Optional filter(Text text) {
30 | process(text, null);
31 | return Optional.empty();
32 | }
33 |
34 | /**
35 | * Consumes text.
36 | *
37 | * @param text Final text to process
38 | * @param unfiltered Original text (if available)
39 | * @return If the processing was a success
40 | */
41 | boolean process(Text text, @Nullable Text unfiltered);
42 |
43 | default boolean process(Text text, @Nullable Text unfilterered, @Nullable MessageSignatureData signature, @Nullable MessageIndicator indicator) {
44 | return process(text, unfilterered);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/interfaces/IScreenSupplier.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.interfaces;
9 |
10 | import java.util.function.Supplier;
11 | import net.minecraft.client.gui.screen.Screen;
12 | import org.jetbrains.annotations.Nullable;
13 |
14 | /** An interface to supply a screen. */
15 | public interface IScreenSupplier {
16 | /**
17 | * Get's a supplier of a screen based off of a parent.
18 | *
19 | * @param parent Parent screen (nullable)
20 | * @return Supplier of a screen
21 | */
22 | Supplier getScreen(@Nullable Screen parent);
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/interfaces/IStringFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.interfaces;
9 |
10 | import java.util.Optional;
11 |
12 | /** An interface to modify raw string */
13 | public interface IStringFilter {
14 |
15 | Optional filter(String input);
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/interfaces/RegistryOption.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.interfaces;
9 |
10 | import io.github.darkkronicle.advancedchatcore.util.AbstractRegistry;
11 | import java.util.List;
12 | import java.util.function.Supplier;
13 | import net.minecraft.client.gui.screen.Screen;
14 |
15 | /**
16 | * An interface to get a RegistryOption that can be saved/configured in game.
17 | *
18 | * @param Object type to be wrapped
19 | */
20 | public interface RegistryOption {
21 | /**
22 | * Get's the object that this option is wrapping
23 | *
24 | * @return Object that is wrapped
25 | */
26 | TYPE getOption();
27 |
28 | /**
29 | * Whether or not this option is currently active
30 | *
31 | * @return If it is active
32 | */
33 | boolean isActive();
34 |
35 | /**
36 | * Get's the string that will be saved inside of the JSON.
37 | *
38 | * @return Save string
39 | */
40 | String getSaveString();
41 |
42 | /**
43 | * Copies the registry option without a parent registry
44 | *
45 | * @return A copy of this object
46 | */
47 | default RegistryOption copy() {
48 | return copy(null);
49 | }
50 |
51 | /**
52 | * If this value should be hidden in the menu
53 | *
54 | * @return If it should be hidden
55 | */
56 | default boolean isHidden() {
57 | return false;
58 | }
59 |
60 | /**
61 | * Copies the registry option with a parent registry that it will be tied to.
62 | *
63 | *
Used for copying registries so that options can be modified easily.
64 | *
65 | * @param registry Registry that will be the parent
66 | * @return Copied object
67 | */
68 | RegistryOption copy(AbstractRegistry registry);
69 |
70 | /**
71 | * Get's the configuration screen of this option. If this isn't null a button will be generated
72 | * if in a GUI.
73 | *
74 | * @param parent Parent screen
75 | * @return Supplier for the config screen. Null if it doesn't exist.
76 | */
77 | default Supplier getScreen(Screen parent) {
78 | if (!(getOption() instanceof IScreenSupplier)) {
79 | return null;
80 | }
81 | return ((IScreenSupplier) getOption()).getScreen(parent);
82 | }
83 |
84 | /**
85 | * Hover lines to show when in the GUI and hovering.
86 | *
87 | * @return List of strings that contain the hover lines
88 | */
89 | default List getHoverLines() {
90 | return null;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/interfaces/Translatable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.interfaces;
9 |
10 | import fi.dy.masa.malilib.util.StringUtils;
11 |
12 | /** An interface for a translatable object */
13 | public interface Translatable {
14 | /**
15 | * Translation key of the object
16 | *
17 | * @return Translation key
18 | */
19 | String getTranslationKey();
20 |
21 | /**
22 | * Translates the object
23 | *
24 | * @return Translated string
25 | */
26 | default String translate() {
27 | return StringUtils.translate(getTranslationKey());
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/konstruct/AdvancedChatKonstruct.java:
--------------------------------------------------------------------------------
1 | package io.github.darkkronicle.advancedchatcore.konstruct;
2 |
3 | import io.github.darkkronicle.Konstruct.functions.Function;
4 | import io.github.darkkronicle.Konstruct.functions.NamedFunction;
5 | import io.github.darkkronicle.Konstruct.functions.Variable;
6 | import io.github.darkkronicle.Konstruct.nodes.Node;
7 | import io.github.darkkronicle.Konstruct.parser.*;
8 | import io.github.darkkronicle.Konstruct.reader.builder.NodeBuilder;
9 | import io.github.darkkronicle.Konstruct.type.IntegerObject;
10 | import io.github.darkkronicle.Konstruct.type.StringObject;
11 | import io.github.darkkronicle.addons.*;
12 | import io.github.darkkronicle.advancedchatcore.AdvancedChatCore;
13 | import io.github.darkkronicle.advancedchatcore.util.Color;
14 | import io.github.darkkronicle.advancedchatcore.util.Colors;
15 | import io.github.darkkronicle.advancedchatcore.util.TextUtil;
16 | import lombok.Getter;
17 | import net.minecraft.util.Util;
18 |
19 | import java.util.List;
20 |
21 | public class AdvancedChatKonstruct {
22 |
23 | private static final AdvancedChatKonstruct INSTANCE = new AdvancedChatKonstruct();
24 |
25 | public static AdvancedChatKonstruct getInstance() {
26 | return INSTANCE;
27 | }
28 |
29 | @Getter
30 | private NodeProcessor processor;
31 |
32 | private AdvancedChatKonstruct() {
33 | reset();
34 | addFunction(new CalculatorFunction());
35 | addFunction(new RandomFunction());
36 | addFunction(new ReplaceFunction());
37 | addFunction(new RoundFunction());
38 | addFunction(new OwOFunction());
39 | addFunction(new RomanNumeralFunction());
40 | addFunction(new IsMatchFunction());
41 | addFunction(new TimeFunction());
42 | addVariable("server", () -> new StringObject(AdvancedChatCore.getServer()));
43 | addFunction("randomString", new Function() {
44 | @Override
45 | public Result parse(ParseContext context, List input) {
46 | return Result.success(AdvancedChatCore.getRandomString());
47 | }
48 |
49 | @Override
50 | public IntRange getArgumentCount() {
51 | return IntRange.none();
52 | }
53 | });
54 | addFunction("getColor", new Function() {
55 | @Override
56 | public Result parse(ParseContext context, List input) {
57 | Result res = Function.parseArgument(context, input, 0);
58 | if (Function.shouldReturn(res)) return res;
59 | Color color = Colors.getInstance().getColorOrWhite(res.getContent().getString());
60 | return Result.success(color.getString());
61 | }
62 |
63 | @Override
64 | public IntRange getArgumentCount() {
65 | return IntRange.of(1);
66 | }
67 | });
68 | addFunction("superscript", new Function() {
69 | @Override
70 | public Result parse(ParseContext context, List input) {
71 | int number;
72 | try {
73 | Result res = Function.parseArgument(context, input, 0);
74 | if (Function.shouldReturn(res)) return res;
75 | number = Integer.parseInt(res.getContent().getString().strip());
76 | } catch (NumberFormatException e) {
77 | return Result.success("NaN");
78 | }
79 | return Result.success(TextUtil.toSuperscript(number));
80 | }
81 |
82 | @Override
83 | public IntRange getArgumentCount() {
84 | return IntRange.of(1);
85 | }
86 | });
87 | addVariable("ms", () -> new IntegerObject((int) Util.getMeasuringTimeMs()));
88 | }
89 |
90 | public ParseResult parse(Node node) {
91 | return processor.parse(node);
92 | }
93 |
94 | public Node getNode(String string) {
95 | return new NodeBuilder(string).build();
96 | }
97 |
98 | public NodeProcessor copy() {
99 | return processor.copy();
100 | }
101 |
102 | /** Not really recommended to call... */
103 | public void reset() {
104 | this.processor = new NodeProcessor();
105 | }
106 |
107 | public void addVariable(String key, Variable variable) {
108 | processor.addVariable(key, variable);
109 | }
110 |
111 | public void addFunction(NamedFunction function) {
112 | processor.addFunction(function);
113 | }
114 |
115 | public void addFunction(String key, Function function) {
116 | processor.addFunction(key, function);
117 | }
118 |
119 | }
120 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/konstruct/StringMatchObject.java:
--------------------------------------------------------------------------------
1 | package io.github.darkkronicle.advancedchatcore.konstruct;
2 |
3 | import io.github.darkkronicle.Konstruct.functions.ObjectFunction;
4 | import io.github.darkkronicle.Konstruct.nodes.Node;
5 | import io.github.darkkronicle.Konstruct.parser.IntRange;
6 | import io.github.darkkronicle.Konstruct.parser.ParseContext;
7 | import io.github.darkkronicle.Konstruct.parser.Result;
8 | import io.github.darkkronicle.Konstruct.type.IntegerObject;
9 | import io.github.darkkronicle.Konstruct.type.KonstructObject;
10 | import io.github.darkkronicle.Konstruct.type.StringObject;
11 | import io.github.darkkronicle.advancedchatcore.util.StringMatch;
12 |
13 | import java.util.List;
14 |
15 | public class StringMatchObject extends KonstructObject {
16 |
17 | private final StringMatch result;
18 |
19 | private final static List> FUNCTIONS = List.of(
20 | new ObjectFunction<>() {
21 | @Override
22 | public Result parse(ParseContext context, StringMatchObject self, List input) {
23 | return Result.success(new IntegerObject(self.result.start));
24 | }
25 |
26 | @Override
27 | public String getName() {
28 | return "getStart";
29 | }
30 |
31 | @Override
32 | public IntRange getArgumentCount() {
33 | return IntRange.of(0);
34 | }
35 | },
36 | new ObjectFunction<>() {
37 | @Override
38 | public Result parse(ParseContext context, StringMatchObject self, List input) {
39 | return Result.success(new IntegerObject(self.result.end));
40 | }
41 |
42 | @Override
43 | public String getName() {
44 | return "getEnd";
45 | }
46 |
47 | @Override
48 | public IntRange getArgumentCount() {
49 | return IntRange.of(0);
50 | }
51 | },
52 | new ObjectFunction<>() {
53 | @Override
54 | public Result parse(ParseContext context, StringMatchObject self, List input) {
55 | return Result.success(new StringObject(self.result.match));
56 | }
57 |
58 | @Override
59 | public String getName() {
60 | return "getMessage";
61 | }
62 |
63 | @Override
64 | public IntRange getArgumentCount() {
65 | return IntRange.of(0);
66 | }
67 | }
68 | );
69 |
70 | public StringMatchObject(StringMatch result) {
71 | super(FUNCTIONS);
72 | this.result = result;
73 | }
74 |
75 | @Override
76 | public String getString() {
77 | return result.toString();
78 | }
79 |
80 | @Override
81 | public String getTypeName() {
82 | return "string_match";
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/mixin/MixinChatHud.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.mixin;
9 |
10 | import io.github.darkkronicle.advancedchatcore.chat.AdvancedChatScreen;
11 | import io.github.darkkronicle.advancedchatcore.chat.MessageDispatcher;
12 | import io.github.darkkronicle.advancedchatcore.config.ConfigStorage;
13 | import net.minecraft.client.MinecraftClient;
14 | import net.minecraft.client.gui.hud.ChatHud;
15 | import net.minecraft.client.gui.hud.MessageIndicator;
16 | import net.minecraft.network.message.MessageSignatureData;
17 | import net.minecraft.text.Text;
18 | import org.jetbrains.annotations.Nullable;
19 | import org.spongepowered.asm.mixin.Final;
20 | import org.spongepowered.asm.mixin.Mixin;
21 | import org.spongepowered.asm.mixin.Shadow;
22 | import org.spongepowered.asm.mixin.injection.At;
23 | import org.spongepowered.asm.mixin.injection.Inject;
24 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
25 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
26 |
27 | @Mixin(value = ChatHud.class, priority = 1050)
28 | public class MixinChatHud {
29 |
30 | @Shadow @Final private MinecraftClient client;
31 |
32 | @Inject(
33 | method = "addMessage(Lnet/minecraft/text/Text;Lnet/minecraft/network/message/MessageSignatureData;Lnet/minecraft/client/gui/hud/MessageIndicator;)V",
34 | at = @At("HEAD"),
35 | cancellable = true)
36 | private void addMessage(Text message, @Nullable MessageSignatureData signature, @Nullable MessageIndicator indicator, CallbackInfo ci) {
37 | // Pass forward messages to dispatcher
38 | MessageDispatcher.getInstance().handleText(message, signature, indicator);
39 | ci.cancel();
40 | }
41 |
42 | @Inject(method = "clear", at = @At("HEAD"), cancellable = true)
43 | private void clearMessages(boolean clearTextHistory, CallbackInfo ci) {
44 | if (!clearTextHistory) {
45 | // This only gets called if it is the keybind f3 + d
46 | return;
47 | }
48 | if (!ConfigStorage.General.CLEAR_ON_DISCONNECT.config.getBooleanValue()) {
49 | // Cancel clearing if it's turned off
50 | ci.cancel();
51 | }
52 | }
53 |
54 | @Inject(method = "isChatFocused", at = @At("HEAD"), cancellable = true)
55 | private void isChatFocused(CallbackInfoReturnable ci) {
56 | // If the chat is focused
57 | ci.setReturnValue(AdvancedChatScreen.PERMANENT_FOCUS || client.currentScreen instanceof AdvancedChatScreen);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/mixin/MixinChatHudInvoker.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.mixin;
9 |
10 | import net.minecraft.client.gui.hud.ChatHud;
11 | import net.minecraft.client.gui.hud.MessageIndicator;
12 | import net.minecraft.network.message.MessageSignatureData;
13 | import net.minecraft.text.Text;
14 | import org.jetbrains.annotations.Nullable;
15 | import org.spongepowered.asm.mixin.Mixin;
16 | import org.spongepowered.asm.mixin.gen.Invoker;
17 |
18 | @Mixin(ChatHud.class)
19 | public interface MixinChatHudInvoker {
20 | @Invoker
21 | void invokeAddMessage(Text message, @Nullable MessageSignatureData signature, int ticks, @Nullable MessageIndicator indicator, boolean refresh);
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/mixin/MixinChatScreen.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021-2022 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.mixin;
9 |
10 | import net.fabricmc.api.EnvType;
11 | import net.fabricmc.api.Environment;
12 | import net.minecraft.client.gui.screen.ChatScreen;
13 | import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
14 | import org.spongepowered.asm.mixin.Mixin;
15 | import org.spongepowered.asm.mixin.injection.At;
16 | import org.spongepowered.asm.mixin.injection.Inject;
17 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
18 |
19 | @Environment(EnvType.CLIENT)
20 | @Mixin(ChatScreen.class)
21 | public class MixinChatScreen {
22 |
23 | @Inject(method = "addScreenNarrations", at = @At("HEAD"), cancellable = true)
24 | public void screenNarrations(NarrationMessageBuilder builder, CallbackInfo ci) {
25 | // Don't cause random narrations to happen/crashes
26 | ci.cancel();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/mixin/MixinClientPlayerEntity.java:
--------------------------------------------------------------------------------
1 | package io.github.darkkronicle.advancedchatcore.mixin;
2 |
3 | import io.github.darkkronicle.advancedchatcore.chat.AdvancedChatScreen;
4 | import net.minecraft.client.MinecraftClient;
5 | import net.minecraft.client.network.ClientPlayerEntity;
6 | import net.minecraft.entity.Entity;
7 | import net.minecraft.entity.EntityType;
8 | import net.minecraft.world.World;
9 | import org.spongepowered.asm.mixin.Final;
10 | import org.spongepowered.asm.mixin.Mixin;
11 | import org.spongepowered.asm.mixin.Shadow;
12 | import org.spongepowered.asm.mixin.injection.At;
13 | import org.spongepowered.asm.mixin.injection.Inject;
14 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
15 |
16 | @Mixin(ClientPlayerEntity.class)
17 | public abstract class MixinClientPlayerEntity extends Entity {
18 |
19 | @Shadow @Final protected MinecraftClient client;
20 |
21 | @Shadow public float nauseaIntensity;
22 |
23 | public MixinClientPlayerEntity(EntityType> type, World world) {
24 | super(type, world);
25 | }
26 |
27 | @Inject(
28 | method="updateNausea",
29 | at = @At(value="INVOKE", target="Lnet/minecraft/client/MinecraftClient;setScreen(Lnet/minecraft/client/gui/screen/Screen;)V"),
30 | cancellable = true
31 | )
32 | public void updateNauseaHook(CallbackInfo ci) {
33 | if (client.currentScreen instanceof AdvancedChatScreen) {
34 | ci.cancel();
35 | nauseaIntensity += 0.0125f;
36 | if (this.nauseaIntensity >= 1.0f) {
37 | this.nauseaIntensity = 1.0f;
38 | }
39 | inNetherPortal = false;
40 | }
41 | }
42 |
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/mixin/MixinKeyboard.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.mixin;
9 |
10 | import io.github.darkkronicle.advancedchatcore.chat.ChatHistory;
11 | import net.fabricmc.api.EnvType;
12 | import net.fabricmc.api.Environment;
13 | import net.minecraft.client.Keyboard;
14 | import org.spongepowered.asm.mixin.Mixin;
15 | import org.spongepowered.asm.mixin.injection.At;
16 | import org.spongepowered.asm.mixin.injection.Inject;
17 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
18 |
19 | @Environment(EnvType.CLIENT)
20 | @Mixin(Keyboard.class)
21 | public class MixinKeyboard {
22 |
23 | @Inject(
24 | method = "processF3",
25 | at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/ChatHud;clear(Z)V"))
26 | public void processF3Chat(int key, CallbackInfoReturnable ci) {
27 | // Make it so that history can still be cleared
28 | ChatHistory.getInstance().clearAll();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/mixin/MixinMessageIndicator.java:
--------------------------------------------------------------------------------
1 | package io.github.darkkronicle.advancedchatcore.mixin;
2 |
3 | import io.github.darkkronicle.advancedchatcore.config.ConfigStorage;
4 | import net.minecraft.client.gui.hud.MessageIndicator;
5 | import org.spongepowered.asm.mixin.Mixin;
6 | import org.spongepowered.asm.mixin.injection.At;
7 | import org.spongepowered.asm.mixin.injection.Inject;
8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
9 |
10 | @Mixin(MessageIndicator.class)
11 | public class MixinMessageIndicator {
12 |
13 | @Inject(method = "indicatorColor", at = @At("HEAD"), cancellable = true)
14 | private void getColor(CallbackInfoReturnable ci) {
15 | MessageIndicator indicator = ((MessageIndicator) (Object) this);
16 | String name = indicator.loggedName();
17 | ci.setReturnValue(switch (name) {
18 | case "Modified" -> ConfigStorage.ChatScreen.MODIFIED.config.getColor().intValue;
19 | case "Filtered" -> ConfigStorage.ChatScreen.FILTERED.config.getColor().intValue;
20 | case "Not Secure" -> ConfigStorage.ChatScreen.NOT_SECURE.config.getColor().intValue;
21 | default -> // And "System"
22 | ConfigStorage.ChatScreen.SYSTEM.config.getColor().intValue;
23 | });
24 |
25 | }
26 |
27 | @Inject(method = "icon", at = @At("HEAD"), cancellable = true)
28 | private void getIcon(CallbackInfoReturnable ci) {
29 | if (!ConfigStorage.ChatScreen.SHOW_CHAT_ICONS.config.getBooleanValue()) {
30 | ci.setReturnValue(null);
31 | }
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/mixin/MixinMinecraftClient.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021-2022 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.mixin;
9 |
10 | import io.github.darkkronicle.advancedchatcore.chat.AdvancedChatScreen;
11 | import io.github.darkkronicle.advancedchatcore.chat.AdvancedSleepingChatScreen;
12 | import io.github.darkkronicle.advancedchatcore.chat.ChatHistory;
13 | import io.github.darkkronicle.advancedchatcore.config.ConfigStorage;
14 | import net.fabricmc.api.EnvType;
15 | import net.fabricmc.api.Environment;
16 | import net.minecraft.client.MinecraftClient;
17 | import net.minecraft.client.gui.screen.Screen;
18 | import org.jetbrains.annotations.Nullable;
19 | import org.spongepowered.asm.mixin.Mixin;
20 | import org.spongepowered.asm.mixin.injection.At;
21 | import org.spongepowered.asm.mixin.injection.Inject;
22 | import org.spongepowered.asm.mixin.injection.ModifyArg;
23 | import org.spongepowered.asm.mixin.injection.ModifyArgs;
24 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
25 | import org.spongepowered.asm.mixin.injection.invoke.arg.Args;
26 |
27 | @Environment(EnvType.CLIENT)
28 | @Mixin(MinecraftClient.class)
29 | public class MixinMinecraftClient {
30 |
31 | @Inject(method = "disconnect(Lnet/minecraft/client/gui/screen/Screen;)V", at = @At("RETURN"))
32 | public void onDisconnect(Screen screen, CallbackInfo ci) {
33 | // Clear data on disconnect
34 | if (ConfigStorage.General.CLEAR_ON_DISCONNECT.config.getBooleanValue()) {
35 | ChatHistory.getInstance().clearAll();
36 | }
37 | }
38 |
39 | @Inject(method = "openChatScreen(Ljava/lang/String;)V",
40 | at = @At(value = "HEAD"), cancellable = true)
41 | public void openChatScreen(String text, CallbackInfo ci) {
42 | MinecraftClient.getInstance().setScreen(new AdvancedChatScreen(text));
43 | ci.cancel();
44 | }
45 |
46 | @ModifyArg(method = "tick()V",
47 | at = @At(value = "INVOKE",
48 | target = "Lnet/minecraft/client/MinecraftClient;setScreen(Lnet/minecraft/client/gui/screen/Screen;)V", ordinal = 1))
49 | public Screen openSleepingChatScreen(@Nullable Screen screen) {
50 | return new AdvancedSleepingChatScreen();
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/mixin/MixinSleepingChatScreen.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021-2022 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.mixin;
9 |
10 | import io.github.darkkronicle.advancedchatcore.chat.AdvancedChatScreen;
11 | import net.fabricmc.api.EnvType;
12 | import net.fabricmc.api.Environment;
13 | import net.minecraft.client.gui.screen.ChatScreen;
14 | import net.minecraft.client.gui.screen.Screen;
15 | import net.minecraft.client.gui.screen.SleepingChatScreen;
16 | import org.jetbrains.annotations.Nullable;
17 | import org.spongepowered.asm.mixin.Mixin;
18 | import org.spongepowered.asm.mixin.injection.At;
19 | import org.spongepowered.asm.mixin.injection.ModifyArg;
20 |
21 | @Environment(EnvType.CLIENT)
22 | @Mixin(SleepingChatScreen.class)
23 | public class MixinSleepingChatScreen extends ChatScreen {
24 |
25 | public MixinSleepingChatScreen() {
26 | super("");
27 | }
28 |
29 | @ModifyArg(method = "closeChatIfEmpty",
30 | at = @At(value = "INVOKE",
31 | target = "Lnet/minecraft/client/MinecraftClient;setScreen(Lnet/minecraft/client/gui/screen/Screen;)V", ordinal = 1))
32 | public Screen openSleepingChatScreen(@Nullable Screen screen) {
33 |
34 | return new AdvancedChatScreen(this.chatField.getText());
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/io/github/darkkronicle/advancedchatcore/util/AbstractRegistry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 DarkKronicle
3 | *
4 | * This Source Code Form is subject to the terms of the Mozilla Public
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 | */
8 | package io.github.darkkronicle.advancedchatcore.util;
9 |
10 | import io.github.darkkronicle.advancedchatcore.interfaces.RegistryOption;
11 | import java.util.ArrayList;
12 | import java.util.List;
13 | import java.util.function.Supplier;
14 | import lombok.Getter;
15 | import lombok.NonNull;
16 |
17 | /**
18 | * Create a registry with options that can be added from anywhere.
19 | *
20 | * @param Class to be wrapped
21 | * @param