├── .editorconfig ├── .gitattributes ├── .github ├── scripts │ ├── test-no-error-reports.sh │ └── update_version └── workflows │ ├── build-and-test.yml │ └── release-tags.yml ├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── dependencies.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── jitpack.yml ├── latest ├── repositories.gradle ├── settings.gradle └── src └── main ├── java └── acs │ └── tabbychat │ ├── api │ ├── IChatExtension.java │ ├── IChatKeyboardExtension.java │ ├── IChatMouseExtension.java │ ├── IChatRenderExtension.java │ ├── IChatUpdateExtension.java │ ├── TCExtensionManager.java │ └── package-info.java │ ├── compat │ ├── MacroKeybindCompat.java │ └── MacrosContext.java │ ├── core │ ├── ChatChannel.java │ ├── GuiChatTC.java │ ├── GuiNewChatTC.java │ ├── GuiSleepTC.java │ ├── TCChatLine.java │ ├── TabbyChat.java │ └── TabbyChatMod.java │ ├── gui │ ├── ChatBox.java │ ├── ChatButton.java │ ├── ChatChannelGUI.java │ ├── ChatScrollBar.java │ ├── ITCSettingsGUI.java │ ├── PrefsButton.java │ ├── TCSettingsAdvanced.java │ ├── TCSettingsFilters.java │ ├── TCSettingsGUI.java │ ├── TCSettingsGeneral.java │ ├── TCSettingsServer.java │ ├── TCSettingsSpelling.java │ └── context │ │ ├── ChatContext.java │ │ ├── ChatContextMenu.java │ │ ├── ContextCopy.java │ │ ├── ContextCut.java │ │ ├── ContextDummy.java │ │ ├── ContextPaste.java │ │ └── ContextSpellingSuggestion.java │ ├── jazzy │ ├── TCSpellCheckListener.java │ └── TCSpellCheckManager.java │ ├── proxy │ ├── ClientProxy.java │ ├── CommonProxy.java │ └── ServerProxy.java │ ├── settings │ ├── ChannelDelimEnum.java │ ├── ColorCodeEnum.java │ ├── FormatCodeEnum.java │ ├── ITCSetting.java │ ├── NotificationSoundEnum.java │ ├── TCChatFilter.java │ ├── TCSetting.java │ ├── TCSettingBool.java │ ├── TCSettingEnum.java │ ├── TCSettingList.java │ ├── TCSettingSlider.java │ ├── TCSettingTextBox.java │ ├── TimeStampEnum.java │ └── files │ │ └── TCSettingsAdvancedFile.java │ ├── threads │ ├── BackgroundChatThread.java │ └── BackgroundUpdateCheck.java │ └── util │ ├── ChatComponentUtils.java │ ├── ChatExtensions.java │ ├── IPResolver.java │ ├── TCChatLineFake.java │ └── TabbyChatUtils.java └── resources ├── META-INF └── tabbychat_at.cfg ├── assets └── tabbychat │ ├── lang │ ├── de_DE.lang │ ├── en_US.lang │ ├── es_ES.lang │ ├── et_EE.lang │ ├── fi_FI.lang │ ├── fr_FR.lang │ ├── ru_RU.lang │ ├── sv_SE.lang │ └── uk_UA.lang │ └── textures │ └── gui │ └── icons │ ├── copy.png │ ├── cut.png │ └── paste.png ├── english.0 └── mcmod.info /.editorconfig: -------------------------------------------------------------------------------- 1 | # This is the universal Text Editor Configuration 2 | # for all GTNewHorizons projects 3 | # See: https://editorconfig.org/ 4 | 5 | root = true 6 | 7 | [*] 8 | charset = utf-8 9 | end_of_line = lf 10 | indent_size = 4 11 | indent_style = space 12 | insert_final_newline = true 13 | trim_trailing_whitespace = true 14 | 15 | [*.{bat,ini}] 16 | end_of_line = crlf 17 | 18 | [*.{dtd,json,info,mcmeta,md,sh,svg,xml,xsd,xsl,yaml,yml}] 19 | indent_size = 2 20 | 21 | [*.lang] 22 | trim_trailing_whitespace = false 23 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | 3 | *.[jJ][aA][rR] binary 4 | 5 | *.[pP][nN][gG] binary 6 | *.[jJ][pP][gG] binary 7 | *.[jJ][pP][eE][gG] binary 8 | *.[gG][iI][fF] binary 9 | *.[tT][iI][fF] binary 10 | *.[tT][iI][fF][fF] binary 11 | *.[iI][cC][oO] binary 12 | *.[sS][vV][gG] text 13 | *.[eE][pP][sS] binary 14 | *.[xX][cC][fF] binary 15 | 16 | *.[kK][aA][rR] binary 17 | *.[mM]4[aA] binary 18 | *.[mM][iI][dD] binary 19 | *.[mM][iI][dD][iI] binary 20 | *.[mM][pP]3 binary 21 | *.[oO][gG][gG] binary 22 | *.[rR][aA] binary 23 | 24 | *.7[zZ] binary 25 | *.[gG][zZ] binary 26 | *.[tT][aA][rR] binary 27 | *.[tT][gG][zZ] binary 28 | *.[zZ][iI][pP] binary 29 | 30 | *.[tT][cC][nN] binary 31 | *.[sS][oO] binary 32 | *.[dD][lL][lL] binary 33 | *.[dD][yY][lL][iI][bB] binary 34 | *.[pP][sS][dD] binary 35 | *.[tT][tT][fF] binary 36 | *.[oO][tT][fF] binary 37 | 38 | *.[pP][aA][tT][cC][hH] -text 39 | 40 | *.[bB][aA][tT] text eol=crlf 41 | *.[cC][mM][dD] text eol=crlf 42 | *.[pP][sS]1 text eol=crlf 43 | 44 | *[aA][uU][tT][oO][gG][eE][nN][eE][rR][aA][tT][eE][dD]* binary 45 | -------------------------------------------------------------------------------- /.github/scripts/test-no-error-reports.sh: -------------------------------------------------------------------------------- 1 | if [[ -d "run/crash-reports" ]]; then 2 | echo "Crash reports detected:" 3 | cat $directory/* 4 | exit 1 5 | fi 6 | 7 | if grep --quiet "Fatal errors were detected" server.log; then 8 | echo "Fatal errors detected:" 9 | cat server.log 10 | exit 1 11 | fi 12 | 13 | if grep --quiet "The state engine was in incorrect state ERRORED and forced into state SERVER_STOPPED" server.log; then 14 | echo "Server force stopped:" 15 | cat server.log 16 | exit 1 17 | fi 18 | 19 | if grep --quiet 'Done .+ For help, type "help" or "?"' server.log; then 20 | echo "Server didn't finish startup:" 21 | cat server.log 22 | exit 1 23 | fi 24 | 25 | echo "No crash reports detected" 26 | exit 0 27 | 28 | -------------------------------------------------------------------------------- /.github/scripts/update_version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if ! git diff --name-only HEAD HEAD~1 | grep -qF 'build.gradle'; then 4 | new_version="$(date +%s)" 5 | sed --in-place "s!^//version:.*!//version: $new_version!g" build.gradle 6 | git add build.gradle 7 | git commit -m "[ci skip] update build script version to $new_version" 8 | git push 9 | printf 'Updated buildscript version to %s\n' "$new_version" 10 | else 11 | printf 'Ignored buildscript version update: no changes detected\n' 12 | fi 13 | -------------------------------------------------------------------------------- /.github/workflows/build-and-test.yml: -------------------------------------------------------------------------------- 1 | 2 | name: Build and test 3 | 4 | on: 5 | pull_request: 6 | branches: [ master, main ] 7 | push: 8 | branches: [ master, main ] 9 | 10 | jobs: 11 | build-and-test: 12 | uses: GTNewHorizons/GTNH-Actions-Workflows/.github/workflows/build-and-test.yml@master 13 | secrets: inherit 14 | -------------------------------------------------------------------------------- /.github/workflows/release-tags.yml: -------------------------------------------------------------------------------- 1 | 2 | name: Release tagged build 3 | 4 | on: 5 | push: 6 | tags: [ '*' ] 7 | 8 | permissions: 9 | contents: write 10 | 11 | jobs: 12 | release-tags: 13 | uses: GTNewHorizons/GTNH-Actions-Workflows/.github/workflows/release-tags.yml@master 14 | secrets: inherit 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | .settings 3 | /.idea/ 4 | /.vscode/ 5 | /run/ 6 | /build/ 7 | /eclipse/ 8 | .classpath 9 | .project 10 | /bin/ 11 | /config/ 12 | /crash-reports/ 13 | /logs/ 14 | options.txt 15 | /saves/ 16 | usernamecache.json 17 | banned-ips.json 18 | banned-players.json 19 | eula.txt 20 | ops.json 21 | server.properties 22 | servers.dat 23 | usercache.json 24 | whitelist.json 25 | /out/ 26 | *.iml 27 | *.ipr 28 | *.iws 29 | src/main/resources/mixins.*([!.]).json 30 | *.bat 31 | *.DS_Store 32 | !gradlew.bat 33 | .factorypath 34 | addon.local.gradle 35 | addon.local.gradle.kts 36 | addon.late.local.gradle 37 | addon.late.local.gradle.kts 38 | layout.json 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This code is released under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 (CC-NC-SA) license, the contents of which are available at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | TabbyChat 2 | ========= 3 | TabbyChat chat mod for Minecraft 4 | 5 | Fork of 1.7.10 TabbyChat with the following changes: 6 | - Global filters 7 | - Fix incompatibility with lotr where lotr's /fmsg could send messages to the wrong fellowship 8 | - No LiteLoader support 9 | - No server side crashes but logged warning instead 10 | - Fixes crash with Botania's Corporea Index 11 | - Cleaner & more optimized codebase 12 | - Some updated translations (thanks to those who helped) 13 | 14 | [Latest builds](https://github.com/mist475/tabbychat/releases) 15 | 16 | Legacy Information: 17 | [Old builds](https://drone.io/github.com/killjoy1221/tabbychat/files) 18 | 19 | Forum thread: http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/2181597-new-tabbychat-v1-11-1-smp-chat-overhaul-new 20 | 21 | This code is released under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 (CC-NC-SA) license, the contents of which are available at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode 22 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | //version: 1707058017 2 | 3 | plugins { 4 | id 'com.gtnewhorizons.gtnhconvention' 5 | } 6 | -------------------------------------------------------------------------------- /dependencies.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Add your dependencies here. Supported configurations: 3 | * - api("group:name:version:classifier"): if you use the types from this dependency in the public API of this mod 4 | * Available at runtime and compiletime for mods depending on this mod 5 | * - implementation("g:n:v:c"): if you need this for internal implementation details of the mod, but none of it is visible via the public API 6 | * Available at runtime but not compiletime for mods depending on this mod 7 | * - compileOnly("g:n:v:c"): if the mod you're building doesn't need this dependency during runtime at all, e.g. for optional mods 8 | * Not available at all for mods depending on this mod, only visible at compiletime for this mod 9 | * - compileOnlyApi("g:n:v:c"): like compileOnly, but also visible at compiletime for mods depending on this mod 10 | * Available at compiletime but not runtime for mods depending on this mod 11 | * - runtimeOnlyNonPublishable("g:n:v:c"): if you want to include a mod in this mod's runClient/runServer runs, but not publish it as a dependency 12 | * Not available at all for mods depending on this mod, only visible at runtime for this mod 13 | * - devOnlyNonPublishable("g:n:v:c"): a combination of runtimeOnlyNonPublishable and compileOnly for dependencies present at both compiletime and runtime, 14 | * but not published as Maven dependencies - useful for RFG-deobfuscated dependencies or local testing 15 | * - runtimeOnly("g:n:v:c"): if you don't need this at compile time, but want it to be present at runtime 16 | * Available at runtime for mods depending on this mod 17 | * - annotationProcessor("g:n:v:c"): mostly for java compiler plugins, if you know you need this, use it, otherwise don't worry 18 | * - testCONFIG("g:n:v:c") - replace CONFIG by one of the above (except api), same as above but for the test sources instead of main 19 | * 20 | * - shadowImplementation("g:n:v:c"): effectively the same as API, but the dependency is included in your jar under a renamed package name 21 | * Requires you to enable usesShadowedDependencies in gradle.properties 22 | * 23 | * - compile("g:n:v:c"): deprecated, replace with "api" (works like the old "compile") or "implementation" (can be more efficient) 24 | * 25 | * You can exclude transitive dependencies (dependencies of the chosen dependency) by appending { transitive = false } if needed, 26 | * but use this sparingly as it can break using your mod as another mod's dependency if you're not careful. 27 | * 28 | * To depend on obfuscated jars you can use `devOnlyNonPublishable(rfg.deobf("dep:spec:1.2.3"))` to fetch an obfuscated jar from maven, 29 | * or `devOnlyNonPublishable(rfg.deobf(project.files("libs/my-mod-jar.jar")))` to use a file. 30 | * 31 | * Gradle names for some of the configuration can be misleading, compileOnlyApi and runtimeOnly both get published as dependencies in Maven, but compileOnly does not. 32 | * The buildscript adds runtimeOnlyNonPublishable to also have a runtime dependency that's not published. 33 | * 34 | * For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph 35 | */ 36 | dependencies { 37 | // https://mvnrepository.com/artifact/net.sf.jazzy/jazzy 38 | shadeCompile("net.sf.jazzy:jazzy:0.5.2-rtext-1.4.1-2") 39 | } 40 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mist475/tabbychat/bcda1aed7344a0a617cde55f8bd44a7fdfe5e3b4/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /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 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 1>&2 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 48 | echo. 1>&2 49 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 50 | echo location of your Java installation. 1>&2 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 1>&2 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 62 | echo. 1>&2 63 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 64 | echo location of your Java installation. 1>&2 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /jitpack.yml: -------------------------------------------------------------------------------- 1 | before_install: 2 | - ./gradlew setupCIWorkspace -------------------------------------------------------------------------------- /latest: -------------------------------------------------------------------------------- 1 | 1.12.2 2 | -------------------------------------------------------------------------------- /repositories.gradle: -------------------------------------------------------------------------------- 1 | // Add any additional repositories for your dependencies here 2 | 3 | repositories { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | 2 | pluginManagement { 3 | repositories { 4 | maven { 5 | // RetroFuturaGradle 6 | name "GTNH Maven" 7 | url "https://nexus.gtnewhorizons.com/repository/public/" 8 | mavenContent { 9 | includeGroup("com.gtnewhorizons") 10 | includeGroupByRegex("com\\.gtnewhorizons\\..+") 11 | } 12 | } 13 | gradlePluginPortal() 14 | mavenCentral() 15 | mavenLocal() 16 | } 17 | } 18 | 19 | plugins { 20 | id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.22' 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/api/IChatExtension.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.api; 2 | 3 | /** 4 | * Base interface for adding additional functionality to {@link acs.tabbychat.core.GuiChatTC}.
5 | * See {@link net.minecraft.client.gui.GuiScreen} for more in-depth explanations OF methods. 6 | */ 7 | public interface IChatExtension { 8 | 9 | /** 10 | * Run once when the game starts. 11 | * Can be used to check compatibility. 12 | */ 13 | void load(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/api/IChatKeyboardExtension.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.api; 2 | 3 | public interface IChatKeyboardExtension extends IChatExtension { 4 | 5 | void keyTyped(char c, int code); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/api/IChatMouseExtension.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.api; 2 | 3 | import net.minecraft.client.gui.GuiButton; 4 | 5 | public interface IChatMouseExtension extends IChatExtension { 6 | /** 7 | * if returns true, nothing else will be clicked. 8 | */ 9 | boolean mouseClicked(int x, int y, int button); 10 | 11 | /** 12 | * if returns true, nothing else will be clicked. 13 | */ 14 | boolean actionPerformed(GuiButton button); 15 | 16 | void handleMouseInput(); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/api/IChatRenderExtension.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.api; 2 | 3 | public interface IChatRenderExtension extends IChatExtension { 4 | void drawScreen(int x, int y, float tick); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/api/IChatUpdateExtension.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.api; 2 | 3 | import net.minecraft.client.gui.GuiScreen; 4 | 5 | public interface IChatUpdateExtension extends IChatExtension { 6 | 7 | /** 8 | * Run every time the chat is opened 9 | * 10 | * @param screen The instance of the GuiScreen 11 | */ 12 | void initGui(GuiScreen screen); 13 | 14 | void updateScreen(); 15 | 16 | /** 17 | * Runs when the chat is closed 18 | */ 19 | void onGuiClosed(); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/api/TCExtensionManager.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.api; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * Stores the registered extension classes. 10 | */ 11 | public class TCExtensionManager { 12 | 13 | public static final TCExtensionManager INSTANCE = new TCExtensionManager(); 14 | private final List> list = new ArrayList<>(); 15 | 16 | private TCExtensionManager() { 17 | } 18 | 19 | public List> getExtensions() { 20 | return ImmutableList.copyOf(list); 21 | } 22 | 23 | public void registerExtension(Class ext) { 24 | if (!list.contains(ext)) 25 | list.add(ext); 26 | } 27 | 28 | public void unregisterExtension(Class ext) { 29 | list.remove(ext); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/api/package-info.java: -------------------------------------------------------------------------------- 1 | @API(apiVersion = "0.1", owner = "tabbychat", provides = "") 2 | package acs.tabbychat.api; 3 | 4 | import cpw.mods.fml.common.API; 5 | 6 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/compat/MacrosContext.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.compat; 2 | 3 | import acs.tabbychat.gui.context.ChatContext; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.gui.GuiScreen; 6 | import net.minecraft.util.ResourceLocation; 7 | 8 | import java.lang.reflect.Constructor; 9 | import java.lang.reflect.Field; 10 | import java.lang.reflect.Method; 11 | import java.util.List; 12 | 13 | public class MacrosContext extends ChatContext { 14 | 15 | private int id; // 0 = execute, 1 = edit, 2 = design 16 | 17 | public MacrosContext(int name) { 18 | this.id = name; 19 | switch (name) { 20 | case 0 -> this.displayString = "Execute Macro"; 21 | case 1 -> this.displayString = "Edit Macro"; 22 | case 2 -> { 23 | try { 24 | Class loc = Class 25 | .forName("net.eq2online.macros.compatibility.LocalisationProvider"); 26 | Method locStr = loc.getMethod("getLocalisedString", String.class); 27 | this.displayString = "\u0A7e" + locStr.invoke(null, "tooltip.guiedit"); 28 | // this.setIconUV(26, 16); 29 | } 30 | catch (Exception e) { 31 | e.printStackTrace(); 32 | } 33 | } 34 | } 35 | } 36 | 37 | @Override 38 | public void onClicked() { 39 | try { 40 | Class guiChatAdapter = Class.forName("net.eq2online.macros.gui.ext.GuiChatAdapter"); 41 | Class guiControl = Class 42 | .forName("net.eq2online.macros.gui.designable.DesignableGuiControl"); 43 | Class guiMacroEdit = Class.forName("net.eq2online.macros.gui.screens.GuiMacroEdit"); 44 | Class guiDesigner = Class.forName("net.eq2online.macros.gui.screens.GuiDesigner"); 45 | Constructor editConst = guiMacroEdit.getConstructor(int.class, GuiScreen.class); 46 | Constructor designerConst = guiDesigner.getConstructor(String.class, 47 | GuiScreen.class, boolean.class); 48 | Method bindable = guiControl.getMethod("getWidgetIsBindable"); 49 | Method playMacro = guiChatAdapter.getDeclaredMethod("playMacro"); 50 | playMacro.setAccessible(true); 51 | Field controlId = guiControl.getField("id"); 52 | Object control = MacroKeybindCompat.getControl(); 53 | boolean isBindable = false; 54 | if (control != null) 55 | isBindable = (Boolean) bindable.invoke(control, new Object[0]); 56 | switch (id) { 57 | case 0 -> { 58 | if (isBindable) { 59 | playMacro.invoke(MacroKeybindCompat.getChatHook()); 60 | } 61 | } 62 | case 1 -> { 63 | if (isBindable) { 64 | int id = controlId.getInt(control); 65 | GuiScreen screen = (GuiScreen) editConst.newInstance(id, 66 | Minecraft.getMinecraft().currentScreen); 67 | Minecraft.getMinecraft().displayGuiScreen(screen); 68 | } 69 | } 70 | case 2 -> { 71 | GuiScreen screen = (GuiScreen) designerConst.newInstance("inchat", 72 | Minecraft.getMinecraft().currentScreen, true); 73 | Minecraft.getMinecraft().displayGuiScreen(screen); 74 | } 75 | } 76 | } 77 | catch (Exception e) { 78 | e.printStackTrace(); 79 | } 80 | } 81 | 82 | @Override 83 | public String getDisplayString() { 84 | return this.displayString; 85 | } 86 | 87 | @Override 88 | public ResourceLocation getDisplayIcon() { 89 | return null; 90 | } 91 | 92 | @Override 93 | public List getChildren() { 94 | return null; 95 | } 96 | 97 | @Override 98 | public boolean isPositionValid(int x, int y) { 99 | return true; 100 | } 101 | 102 | @Override 103 | public Behavior getDisabledBehavior() { 104 | return Behavior.HIDE; 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/core/GuiSleepTC.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.core; 2 | 3 | import net.minecraft.client.gui.GuiButton; 4 | import net.minecraft.client.network.NetHandlerPlayClient; 5 | import net.minecraft.client.resources.I18n; 6 | import net.minecraft.network.play.client.C0BPacketEntityAction; 7 | import org.lwjgl.input.Keyboard; 8 | 9 | public class GuiSleepTC extends GuiChatTC { 10 | 11 | @Override 12 | public void initGui() { 13 | super.initGui(); 14 | GuiButton leaveBed = new GuiButton(1, this.width / 2 - 100, this.height - 40, 15 | I18n.format("multiplayer.stopSleeping")); 16 | this.buttonList.add(leaveBed); 17 | } 18 | 19 | @Override 20 | public void keyTyped(char c, int code) { 21 | switch (code) { 22 | case Keyboard.KEY_ESCAPE: 23 | this.playerWakeUp(); 24 | break; 25 | case Keyboard.KEY_RETURN: 26 | case Keyboard.KEY_NUMPADENTER: 27 | this.sendChat(true); 28 | default: 29 | super.keyTyped(c, code); 30 | break; 31 | } 32 | } 33 | 34 | @Override 35 | public void actionPerformed(GuiButton button) { 36 | if (button.id == 1) 37 | playerWakeUp(); 38 | else 39 | super.actionPerformed(button); 40 | } 41 | 42 | /** 43 | * Wakes up the player 44 | */ 45 | private void playerWakeUp() { 46 | NetHandlerPlayClient var1 = mc.thePlayer.sendQueue; 47 | var1.addToSendQueue(new C0BPacketEntityAction(mc.thePlayer, 3)); 48 | } 49 | 50 | @Override 51 | public void updateScreen() { 52 | if (!mc.thePlayer.isPlayerSleeping()) 53 | mc.displayGuiScreen(null); 54 | super.updateScreen(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/core/TCChatLine.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.core; 2 | 3 | import acs.tabbychat.util.TCChatLineFake; 4 | import com.google.gson.annotations.Expose; 5 | import net.minecraft.client.gui.ChatLine; 6 | import net.minecraft.util.ChatComponentText; 7 | import net.minecraft.util.IChatComponent; 8 | 9 | import java.util.Date; 10 | 11 | public class TCChatLine extends TCChatLineFake { 12 | @Expose 13 | public Date timeStamp; 14 | @Expose 15 | protected boolean statusMsg = false; 16 | 17 | public TCChatLine(int _counter, IChatComponent _string, int _id) { 18 | super(_counter, _string, _id); 19 | } 20 | 21 | public TCChatLine(ChatLine _cl) { 22 | super(_cl.getUpdatedCounter(), _cl.func_151461_a(), _cl.getChatLineID()); 23 | if (_cl instanceof TCChatLine line) { 24 | timeStamp = line.timeStamp; 25 | statusMsg = line.statusMsg; 26 | } 27 | } 28 | 29 | public TCChatLine(int _counter, IChatComponent _string, int _id, boolean _stat) { 30 | this(_counter, _string, _id); 31 | this.statusMsg = _stat; 32 | } 33 | 34 | protected void setChatLineString(IChatComponent newLine) { 35 | this.chatComponent = newLine; 36 | } 37 | 38 | public IChatComponent getTimeStamp() { 39 | String format = TabbyChat.generalSettings.timeStamp.format(timeStamp); 40 | return new ChatComponentText(format + " "); 41 | } 42 | 43 | public IChatComponent getChatComponentWithTimestamp() { 44 | IChatComponent result = getChatComponent(); 45 | if (TabbyChat.generalSettings.timeStampEnable.getValue() && timeStamp != null) { 46 | result = getTimeStamp().appendSibling(result); 47 | } 48 | return result; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/core/TabbyChatMod.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.core; 2 | 3 | import acs.tabbychat.proxy.CommonProxy; 4 | import acs.tabbychat.util.TabbyChatUtils; 5 | import cpw.mods.fml.common.Mod; 6 | import cpw.mods.fml.common.Mod.EventHandler; 7 | import cpw.mods.fml.common.SidedProxy; 8 | import cpw.mods.fml.common.event.FMLInitializationEvent; 9 | 10 | @Mod(name = TabbyChatUtils.name, modid = TabbyChatUtils.modid, version = TabbyChatUtils.version) 11 | public class TabbyChatMod { 12 | 13 | @SidedProxy(serverSide = "acs.tabbychat.proxy.ServerProxy", clientSide = "acs.tabbychat.proxy.ClientProxy") 14 | public static CommonProxy proxy; 15 | 16 | @EventHandler 17 | public void load(FMLInitializationEvent event) { 18 | proxy.load(event); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/gui/ChatButton.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.gui; 2 | 3 | import acs.tabbychat.core.ChatChannel; 4 | import acs.tabbychat.core.GuiNewChatTC; 5 | import acs.tabbychat.core.TabbyChat; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.client.gui.FontRenderer; 8 | import net.minecraft.client.gui.GuiButton; 9 | import org.lwjgl.input.Keyboard; 10 | import org.lwjgl.opengl.GL11; 11 | 12 | import java.awt.Rectangle; 13 | 14 | public class ChatButton extends GuiButton { 15 | 16 | public ChatChannel channel; 17 | 18 | public ChatButton() { 19 | super(9999, 0, 0, 1, 1, ""); 20 | } 21 | 22 | public ChatButton(int _id, int _x, int _y, int _w, int _h, String _title) { 23 | super(_id, _x, _y, _w, _h, _title); 24 | } 25 | 26 | private static Rectangle translateButtonDims(Rectangle unscaled) { 27 | float scaleSetting = GuiNewChatTC.getInstance().getScaleSetting(); 28 | int adjX = Math.round((unscaled.x - ChatBox.current.x) * scaleSetting + ChatBox.current.x); 29 | 30 | int adjY = Math.round((TabbyChat.mc.currentScreen.height - unscaled.y + ChatBox.current.y) 31 | * (1.0f - scaleSetting)) 32 | + unscaled.y; 33 | 34 | int adjW = Math.round(unscaled.width * scaleSetting); 35 | int adjH = Math.round(unscaled.height * scaleSetting); 36 | return new Rectangle(adjX, adjY, adjW, adjH); 37 | } 38 | 39 | /** 40 | * Returns button width 41 | */ 42 | public int width() { 43 | return this.width; 44 | } 45 | 46 | /** 47 | * Sets button width 48 | */ 49 | public void width(int _w) { 50 | this.width = _w; 51 | } 52 | 53 | /** 54 | * Returns button height 55 | */ 56 | public int height() { 57 | return this.height; 58 | } 59 | 60 | /** 61 | * Sets button height 62 | */ 63 | public void height(int _h) { 64 | this.height = _h; 65 | } 66 | 67 | /** 68 | * Returns X-position of button 69 | */ 70 | public int x() { 71 | return xPosition; 72 | } 73 | 74 | /** 75 | * Sets X-position of button 76 | */ 77 | public void x(int _x) { 78 | xPosition = _x; 79 | } 80 | 81 | /** 82 | * Returns Y-position of button 83 | */ 84 | public int y() { 85 | return yPosition; 86 | } 87 | 88 | /** 89 | * Sets Y-position of button 90 | */ 91 | public void y(int _y) { 92 | yPosition = _y; 93 | } 94 | 95 | public void clear() { 96 | this.channel = null; 97 | } 98 | 99 | @Override 100 | public boolean mousePressed(Minecraft mc, int par2, int par3) { 101 | Rectangle cursor = translateButtonDims(new Rectangle(this.x(), this.y(), this.width(), 102 | this.height())); 103 | return this.enabled && this.visible && par2 >= cursor.x && par3 >= cursor.y 104 | && par2 < cursor.x + cursor.width && par3 < cursor.y + cursor.height; 105 | } 106 | 107 | @Override 108 | public void drawButton(Minecraft mc, int cursorX, int cursorY) { 109 | if (this.visible) { 110 | FontRenderer fr = mc.fontRenderer; 111 | float _mult = mc.gameSettings.chatOpacity * 0.9F + 0.1F; 112 | int _opacity = (int) (255 * _mult); 113 | int textOpacity = (TabbyChat.advancedSettings.textIgnoreOpacity.getValue() ? 255 114 | : _opacity); 115 | 116 | Rectangle cursor = translateButtonDims(new Rectangle(this.x(), this.y(), this.width(), 117 | this.height())); 118 | 119 | boolean hovered = cursorX >= cursor.x && cursorY >= cursor.y 120 | && cursorX < cursor.x + cursor.width && cursorY < cursor.y + cursor.height; 121 | 122 | int var7 = 0xa0a0a0; 123 | int var8 = 0; 124 | if (!this.enabled) { 125 | var7 = -0x5f5f60; 126 | } 127 | else if (hovered) { 128 | var7 = 0xffffa0; 129 | var8 = 0x7f8052; 130 | } 131 | else if (this.channel.active) { 132 | var7 = 0xa5e7e4; 133 | var8 = 0x5b7c7b; 134 | } 135 | else if (this.channel.unread) { 136 | var7 = 0xff0000; 137 | var8 = 0x720000; 138 | } 139 | drawRect(this.x(), this.y(), this.x() + this.width(), this.y() + this.height(), var8 140 | + (_opacity / 2 << 24)); 141 | GL11.glEnable(GL11.GL_BLEND); 142 | if (hovered && Keyboard.isKeyDown(42)) { 143 | String special = (this.channel.getTitle().equalsIgnoreCase("*") ? "\u2398" 144 | : "\u26A0"); 145 | this.drawCenteredString(fr, special, this.x() + this.width() / 2, 146 | this.y() + (this.height() - 8) / 2, var7 + (textOpacity << 24)); 147 | } 148 | else { 149 | this.drawCenteredString(fr, this.displayString, this.x() + this.width() / 2, 150 | this.y() + (this.height() - 8) / 2, var7 + (textOpacity << 24)); 151 | } 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/gui/ChatChannelGUI.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.gui; 2 | 3 | import acs.tabbychat.core.ChatChannel; 4 | import acs.tabbychat.core.GuiNewChatTC; 5 | import acs.tabbychat.core.TabbyChat; 6 | import acs.tabbychat.settings.ITCSetting; 7 | import acs.tabbychat.settings.TCSettingBool; 8 | import acs.tabbychat.settings.TCSettingTextBox; 9 | import acs.tabbychat.util.TabbyChatUtils; 10 | import net.minecraft.client.gui.GuiButton; 11 | import net.minecraft.client.gui.GuiScreen; 12 | import net.minecraft.client.resources.I18n; 13 | import org.lwjgl.input.Keyboard; 14 | 15 | import java.util.LinkedHashMap; 16 | 17 | public class ChatChannelGUI extends GuiScreen { 18 | private static final int SAVE_ID = 8981; 19 | private static final int CANCEL_ID = 8982; 20 | private static final int NOTIFICATIONS_ON_ID = 8983; 21 | private static final int ALIAS_ID = 8984; 22 | private static final int CMD_PREFIX_ID = 8985; 23 | private static final int PREV_ID = 8986; 24 | private static final int NEXT_ID = 8987; 25 | private static final int HIDE_PREFIX = 8988; 26 | public final int displayWidth = 255; 27 | public final int displayHeight = 120; 28 | private final String title; 29 | private final TabbyChat tc; 30 | private final TCSettingBool hidePrefix = new TCSettingBool(false, "hidePrefix", "settings.channel", 31 | HIDE_PREFIX); 32 | private final TCSettingBool notificationsOn = new TCSettingBool(false, "notificationsOn", 33 | "settings.channel", NOTIFICATIONS_ON_ID); 34 | private final TCSettingTextBox alias = new TCSettingTextBox("", "alias", "settings.channel", ALIAS_ID); 35 | private final TCSettingTextBox cmdPrefix = new TCSettingTextBox("", "cmdPrefix", "settings.channel", 36 | CMD_PREFIX_ID); 37 | protected ChatChannel channel; 38 | private int position; 39 | 40 | public ChatChannelGUI(ChatChannel _c) { 41 | this.tc = GuiNewChatTC.tc; 42 | this.channel = _c; 43 | this.hidePrefix.setValue(_c.hidePrefix); 44 | this.notificationsOn.setValue(_c.notificationsOn); 45 | this.alias.setCharLimit(20); 46 | this.alias.setValue(_c.getAlias()); 47 | this.cmdPrefix.setCharLimit(100); 48 | this.cmdPrefix.setValue(_c.cmdPrefix); 49 | this.resetTempVars(); 50 | this.title = _c.getTitle(); 51 | } 52 | 53 | @Override 54 | public void actionPerformed(GuiButton _button) { 55 | switch (_button.id) { 56 | case SAVE_ID: 57 | this.channel.notificationsOn = this.notificationsOn.getTempValue(); 58 | this.channel.setAlias(this.alias.getTempValue().trim()); 59 | this.channel.cmdPrefix = this.cmdPrefix.getTempValue().trim(); 60 | this.channel.hidePrefix = this.hidePrefix.getTempValue(); 61 | this.tc.storeChannelData(); 62 | case CANCEL_ID: 63 | mc.displayGuiScreen(null); 64 | break; 65 | case NOTIFICATIONS_ON_ID: 66 | this.notificationsOn.actionPerformed(); 67 | break; 68 | case PREV_ID: 69 | if (this.position <= 2) 70 | return; 71 | LinkedHashMap newMap = TabbyChatUtils.swapChannels( 72 | this.tc.channelMap, this.position - 2, this.position - 1); 73 | this.tc.channelMap.clear(); 74 | this.tc.channelMap = newMap; 75 | this.position--; 76 | break; 77 | case NEXT_ID: 78 | if (this.position >= this.tc.channelMap.size()) 79 | return; 80 | LinkedHashMap newMap2 = TabbyChatUtils.swapChannels( 81 | this.tc.channelMap, this.position - 1, this.position); 82 | this.tc.channelMap.clear(); 83 | this.tc.channelMap = newMap2; 84 | this.position++; 85 | break; 86 | case HIDE_PREFIX: 87 | this.hidePrefix.actionPerformed(); 88 | } 89 | } 90 | 91 | @Override 92 | public void drawScreen(int _x, int _y, float _f) { 93 | int leftX = (this.width - this.displayWidth) / 2; 94 | int topY = (this.height - this.displayHeight) / 2; 95 | int rightX = leftX + this.displayWidth; 96 | 97 | // Draw main background and title 98 | drawRect(leftX, topY, leftX + this.displayWidth, topY + this.displayHeight, 0x88000000); 99 | drawRect(leftX, topY + 14, leftX + this.displayWidth, topY + 15, 0x88ffffff); 100 | this.drawString(mc.fontRenderer, this.title, leftX + 3, topY + 3, 0xaaaaaa); 101 | 102 | // Draw tab position info 103 | this.drawString(mc.fontRenderer, Integer.toString(this.position), rightX - 34, topY + 22, 104 | 0xffffff); 105 | this.drawString(mc.fontRenderer, I18n.format("settings.channel.position"), rightX - 55 106 | - mc.fontRenderer.getStringWidth(I18n.format("settings.channel.position")), 107 | topY + 22, 0xffffff); 108 | this.drawString(mc.fontRenderer, I18n.format("settings.channel.of") + " " 109 | + this.tc.channelMap.size(), rightX - 34, topY + 35, 0xffffff); 110 | 111 | // Draw buttons 112 | for (GuiButton guiButton : this.buttonList) { 113 | guiButton.drawButton(mc, _x, _y); 114 | } 115 | } 116 | 117 | @Override 118 | public void initGui() { 119 | int leftX = (this.width - this.displayWidth) / 2; 120 | int topY = (this.height - this.displayHeight) / 2; 121 | int rightX = leftX + this.displayWidth; 122 | int botY = topY + this.displayHeight; 123 | Keyboard.enableRepeatEvents(true); 124 | this.buttonList.clear(); 125 | 126 | // Define generic buttons 127 | PrefsButton savePrefs = new PrefsButton(SAVE_ID, rightX - 45, botY - 19, 40, 14, 128 | I18n.format("settings.save")); 129 | this.buttonList.add(savePrefs); 130 | PrefsButton cancelPrefs = new PrefsButton(CANCEL_ID, rightX - 90, botY - 19, 40, 14, 131 | I18n.format("settings.cancel")); 132 | this.buttonList.add(cancelPrefs); 133 | PrefsButton nextButton = new PrefsButton(NEXT_ID, rightX - 20, topY + 20, 15, 14, ">>"); 134 | this.buttonList.add(nextButton); 135 | PrefsButton prevButton = new PrefsButton(PREV_ID, rightX - 50, topY + 20, 15, 14, "<<"); 136 | this.buttonList.add(prevButton); 137 | 138 | // Define settings buttons 139 | this.alias.setLabelLoc(leftX + 15); 140 | this.alias.setButtonLoc( 141 | leftX + 20 + mc.fontRenderer.getStringWidth(this.alias.description), topY + 20); 142 | this.alias.setButtonDims(70, 11); 143 | this.buttonList.add(this.alias); 144 | 145 | this.notificationsOn.setButtonLoc(leftX + 15, topY + 40); 146 | this.notificationsOn.setLabelLoc(leftX + 34); 147 | this.buttonList.add(this.notificationsOn); 148 | 149 | this.cmdPrefix.setLabelLoc(leftX + 15); 150 | this.cmdPrefix.setButtonLoc( 151 | leftX + 20 + mc.fontRenderer.getStringWidth(this.cmdPrefix.description), topY + 57); 152 | this.cmdPrefix.setButtonDims(100, 11); 153 | this.buttonList.add(this.cmdPrefix); 154 | 155 | this.hidePrefix.setButtonLoc(leftX + 15, topY + 78); 156 | this.hidePrefix.setLabelLoc(leftX + 34); 157 | this.buttonList.add(this.hidePrefix); 158 | 159 | // Determine tab position 160 | position = 1; 161 | for (String s : this.tc.channelMap.keySet()) { 162 | if (this.channel.getTitle().equals(s)) 163 | break; 164 | position++; 165 | } 166 | for (GuiButton drawable : this.buttonList) { 167 | if (drawable instanceof ITCSetting setting) 168 | setting.resetDescription(); 169 | } 170 | } 171 | 172 | @Override 173 | protected void keyTyped(char par1, int par2) { 174 | for (GuiButton o : this.buttonList) { 175 | if (o instanceof TCSettingTextBox tmp) { 176 | tmp.keyTyped(par1, par2); 177 | } 178 | } 179 | super.keyTyped(par1, par2); 180 | } 181 | 182 | @Override 183 | public void mouseClicked(int par1, int par2, int par3) { 184 | for (GuiButton o : this.buttonList) { 185 | if (o instanceof TCSettingTextBox tmp) { 186 | tmp.mouseClicked(par1, par2, par3); 187 | } 188 | } 189 | super.mouseClicked(par1, par2, par3); 190 | } 191 | 192 | /** 193 | * Resets temporary variables 194 | */ 195 | public void resetTempVars() { 196 | this.hidePrefix.reset(); 197 | this.notificationsOn.reset(); 198 | this.alias.reset(); 199 | this.cmdPrefix.reset(); 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/gui/ChatScrollBar.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.gui; 2 | 3 | import acs.tabbychat.core.GuiNewChatTC; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.gui.Gui; 6 | import net.minecraft.util.MathHelper; 7 | import org.lwjgl.input.Mouse; 8 | 9 | import java.awt.Point; 10 | 11 | public class ChatScrollBar { 12 | private static final Minecraft mc = Minecraft.getMinecraft(); 13 | private static final GuiNewChatTC gnc = GuiNewChatTC.getInstance(); 14 | protected static int barHeight = 5; 15 | protected static int barWidth = 5; 16 | private static float mouseLoc = 0.0f; 17 | private static int scrollBarCenter = 0; 18 | private static int barBottomY = 0; 19 | private static int barTopY = 0; 20 | private static int barX = 326; 21 | private static int barMinY = 0; 22 | private static int barMaxY = 0; 23 | private static int lastY = 0; 24 | private static boolean scrolling = false; 25 | 26 | public static void handleMouse() { 27 | Point cursor = ChatBox.scaleMouseCoords(Mouse.getEventX(), Mouse.getEventY()); 28 | 29 | if (Mouse.getEventButton() == 0 && Mouse.isButtonDown(0)) { 30 | int offsetX = barX + ChatBox.current.x; 31 | int offsetY = ChatBox.current.y; 32 | scrolling = cursor.x - offsetX > 0 && cursor.x - offsetX <= barWidth 33 | && cursor.y <= barMaxY + offsetY && cursor.y >= barMinY + offsetY; 34 | } 35 | else if (!Mouse.isButtonDown(0)) { 36 | scrolling = false; 37 | } 38 | 39 | if (Math.abs(cursor.y - lastY) > 1 && scrolling) { 40 | scrollBarMouseDrag(cursor.y); 41 | } 42 | } 43 | 44 | private static void update() { 45 | barHeight = MathHelper.floor_float(5 * gnc.getScaleSetting()); 46 | barWidth = MathHelper.floor_float(5 * gnc.getScaleSetting()); 47 | 48 | barX = ChatBox.current.width - barWidth - 2; 49 | 50 | if (ChatBox.anchoredTop) { 51 | barBottomY = ChatBox.current.height - ChatBox.tabTrayHeight; 52 | barTopY = 0; 53 | } 54 | else { 55 | barBottomY = 0; 56 | barTopY = -ChatBox.current.height + ChatBox.tabTrayHeight; 57 | } 58 | 59 | barMaxY = barBottomY - barHeight / 2 - 1; 60 | barMinY = barTopY + barHeight / 2 + 1; 61 | if (!ChatBox.anchoredTop) 62 | scrollBarCenter = Math.round(mouseLoc * barMinY + (1.0f - mouseLoc) * barMaxY); 63 | else 64 | scrollBarCenter = Math.round(mouseLoc * barMaxY + (1.0f - mouseLoc) * barMinY); 65 | } 66 | 67 | /** 68 | * Draws the scroll bar 69 | */ 70 | public static void drawScrollBar() { 71 | update(); 72 | int minX = barX + 1; 73 | int maxlines = gnc.getHeightSetting() / 9; 74 | float chatOpacity = mc.gameSettings.chatOpacity * 0.9f + 0.1f; 75 | int currentOpacity = (int) (180 * chatOpacity); 76 | Gui.drawRect(barX, barTopY, barX + barWidth + 2, barBottomY, currentOpacity << 24); 77 | if (gnc.getChatSize() > maxlines) { 78 | Gui.drawRect(minX, scrollBarCenter - barHeight / 2, minX + barWidth, scrollBarCenter 79 | + barHeight / 2, 0xffffff + (currentOpacity / 2 << 24)); 80 | Gui.drawRect(minX + 1, scrollBarCenter - barHeight / 2 - 1, minX + barWidth - 1, 81 | scrollBarCenter + barHeight / 2 + 1, 0xffffff + (currentOpacity / 2 << 24)); 82 | } 83 | } 84 | 85 | /** 86 | * Handles mouse wheel 87 | */ 88 | public static void scrollBarMouseWheel() { 89 | update(); 90 | int maxlines = gnc.getHeightSetting() / 9; 91 | int blines = gnc.getChatSize(); 92 | if (blines > maxlines) 93 | mouseLoc = (float) gnc.chatLinesTraveled() / (blines - maxlines); 94 | else 95 | mouseLoc = 0f; 96 | 97 | if (!ChatBox.anchoredTop) 98 | scrollBarCenter = Math.round(mouseLoc * barMinY + (1.0f - mouseLoc) * barMaxY); 99 | else 100 | scrollBarCenter = Math.round(mouseLoc * barMaxY + (1.0f - mouseLoc) * barMinY); 101 | } 102 | 103 | /** 104 | * Handles scrolling from dragging the scroll bar 105 | */ 106 | public static void scrollBarMouseDrag(int _absY) { 107 | int maxlines = gnc.getHeightSetting() / 9; 108 | int blines = gnc.getChatSize(); 109 | if (blines <= maxlines) { 110 | mouseLoc = 0f; 111 | return; 112 | } 113 | 114 | int adjBarMin = barMinY + ChatBox.current.y; 115 | int adjBarMax = barMaxY + ChatBox.current.y; 116 | 117 | if (_absY < adjBarMin) 118 | mouseLoc = ChatBox.anchoredTop ? 0.0f : 1.0f; 119 | else if (_absY > adjBarMax) 120 | mouseLoc = ChatBox.anchoredTop ? 1.0f : 0.0f; 121 | else { 122 | if (!ChatBox.anchoredTop) 123 | mouseLoc = Math.abs((float) (adjBarMax - _absY)) / (adjBarMax - adjBarMin); 124 | else 125 | mouseLoc = Math.abs((float) (adjBarMin - _absY)) / (adjBarMax - adjBarMin); 126 | } 127 | float moveInc = 1.0f / (blines - maxlines); 128 | 129 | int moveLines = (int) (mouseLoc / moveInc); 130 | if (moveLines > blines - maxlines) 131 | moveLines = blines - maxlines; 132 | 133 | gnc.setVisChatLines(moveLines); 134 | mouseLoc = moveInc * moveLines; 135 | if (!ChatBox.anchoredTop) 136 | scrollBarCenter = Math.round(mouseLoc * (barMinY - barMaxY) + barMaxY); 137 | else 138 | scrollBarCenter = Math.round(mouseLoc * (barMaxY - barMinY) + barMinY); 139 | lastY = _absY; 140 | } 141 | 142 | public static void setOffset(int _x, int _y) { 143 | int maxlines = gnc.getHeightSetting() / 9; 144 | int clines = Math.min(gnc.getChatSize(), maxlines); 145 | barX = 324 + _x; 146 | barMinY = mc.currentScreen.height - ((clines - 1) * 9 + 8) - 35 + _y; 147 | barTopY = barMinY + barHeight / 2 + _y; 148 | barMaxY = mc.currentScreen.height - 45 + _y; 149 | barBottomY = barMaxY - barHeight / 2 + _y; 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/gui/ITCSettingsGUI.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.gui; 2 | 3 | import acs.tabbychat.util.TabbyChatUtils; 4 | import net.minecraft.client.gui.GuiButton; 5 | 6 | import java.io.File; 7 | import java.util.Properties; 8 | 9 | public interface ITCSettingsGUI { 10 | int SAVEBUTTON = 8901; 11 | int CANCELBUTTON = 8902; 12 | int MARGIN = 4; 13 | int LINE_HEIGHT = 14; 14 | int DISPLAY_WIDTH = 300; 15 | int DISPLAY_HEIGHT = 180; 16 | File tabbyChatDir = TabbyChatUtils.getTabbyChatDir(); 17 | 18 | void actionPerformed(GuiButton button); 19 | 20 | void defineDrawableSettings(); 21 | 22 | void drawScreen(int x, int y, float f); 23 | 24 | void handleMouseInput(); 25 | 26 | void initDrawableSettings(); 27 | 28 | 29 | void initGui(); 30 | 31 | void keyTyped(char par1, int par2); 32 | 33 | /** 34 | * Loads config file 35 | */ 36 | Properties loadSettingsFile(); 37 | 38 | void mouseClicked(int par1, int par2, int par3); 39 | 40 | void resetTempVars(); 41 | 42 | int rowY(int rowNum); 43 | 44 | /** 45 | * Saves settings 46 | */ 47 | void saveSettingsFile(); 48 | 49 | /** 50 | * Specifies config file 51 | */ 52 | void saveSettingsFile(Properties preProps); 53 | 54 | void storeTempVars(); 55 | 56 | void validateButtonStates(); 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/gui/PrefsButton.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.gui; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.gui.FontRenderer; 5 | import net.minecraft.client.gui.GuiButton; 6 | 7 | public class PrefsButton extends GuiButton { 8 | protected int bgcolor = 0xDD000000; 9 | protected boolean hasControlCodes = false; 10 | protected String type; 11 | 12 | public PrefsButton() { 13 | super(9999, 0, 0, 1, 1, ""); 14 | } 15 | 16 | public PrefsButton(int _id, int _x, int _y, int _w, int _h, String _title) { 17 | super(_id, _x, _y, _w, _h, _title); 18 | } 19 | 20 | public PrefsButton(int _id, int _x, int _y, int _w, int _h, String _title, int _bgcolor) { 21 | super(_id, _x, _y, _w, _h, _title); 22 | this.bgcolor = _bgcolor; 23 | } 24 | 25 | /** 26 | * Sets name of button 27 | */ 28 | protected void title(String newTitle) { 29 | this.displayString = newTitle; 30 | } 31 | 32 | /** 33 | * Returns name of button 34 | */ 35 | protected String title() { 36 | return this.displayString; 37 | } 38 | 39 | /** 40 | * Returns button width 41 | */ 42 | public int width() { 43 | return this.width; 44 | } 45 | 46 | /** 47 | * Sets button width 48 | */ 49 | public void width(int _w) { 50 | this.width = _w; 51 | } 52 | 53 | /** 54 | * Returns button height 55 | */ 56 | public int height() { 57 | return this.height; 58 | } 59 | 60 | /** 61 | * Sets button height 62 | */ 63 | public void height(int _h) { 64 | this.height = _h; 65 | } 66 | 67 | /** 68 | * Return x position 69 | */ 70 | public int x() { 71 | return xPosition; 72 | } 73 | 74 | /** 75 | * Set x position 76 | */ 77 | public void x(int _x) { 78 | xPosition = _x; 79 | } 80 | 81 | /** 82 | * Return y position 83 | */ 84 | public int y() { 85 | return yPosition; 86 | } 87 | 88 | /** 89 | * Set y position 90 | */ 91 | public void y(int _y) { 92 | yPosition = _y; 93 | } 94 | 95 | protected int adjustWidthForControlCodes() { 96 | String cleaned = this.displayString.replaceAll("(?i)\u00A7[0-9A-FK-OR]", ""); 97 | boolean bold = (this.displayString.replaceAll("(?i)\u00A7L", "").length() != this.displayString 98 | .length()); 99 | int badWidth = Minecraft.getMinecraft().fontRenderer.getStringWidth(this.displayString); 100 | int goodWidth = Minecraft.getMinecraft().fontRenderer.getStringWidth(cleaned); 101 | if (bold) 102 | goodWidth += cleaned.length(); 103 | return (badWidth > goodWidth) ? badWidth - goodWidth : 0; 104 | } 105 | 106 | @Override 107 | public void drawButton(Minecraft mc, int cursorX, int cursorY) { 108 | if (this.visible) { 109 | FontRenderer fr = mc.fontRenderer; 110 | drawRect(this.x(), this.y(), this.x() + this.width(), this.y() + this.height(), 111 | this.bgcolor); 112 | boolean hovered = cursorX >= this.x() && cursorY >= this.y() 113 | && cursorX < this.x() + this.width() && cursorY < this.y() + this.height(); 114 | 115 | if (bgcolor == 0xDD000000 || bgcolor == 0x99999999) { 116 | drawRect(this.x() - 1, this.y() - 1, this.x(), this.y() + this.height(), 0xc0c0c0c0); 117 | drawRect(this.x() - 1, this.y() - 1, this.x() + this.width() + 1, this.y(), 118 | 0xc0c0c0c0); 119 | drawRect(this.x() - 1, this.y() + this.height(), this.x() + this.width() + 1, 120 | this.y() + this.height() + 1, 0x70707070); 121 | drawRect(this.x() + this.width(), this.y() - 1, this.x() + this.width() + 1, 122 | this.y() + this.height() + 1, 0x70707070); 123 | } 124 | 125 | int var7 = 0xa0a0a0; 126 | if (!this.enabled) { 127 | var7 = -0x5f5f60; 128 | } 129 | else if (hovered) { 130 | var7 = 0xffffa0; 131 | } 132 | 133 | if (this.hasControlCodes) { 134 | int offset = this.adjustWidthForControlCodes(); 135 | this.drawCenteredString(fr, this.displayString, this.x() + (this.width() + offset) 136 | / 2, this.y() + (this.height() - 8) / 2, var7); 137 | } 138 | else 139 | this.drawCenteredString(fr, this.displayString, this.x() + this.width() / 2, 140 | this.y() + (this.height() - 8) / 2, var7); 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/gui/TCSettingsAdvanced.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.gui; 2 | 3 | import acs.tabbychat.core.TabbyChat; 4 | import acs.tabbychat.settings.TCSettingBool; 5 | import acs.tabbychat.settings.TCSettingSlider; 6 | import acs.tabbychat.settings.TCSettingTextBox; 7 | import acs.tabbychat.settings.files.TCSettingsAdvancedFile; 8 | import acs.tabbychat.util.TabbyChatUtils; 9 | import net.minecraft.client.resources.I18n; 10 | 11 | import java.io.File; 12 | import java.util.Properties; 13 | 14 | /** 15 | * UI handling for advanced settings 16 | * Actual settings file handling happens in {@link TCSettingsAdvancedFile} 17 | */ 18 | public class TCSettingsAdvanced extends TCSettingsGUI { 19 | private static final int CHAT_SCROLL_HISTORY_ID = 9401; 20 | private static final int MAXLENGTH_CHANNEL_NAME_ID = 9402; 21 | private static final int MULTICHAT_DELAY_ID = 9403; 22 | private static final int CHATBOX_UNFOC_HEIGHT_ID = 9406; 23 | private static final int CHAT_FADE_TICKS_ID = 9408; 24 | private static final int TEXT_IGNORE_OPACITY_ID = 9410; 25 | private static final int CONVERT_UNICODE_TEXT_ID = 9411; 26 | 27 | private final TCSettingsAdvancedFile settings = new TCSettingsAdvancedFile(); 28 | public TCSettingTextBox chatScrollHistory; 29 | public TCSettingTextBox maxLengthChannelName; 30 | public TCSettingTextBox multiChatDelay; 31 | public TCSettingSlider chatBoxUnfocHeight; 32 | public TCSettingSlider chatFadeTicks; 33 | public TCSettingBool textIgnoreOpacity; 34 | public TCSettingBool convertUnicodeText; 35 | 36 | public TCSettingsAdvanced(TabbyChat _tc) { 37 | super(_tc); 38 | propertyPrefix = "settings.advanced"; 39 | 40 | chatScrollHistory = new TCSettingTextBox("100", "chatScrollHistory", 41 | propertyPrefix, CHAT_SCROLL_HISTORY_ID); 42 | maxLengthChannelName = new TCSettingTextBox("10", 43 | "maxLengthChannelName", propertyPrefix, MAXLENGTH_CHANNEL_NAME_ID); 44 | multiChatDelay = new TCSettingTextBox("500", "multiChatDelay", 45 | propertyPrefix, MULTICHAT_DELAY_ID); 46 | chatBoxUnfocHeight = new TCSettingSlider(50.0f, "chatBoxUnfocHeight", 47 | propertyPrefix, CHATBOX_UNFOC_HEIGHT_ID, 20.0f, 100.0f); 48 | chatFadeTicks = new TCSettingSlider(200.0f, "chatFadeTicks", 49 | propertyPrefix, CHAT_FADE_TICKS_ID, 10.0f, 2000.0f); 50 | 51 | textIgnoreOpacity = new TCSettingBool(false, "textignoreopacity", 52 | propertyPrefix, TEXT_IGNORE_OPACITY_ID); 53 | convertUnicodeText = new TCSettingBool(false, "convertunicodetext", 54 | propertyPrefix, CONVERT_UNICODE_TEXT_ID); 55 | this.name = I18n.format("settings.advanced.name"); 56 | this.settingsFile = new File(tabbyChatDir, "advanced.cfg"); 57 | this.bgcolor = 0x66802e94; 58 | this.chatScrollHistory.setCharLimit(3); 59 | this.maxLengthChannelName.setCharLimit(2); 60 | this.multiChatDelay.setCharLimit(4); 61 | this.defineDrawableSettings(); 62 | } 63 | 64 | @Override 65 | public void defineDrawableSettings() { 66 | this.buttonList.add(this.chatScrollHistory); 67 | this.buttonList.add(this.maxLengthChannelName); 68 | this.buttonList.add(this.multiChatDelay); 69 | this.buttonList.add(this.chatBoxUnfocHeight); 70 | this.buttonList.add(this.chatFadeTicks); 71 | this.buttonList.add(this.textIgnoreOpacity); 72 | this.buttonList.add(this.convertUnicodeText); 73 | } 74 | 75 | @Override 76 | public void initDrawableSettings() { 77 | int col1x = (this.width - DISPLAY_WIDTH) / 2 + 55; 78 | 79 | int buttonColor = (this.bgcolor & 0x00ffffff) + 0xff000000; 80 | 81 | this.chatScrollHistory.setLabelLoc(col1x); 82 | this.chatScrollHistory.setButtonLoc( 83 | col1x + 5 + mc.fontRenderer.getStringWidth(this.chatScrollHistory.description), 84 | this.rowY(1)); 85 | this.chatScrollHistory.setButtonDims(30, 11); 86 | 87 | this.maxLengthChannelName.setLabelLoc(col1x); 88 | this.maxLengthChannelName.setButtonLoc( 89 | col1x + 5 + mc.fontRenderer.getStringWidth(this.maxLengthChannelName.description), 90 | this.rowY(2)); 91 | this.maxLengthChannelName.setButtonDims(20, 11); 92 | 93 | this.multiChatDelay.setLabelLoc(col1x); 94 | this.multiChatDelay.setButtonLoc( 95 | col1x + 5 + mc.fontRenderer.getStringWidth(this.multiChatDelay.description), 96 | this.rowY(3)); 97 | this.multiChatDelay.setButtonDims(40, 11); 98 | 99 | this.chatBoxUnfocHeight.setLabelLoc(col1x); 100 | this.chatBoxUnfocHeight.setButtonLoc( 101 | col1x + 5 + mc.fontRenderer.getStringWidth(this.chatBoxUnfocHeight.description), 102 | this.rowY(4)); 103 | this.chatBoxUnfocHeight.buttonColor = buttonColor; 104 | 105 | this.chatFadeTicks.setLabelLoc(col1x); 106 | this.chatFadeTicks.setButtonLoc( 107 | col1x + 5 + mc.fontRenderer.getStringWidth(this.chatFadeTicks.description), 108 | this.rowY(5)); 109 | this.chatFadeTicks.buttonColor = buttonColor; 110 | this.chatFadeTicks.units = ""; 111 | 112 | this.textIgnoreOpacity.setButtonLoc(col1x, this.rowY(6)); 113 | this.textIgnoreOpacity.setLabelLoc(col1x + 19); 114 | this.textIgnoreOpacity.buttonColor = buttonColor; 115 | 116 | this.convertUnicodeText.setButtonLoc(col1x, this.rowY(7)); 117 | this.convertUnicodeText.setLabelLoc(col1x + 19); 118 | this.convertUnicodeText.buttonColor = buttonColor; 119 | } 120 | 121 | @Override 122 | public Properties loadSettingsFile() { 123 | //Refreshes settings 124 | settings.loadSettingsFile(); 125 | 126 | chatScrollHistory.setValue(Integer.toString(settings.chatScrollHistory)); 127 | maxLengthChannelName.setValue(Integer.toString(settings.maxLengthChannelName)); 128 | ChatBox.anchoredTop = settings.anchoredTop; 129 | convertUnicodeText.setValue(settings.convertUnicodeText); 130 | multiChatDelay.setValue(Integer.toString(settings.multiChatDelay)); 131 | ChatBox.current.height = TabbyChatUtils.parseInteger(String.valueOf(settings.chatBoxHeight), 132 | ChatBox.absMinH, 10000, 180); 133 | chatBoxUnfocHeight.setValue(settings.chatBoxUnfocHeight); 134 | ChatBox.current.y = TabbyChatUtils.parseInteger(String.valueOf(settings.chatBoxY), -10000, 135 | ChatBox.absMinY, ChatBox.absMinY); 136 | ChatBox.current.x = TabbyChatUtils.parseInteger(String.valueOf(settings.chatBoxX), 137 | ChatBox.absMinX, 10000, ChatBox.absMinX); 138 | textIgnoreOpacity.setValue(settings.textIgnoreOpacity); 139 | ChatBox.current.width = TabbyChatUtils.parseInteger(String.valueOf(settings.chatBoxWidth), 140 | ChatBox.absMinW, 10000, 320); 141 | chatFadeTicks.setValue(settings.chatFadeTicks); 142 | ChatBox.pinned = settings.pinned; 143 | return null; 144 | } 145 | 146 | @Override 147 | public void saveSettingsFile() { 148 | try { 149 | settings.anchoredTop = ChatBox.anchoredTop; 150 | settings.convertUnicodeText = convertUnicodeText.getValue(); 151 | settings.chatBoxHeight = ChatBox.current.height; 152 | settings.chatBoxUnfocHeight = chatBoxUnfocHeight.getValue(); 153 | settings.chatBoxY = ChatBox.current.y; 154 | settings.chatBoxX = ChatBox.current.x; 155 | settings.textIgnoreOpacity = textIgnoreOpacity.getValue(); 156 | settings.chatBoxWidth = ChatBox.current.width; 157 | settings.chatFadeTicks = chatFadeTicks.getValue(); 158 | settings.pinned = ChatBox.pinned; 159 | //Save last to prevent information from getting lost if one of these values is invalid 160 | settings.chatScrollHistory = Integer.parseInt(chatScrollHistory.getValue()); 161 | settings.maxLengthChannelName = Integer.parseInt(maxLengthChannelName.getValue()); 162 | settings.multiChatDelay = Integer.parseInt(multiChatDelay.getValue()); 163 | } 164 | catch (NumberFormatException e) { 165 | TabbyChatUtils.log.warn("Invalid format in advanced settings"); 166 | } 167 | settings.saveSettingsFile(); 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/gui/TCSettingsGeneral.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.gui; 2 | 3 | import acs.tabbychat.core.TabbyChat; 4 | import acs.tabbychat.settings.ColorCodeEnum; 5 | import acs.tabbychat.settings.FormatCodeEnum; 6 | import acs.tabbychat.settings.TCSettingBool; 7 | import acs.tabbychat.settings.TCSettingEnum; 8 | import acs.tabbychat.settings.TimeStampEnum; 9 | import net.minecraft.client.gui.GuiButton; 10 | import net.minecraft.client.resources.I18n; 11 | 12 | import java.io.File; 13 | import java.text.SimpleDateFormat; 14 | import java.util.Properties; 15 | 16 | public class TCSettingsGeneral extends TCSettingsGUI { 17 | private static final int TABBYCHAT_ENABLE_ID = 9101; 18 | private static final int SAVE_CHATLOG_ID = 9102; 19 | private static final int TIMESTAMP_ENABLE_ID = 9103; 20 | private static final int TIMESTAMP_STYLE_ID = 9104; 21 | private static final int GROUP_SPAM_ID = 9105; 22 | private static final int UNREAD_FLASHING_ID = 9106; 23 | private static final int TIMESTAMP_COLOR_ID = 9107; 24 | private static final int UPDATE_CHECK_ENABLE = 9109; 25 | private static final int SPLIT_CHATLOG = 9110; 26 | 27 | public SimpleDateFormat timeStamp = new SimpleDateFormat(); 28 | public TCSettingBool tabbyChatEnable; 29 | public TCSettingBool saveChatLog; 30 | public TCSettingBool timeStampEnable; 31 | public TCSettingEnum timeStampStyle; 32 | public TCSettingEnum timeStampColor; 33 | public TCSettingBool groupSpam; 34 | public TCSettingBool unreadFlashing; 35 | public TCSettingBool updateCheckEnable; 36 | public TCSettingBool splitChatLog; 37 | 38 | public TCSettingsGeneral(TabbyChat _tc) { 39 | super(_tc); 40 | this.propertyPrefix = "settings.general"; 41 | tabbyChatEnable = new TCSettingBool(true, "tabbyChatEnable", 42 | this.propertyPrefix, TABBYCHAT_ENABLE_ID); 43 | saveChatLog = new TCSettingBool(false, "saveChatLog", this.propertyPrefix, 44 | SAVE_CHATLOG_ID); 45 | timeStampEnable = new TCSettingBool(false, "timeStampEnable", 46 | this.propertyPrefix, TIMESTAMP_ENABLE_ID); 47 | timeStampStyle = new TCSettingEnum(TimeStampEnum.MILITARY, 48 | "timeStampStyle", this.propertyPrefix, TIMESTAMP_STYLE_ID, FormatCodeEnum.ITALIC); 49 | timeStampColor = new TCSettingEnum(ColorCodeEnum.DEFAULT, 50 | "timeStampColor", this.propertyPrefix, TIMESTAMP_COLOR_ID, FormatCodeEnum.ITALIC); 51 | groupSpam = new TCSettingBool(false, "groupSpam", this.propertyPrefix, 52 | GROUP_SPAM_ID); 53 | unreadFlashing = new TCSettingBool(true, "unreadFlashing", 54 | this.propertyPrefix, UNREAD_FLASHING_ID); 55 | updateCheckEnable = new TCSettingBool(true, "updateCheckEnable", 56 | this.propertyPrefix, UPDATE_CHECK_ENABLE); 57 | splitChatLog = new TCSettingBool(false, "splitChatLog", 58 | this.propertyPrefix, SPLIT_CHATLOG); 59 | 60 | this.name = I18n.format("settings.general.name"); 61 | this.settingsFile = new File(tabbyChatDir, "general.cfg"); 62 | this.bgcolor = 0x664782be; 63 | this.defineDrawableSettings(); 64 | } 65 | 66 | @Override 67 | public void actionPerformed(GuiButton button) { 68 | if (button.id == TABBYCHAT_ENABLE_ID) { 69 | if (tc.enabled()) 70 | tc.disable(); 71 | else { 72 | tc.enable(); 73 | } 74 | } 75 | super.actionPerformed(button); 76 | } 77 | 78 | private void applyTimestampPattern() { 79 | if (((ColorCodeEnum) this.timeStampColor.getValue()).toCode().length() > 0) { 80 | String tsPattern = "'" + ((ColorCodeEnum) this.timeStampColor.getValue()).toCode() + 81 | "'" + 82 | ((TimeStampEnum) this.timeStampStyle.getValue()).toCode() + 83 | "'\u00A7r'"; 84 | this.timeStamp.applyPattern(tsPattern); 85 | } 86 | else { 87 | this.timeStamp.applyPattern(((TimeStampEnum) this.timeStampStyle.getValue()).toCode()); 88 | } 89 | } 90 | 91 | @Override 92 | public void defineDrawableSettings() { 93 | this.buttonList.add(this.tabbyChatEnable); 94 | this.buttonList.add(this.saveChatLog); 95 | this.buttonList.add(this.timeStampEnable); 96 | this.buttonList.add(this.timeStampStyle); 97 | this.buttonList.add(this.timeStampColor); 98 | this.buttonList.add(this.groupSpam); 99 | this.buttonList.add(this.unreadFlashing); 100 | this.buttonList.add(this.updateCheckEnable); 101 | this.buttonList.add(this.splitChatLog); 102 | } 103 | 104 | @Override 105 | public void initDrawableSettings() { 106 | int effRight = (this.width + DISPLAY_WIDTH) / 2; 107 | int col1x = (this.width - DISPLAY_WIDTH) / 2 + 55; 108 | int col2x = this.width / 2 + 25; 109 | 110 | int buttonColor = (this.bgcolor & 0x00ffffff) + 0xff000000; 111 | 112 | this.tabbyChatEnable.setButtonLoc(col1x, this.rowY(1)); 113 | this.tabbyChatEnable.setLabelLoc(col1x + 19); 114 | this.tabbyChatEnable.buttonColor = buttonColor; 115 | 116 | this.saveChatLog.setButtonLoc(col1x, this.rowY(2)); 117 | this.saveChatLog.setLabelLoc(col1x + 19); 118 | this.saveChatLog.buttonColor = buttonColor; 119 | 120 | this.splitChatLog.setButtonLoc(col2x, this.rowY(2)); 121 | this.splitChatLog.setLabelLoc(col2x + 19); 122 | this.splitChatLog.buttonColor = buttonColor; 123 | 124 | this.timeStampEnable.setButtonLoc(col1x, this.rowY(3)); 125 | this.timeStampEnable.setLabelLoc(col1x + 19); 126 | this.timeStampEnable.buttonColor = buttonColor; 127 | 128 | this.timeStampStyle.setButtonDims(80, 11); 129 | this.timeStampStyle.setButtonLoc(effRight - 80, this.rowY(4)); 130 | this.timeStampStyle.setLabelLoc(this.timeStampStyle.x() - 10 131 | - mc.fontRenderer.getStringWidth(this.timeStampStyle.description)); 132 | 133 | this.timeStampColor.setButtonDims(80, 11); 134 | this.timeStampColor.setButtonLoc(effRight - 80, this.rowY(5)); 135 | this.timeStampColor.setLabelLoc(this.timeStampColor.x() - 10 136 | - mc.fontRenderer.getStringWidth(this.timeStampColor.description)); 137 | 138 | this.groupSpam.setButtonLoc(col1x, this.rowY(6)); 139 | this.groupSpam.setLabelLoc(col1x + 19); 140 | this.groupSpam.buttonColor = buttonColor; 141 | 142 | this.unreadFlashing.setButtonLoc(col1x, this.rowY(7)); 143 | this.unreadFlashing.setLabelLoc(col1x + 19); 144 | this.unreadFlashing.buttonColor = buttonColor; 145 | 146 | this.updateCheckEnable.setButtonLoc(col1x, this.rowY(8)); 147 | this.updateCheckEnable.setLabelLoc(col1x + 19); 148 | this.updateCheckEnable.buttonColor = buttonColor; 149 | } 150 | 151 | @Override 152 | public Properties loadSettingsFile() { 153 | super.loadSettingsFile(); 154 | this.applyTimestampPattern(); 155 | return null; 156 | } 157 | 158 | @Override 159 | public void storeTempVars() { 160 | super.storeTempVars(); 161 | this.applyTimestampPattern(); 162 | } 163 | 164 | @Override 165 | public void validateButtonStates() { 166 | this.timeStampColor.enabled = this.timeStampEnable.getTempValue(); 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/gui/TCSettingsSpelling.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.gui; 2 | 3 | import acs.tabbychat.core.TabbyChat; 4 | import acs.tabbychat.settings.TCSettingBool; 5 | import acs.tabbychat.settings.TCSettingList; 6 | import acs.tabbychat.settings.TCSettingList.Entry; 7 | import net.minecraft.client.gui.GuiButton; 8 | import net.minecraft.client.gui.GuiTextField; 9 | import net.minecraft.client.resources.I18n; 10 | 11 | import java.awt.Desktop; 12 | import java.io.File; 13 | import java.io.IOException; 14 | import java.nio.file.Files; 15 | import java.util.Properties; 16 | 17 | public class TCSettingsSpelling extends TCSettingsGUI { 18 | 19 | private static final int SPELL_CHECK_ENABLE = 9108; 20 | private static final int ADD_WORD = 9502; 21 | private static final int REMOVE_WORD = 9503; 22 | private static final int CLEAR_WORDS = 9504; 23 | 24 | private static final int NEXT = 9506; 25 | private static final int PREV = 9507; 26 | private static final int OPEN = 9508; 27 | private static final int RELOAD = 9509; 28 | 29 | public TCSettingBool spellCheckEnable; 30 | private GuiTextField wordInput; 31 | private final PrefsButton addWord = new PrefsButton(ADD_WORD, 0, 0, 15, 12, ">"); 32 | private final PrefsButton removeWords = new PrefsButton(REMOVE_WORD, 0, 0, 15, 12, "<"); 33 | private final PrefsButton clearWords = new PrefsButton(CLEAR_WORDS, 0, 0, 15, 12, "<<"); 34 | private final PrefsButton next = new PrefsButton(NEXT, 0, 0, 15, 12, "->"); 35 | private final PrefsButton prev = new PrefsButton(PREV, 0, 0, 15, 12, "<-"); 36 | private final PrefsButton open = new PrefsButton(OPEN, 0, 0, 85, 15, ""); 37 | private final PrefsButton reload = new PrefsButton(RELOAD, 0, 0, 85, 15, ""); 38 | private final File dictionary = new File(tabbyChatDir, "dictionary.txt"); 39 | public TCSettingList spellingList = new TCSettingList(dictionary); 40 | 41 | public TCSettingsSpelling(TabbyChat _tc) { 42 | super(_tc); 43 | this.propertyPrefix = "settings.spelling"; 44 | spellCheckEnable = new TCSettingBool(true, "spellCheckEnable", 45 | this.propertyPrefix, SPELL_CHECK_ENABLE); 46 | this.name = I18n.format("settings.spelling.name"); 47 | this.settingsFile = new File(tabbyChatDir, "spellcheck.cfg"); 48 | this.bgcolor = 0x66ffb62f; 49 | this.defineDrawableSettings(); 50 | } 51 | 52 | @Override 53 | public void saveSettingsFile() { 54 | try { 55 | this.spellingList.saveEntries(); 56 | } 57 | catch (IOException e) { 58 | e.printStackTrace(); 59 | } 60 | super.saveSettingsFile(); 61 | } 62 | 63 | @Override 64 | public Properties loadSettingsFile() { 65 | super.loadSettingsFile(); 66 | try { 67 | if (! dictionary.exists()) { 68 | Files.createDirectories(dictionary.getParentFile().toPath()); 69 | Files.createFile(dictionary.toPath()); 70 | } 71 | spellingList.loadEntries(); 72 | } 73 | catch (IOException e) { 74 | e.printStackTrace(); 75 | } 76 | return null; 77 | } 78 | 79 | @Override 80 | public void defineDrawableSettings() { 81 | this.buttonList.add(this.spellCheckEnable); 82 | this.buttonList.add(addWord); 83 | this.buttonList.add(removeWords); 84 | this.buttonList.add(clearWords); 85 | this.buttonList.add(next); 86 | this.buttonList.add(prev); 87 | this.buttonList.add(open); 88 | this.buttonList.add(reload); 89 | } 90 | 91 | @Override 92 | public void initDrawableSettings() { 93 | int col1x = (this.width - DISPLAY_WIDTH) / 2 + 55; 94 | int col2x = this.width / 2 + 25; 95 | 96 | int buttonColor = (this.bgcolor & 0x00ffffff) + 0xff000000; 97 | 98 | this.spellCheckEnable.setButtonLoc(col1x, this.rowY(1)); 99 | this.spellCheckEnable.setLabelLoc(col1x + 19); 100 | this.spellCheckEnable.buttonColor = buttonColor; 101 | 102 | this.spellingList.x(col2x); 103 | this.spellingList.y(rowY(4)); 104 | this.spellingList.width(100); 105 | this.spellingList.height(96); 106 | 107 | this.wordInput = new GuiTextField(mc.fontRenderer, col1x, rowY(6), 75, 12); 108 | this.wordInput.setCanLoseFocus(true); 109 | 110 | this.open.displayString = I18n.format("settings.spelling.opendictionary"); 111 | this.open.x(col1x); 112 | this.open.y(rowY(10)); 113 | 114 | this.reload.displayString = I18n.format("settings.spelling.reloaddictionary"); 115 | this.reload.x(col1x); 116 | this.reload.y(rowY(9)); 117 | 118 | this.addWord.x(col2x - 25); 119 | this.addWord.y(rowY(5)); 120 | 121 | this.removeWords.x(col2x - 25); 122 | this.removeWords.y(rowY(6)); 123 | 124 | this.clearWords.x(col2x - 25); 125 | this.clearWords.y(rowY(7)); 126 | 127 | this.next.x(col2x + 53); 128 | this.next.y(rowY(10)); 129 | 130 | this.prev.x(col2x + 33); 131 | this.prev.y(rowY(10)); 132 | 133 | } 134 | 135 | @Override 136 | public void drawScreen(int x, int y, float f) { 137 | int col1x = (this.width - DISPLAY_WIDTH) / 2 + 55; 138 | int col2x = this.width / 2 + 45; 139 | super.drawScreen(x, y, f); 140 | this.wordInput.drawTextBox(); 141 | this.spellingList.drawList(mc, x, y); 142 | this.drawString(fontRendererObj, I18n.format("settings.spelling.userdictionary"), col1x, 143 | rowY(3), 0xffffff); 144 | this.drawString( 145 | fontRendererObj, 146 | I18n.format("book.pageIndicator", this.spellingList.getPageNum(), 147 | this.spellingList.getTotalPages()), col2x, rowY(3), 0xffffff); 148 | } 149 | 150 | @Override 151 | public void initGui() { 152 | super.initGui(); 153 | try { 154 | spellingList.loadEntries(); 155 | } 156 | catch (IOException e) { 157 | e.printStackTrace(); 158 | } 159 | } 160 | 161 | @Override 162 | public void mouseClicked(int x, int y, int button) { 163 | super.mouseClicked(x, y, button); 164 | this.wordInput.mouseClicked(x, y, button); 165 | this.spellingList.mouseClicked(x, y, button); 166 | } 167 | 168 | @Override 169 | public void keyTyped(char c, int i) { 170 | super.keyTyped(c, i); 171 | this.wordInput.textboxKeyTyped(c, i); 172 | } 173 | 174 | @Override 175 | public void actionPerformed(GuiButton button) { 176 | switch (button.id) { 177 | case ADD_WORD -> { 178 | this.spellingList.addToList(this.wordInput.getText()); 179 | this.wordInput.setText(""); 180 | } 181 | case REMOVE_WORD -> { 182 | for (Entry entry : this.spellingList.getSelected()) { 183 | entry.remove(); 184 | } 185 | } 186 | case CLEAR_WORDS -> this.spellingList.clearList(); 187 | case NEXT -> this.spellingList.nextPage(); 188 | case PREV -> this.spellingList.previousPage(); 189 | case OPEN -> { 190 | try { 191 | if (Desktop.isDesktopSupported()) 192 | Desktop.getDesktop().open(dictionary); 193 | } 194 | catch (IOException ignored) { 195 | } 196 | } 197 | case RELOAD -> { 198 | try { 199 | this.spellingList.loadEntries(); 200 | } 201 | catch (IOException e) { 202 | e.printStackTrace(); 203 | } 204 | } 205 | } 206 | super.actionPerformed(button); 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/gui/context/ChatContext.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.gui.context; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.gui.Gui; 5 | import net.minecraft.client.gui.GuiButton; 6 | import net.minecraft.client.renderer.Tessellator; 7 | import net.minecraft.util.ResourceLocation; 8 | import org.lwjgl.opengl.GL11; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * Extend this class to create a context menu.
14 | * Call {@code ChatContextMenu.addContext(ChatContext)} to register
15 | * Don't register children. 16 | */ 17 | public abstract class ChatContext extends GuiButton { 18 | 19 | public ChatContextMenu children; 20 | protected boolean enabled; 21 | ChatContextMenu menu; 22 | 23 | public ChatContext() { 24 | super(0, 0, 0, 100, 15, null); 25 | } 26 | 27 | @Override 28 | public void drawButton(Minecraft mc, int x, int y) { 29 | if (!visible) 30 | return; 31 | if (getChildren() != null) 32 | children = new ChatContextMenu(this, xPosition + width, yPosition, getChildren()); 33 | 34 | this.displayString = this.getDisplayString(); 35 | if (!visible) 36 | return; 37 | Gui.drawRect(xPosition + 1, yPosition + 1, xPosition + width - 1, yPosition + height - 1, 38 | getBackgroundColor(isHovered(x, y))); 39 | drawBorders(); 40 | if (getDisplayIcon() != null) 41 | drawIcon(); 42 | this.drawString(mc.fontRenderer, this.displayString, xPosition + 18, yPosition + 4, 43 | getStringColor()); 44 | if (this.getChildren() != null) { 45 | // This has children. 46 | int length = mc.fontRenderer.getCharWidth('>'); 47 | this.drawString(mc.fontRenderer, ">", xPosition + width - length, yPosition + 4, 48 | getStringColor()); 49 | for (ChatContext chat : children.items) { 50 | chat.visible = isHoveredWithChildren(x, y); 51 | } 52 | children.drawMenu(x, y); 53 | } 54 | } 55 | 56 | protected boolean isHovered(int x, int y) { 57 | return x >= xPosition && x <= xPosition + width && y >= yPosition 58 | && y <= yPosition + height; 59 | } 60 | 61 | protected boolean isHoveredWithChildren(int x, int y) { 62 | boolean hovered = isHovered(x, y); 63 | if (!hovered && getChildren() != null) 64 | for (ChatContext item : children.items) { 65 | if (item.visible) 66 | hovered = item.isHoveredWithChildren(x, y); 67 | if (hovered) 68 | break; 69 | } 70 | return hovered; 71 | } 72 | 73 | protected void drawIcon() { 74 | int x1 = xPosition + 4, y1 = yPosition + 3, x2 = x1 + 9, y2 = y1 + 9; 75 | GL11.glColor4f(1F, 1F, 1F, 1F); 76 | Minecraft.getMinecraft().getTextureManager().bindTexture(getDisplayIcon()); 77 | Tessellator tess = Tessellator.instance; 78 | tess.startDrawingQuads(); 79 | tess.addVertexWithUV(x1, y1, this.zLevel, 0, 0); 80 | tess.addVertexWithUV(x1, y2, this.zLevel, 0, 1); 81 | tess.addVertexWithUV(x2, y2, this.zLevel, 1, 1); 82 | tess.addVertexWithUV(x2, y1, this.zLevel, 1, 0); 83 | tess.draw(); 84 | } 85 | 86 | protected void drawBorders() { 87 | Gui.drawRect(xPosition, yPosition, xPosition + width, yPosition + 1, -0xffffff); 88 | Gui.drawRect(xPosition, yPosition, xPosition + 1, yPosition + height, -0xffffff); 89 | Gui.drawRect(xPosition, yPosition + height, xPosition + width, yPosition + height - 1, 90 | -0xffffff); 91 | Gui.drawRect(xPosition + width, yPosition, xPosition + width - 1, yPosition + height, 92 | -0xffffff); 93 | 94 | Gui.drawRect(xPosition + height, yPosition, xPosition + height + 1, yPosition + height, 95 | -0xffffff); 96 | } 97 | 98 | private int getStringColor() { 99 | if (!enabled && getDisabledBehavior() == Behavior.GRAY) 100 | return 0x999999; 101 | return 0xeeeeee; 102 | } 103 | 104 | private int getBackgroundColor(boolean hovered) { 105 | if (hovered) 106 | return Integer.MIN_VALUE + 0x252525; 107 | else 108 | return Integer.MIN_VALUE; 109 | 110 | } 111 | 112 | protected boolean mouseClicked(int x, int y) { 113 | if (getChildren() == null) { 114 | this.onClicked(); 115 | return true; 116 | } 117 | else { 118 | return children.mouseClicked(x, y); 119 | } 120 | } 121 | 122 | /** 123 | * what happens when clicked 124 | */ 125 | public abstract void onClicked(); 126 | 127 | /** 128 | * The display string 129 | */ 130 | public abstract String getDisplayString(); 131 | 132 | /** 133 | * the display icon, may be null 134 | */ 135 | public abstract ResourceLocation getDisplayIcon(); 136 | 137 | /** 138 | * This item's children. Shown when hovered or clicked. 139 | */ 140 | public abstract List getChildren(); 141 | 142 | /** 143 | * Checks if the clicked location is valid to place this menu. 144 | * 145 | * @param x Mouse X position 146 | * @param y Mouse Y position 147 | */ 148 | public abstract boolean isPositionValid(int x, int y); 149 | 150 | /** 151 | * How this item displays when {@code isPositionValid(int, int)} return 152 | * false. 153 | */ 154 | public abstract Behavior getDisabledBehavior(); 155 | 156 | public ChatContextMenu getMenu() { 157 | return this.menu; 158 | } 159 | 160 | public enum Behavior { 161 | HIDE, 162 | GRAY; 163 | } 164 | 165 | } 166 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/gui/context/ChatContextMenu.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.gui.context; 2 | 3 | import acs.tabbychat.core.GuiChatTC; 4 | import acs.tabbychat.gui.ChatBox; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.client.gui.Gui; 7 | import net.minecraft.client.gui.ScaledResolution; 8 | 9 | import java.awt.Point; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | public class ChatContextMenu extends Gui { 14 | 15 | private static final List registered = new ArrayList<>(); 16 | public ChatContext parent; 17 | public GuiChatTC screen; 18 | public int xPos; 19 | public int yPos; 20 | public int width; 21 | public int height; 22 | protected List items; 23 | private final Minecraft mc = Minecraft.getMinecraft(); 24 | 25 | public ChatContextMenu(GuiChatTC chat, int x, int y) { 26 | this.items = registered; 27 | this.screen = chat; 28 | setup(chat, x, y); 29 | } 30 | 31 | ChatContextMenu(ChatContext parent, int x, int y, List items) { 32 | // this(parent.screen, x, y); 33 | this.parent = parent; 34 | this.items = items; 35 | this.screen = parent.getMenu().screen; 36 | setup(screen, x, y); 37 | } 38 | 39 | public static void addContext(ChatContext item) { 40 | registered.add(item); 41 | } 42 | 43 | public static void insertContextAtPos(int pos, ChatContext item) { 44 | registered.add(pos, item); 45 | } 46 | 47 | public static void removeContext(ChatContext item) { 48 | registered.remove(item); 49 | } 50 | 51 | public static void removeContext(int pos) { 52 | registered.remove(pos); 53 | } 54 | 55 | public static List getRegisteredMenus() { 56 | return registered; 57 | } 58 | 59 | private void setup(GuiChatTC chat, int x, int y) { 60 | ScaledResolution sr = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); 61 | this.xPos = x; 62 | this.yPos = y; 63 | this.width = 100; 64 | if (x > sr.getScaledWidth() - width) { 65 | if (this.parent == null) 66 | xPos -= width; 67 | else 68 | xPos -= width * 2; 69 | } 70 | List visible = new ArrayList<>(); 71 | for (ChatContext item : items) { 72 | item.menu = this; 73 | item.enabled = item.isPositionValid(xPos, yPos); 74 | if (!item.enabled && item.getDisabledBehavior() == ChatContext.Behavior.HIDE) 75 | continue; 76 | visible.add(item); 77 | } 78 | this.height = visible.size() * 15; 79 | if (yPos + height > sr.getScaledHeight()) { 80 | yPos -= height; 81 | if (this.parent != null) 82 | yPos += 15; 83 | } 84 | if (yPos < 0) 85 | yPos = 0; 86 | int i = 0; 87 | for (ChatContext item : visible) { 88 | item.id = i; 89 | item.xPosition = xPos; 90 | item.yPosition = yPos + i * 15; 91 | // if(item.yPosition + item.height > sr.getScaledHeight() || 92 | // item.yPosition < 0) 93 | // item.visible = false; 94 | i++; 95 | } 96 | } 97 | 98 | public void drawMenu(int x, int y) { 99 | Point scaled = ChatBox.scaleMouseCoords(x, y, true); 100 | for (ChatContext item : items) { 101 | if (!item.enabled && item.getDisabledBehavior() == ChatContext.Behavior.HIDE) 102 | continue; 103 | if (scaled != null) { 104 | item.drawButton(mc, scaled.x, scaled.y); 105 | } 106 | } 107 | } 108 | 109 | public boolean mouseClicked(int mouseX, int mouseY) { 110 | for (ChatContext item : items) { 111 | if (!item.enabled) 112 | continue; 113 | if (item.isHoveredWithChildren(mouseX, mouseY)) { 114 | return item.mouseClicked(mouseX, mouseY); 115 | } 116 | } 117 | return false; 118 | } 119 | 120 | public void buttonClicked(ChatContext item) { 121 | item.onClicked(); 122 | } 123 | 124 | public boolean isCursorOver(int x, int y) { 125 | boolean children = false; 126 | for (ChatContext cont : this.items) { 127 | if (cont.isHoveredWithChildren(x, y) && cont.children != null) { 128 | children = cont.children.isCursorOver(x, y); 129 | } 130 | if (children) 131 | break; 132 | } 133 | return (x > xPos && x < xPos + width && y > yPos && y < yPos + height) || children; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/gui/context/ContextCopy.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.gui.context; 2 | 3 | import acs.tabbychat.core.GuiChatTC; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.gui.GuiScreen; 6 | import net.minecraft.client.gui.GuiTextField; 7 | import net.minecraft.util.ResourceLocation; 8 | 9 | import java.util.List; 10 | 11 | public class ContextCopy extends ChatContext { 12 | 13 | @Override 14 | public void onClicked() { 15 | if (Minecraft.getMinecraft().currentScreen instanceof GuiChatTC screen) { 16 | GuiScreen.setClipboardString(screen.inputField.getSelectedText()); 17 | } 18 | } 19 | 20 | @Override 21 | public String getDisplayString() { 22 | return "Copy"; 23 | } 24 | 25 | @Override 26 | public ResourceLocation getDisplayIcon() { 27 | return new ResourceLocation("tabbychat:textures/gui/icons/copy.png"); 28 | } 29 | 30 | @Override 31 | public boolean isPositionValid(int x, int y) { 32 | GuiTextField text = menu.screen.inputField; 33 | return text != null && !text.getSelectedText().isEmpty(); 34 | } 35 | 36 | @Override 37 | public Behavior getDisabledBehavior() { 38 | return Behavior.GRAY; 39 | } 40 | 41 | @Override 42 | public List getChildren() { 43 | return null; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/gui/context/ContextCut.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.gui.context; 2 | 3 | import net.minecraft.client.gui.GuiScreen; 4 | import net.minecraft.client.gui.GuiTextField; 5 | import net.minecraft.util.ResourceLocation; 6 | 7 | import java.util.List; 8 | 9 | public class ContextCut extends ChatContext { 10 | 11 | @Override 12 | public void onClicked() { 13 | GuiTextField chat = getMenu().screen.inputField; 14 | GuiScreen.setClipboardString(chat.getSelectedText()); 15 | String text = chat.getText().replace(chat.getSelectedText(), ""); 16 | chat.setText(text); 17 | } 18 | 19 | @Override 20 | public String getDisplayString() { 21 | return "Cut"; 22 | } 23 | 24 | @Override 25 | public ResourceLocation getDisplayIcon() { 26 | return new ResourceLocation("tabbychat:textures/gui/icons/cut.png"); 27 | } 28 | 29 | @Override 30 | public boolean isPositionValid(int x, int y) { 31 | GuiTextField text = getMenu().screen.inputField; 32 | return text != null && !text.getSelectedText().isEmpty(); 33 | } 34 | 35 | @Override 36 | public Behavior getDisabledBehavior() { 37 | return Behavior.GRAY; 38 | } 39 | 40 | @Override 41 | public List getChildren() { 42 | return null; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/gui/context/ContextDummy.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.gui.context; 2 | 3 | import net.minecraft.util.ResourceLocation; 4 | import org.apache.logging.log4j.LogManager; 5 | 6 | import java.lang.reflect.Method; 7 | import java.util.List; 8 | 9 | /** 10 | * Dummy context menu that includes setter methods and extra getter methods. 11 | */ 12 | public class ContextDummy extends ChatContext { 13 | 14 | private Method onClick; 15 | private Method isValid; 16 | private Behavior behavior = Behavior.GRAY; 17 | private ResourceLocation icon; 18 | private List children; 19 | 20 | public ContextDummy() {} 21 | 22 | public ContextDummy(String display) { 23 | this.displayString = display; 24 | } 25 | 26 | @Override 27 | public void onClicked() { 28 | if (onClick == null) 29 | return; 30 | try { 31 | onClick.invoke(null); 32 | } 33 | catch (Exception e) { 34 | LogManager.getLogger().error(e); 35 | } 36 | } 37 | 38 | @Override 39 | public String getDisplayString() { 40 | return this.displayString; 41 | } 42 | 43 | public void setDisplayString(String string) { 44 | this.displayString = string; 45 | } 46 | 47 | @Override 48 | public ResourceLocation getDisplayIcon() { 49 | return this.icon; 50 | } 51 | 52 | public void setDisplayIcon(ResourceLocation icon) { 53 | this.icon = icon; 54 | } 55 | 56 | @Override 57 | public List getChildren() { 58 | return this.children; 59 | } 60 | 61 | public void setChildren(List children) { 62 | this.children = children; 63 | } 64 | 65 | @Override 66 | public boolean isPositionValid(int x, int y) { 67 | if (this.isValid == null) 68 | return false; 69 | try { 70 | return ((Boolean) isValid.invoke(null)).booleanValue(); 71 | } 72 | catch (Exception e) { 73 | LogManager.getLogger().error(e); 74 | return false; 75 | } 76 | } 77 | 78 | @Override 79 | public Behavior getDisabledBehavior() { 80 | return this.behavior; 81 | } 82 | 83 | public Method getOnClickMethod() { 84 | return this.onClick; 85 | } 86 | 87 | /** 88 | * Sets the method that is invoked when clicked 89 | * 90 | * @param method Must be public static 91 | */ 92 | public void setOnClickMethod(Method method) { 93 | this.onClick = method; 94 | } 95 | 96 | public Method getIsValidMethod() { 97 | return this.isValid; 98 | } 99 | 100 | /** 101 | * Sets the method called to determine the if the current location is valid. 102 | * If null, will return true. If errors, returns false. 103 | * 104 | * @param method Must be public static and return boolean 105 | */ 106 | public void setIsValidMethod(Method method) { 107 | this.isValid = method; 108 | } 109 | 110 | public void setBehavior(Behavior behavior) { 111 | this.behavior = behavior; 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/gui/context/ContextPaste.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.gui.context; 2 | 3 | import net.minecraft.client.gui.GuiScreen; 4 | import net.minecraft.util.ResourceLocation; 5 | 6 | import java.util.List; 7 | 8 | public class ContextPaste extends ChatContext { 9 | 10 | @Override 11 | public void onClicked() { 12 | getMenu().screen.inputField.writeText(GuiScreen.getClipboardString()); 13 | } 14 | 15 | @Override 16 | public ResourceLocation getDisplayIcon() { 17 | return new ResourceLocation("tabbychat:textures/gui/icons/paste.png"); 18 | } 19 | 20 | @Override 21 | public String getDisplayString() { 22 | return "Paste"; 23 | } 24 | 25 | @Override 26 | public boolean isPositionValid(int x, int y) { 27 | String clipboard = GuiScreen.getClipboardString(); 28 | return !clipboard.isEmpty(); 29 | } 30 | 31 | @Override 32 | public Behavior getDisabledBehavior() { 33 | return Behavior.GRAY; 34 | } 35 | 36 | @Override 37 | public List getChildren() { 38 | return null; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/gui/context/ContextSpellingSuggestion.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.gui.context; 2 | 3 | import acs.tabbychat.core.TabbyChat; 4 | import net.minecraft.client.gui.GuiTextField; 5 | import net.minecraft.util.ResourceLocation; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public class ContextSpellingSuggestion extends ChatContext { 11 | 12 | private String[] suggestions; 13 | private String title; 14 | 15 | @Override 16 | public void onClicked() { 17 | 18 | } 19 | 20 | @Override 21 | public String getDisplayString() { 22 | return title; 23 | } 24 | 25 | @Override 26 | public ResourceLocation getDisplayIcon() { 27 | return null; 28 | } 29 | 30 | @Override 31 | public List getChildren() { 32 | List list = new ArrayList<>(); 33 | if (suggestions == null) { 34 | return null; 35 | } 36 | for (final String word : suggestions) { 37 | list.add(makeBaby(word)); 38 | } 39 | return list; 40 | } 41 | 42 | @Override 43 | public boolean isPositionValid(int x, int y) { 44 | this.title = "Spelling"; 45 | GuiTextField text = getMenu().screen.inputField; 46 | int start = text.getNthWordFromCursor(-1); 47 | int end = text.getNthWordFromCursor(1); 48 | String word = text.getText().substring(start, end); 49 | if (!word.isEmpty()) { 50 | if (!TabbyChat.spellChecker.isSpelledCorrectly(word)) { 51 | List suggs = TabbyChat.spellChecker.getSuggestions(word, 0); 52 | suggestions = objectToStringArray(suggs.toArray()); 53 | if (suggestions.length == 0) { 54 | this.title = "No Suggestions"; 55 | return false; 56 | } 57 | return true; 58 | } 59 | } 60 | suggestions = null; 61 | return false; 62 | } 63 | 64 | private String[] objectToStringArray(Object[] object) { 65 | String[] array = new String[object.length]; 66 | for (int i = 0; i < array.length; i++) { 67 | array[i] = object[i].toString(); 68 | } 69 | return array; 70 | } 71 | 72 | @Override 73 | public Behavior getDisabledBehavior() { 74 | if (suggestions == null) 75 | return Behavior.HIDE; 76 | else 77 | return Behavior.GRAY; 78 | } 79 | 80 | // Sexy time for spell checker 81 | private ChatContext makeBaby(final String word) { 82 | return new ChatContext() { 83 | 84 | @Override 85 | public void onClicked() { 86 | GuiTextField field = getMenu().screen.inputField; 87 | int start = field.getNthWordFromCursor(-1); 88 | int end = field.getNthWordFromCursor(1); 89 | field.setCursorPosition(start); 90 | field.setSelectionPos(end); 91 | String sel = field.getSelectedText(); 92 | char pref = sel.charAt(0); 93 | char suff = sel.charAt(sel.length() - 1); 94 | if (Character.isLetter(pref)) 95 | pref = 0; 96 | if (Character.isLetter(suff)) 97 | suff = ' '; 98 | this.getMenu().screen.inputField.writeText((pref != 0 ? pref : "") + word + suff); 99 | } 100 | 101 | @Override 102 | public boolean isPositionValid(int x, int y) { 103 | return true; 104 | } 105 | 106 | @Override 107 | public String getDisplayString() { 108 | return word; 109 | } 110 | 111 | @Override 112 | public ResourceLocation getDisplayIcon() { 113 | return null; 114 | } 115 | 116 | @Override 117 | public Behavior getDisabledBehavior() { 118 | return Behavior.GRAY; 119 | } 120 | 121 | @Override 122 | public List getChildren() { 123 | return null; 124 | } 125 | }; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/jazzy/TCSpellCheckListener.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.jazzy; 2 | 3 | import acs.tabbychat.core.TabbyChat; 4 | import com.swabunga.spell.engine.SpellDictionary; 5 | import com.swabunga.spell.engine.SpellDictionaryHashMap; 6 | import com.swabunga.spell.event.SpellCheckEvent; 7 | import com.swabunga.spell.event.SpellCheckListener; 8 | import com.swabunga.spell.event.SpellChecker; 9 | import com.swabunga.spell.event.StringWordTokenizer; 10 | 11 | import java.io.File; 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | import java.io.InputStreamReader; 15 | 16 | public class TCSpellCheckListener implements SpellCheckListener { 17 | protected SpellChecker spellCheck = null; 18 | 19 | public TCSpellCheckListener() { 20 | try { 21 | InputStream in = TCSpellCheckListener.class.getResourceAsStream("/english.0"); 22 | if (in != null) { 23 | SpellDictionary dictionary = new SpellDictionaryHashMap(new InputStreamReader(in)); 24 | this.spellCheck = new SpellChecker(dictionary); 25 | this.spellCheck.addSpellCheckListener(this); 26 | } 27 | } 28 | catch (IOException e) { 29 | TabbyChat.printException("", e); 30 | } 31 | 32 | } 33 | 34 | public TCSpellCheckListener(File dict) { 35 | try { 36 | SpellDictionary dictionary = new SpellDictionaryHashMap(dict); 37 | this.spellCheck = new SpellChecker(dictionary); 38 | this.spellCheck.addSpellCheckListener(this); 39 | } 40 | catch (Exception e) { 41 | TabbyChat.printException("Error instantiating spell checker", e); 42 | } 43 | } 44 | 45 | @Override 46 | public void spellingError(SpellCheckEvent event) { 47 | TabbyChat.spellChecker.handleListenerEvent(event); 48 | } 49 | 50 | public void checkSpelling(String line) { 51 | this.spellCheck.checkSpelling(new StringWordTokenizer(line)); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/proxy/ClientProxy.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.proxy; 2 | 3 | import acs.tabbychat.core.GuiNewChatTC; 4 | import acs.tabbychat.core.TabbyChat; 5 | import acs.tabbychat.util.TabbyChatUtils; 6 | import cpw.mods.fml.common.FMLCommonHandler; 7 | import cpw.mods.fml.common.event.FMLInitializationEvent; 8 | import cpw.mods.fml.common.eventhandler.SubscribeEvent; 9 | import cpw.mods.fml.common.gameevent.TickEvent; 10 | import cpw.mods.fml.common.network.FMLNetworkEvent; 11 | import net.minecraft.client.Minecraft; 12 | 13 | public class ClientProxy extends CommonProxy { 14 | @Override 15 | public void load(FMLInitializationEvent event) { 16 | TabbyChatUtils.startup(); 17 | FMLCommonHandler.instance().bus().register(this); 18 | TabbyChat.modLoaded = true; 19 | } 20 | 21 | @SubscribeEvent 22 | public void postLoad(FMLNetworkEvent.ClientConnectedToServerEvent event) { 23 | //ensure the chat gets loaded quickly 24 | GuiNewChatTC.getInstance(); 25 | } 26 | 27 | @SubscribeEvent 28 | public void onTick(TickEvent.RenderTickEvent event) { 29 | if (!event.phase.equals(TickEvent.Phase.START) && Minecraft.getMinecraft().theWorld != null) { 30 | onTickInGui(Minecraft.getMinecraft()); 31 | } 32 | } 33 | 34 | private boolean onTickInGui(Minecraft minecraft) { 35 | TabbyChatUtils.chatGuiTick(minecraft); 36 | return true; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/proxy/CommonProxy.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.proxy; 2 | 3 | import cpw.mods.fml.common.event.FMLInitializationEvent; 4 | 5 | public abstract class CommonProxy { 6 | public abstract void load(FMLInitializationEvent event); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/proxy/ServerProxy.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.proxy; 2 | 3 | import cpw.mods.fml.common.event.FMLInitializationEvent; 4 | import org.apache.logging.log4j.LogManager; 5 | import org.apache.logging.log4j.Logger; 6 | 7 | public class ServerProxy extends CommonProxy { 8 | @Override 9 | public void load(FMLInitializationEvent event) { 10 | Logger logger = LogManager.getLogger("tabbychat"); 11 | logger.warn("tabbychat found on server side, tabbychat won't crash the server but it'll do nothing but waste resources"); 12 | } 13 | } -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/settings/ChannelDelimEnum.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.settings; 2 | 3 | import net.minecraft.client.resources.I18n; 4 | 5 | public enum ChannelDelimEnum { 6 | ANGLES(I18n.format("delims.angles"), "<", ">"), 7 | BRACES(I18n.format("delims.braces"), "{", "}"), 8 | BRACKETS(I18n.format("delims.brackets"), "[", "]"), 9 | PARENTHESIS(I18n.format("delims.parenthesis"), "(", ")"), 10 | ANGLESPARENSCOMBO(I18n.format("delims.anglesparenscombo"), "<\\(", 11 | ")(?: |\u00A7r)?[A-Za-z0-9_]{1,16}>"), 12 | ANGLESBRACKETSCOMBO(I18n.format("delims.anglesbracketscombo"), "<\\[", 13 | "](?: |\u00A7r)?[A-Za-z0-9_]{1,16}>"); 14 | 15 | private String title; 16 | private String open; 17 | private String close; 18 | 19 | ChannelDelimEnum(String title, String open, String close) { 20 | this.title = title; 21 | this.open = open; 22 | this.close = close; 23 | } 24 | 25 | public String getTitle() { 26 | return this.title; 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return this.title; 32 | } 33 | 34 | public void setValue(String _title) { 35 | for (ChannelDelimEnum tmp : ChannelDelimEnum.values()) { 36 | if (_title.equals(tmp.title)) { 37 | this.title = tmp.title; 38 | this.open = tmp.open; 39 | this.close = tmp.close; 40 | break; 41 | } 42 | } 43 | } 44 | 45 | public String open() { 46 | return this.open; 47 | } 48 | 49 | public String close() { 50 | return this.close; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/settings/ColorCodeEnum.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.settings; 2 | 3 | import net.minecraft.client.resources.I18n; 4 | import net.minecraft.util.EnumChatFormatting; 5 | 6 | public enum ColorCodeEnum { 7 | DEFAULT(I18n.format("colors.default"), "", null), 8 | BLACK(I18n.format("colors.black"), "\u00A70", EnumChatFormatting.BLACK), 9 | DARKBLUE(I18n.format("colors.darkblue"), "\u00A71", EnumChatFormatting.DARK_BLUE), 10 | DARKGREEN(I18n.format("colors.darkgreen"), "\u00A72", EnumChatFormatting.DARK_GREEN), 11 | DARKAQUA(I18n.format("colors.darkaqua"), "\u00A73", EnumChatFormatting.DARK_AQUA), 12 | DARKRED(I18n.format("colors.darkred"), "\u00A74", EnumChatFormatting.DARK_RED), 13 | PURPLE(I18n.format("colors.purple"), "\u00A75", EnumChatFormatting.DARK_PURPLE), 14 | GOLD(I18n.format("colors.gold"), "\u00A76", EnumChatFormatting.GOLD), 15 | GRAY(I18n.format("colors.gray"), "\u00A77", EnumChatFormatting.GRAY), 16 | DARKGRAY(I18n.format("colors.darkgray"), "\u00A78", EnumChatFormatting.DARK_GRAY), 17 | INDIGO(I18n.format("colors.indigo"), "\u00A79", EnumChatFormatting.BLUE), 18 | BRIGHTGREEN(I18n.format("colors.brightgreen"), "\u00A7a", EnumChatFormatting.GREEN), 19 | AQUA(I18n.format("colors.aqua"), "\u00A7b", EnumChatFormatting.AQUA), 20 | RED(I18n.format("colors.red"), "\u00A7c", EnumChatFormatting.RED), 21 | PINK(I18n.format("colors.pink"), "\u00A7d", EnumChatFormatting.LIGHT_PURPLE), 22 | YELLOW(I18n.format("colors.yellow"), "\u00A7e", EnumChatFormatting.YELLOW), 23 | WHITE(I18n.format("colors.white"), "\u00A7f", EnumChatFormatting.WHITE); 24 | 25 | private final String title; 26 | private final String code; 27 | private final EnumChatFormatting vanilla; 28 | 29 | ColorCodeEnum(String _name, String _code, EnumChatFormatting _vanilla) { 30 | this.title = _name; 31 | this.code = _code; 32 | this.vanilla = _vanilla; 33 | } 34 | 35 | public static ColorCodeEnum cleanValueOf(String name) { 36 | try { 37 | return ColorCodeEnum.valueOf(name); 38 | } 39 | catch (Exception e) { 40 | return ColorCodeEnum.YELLOW; 41 | } 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return this.code + this.title + "\u00A7r"; 47 | } 48 | 49 | public String toCode() { 50 | return this.code; 51 | } 52 | 53 | public String color() { 54 | return this.title; 55 | } 56 | 57 | public EnumChatFormatting toVanilla() { 58 | return this.vanilla; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/settings/FormatCodeEnum.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.settings; 2 | 3 | import net.minecraft.client.resources.I18n; 4 | 5 | public enum FormatCodeEnum { 6 | DEFAULT(I18n.format("formats.default"), ""), 7 | BOLD(I18n.format("formats.bold"), "\u00A7l"), 8 | STRIKED(I18n.format("formats.striked"), "\u00A7m"), 9 | UNDERLINE(I18n.format("formats.underline"), "\u00A7n"), 10 | ITALIC(I18n.format("formats.italic"), "\u00A7o"), 11 | MAGIC(I18n.format("formats.magic"), "\u00A7k"); 12 | 13 | private final String title; 14 | private final String code; 15 | 16 | FormatCodeEnum(String _name, String _code) { 17 | this.title = _name; 18 | this.code = _code; 19 | } 20 | 21 | public static FormatCodeEnum cleanValueOf(String name) { 22 | try { 23 | return FormatCodeEnum.valueOf(name); 24 | } 25 | catch (Exception e) { 26 | return FormatCodeEnum.DEFAULT; 27 | } 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return this.code + this.title + "\u00A7r"; 33 | } 34 | 35 | public String toCode() { 36 | return this.code; 37 | } 38 | 39 | public String color() { 40 | return this.title; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/settings/ITCSetting.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.settings; 2 | 3 | import net.minecraft.client.Minecraft; 4 | 5 | import java.util.Properties; 6 | 7 | public interface ITCSetting { 8 | 9 | void actionPerformed(); 10 | 11 | void clear(); 12 | 13 | void disable(); 14 | 15 | void drawButton(Minecraft mc, int cursorX, int cursorY); 16 | 17 | void enable(); 18 | 19 | boolean enabled(); 20 | 21 | T getDefault(); 22 | 23 | String getProperty(); 24 | 25 | T getTempValue(); 26 | 27 | T getValue(); 28 | 29 | void setTempValue(T updateVal); 30 | 31 | TCSettingType getType(); 32 | 33 | Boolean hovered(int cursorX, int cursorY); 34 | 35 | void loadSelfFromProps(Properties readProps); 36 | 37 | void mouseClicked(int par1, int par2, int par3); 38 | 39 | void reset(); 40 | 41 | void resetDescription(); 42 | 43 | void save(); 44 | 45 | void saveSelfToProps(Properties writeProps); 46 | 47 | void setButtonDims(int wide, int tall); 48 | 49 | void setButtonLoc(int bx, int by); 50 | 51 | void setLabelLoc(int lx); 52 | 53 | void setCleanValue(T uncleanVal); 54 | 55 | void setValue(T updateVal); 56 | 57 | enum TCSettingType { 58 | BOOL, 59 | ENUM, 60 | SLIDER, 61 | TEXTBOX, 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/settings/NotificationSoundEnum.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.settings; 2 | 3 | import net.minecraft.client.resources.I18n; 4 | 5 | public enum NotificationSoundEnum { 6 | ORB(I18n.format("sounds.orb"), "random.orb"), 7 | ANVIL(I18n.format("sounds.anvil"), "random.anvil_land"), 8 | BOWHIT(I18n.format("sounds.bowhit"), "random.bowhit"), 9 | BREAK(I18n.format("sounds.break"), "random.break"), 10 | CLICK(I18n.format("sounds.click"), "random.click"), 11 | GLASS(I18n.format("sounds.glass"), "random.glass"), 12 | BASS(I18n.format("sounds.bass"), "note.bassattack"), 13 | HARP(I18n.format("sounds.harp"), "note.harp"), 14 | PLING(I18n.format("sounds.pling"), "note.pling"), 15 | CAT(I18n.format("sounds.cat"), "mob.cat.meow"), 16 | BLAST(I18n.format("sounds.blast"), "fireworks.blast"), 17 | SPLASH(I18n.format("sounds.splash"), "liquid.splash"), 18 | SWIM(I18n.format("sounds.swim"), "liquid.swim"), 19 | BAT(I18n.format("sounds.bat"), "mob.bat.hurt"), 20 | BLAZE(I18n.format("sounds.blaze"), "mob.blaze.hit"), 21 | CHICKEN(I18n.format("sounds.chicken"), "mob.chicken.hurt"), 22 | COW(I18n.format("sounds.cow"), "mob.cow.hurt"), 23 | DRAGON(I18n.format("sounds.dragon"), "mob.enderdragon.hit"), 24 | ENDERMEN(I18n.format("sounds.endermen"), "mob.endermen.hit"), 25 | GHAST(I18n.format("sounds.ghast"), "mob.ghast.moan"), 26 | PIG(I18n.format("sounds.pig"), "mob.pig.say"), 27 | WOLF(I18n.format("sounds.wolf"), "mob.wolf.bark"); 28 | 29 | private final String title; 30 | private final String file; 31 | 32 | NotificationSoundEnum(String _title, String _file) { 33 | this.title = _title; 34 | this.file = _file; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return this.title; 40 | } 41 | 42 | public String file() { 43 | return this.file; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/settings/TCChatFilter.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.settings; 2 | 3 | import acs.tabbychat.core.TabbyChat; 4 | import acs.tabbychat.util.TabbyChatUtils; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.util.EnumChatFormatting; 7 | import net.minecraft.util.IChatComponent; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | import java.util.Properties; 12 | import java.util.regex.Matcher; 13 | import java.util.regex.Pattern; 14 | import java.util.regex.PatternSyntaxException; 15 | 16 | public class TCChatFilter { 17 | public boolean inverseMatch = false; 18 | public boolean caseSensitive = false; 19 | public boolean highlightBool = true; 20 | public boolean audioNotificationBool = false; 21 | public boolean sendToTabBool = false; 22 | public boolean sendToAllTabs = false; 23 | public boolean removeMatches = false; 24 | public boolean globalFilter = true; 25 | 26 | public ColorCodeEnum highlightColor = ColorCodeEnum.YELLOW; 27 | public FormatCodeEnum highlightFormat = FormatCodeEnum.BOLD; 28 | public NotificationSoundEnum audioNotificationSound = NotificationSoundEnum.ORB; 29 | { 30 | this.highlightBool = false; 31 | } 32 | 33 | public String sendToTabName = ""; 34 | public String expressionString = ".*"; 35 | public Pattern expressionPattern = Pattern.compile(this.expressionString); 36 | // private static final Pattern allFormatCodes = 37 | // Pattern.compile("(?i)(\\u00A7[0-9A-FK-OR])+"); 38 | public String filterName; 39 | private int[] lastMatch; 40 | private String tabName = null; 41 | 42 | public TCChatFilter(String name) { 43 | this.filterName = name; 44 | } 45 | 46 | public TCChatFilter(TCChatFilter orig) { 47 | this(orig.filterName); 48 | this.copyFrom(orig); 49 | } 50 | 51 | public boolean applyFilterToDirtyChat(IChatComponent input) { 52 | 53 | // Apply filter 54 | Matcher findFilterMatches = this.expressionPattern.matcher(EnumChatFormatting 55 | .getTextWithoutFormattingCodes(input.getUnformattedText())); 56 | boolean foundMatch = false; 57 | List list = new ArrayList<>(); 58 | while (findFilterMatches.find()) { 59 | 60 | foundMatch = true; 61 | // If highlighting, store desired locations for format codes 62 | if (this.highlightBool) { 63 | list.add(findFilterMatches.start()); 64 | list.add(findFilterMatches.end()); 65 | } 66 | else 67 | break; 68 | } 69 | this.lastMatch = list.stream().mapToInt(value -> value).toArray(); 70 | 71 | // Pull name of destination tab 72 | if (this.sendToTabBool && !this.sendToAllTabs) { 73 | if (this.inverseMatch) 74 | this.tabName = this.sendToTabName; 75 | else if (this.sendToTabName.startsWith("%")) { 76 | int group = TabbyChatUtils.parseInteger(this.sendToTabName.substring(1)); 77 | if (foundMatch && group >= 0 && findFilterMatches.groupCount() >= group) { 78 | this.tabName = findFilterMatches.group(group); 79 | if (this.tabName == null) 80 | this.tabName = this.filterName; 81 | } 82 | else { 83 | this.tabName = this.filterName; 84 | } 85 | } 86 | else { 87 | this.tabName = this.sendToTabName; 88 | } 89 | } 90 | else { 91 | this.tabName = null; 92 | } 93 | 94 | // Return result status of filter application 95 | return (!foundMatch && inverseMatch) || (foundMatch && !inverseMatch); 96 | 97 | } 98 | 99 | public void audioNotification() { 100 | Minecraft.getMinecraft().thePlayer 101 | .playSound(this.audioNotificationSound.file(), 1.0F, 1.0F); 102 | } 103 | 104 | public void compilePattern() { 105 | try { 106 | if (this.caseSensitive) 107 | this.expressionPattern = Pattern.compile(this.expressionString); 108 | else 109 | this.expressionPattern = Pattern.compile(this.expressionString, 110 | Pattern.CASE_INSENSITIVE); 111 | } 112 | catch (PatternSyntaxException e) { 113 | TabbyChat.printMessageToChat("Invalid expression entered for filter '" 114 | + this.filterName + "', resetting to default."); 115 | this.expressionString = ".*"; 116 | this.expressionPattern = Pattern.compile(this.expressionString); 117 | } 118 | } 119 | 120 | public void compilePattern(String newExpression) { 121 | this.expressionString = newExpression; 122 | this.compilePattern(); 123 | } 124 | 125 | public void copyFrom(TCChatFilter orig) { 126 | this.filterName = orig.filterName; 127 | this.inverseMatch = orig.inverseMatch; 128 | this.caseSensitive = orig.caseSensitive; 129 | this.highlightBool = orig.highlightBool; 130 | this.audioNotificationBool = orig.audioNotificationBool; 131 | this.sendToTabBool = orig.sendToTabBool; 132 | this.sendToAllTabs = orig.sendToAllTabs; 133 | this.removeMatches = orig.removeMatches; 134 | this.highlightColor = orig.highlightColor; 135 | this.highlightFormat = orig.highlightFormat; 136 | this.audioNotificationSound = orig.audioNotificationSound; 137 | this.sendToTabName = orig.sendToTabName; 138 | this.expressionString = orig.expressionString; 139 | this.globalFilter = orig.globalFilter; 140 | 141 | this.compilePattern(); 142 | } 143 | 144 | /** 145 | * Returns an array containing indexes of the starts and ends of the current 146 | * filter. 147 | * Will always be even and be in order.
148 | * {start1, end1, start2, end2...} 149 | */ 150 | public int[] getLastMatch() { 151 | int[] tmp = this.lastMatch; 152 | this.lastMatch = null; 153 | return tmp; 154 | } 155 | 156 | public Properties getProperties() { 157 | Properties myProps = new Properties(); 158 | myProps.put("filterName", this.filterName); 159 | myProps.put("inverseMatch", this.inverseMatch); 160 | myProps.put("caseSensitive", this.caseSensitive); 161 | myProps.put("highlightBool", this.highlightBool); 162 | myProps.put("audioNotificationBool", this.audioNotificationBool); 163 | myProps.put("sendToTabBool", this.sendToTabBool); 164 | myProps.put("sendToAllTabs", this.sendToAllTabs); 165 | myProps.put("removeMatches", this.removeMatches); 166 | myProps.put("highlightColor", this.highlightColor.name()); 167 | myProps.put("highlightFormat", this.highlightFormat.name()); 168 | myProps.put("audioNotificationSound", this.audioNotificationSound.name()); 169 | myProps.put("sendToTabName", this.sendToTabName); 170 | myProps.put("expressionString", this.expressionString); 171 | myProps.put("globalFilter", this.globalFilter); 172 | return myProps; 173 | } 174 | 175 | public String getTabName() { 176 | String tmp = this.tabName; 177 | this.tabName = null; 178 | return tmp; 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/settings/TCSetting.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.settings; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.gui.GuiButton; 5 | import net.minecraft.client.resources.I18n; 6 | 7 | import java.util.Properties; 8 | 9 | abstract class TCSetting extends GuiButton implements ITCSetting { 10 | protected static Minecraft mc = Minecraft.getMinecraft(); 11 | public final String categoryName; 12 | public final String propertyName; 13 | public int buttonColor = 0xbba5e7e4; 14 | public String description; 15 | protected int labelX; 16 | protected T value; 17 | protected T tempValue; 18 | protected T theDefault; 19 | 20 | public TCSetting(T theSetting, String theProperty, String theCategory, int theID) { 21 | super(theID, 0, 0, ""); 22 | this.labelX = 0; 23 | this.value = theSetting; 24 | this.tempValue = theSetting; 25 | this.theDefault = theSetting; 26 | this.propertyName = theProperty; 27 | this.categoryName = theCategory; 28 | this.description = I18n.format(theCategory + "." + theProperty.toLowerCase()); 29 | } 30 | 31 | public TCSetting(T theSetting, String theProperty, String theCategory, int theID, 32 | FormatCodeEnum theFormat) { 33 | this(theSetting, theProperty, theCategory, theID); 34 | this.description = theFormat.toCode() + this.description + "\u00A7r"; 35 | } 36 | 37 | @Override 38 | public void actionPerformed() { 39 | } 40 | 41 | public int width() { 42 | return this.width; 43 | } 44 | 45 | public void width(int _w) { 46 | this.width = _w; 47 | } 48 | 49 | public int height() { 50 | return this.height; 51 | } 52 | 53 | public void height(int _h) { 54 | this.height = _h; 55 | } 56 | 57 | public int x() { 58 | return xPosition; 59 | } 60 | 61 | public void x(int _x) { 62 | xPosition = _x; 63 | } 64 | 65 | public int y() { 66 | return yPosition; 67 | } 68 | 69 | public void y(int _y) { 70 | yPosition = _y; 71 | } 72 | 73 | @Override 74 | public void clear() { 75 | this.value = this.theDefault; 76 | this.tempValue = this.theDefault; 77 | } 78 | 79 | @Override 80 | public void disable() { 81 | this.enabled = false; 82 | } 83 | 84 | @Override 85 | public void drawButton(Minecraft mc, int cursorX, int cursorY) { 86 | } 87 | 88 | @Override 89 | public void enable() { 90 | this.enabled = true; 91 | } 92 | 93 | @Override 94 | public boolean enabled() { 95 | return this.enabled; 96 | } 97 | 98 | @Override 99 | public T getDefault() { 100 | return this.theDefault; 101 | } 102 | 103 | @Override 104 | public String getProperty() { 105 | return this.propertyName; 106 | } 107 | 108 | @Override 109 | public T getTempValue() { 110 | return this.tempValue; 111 | } 112 | 113 | @Override 114 | public void setTempValue(T updateVal) { 115 | this.tempValue = updateVal; 116 | } 117 | 118 | @Override 119 | public abstract TCSettingType getType(); 120 | 121 | @Override 122 | public T getValue() { 123 | return this.value; 124 | } 125 | 126 | @Override 127 | public void setValue(T updateVal) { 128 | this.value = updateVal; 129 | this.tempValue = updateVal; 130 | } 131 | 132 | @Override 133 | public Boolean hovered(int cursorX, int cursorY) { 134 | return cursorX >= this.x() && cursorY >= this.y() && cursorX < this.x() + this.width() 135 | && cursorY < this.y() + this.height(); 136 | } 137 | 138 | @Override 139 | @SuppressWarnings("unchecked") 140 | public void loadSelfFromProps(Properties readProps) { 141 | this.setCleanValue((T) readProps.get(this.propertyName)); 142 | } 143 | 144 | @Override 145 | public void mouseClicked(int par1, int par2, int par3) { 146 | } 147 | 148 | @Override 149 | public void reset() { 150 | this.tempValue = this.value; 151 | } 152 | 153 | @Override 154 | public void resetDescription() { 155 | this.description = this.categoryName.isEmpty() ? "" : I18n.format(this.categoryName + "." 156 | + this.propertyName.toLowerCase()); 157 | } 158 | 159 | @Override 160 | public void save() { 161 | this.value = this.tempValue; 162 | } 163 | 164 | @Override 165 | public void saveSelfToProps(Properties writeProps) { 166 | writeProps.put(this.propertyName, this.value.toString()); 167 | } 168 | 169 | @Override 170 | public void setButtonDims(int wide, int tall) { 171 | this.width(wide); 172 | this.height(tall); 173 | } 174 | 175 | @Override 176 | public void setButtonLoc(int bx, int by) { 177 | this.x(bx); 178 | this.y(by); 179 | } 180 | 181 | @Override 182 | public void setLabelLoc(int _x) { 183 | this.labelX = _x; 184 | } 185 | 186 | @Override 187 | public void setCleanValue(T updateVal) { 188 | if (updateVal == null) 189 | this.clear(); 190 | else 191 | this.value = updateVal; 192 | } 193 | 194 | } 195 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/settings/TCSettingBool.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.settings; 2 | 3 | import net.minecraft.client.Minecraft; 4 | 5 | import java.util.Properties; 6 | 7 | public class TCSettingBool extends TCSetting { 8 | 9 | public TCSettingBool(Boolean theSetting, String theProperty, String theCategory, int theID) { 10 | super(theSetting, theProperty, theCategory, theID); 11 | setCommon(); 12 | } 13 | 14 | public TCSettingBool(Boolean theSetting, String theProperty, String theCategory, int theID, 15 | FormatCodeEnum theFormat) { 16 | super(theSetting, theProperty, theCategory, theID, theFormat); 17 | setCommon(); 18 | } 19 | 20 | public void setCommon() { 21 | this.width(9); 22 | this.height(9); 23 | } 24 | 25 | @Override 26 | public void actionPerformed() { 27 | this.toggle(); 28 | } 29 | 30 | @Override 31 | public void drawButton(Minecraft par1, int cursorX, int cursorY) { 32 | int centerX = this.x() + this.width() / 2; 33 | int centerY = this.y() + this.height() / 2; 34 | int tmpWidth = 9; 35 | int tmpHeight = 9; 36 | int tmpX = centerX - 4; 37 | int tmpY = centerY - 4; 38 | int fgcolor = 0x99a0a0a0; 39 | if (!this.enabled) { 40 | fgcolor = -0x995f5f60; 41 | } 42 | else if (this.hovered(cursorX, cursorY)) { 43 | fgcolor = 0x99ffffa0; 44 | } 45 | 46 | int labelColor = (this.enabled) ? 0xffffff : 0x666666; 47 | 48 | drawRect(tmpX + 1, tmpY, tmpX + tmpWidth - 1, tmpY + 1, fgcolor); 49 | drawRect(tmpX + 1, tmpY + tmpHeight - 1, tmpX + tmpWidth - 1, tmpY + tmpHeight, fgcolor); 50 | drawRect(tmpX, tmpY + 1, tmpX + 1, tmpY + tmpHeight - 1, fgcolor); 51 | drawRect(tmpX + tmpWidth - 1, tmpY + 1, tmpX + tmpWidth, tmpY + tmpHeight - 1, fgcolor); 52 | drawRect(tmpX + 1, tmpY + 1, tmpX + tmpWidth - 1, tmpY + tmpHeight - 1, 0xff000000); 53 | if (this.tempValue) { 54 | drawRect(centerX - 2, centerY, centerX - 1, centerY + 1, this.buttonColor); 55 | drawRect(centerX - 1, centerY + 1, centerX, centerY + 2, this.buttonColor); 56 | drawRect(centerX, centerY + 2, centerX + 1, centerY + 3, this.buttonColor); 57 | drawRect(centerX + 1, centerY + 2, centerX + 2, centerY, this.buttonColor); 58 | drawRect(centerX + 2, centerY, centerX + 3, centerY - 2, this.buttonColor); 59 | drawRect(centerX + 3, centerY - 2, centerX + 4, centerY - 4, this.buttonColor); 60 | } 61 | 62 | this.drawCenteredString(mc.fontRenderer, this.description, 63 | this.labelX + mc.fontRenderer.getStringWidth(this.description) / 2, this.y() 64 | + (this.height() - 6) / 2, labelColor); 65 | } 66 | 67 | @Override 68 | public TCSettingType getType() { 69 | return TCSettingType.BOOL; 70 | } 71 | 72 | public void toggle() { 73 | this.tempValue = !(Boolean) this.tempValue; 74 | } 75 | 76 | @Override 77 | public void loadSelfFromProps(Properties readProps) { 78 | Object result = readProps.get(this.propertyName); 79 | if (result != null) { 80 | this.setCleanValue(Boolean.parseBoolean(result.toString())); 81 | } 82 | else { 83 | this.setCleanValue(false); 84 | } 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/settings/TCSettingEnum.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.settings; 2 | 3 | import acs.tabbychat.util.TabbyChatUtils; 4 | import net.minecraft.client.Minecraft; 5 | 6 | import java.util.Properties; 7 | 8 | public class TCSettingEnum extends TCSetting> { 9 | public TCSettingEnum(Enum theSetting, String theProperty, String theCategory, int theID) { 10 | super(theSetting, theProperty, theCategory, theID); 11 | this.width(30); 12 | this.height(11); 13 | } 14 | 15 | public TCSettingEnum(Enum theSetting, String theProperty, String theCategory, int theID, 16 | FormatCodeEnum theFormat) { 17 | super(theSetting, theProperty, theCategory, theID, theFormat); 18 | } 19 | 20 | @Override 21 | public void drawButton(Minecraft par1, int cursorX, int cursorY) { 22 | int centerX = this.x() + this.width() / 2; 23 | int fgcolor = 0x99a0a0a0; 24 | if (!this.enabled) { 25 | fgcolor = -0x995f5f60; 26 | } 27 | else if (this.hovered(cursorX, cursorY)) { 28 | fgcolor = 0x99ffffa0; 29 | } 30 | 31 | int labelColor = (this.enabled) ? 0xffffff : 0x666666; 32 | 33 | drawRect(this.x() + 1, this.y(), this.x() + this.width() - 1, this.y() + 1, fgcolor); 34 | drawRect(this.x() + 1, this.y() + this.height() - 1, this.x() + this.width() - 1, this.y() 35 | + this.height(), fgcolor); 36 | drawRect(this.x(), this.y() + 1, this.x() + 1, this.y() + this.height() - 1, fgcolor); 37 | drawRect(this.x() + this.width() - 1, this.y() + 1, this.x() + this.width(), this.y() 38 | + this.height() - 1, fgcolor); 39 | drawRect(this.x() + 1, this.y() + 1, this.x() + this.width() - 1, this.y() + this.height() 40 | - 1, 0xff000000); 41 | 42 | this.drawCenteredString(mc.fontRenderer, this.tempValue.toString(), centerX, this.y() + 2, 43 | labelColor); 44 | 45 | this.drawCenteredString(mc.fontRenderer, this.description, 46 | this.labelX + mc.fontRenderer.getStringWidth(this.description) / 2, this.y() 47 | + (this.height() - 6) / 2, labelColor); 48 | } 49 | 50 | @Override 51 | public TCSettingType getType() { 52 | return TCSettingType.ENUM; 53 | } 54 | 55 | @Override 56 | public void loadSelfFromProps(Properties readProps) { 57 | String found = (String) readProps.get(this.propertyName); 58 | if (found == null) { 59 | this.clear(); 60 | return; 61 | } 62 | if (this.propertyName.contains("Color")) { 63 | this.value = TabbyChatUtils.parseColor(found); 64 | } 65 | else if (this.propertyName.contains("Format")) { 66 | this.value = TabbyChatUtils.parseFormat(found); 67 | } 68 | else if (this.propertyName.contains("Sound")) { 69 | this.value = TabbyChatUtils.parseSound(found); 70 | } 71 | else if (this.propertyName.contains("delim")) { 72 | this.value = TabbyChatUtils.parseDelimiters(found); 73 | } 74 | else if (this.propertyName.contains("Stamp")) { 75 | this.value = TabbyChatUtils.parseTimestamp(found); 76 | } 77 | } 78 | 79 | @Override 80 | public void mouseClicked(int par1, int par2, int par3) { 81 | if (this.hovered(par1, par2) && this.enabled) { 82 | if (par3 == 1) 83 | this.previous(); 84 | else if (par3 == 0) 85 | this.next(); 86 | } 87 | } 88 | 89 | @SuppressWarnings("unchecked") 90 | public void next() { 91 | Enum eCast = this.tempValue; 92 | Enum[] E = eCast.getClass().getEnumConstants(); 93 | Enum tmp; 94 | if (eCast.ordinal() == E.length - 1) 95 | tmp = Enum.valueOf(eCast.getClass(), E[0].name()); 96 | else { 97 | tmp = Enum.valueOf(eCast.getClass(), E[eCast.ordinal() + 1].name()); 98 | } 99 | this.tempValue = tmp; 100 | } 101 | 102 | @SuppressWarnings("unchecked") 103 | public void previous() { 104 | Enum eCast = this.tempValue; 105 | Enum[] E = eCast.getClass().getEnumConstants(); 106 | if (eCast.ordinal() == 0) 107 | this.tempValue = Enum.valueOf(eCast.getClass(), E[E.length - 1].name()); 108 | else { 109 | this.tempValue = Enum.valueOf(eCast.getClass(), E[eCast.ordinal() - 1].name()); 110 | } 111 | } 112 | 113 | public void setTempValueFromProps(Properties readProps) { 114 | String found = (String) readProps.get(this.propertyName); 115 | if (found == null) { 116 | this.tempValue = this.theDefault; 117 | return; 118 | } 119 | if (this.propertyName.contains("Color")) { 120 | this.tempValue = TabbyChatUtils.parseColor(found); 121 | } 122 | else if (this.propertyName.contains("Format")) { 123 | this.tempValue = TabbyChatUtils.parseFormat(found); 124 | } 125 | else if (this.propertyName.contains("Sound")) { 126 | this.tempValue = TabbyChatUtils.parseSound(found); 127 | } 128 | else if (this.propertyName.contains("delim")) { 129 | this.tempValue = TabbyChatUtils.parseDelimiters(found); 130 | } 131 | else if (this.propertyName.contains("Stamp")) { 132 | this.tempValue = TabbyChatUtils.parseTimestamp(found); 133 | } 134 | } 135 | 136 | @Override 137 | public void saveSelfToProps(Properties writeProps) { 138 | writeProps.put(this.propertyName, this.value.name()); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/settings/TCSettingList.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.settings; 2 | 3 | import acs.tabbychat.gui.PrefsButton; 4 | import acs.tabbychat.jazzy.TCSpellCheckManager; 5 | import com.google.common.collect.Lists; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.client.gui.Gui; 8 | import net.minecraft.util.MathHelper; 9 | import org.apache.commons.io.IOUtils; 10 | 11 | import java.io.File; 12 | import java.io.FileReader; 13 | import java.io.FileWriter; 14 | import java.io.IOException; 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | 18 | public class TCSettingList extends Gui { 19 | 20 | private final File dictionary; 21 | private final List list = new ArrayList<>(); 22 | private final List selected = new ArrayList<>(); 23 | private int currentPage = 1; 24 | private int id = 0; 25 | private int xPosition, yPosition; 26 | private int width, height; 27 | 28 | public TCSettingList(File file) { 29 | this.dictionary = file; 30 | } 31 | 32 | public void drawList(Minecraft mc, int cursorX, int cursorY) { 33 | Gui.drawRect(xPosition, yPosition, xPosition + width, yPosition + height, Integer.MIN_VALUE); 34 | 35 | Gui.drawRect(xPosition - 1, yPosition - 1, xPosition, yPosition + height, -0xffffff); 36 | Gui.drawRect(xPosition - 1, yPosition + height, xPosition + width + 1, yPosition + height 37 | + 1, -0xffffff); 38 | Gui.drawRect(xPosition + width, yPosition + height + 1, xPosition + width + 1, 39 | yPosition - 1, -0xffffff); 40 | Gui.drawRect(xPosition - 1, yPosition - 1, xPosition + width + 1, yPosition, -0xffffff); 41 | 42 | int i = 0; 43 | for (Entry entry : getVisible()) { 44 | entry.setPos(i); 45 | entry.drawButton(mc, cursorX, cursorY); 46 | i++; 47 | } 48 | } 49 | 50 | public boolean contains(String srt) { 51 | for (Entry entry : list) { 52 | if (srt.equals(entry.displayString)) 53 | return true; 54 | } 55 | return false; 56 | } 57 | 58 | public void addToList(String str) { 59 | if (str == null || str.isEmpty()) 60 | return; 61 | if (!contains(str)) { 62 | char[] chararray = str.toCharArray(); 63 | int j = 0; 64 | label_1: 65 | for (Entry entry : list) { 66 | char[] chararray1 = entry.displayString.toCharArray(); 67 | for (int i = 0; i < Math.min(chararray.length, chararray1.length); i++) { 68 | char c = chararray[i], c1 = chararray1[i]; 69 | if (c > c1) 70 | break; 71 | if (c == c1) 72 | continue; 73 | list.add(j, new Entry(id, str)); 74 | break label_1; 75 | } 76 | j++; 77 | } 78 | if (!contains(str)) 79 | list.add(new Entry(id, str)); 80 | id++; 81 | } 82 | } 83 | 84 | public void removeFromList(String str) { 85 | for (Entry entry : list) { 86 | if (str.equals(entry.displayString)) { 87 | list.remove(entry); 88 | this.deselectEntry(entry); 89 | } 90 | } 91 | } 92 | 93 | public void clearList() { 94 | list.clear(); 95 | } 96 | 97 | public List getEntries() { 98 | return new ArrayList<>(list); 99 | } 100 | 101 | public List getVisible() { 102 | List list = Lists.newArrayList(); 103 | int i = 0; 104 | int i1 = 0; 105 | while (i < currentPage) { 106 | list.clear(); 107 | for (int i2 = 0; i1 < this.list.size(); i2++) { 108 | if (list.size() >= 8) 109 | break; 110 | Entry entry = this.list.get(i1); 111 | entry.setPos(i2); 112 | list.add(entry); 113 | i1++; 114 | } 115 | i++; 116 | } 117 | return list; 118 | } 119 | 120 | public List getSelected() { 121 | return new ArrayList<>(this.selected); 122 | } 123 | 124 | public void selectEntry(Entry entry) { 125 | if (!list.contains(entry)) 126 | list.add(entry); 127 | if (!entry.isSelected()) 128 | this.selected.add(entry); 129 | } 130 | 131 | public void deselectEntry(Entry entry) { 132 | if (entry.isSelected()) 133 | selected.remove(entry); 134 | } 135 | 136 | public void clearSelection() { 137 | this.selected.clear(); 138 | } 139 | 140 | public int getTotalPages() { 141 | double pages = list.size() / 8D; 142 | return MathHelper.ceiling_double_int(pages); 143 | } 144 | 145 | public Object getPageNum() { 146 | return this.currentPage; 147 | } 148 | 149 | public void nextPage() { 150 | this.currentPage = Math.min(currentPage + 1, getTotalPages()); 151 | } 152 | 153 | public void previousPage() { 154 | this.currentPage = Math.max(currentPage - 1, 1); 155 | } 156 | 157 | public void saveEntries() throws IOException { 158 | FileWriter writer = new FileWriter(dictionary); 159 | for (Entry entry : list) { 160 | writer.write(entry.displayString); 161 | writer.write("\n"); 162 | } 163 | writer.close(); 164 | loadEntries(); 165 | } 166 | 167 | public void loadEntries() throws IOException { 168 | clearList(); 169 | for (String val : IOUtils.readLines(new FileReader(dictionary))) { 170 | TCSpellCheckManager.getInstance().addToIgnoredWords(val); 171 | addToList(val); 172 | } 173 | } 174 | 175 | public void mouseClicked(int x, int y, int button) { 176 | if (x > x() && x < x() + width() && y > y() && y < y() + height()) 177 | for (Entry entry : getVisible()) { 178 | if (y > entry.y() && y < entry.y() + entry.height()) { 179 | entry.func_146113_a(Minecraft.getMinecraft().getSoundHandler()); 180 | actionPerformed(entry); 181 | return; 182 | } 183 | } 184 | } 185 | 186 | private void actionPerformed(Entry entry) { 187 | entry.setSelected(!entry.isSelected()); 188 | } 189 | 190 | public int width() { 191 | return width; 192 | } 193 | 194 | public void width(int w) { 195 | this.width = w; 196 | } 197 | 198 | public int height() { 199 | return height; 200 | } 201 | 202 | public void height(int h) { 203 | this.height = h; 204 | } 205 | 206 | public int x() { 207 | return xPosition; 208 | } 209 | 210 | public void x(int x) { 211 | this.xPosition = x; 212 | } 213 | 214 | public int y() { 215 | return yPosition; 216 | } 217 | 218 | public void y(int y) { 219 | this.yPosition = y; 220 | } 221 | 222 | public class Entry extends PrefsButton { 223 | 224 | private final TCSettingList list = TCSettingList.this; 225 | private int pos; 226 | 227 | public Entry(int id, String value) { 228 | super(id, TCSettingList.this.x(), 0, TCSettingList.this.width(), 12, value); 229 | } 230 | 231 | public void setPos(int y) { 232 | this.pos = y; 233 | } 234 | 235 | public boolean isSelected() { 236 | return list.getSelected().contains(this); 237 | } 238 | 239 | public void setSelected(boolean value) { 240 | if (value) 241 | list.selectEntry(this); 242 | else 243 | list.deselectEntry(this); 244 | } 245 | 246 | @Override 247 | public void drawButton(Minecraft mc, int x, int y) { 248 | if (this.isSelected()) 249 | this.bgcolor = 0xDD999999; 250 | else 251 | this.bgcolor = 0xDD000000; 252 | this.y(list.y() + (pos * 12)); 253 | super.drawButton(mc, x, y); 254 | } 255 | 256 | public void remove() { 257 | list.list.remove(this); 258 | } 259 | 260 | public void keyClicked(int x, int y, int button) { 261 | 262 | } 263 | } 264 | } 265 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/settings/TCSettingSlider.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.settings; 2 | 3 | import acs.tabbychat.util.TabbyChatUtils; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.gui.Gui; 6 | import org.lwjgl.input.Keyboard; 7 | import org.lwjgl.input.Mouse; 8 | 9 | public class TCSettingSlider extends TCSetting { 10 | private final int buttonOffColor = 0x44ffffff; 11 | public String units = "%"; 12 | protected float minValue; 13 | protected float maxValue; 14 | protected float sliderValue; 15 | private int sliderX; 16 | private boolean dragging = false; 17 | 18 | public TCSettingSlider(float theSetting, String theProperty, String theCategory, int theID, 19 | float minVal, float maxVal) { 20 | super(theSetting, theProperty, theCategory, theID); 21 | this.width(100); 22 | this.height(11); 23 | this.minValue = minVal; 24 | this.maxValue = maxVal; 25 | } 26 | 27 | @Override 28 | public void clear() { 29 | super.clear(); 30 | calculateSliderValue(); 31 | } 32 | 33 | @Override 34 | public void setValue(Float updateVal) { 35 | this.value = updateVal; 36 | this.tempValue = updateVal; 37 | calculateSliderValue(); 38 | } 39 | 40 | public void calculateSliderValue() { 41 | this.sliderValue = (this.tempValue - this.minValue) 42 | / (this.maxValue - this.minValue); 43 | } 44 | 45 | @Override 46 | public void drawButton(Minecraft par1, int cursorX, int cursorY) { 47 | int fgcolor = 0x99a0a0a0; 48 | if (!this.enabled) { 49 | fgcolor = -0x995f5f60; 50 | } 51 | else if (this.hovered(cursorX, cursorY)) { 52 | fgcolor = 0x99ffffa0; 53 | if (this.dragging) { 54 | this.sliderX = cursorX - 1; 55 | this.sliderValue = (float) (this.sliderX - (this.x() + 1)) / (this.width() - 5); 56 | if (this.sliderValue < 0.0f) 57 | this.sliderValue = 0.0f; 58 | else if (this.sliderValue > 1.0f) 59 | this.sliderValue = 1.0f; 60 | } 61 | } 62 | int labelColor = (this.enabled) ? 0xffffff : 0x666666; 63 | int buttonColor = (this.enabled) ? this.buttonColor : this.buttonOffColor; 64 | 65 | Gui.drawRect(this.x(), this.y() + 1, this.x() + 1, this.y() + this.height() - 1, fgcolor); 66 | Gui.drawRect(this.x() + 1, this.y(), this.x() + this.width() - 1, this.y() + 1, fgcolor); 67 | Gui.drawRect(this.x() + 1, this.y() + this.height() - 1, this.x() + this.width() - 1, 68 | this.y() + this.height(), fgcolor); 69 | Gui.drawRect(this.x() + this.width() - 1, this.y() + 1, this.x() + this.width(), this.y() 70 | + this.height() - 1, fgcolor); 71 | Gui.drawRect(this.x() + 1, this.y() + 1, this.x() + this.width() - 1, 72 | this.y() + this.height() - 1, 0xff000000); 73 | 74 | this.sliderX = Math.round(this.sliderValue * (this.width() - 5)) + this.x() + 1; 75 | Gui.drawRect(this.sliderX, this.y() + 1, this.sliderX + 1, this.y() + 2, 76 | buttonColor & 0x88ffffff); 77 | Gui.drawRect(this.sliderX + 1, this.y() + 1, this.sliderX + 2, this.y() + 2, buttonColor); 78 | Gui.drawRect(this.sliderX + 2, this.y() + 1, this.sliderX + 3, this.y() + 2, 79 | buttonColor & 0x88ffffff); 80 | Gui.drawRect(this.sliderX, this.y() + 2, this.sliderX + 1, this.y() + this.height() - 2, 81 | buttonColor); 82 | Gui.drawRect(this.sliderX + 1, this.y() + 2, this.sliderX + 2, 83 | this.y() + this.height() - 2, buttonColor & 0x88ffffff); 84 | Gui.drawRect(this.sliderX + 2, this.y() + 2, this.sliderX + 3, 85 | this.y() + this.height() - 2, buttonColor); 86 | Gui.drawRect(this.sliderX, this.y() + this.height() - 2, this.sliderX + 1, 87 | this.y() + this.height() - 1, buttonColor & 0x88ffffff); 88 | Gui.drawRect(this.sliderX + 1, this.y() + this.height() - 2, this.sliderX + 2, this.y() 89 | + this.height() - 1, buttonColor); 90 | Gui.drawRect(this.sliderX + 2, this.y() + this.height() - 2, this.sliderX + 3, this.y() 91 | + this.height() - 1, buttonColor & 0x88ffffff); 92 | 93 | int valCenter; 94 | if (this.sliderValue < 0.5f) 95 | valCenter = Math.round(0.7f * this.width()); 96 | else 97 | valCenter = Math.round(0.2f * this.width()); 98 | 99 | String valLabel = Math.round(this.sliderValue 100 | * (this.maxValue - this.minValue) + this.minValue) 101 | + this.units; 102 | this.drawCenteredString(mc.fontRenderer, valLabel, valCenter + this.x(), this.y() + 2, 103 | buttonColor); 104 | 105 | this.drawCenteredString(mc.fontRenderer, this.description, 106 | this.labelX + mc.fontRenderer.getStringWidth(this.description) / 2, this.y() 107 | + (this.height() - 6) / 2, labelColor); 108 | } 109 | 110 | @Override 111 | public Float getTempValue() { 112 | this.tempValue = this.sliderValue * (this.maxValue - this.minValue) + this.minValue; 113 | return this.tempValue; 114 | } 115 | 116 | @Override 117 | public void setTempValue(Float theVal) { 118 | super.setTempValue(theVal); 119 | calculateSliderValue(); 120 | } 121 | 122 | @Override 123 | public TCSettingType getType() { 124 | return TCSettingType.SLIDER; 125 | } 126 | 127 | public void handleMouseInput() { 128 | if (mc.currentScreen == null) 129 | return; 130 | int mX = Mouse.getEventX() * mc.currentScreen.width / mc.displayWidth; 131 | int mY = mc.currentScreen.height - Mouse.getEventY() * mc.currentScreen.height 132 | / mc.displayHeight - 1; 133 | if (!this.hovered(mX, mY)) 134 | return; 135 | 136 | int var1 = Mouse.getEventDWheel(); 137 | if (var1 != 0) { 138 | if (var1 > 1) { 139 | var1 = 3; 140 | } 141 | 142 | if (var1 < -1) { 143 | var1 = -3; 144 | } 145 | 146 | if (Keyboard.isKeyDown(42) || Keyboard.isKeyDown(54)) { 147 | var1 *= -7; 148 | } 149 | } 150 | this.sliderValue += (float) var1 / 100; 151 | if (this.sliderValue < 0.0f) 152 | this.sliderValue = 0.0f; 153 | else if (this.sliderValue > 1.0f) 154 | this.sliderValue = 1.0f; 155 | this.tempValue = this.sliderValue * (this.maxValue - this.minValue) + this.minValue; 156 | } 157 | 158 | @Override 159 | public void mouseClicked(int par1, int par2, int par3) { 160 | if (par3 == 0 && this.hovered(par1, par2) && this.enabled) { 161 | this.sliderX = par1 - 1; 162 | this.sliderValue = (float) (this.sliderX - (this.x() + 1)) / (this.width() - 5); 163 | if (this.sliderValue < 0.0f) 164 | this.sliderValue = 0.0f; 165 | else if (this.sliderValue > 1.0f) 166 | this.sliderValue = 1.0f; 167 | 168 | if (!this.dragging) 169 | this.dragging = true; 170 | } 171 | } 172 | 173 | @Override 174 | public void mouseReleased(int par1, int par2) { 175 | this.dragging = false; 176 | } 177 | 178 | @Override 179 | public void reset() { 180 | super.reset(); 181 | calculateSliderValue(); 182 | } 183 | 184 | @Override 185 | public void save() { 186 | this.tempValue = this.sliderValue * (this.maxValue - this.minValue) + this.minValue; 187 | super.save(); 188 | } 189 | 190 | @Override 191 | public void setCleanValue(Float updateVal) { 192 | if (updateVal == null) 193 | this.clear(); 194 | else 195 | this.value = TabbyChatUtils.median(this.minValue, this.maxValue, 196 | updateVal); 197 | } 198 | 199 | public void setRange(float theMin, float theMax) { 200 | this.minValue = theMin; 201 | this.maxValue = theMax; 202 | calculateSliderValue(); 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/settings/TCSettingTextBox.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.settings; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.gui.GuiTextField; 5 | 6 | public class TCSettingTextBox extends TCSetting { 7 | protected GuiTextField textBox; 8 | protected int charLimit = 32; 9 | 10 | public TCSettingTextBox(String theSetting, String theProperty, String theCategory, int theID) { 11 | super(theSetting, theProperty, theCategory, theID); 12 | this.width(50); 13 | this.height(11); 14 | this.textBox = new GuiTextField(mc.fontRenderer, 0, 0, this.width(), this.height()); 15 | this.textBox.setText(this.value); 16 | } 17 | 18 | @Override 19 | public void clear() { 20 | super.clear(); 21 | this.textBox.setText(this.theDefault); 22 | } 23 | 24 | @Override 25 | public void disable() { 26 | super.disable(); 27 | this.textBox.setEnabled(false); 28 | } 29 | 30 | @Override 31 | public void drawButton(Minecraft par1, int cursorX, int cursorY) { 32 | int labelColor = (this.enabled) ? 0xffffff : 0x666666; 33 | 34 | this.textBox.drawTextBox(); 35 | this.drawCenteredString(mc.fontRenderer, this.description, 36 | this.labelX + mc.fontRenderer.getStringWidth(this.description) / 2, this.y() 37 | + (this.height() - 6) / 2, labelColor); 38 | } 39 | 40 | @Override 41 | public void enable() { 42 | super.enable(); 43 | this.textBox.setEnabled(true); 44 | } 45 | 46 | public void func_146184_c(boolean val) { 47 | this.enabled = val; 48 | this.textBox.setEnabled(val); 49 | } 50 | 51 | @Override 52 | public String getTempValue() { 53 | return this.textBox.getText().trim(); 54 | } 55 | 56 | @Override 57 | public void setTempValue(String theVal) { 58 | this.textBox.setText(theVal); 59 | } 60 | 61 | @Override 62 | public TCSettingType getType() { 63 | return TCSettingType.TEXTBOX; 64 | } 65 | 66 | public void keyTyped(char par1, int par2) { 67 | this.textBox.textboxKeyTyped(par1, par2); 68 | } 69 | 70 | @Override 71 | public void mouseClicked(int par1, int par2, int par3) { 72 | this.textBox.mouseClicked(par1, par2, par3); 73 | } 74 | 75 | private void reassignField() { 76 | String tmp = this.textBox.getText(); 77 | this.textBox = new GuiTextField(mc.fontRenderer, this.x(), this.y() + 1, this.width(), 78 | this.height() + 1); 79 | this.textBox.setMaxStringLength(this.charLimit); 80 | this.textBox.setText(tmp); 81 | } 82 | 83 | @Override 84 | public void reset() { 85 | if (this.value == null) 86 | this.value = ""; 87 | this.textBox.setText(this.value); 88 | } 89 | 90 | @Override 91 | public void save() { 92 | this.value = this.textBox.getText().trim(); 93 | } 94 | 95 | @Override 96 | public void setButtonDims(int wide, int tall) { 97 | super.setButtonDims(wide, tall); 98 | this.reassignField(); 99 | } 100 | 101 | @Override 102 | public void setButtonLoc(int bx, int by) { 103 | super.setButtonLoc(bx, by); 104 | this.reassignField(); 105 | } 106 | 107 | public void setCharLimit(int newLimit) { 108 | this.charLimit = newLimit; 109 | this.textBox.setMaxStringLength(newLimit); 110 | } 111 | 112 | public void setDefault(String newDefault) { 113 | this.theDefault = newDefault; 114 | } 115 | 116 | @Override 117 | public void setValue(String updateVal) { 118 | this.value = updateVal; 119 | this.tempValue = updateVal; 120 | this.textBox.setText(updateVal); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/settings/TimeStampEnum.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.settings; 2 | 3 | public enum TimeStampEnum { 4 | 5 | MILITARY("[HHmm]", "[2359]", "\\[[0-9]{4}\\]"), 6 | MILITARYWITHCOLON("[HH:mm]", "[23:59]", "\\[[0-9]{2}:[0-9]{2}\\]"), 7 | STANDARD("[hh:mm]", "[12:00]", "\\[[0-9]{2}:[0-9]{2}\\]"), 8 | STANDARDWITHMARKER("[hh:mma]", "[12:00PM]", "\\[[0-9]{2}:[0-9]{2}(AM|PM)\\]"), 9 | MILITARYSECONDS("[HH:mm:ss]", "[23:59:01]", "\\[[0-9]{2}:[0-9]{2}:[0-9]{2}\\]"), 10 | STANDARDSECONDS("[hh:mm:ss]", "[12:00:01]", "\\[[0-9]{2}:[0-9]{2}:[0-9]{2}\\]"), 11 | STANDARDSECONDSMARKER("[hh:mm:ssa]", "[12:00:01PM]", "\\[[0-9]{2}:[0-9]{2}:[0-9]{2}(AM|PM)\\]"); 12 | 13 | public final String maxTime; 14 | public final String regEx; 15 | private final String code; 16 | 17 | TimeStampEnum(String _code, String _maxTime, String _regex) { 18 | this.code = _code; 19 | this.maxTime = _maxTime; 20 | this.regEx = _regex; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return this.maxTime; 26 | } 27 | 28 | public String toCode() { 29 | return this.code; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/settings/files/TCSettingsAdvancedFile.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.settings.files; 2 | 3 | import acs.tabbychat.core.TabbyChat; 4 | import acs.tabbychat.gui.ChatBox; 5 | import acs.tabbychat.util.TabbyChatUtils; 6 | import org.apache.commons.lang3.tuple.Pair; 7 | 8 | import java.io.BufferedInputStream; 9 | import java.io.File; 10 | import java.io.FileInputStream; 11 | import java.util.Properties; 12 | 13 | /** 14 | * Data structure for advanced settings 15 | */ 16 | public class TCSettingsAdvancedFile { 17 | private final File settingsFile = new File(TabbyChatUtils.getTabbyChatDir(), "advanced.cfg"); 18 | private final String chatScrollHistoryPropertyName = "chatScrollHistory"; 19 | private final String maxLengthChannelNamePropertyName = "maxLengthChannelName"; 20 | private final String anchoredTopPropertyName = "chatbox.anchoredTop"; 21 | private final String convertUnicodeTextPropertyName = "convertunicodetext"; 22 | private final String multiChatDelayPropertyName = "multiChatDelay"; 23 | private final String chatBoxHeightPropertyName = "chatbox.height"; 24 | private final String chatBoxUnfocHeightPropertyName = "chatBoxUnfocHeight"; 25 | private final String chatBoxYPropertyName = "chatbox.y"; 26 | private final String chatBoxXPropertyName = "chatbox.x"; 27 | private final String textIgnoreOpacityPropertyName = "textignoreopacity"; 28 | private final String chatBoxWidthPropertyName = "chatbox.width"; 29 | private final String chatFadeTicksPropertyName = "chatFadeTicks"; 30 | private final String pinnedPropertyName = "pinchatinterface"; 31 | //Default settings 32 | 33 | public int chatScrollHistory = 100; 34 | public int maxLengthChannelName = 10; 35 | public boolean anchoredTop = false; 36 | public boolean convertUnicodeText = false; 37 | public int multiChatDelay = 500; 38 | public int chatBoxHeight = 180; 39 | public float chatBoxUnfocHeight = 50.0f; 40 | public int chatBoxY = -36; 41 | public int chatBoxX = 0; 42 | public boolean textIgnoreOpacity = true; 43 | public int chatBoxWidth = 320; 44 | public float chatFadeTicks = 200.0f; 45 | public boolean pinned = false; 46 | 47 | public TCSettingsAdvancedFile() { 48 | 49 | } 50 | 51 | public void loadSettingsFile() { 52 | Properties settingsTable = new Properties(); 53 | //Return default settings 54 | if (!settingsFile.exists()) { 55 | return; 56 | } 57 | 58 | try (FileInputStream fInStream = new FileInputStream(settingsFile); BufferedInputStream bInStream = new BufferedInputStream(fInStream)) { 59 | settingsTable.load(bInStream); 60 | } 61 | catch (Exception e) { 62 | TabbyChat.printException("Error while reading settings from file '" + settingsFile 63 | + "'", e); 64 | } 65 | 66 | try { 67 | chatScrollHistory = Integer.parseInt(settingsTable.getProperty(chatScrollHistoryPropertyName)); 68 | maxLengthChannelName = Integer.parseInt(settingsTable.getProperty(maxLengthChannelNamePropertyName)); 69 | anchoredTop = Boolean.parseBoolean(settingsTable.getProperty(anchoredTopPropertyName)); 70 | convertUnicodeText = Boolean.parseBoolean(settingsTable.getProperty(convertUnicodeTextPropertyName)); 71 | multiChatDelay = Integer.parseInt(settingsTable.getProperty(multiChatDelayPropertyName)); 72 | chatBoxHeight = TabbyChatUtils.parseInteger(settingsTable.getProperty(chatBoxHeightPropertyName), 73 | ChatBox.absMinH, 10000, 180); 74 | chatBoxUnfocHeight = Float.parseFloat(settingsTable.getProperty(chatBoxUnfocHeightPropertyName)); 75 | chatBoxX = TabbyChatUtils.parseInteger(settingsTable.getProperty(chatBoxXPropertyName), 76 | ChatBox.absMinX, 10000, ChatBox.absMinX); 77 | chatBoxY = TabbyChatUtils.parseInteger(settingsTable.getProperty(chatBoxYPropertyName), -10000, 78 | ChatBox.absMinY, ChatBox.absMinY); 79 | textIgnoreOpacity = Boolean.parseBoolean(settingsTable.getProperty(textIgnoreOpacityPropertyName)); 80 | chatBoxWidth = TabbyChatUtils.parseInteger(settingsTable.getProperty(chatBoxWidthPropertyName), 81 | ChatBox.absMinW, 10000, 320); 82 | chatFadeTicks = Float.parseFloat(settingsTable.getProperty(chatFadeTicksPropertyName)); 83 | pinned = Boolean.parseBoolean(settingsTable.getProperty(pinnedPropertyName)); 84 | } 85 | catch (NumberFormatException e) { 86 | TabbyChatUtils.log.warn("Failed to load (part of) advanced settings, using defaults"); 87 | } 88 | 89 | } 90 | 91 | 92 | public void saveSettingsFile() { 93 | Properties settingsTable = new Properties(); 94 | settingsTable.put(chatScrollHistoryPropertyName, Integer.toString(chatScrollHistory)); 95 | settingsTable.put(maxLengthChannelNamePropertyName, Integer.toString(maxLengthChannelName)); 96 | settingsTable.put(anchoredTopPropertyName, Boolean.toString(anchoredTop)); 97 | settingsTable.put(convertUnicodeTextPropertyName, Boolean.toString(convertUnicodeText)); 98 | settingsTable.put(multiChatDelayPropertyName, Integer.toString(multiChatDelay)); 99 | settingsTable.put(chatBoxHeightPropertyName, Integer.toString(chatBoxHeight)); 100 | settingsTable.put(chatBoxUnfocHeightPropertyName, Float.toString(chatBoxUnfocHeight)); 101 | settingsTable.put(chatBoxYPropertyName, Integer.toString(chatBoxY)); 102 | settingsTable.put(chatBoxXPropertyName, Integer.toString(chatBoxX)); 103 | settingsTable.put(textIgnoreOpacityPropertyName, Boolean.toString(textIgnoreOpacity)); 104 | settingsTable.put(chatBoxWidthPropertyName, Integer.toString(chatBoxWidth)); 105 | settingsTable.put(chatFadeTicksPropertyName, Float.toString(chatFadeTicks)); 106 | settingsTable.put(pinnedPropertyName, Boolean.toString(pinned)); 107 | TabbyChatUtils.saveProperties(settingsTable, this.settingsFile, Pair.of("Created parent dir for advanced tabbychat settings", "Failed to create parent directory for advanced tabbychat settings"), "settings.advanced"); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/threads/BackgroundChatThread.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.threads; 2 | 3 | import acs.tabbychat.core.TabbyChat; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.util.ChatAllowedCharacters; 6 | import net.minecraftforge.client.ClientCommandHandler; 7 | import org.apache.commons.lang3.StringUtils; 8 | 9 | public class BackgroundChatThread extends Thread { 10 | String sendChat; 11 | String knownPrefix; 12 | 13 | final Minecraft mc; 14 | 15 | public BackgroundChatThread(String _send) { 16 | this.sendChat = _send; 17 | mc = Minecraft.getMinecraft(); 18 | } 19 | 20 | public BackgroundChatThread(String _send, String _prefix) { 21 | this.sendChat = _send; 22 | this.knownPrefix = _prefix; 23 | mc = Minecraft.getMinecraft(); 24 | } 25 | 26 | @Override 27 | public synchronized void run() { 28 | mc.ingameGUI.getChatGUI().addToSentMessages(this.sendChat); 29 | String cmdPrefix = ""; 30 | String[] toSplit; 31 | int start; 32 | if (this.knownPrefix != null && this.sendChat.startsWith(this.knownPrefix)) { 33 | cmdPrefix = this.knownPrefix.trim() + " "; 34 | this.sendChat = this.sendChat.substring(this.knownPrefix.length()).trim(); 35 | toSplit = this.sendChat.split(" "); 36 | start = 0; 37 | } 38 | else { 39 | toSplit = this.sendChat.split(" "); 40 | start = 0; 41 | // command 42 | if (toSplit.length > 0 && toSplit[0].startsWith("/")) { 43 | if (toSplit[0].startsWith("/msg")) { 44 | cmdPrefix = toSplit[0] + " " + toSplit[1] + " "; 45 | start = 2; 46 | } 47 | 48 | // /fmsg is added by lotr to message groups of players 49 | else if (toSplit[0].startsWith("/fmsg") && toSplit.length > 1) { 50 | // /fmsg bind or unbind sets a default fellowship and should not be parsed as a multiline comment 51 | if (!toSplit[1].endsWith("bind")) { 52 | String[] fShipNameArray = this.sendChat.split("\""); 53 | //targeted name is contained with double quotes 54 | if (fShipNameArray.length > 1) { 55 | cmdPrefix = toSplit[0] + " \"" + fShipNameArray[1] + "\" "; 56 | //count number of spaces in fShipNameArray and set start accordingly 57 | start = 2 + StringUtils.countMatches(fShipNameArray[1], " "); 58 | } 59 | // default 60 | else { 61 | cmdPrefix = "/fmsg "; 62 | start = 1; 63 | } 64 | } 65 | } 66 | else if (!toSplit[0].trim().equals("/")) { 67 | cmdPrefix = toSplit[0] + " "; 68 | start = 1; 69 | } 70 | } 71 | } 72 | 73 | 74 | sendChat(start,toSplit,cmdPrefix); 75 | 76 | } 77 | 78 | private void sendChat(int start, String[] toSplit, String cmdPrefix) { 79 | int suffix = cmdPrefix.length(); 80 | StringBuilder sendPart = new StringBuilder(119); 81 | for (int word = start; word < toSplit.length; word++) { 82 | if (sendPart.length() + toSplit[word].length() + suffix > 100) { 83 | mc.thePlayer.sendChatMessage(cmdPrefix + sendPart.toString().trim()); 84 | try { 85 | Thread.sleep(Integer.parseInt(TabbyChat.advancedSettings.multiChatDelay 86 | .getValue())); 87 | } 88 | catch (InterruptedException e) { 89 | e.printStackTrace(); 90 | } 91 | sendPart = new StringBuilder(119); 92 | if (toSplit[word].startsWith("/")) 93 | sendPart.append("_"); 94 | } 95 | sendPart.append(toSplit[word]).append(" "); 96 | } 97 | 98 | if (!(sendPart.length() == 0) || !(cmdPrefix.length() == 0)) { 99 | String message = cmdPrefix + sendPart.toString().trim(); 100 | message = ChatAllowedCharacters.filerAllowedCharacters(message); 101 | 102 | //Check if command is client side 103 | if (ClientCommandHandler.instance.executeCommand(mc.thePlayer, message) == 1) { 104 | return; 105 | } 106 | 107 | mc.thePlayer.sendChatMessage(message); 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/threads/BackgroundUpdateCheck.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.threads; 2 | 3 | import acs.tabbychat.core.TabbyChat; 4 | import acs.tabbychat.util.TabbyChatUtils; 5 | import net.minecraft.client.resources.I18n; 6 | 7 | public class BackgroundUpdateCheck extends Thread { 8 | 9 | @Override 10 | public void run() { 11 | String newest = TabbyChat.getNewestVersion(); 12 | String current = TabbyChatUtils.version; 13 | 14 | boolean updateFound = false; 15 | 16 | if (!TabbyChat.generalSettings.tabbyChatEnable.getValue() 17 | || !TabbyChat.generalSettings.updateCheckEnable.getValue() 18 | || newest.equalsIgnoreCase("invalid")) 19 | return; 20 | 21 | String[] newVersionString = newest.split("\\."); 22 | String[] versionString = current.split("\\."); 23 | 24 | int[] newVersion = new int[newVersionString.length]; 25 | int[] version = new int[versionString.length]; 26 | 27 | int i; 28 | for (i = 0; i < newVersion.length; i++) { 29 | newVersion[i] = TabbyChatUtils.parseInteger(newVersionString[i], Integer.MIN_VALUE, 30 | Integer.MAX_VALUE, 0); 31 | } 32 | 33 | for (i = 0; i < version.length; i++) { 34 | version[i] = TabbyChatUtils.parseInteger(versionString[i], Integer.MIN_VALUE, 35 | Integer.MAX_VALUE, 0); 36 | } 37 | 38 | for (i = 0; i < Math.min(version.length, newVersion.length); i++) { 39 | if (version[i] < newVersion[i]) { 40 | updateFound = true; 41 | break; 42 | } 43 | else if (version[i] > newVersion[i]) { 44 | break; 45 | } 46 | 47 | } 48 | 49 | if (updateFound) { 50 | TabbyChatUtils.log.info("Update Found!"); 51 | String updateReport = "\u00A77" + I18n.format("messages.update1") + ' ' + 52 | current + 53 | I18n.format("messages.update2") + ' ' + 54 | newest + ") " + 55 | I18n.format("messages.update3") + 56 | "\u00A7r"; 57 | TabbyChat.printMessageToChat(updateReport); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/util/ChatExtensions.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.util; 2 | 3 | import acs.tabbychat.api.IChatExtension; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class ChatExtensions { 9 | 10 | private final List list = new ArrayList<>(); 11 | 12 | public ChatExtensions(List> list) { 13 | for (Class ext : list) { 14 | try { 15 | IChatExtension exten = ext.getDeclaredConstructor().newInstance(); 16 | exten.load(); 17 | this.list.add(exten); 18 | } 19 | catch (Exception e) { 20 | TabbyChatUtils.log.error("Unable to initialize " + ext.getName(), e); 21 | } 22 | } 23 | } 24 | 25 | @SuppressWarnings("unchecked") 26 | public List getListOf(Class extClass) { 27 | List t = new ArrayList<>(); 28 | for (IChatExtension ext : list) { 29 | if (extClass.isInstance(ext)) 30 | t.add((T) ext); 31 | } 32 | return t; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/util/IPResolver.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.util; 2 | 3 | import io.netty.util.NetUtil; 4 | 5 | public class IPResolver { 6 | 7 | private String host; 8 | private int port; 9 | 10 | public IPResolver(String ipaddress) { 11 | ipaddress = ipaddress.trim(); 12 | EnumConnection type = getType(ipaddress); 13 | switch (type) { 14 | case DOMAIN, IPv4 -> { 15 | if (ipaddress.contains(":")) { 16 | this.host = ipaddress.substring(0, ipaddress.lastIndexOf(':')); 17 | this.port = Integer.parseInt(ipaddress.substring(ipaddress.lastIndexOf(':') + 1)); 18 | } 19 | else { 20 | this.host = ipaddress; 21 | this.port = 25565; 22 | } 23 | } 24 | case IPv6 -> { 25 | if (ipaddress.startsWith("[") && ipaddress.contains("]:")) { 26 | this.host = ipaddress.substring(0, ipaddress.lastIndexOf(':')); 27 | this.port = Integer.parseInt(ipaddress.substring(ipaddress.lastIndexOf(':') + 1)); 28 | } 29 | else { 30 | this.host = ipaddress; 31 | this.port = 25565; 32 | } 33 | } 34 | } 35 | if (this.host.isEmpty()) 36 | this.host = "localhost"; 37 | } 38 | 39 | private static EnumConnection getType(String ipaddress) { 40 | // InetAddressUtils, Y U NO WORK? 41 | if (NetUtil.isValidIpV4Address(ipaddress)) 42 | return EnumConnection.IPv4; 43 | if (NetUtil.isValidIpV6Address(ipaddress)) 44 | return EnumConnection.IPv6; 45 | return EnumConnection.DOMAIN; 46 | } 47 | 48 | public String getHost() { 49 | return host; 50 | } 51 | 52 | public int getPort() { 53 | return port; 54 | } 55 | 56 | public boolean hasPort() { 57 | return port != 25565 || port != -1; 58 | } 59 | 60 | public String getAddress() { 61 | return host + (hasPort() ? "" : ":" + port); 62 | } 63 | 64 | /** 65 | * Used for getting the ip for use as a filename. 66 | */ 67 | public String getSafeAddress() { 68 | return host.replace(':', '_') + (port == 25565 ? "" : "(" + port + ")"); 69 | } 70 | 71 | private enum EnumConnection { 72 | IPv4, 73 | IPv6, 74 | DOMAIN; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/acs/tabbychat/util/TCChatLineFake.java: -------------------------------------------------------------------------------- 1 | package acs.tabbychat.util; 2 | 3 | import com.google.gson.annotations.Expose; 4 | import net.minecraft.client.gui.ChatLine; 5 | import net.minecraft.util.ChatComponentText; 6 | import net.minecraft.util.IChatComponent; 7 | 8 | public class TCChatLineFake extends ChatLine { 9 | //TODO: experiment with old chat messages to check if I can remove this without consequences 10 | @Expose 11 | protected IChatComponent chatComponent; 12 | 13 | public TCChatLineFake() { 14 | super(-1, new ChatComponentText(""), 0); 15 | } 16 | 17 | public TCChatLineFake(int _counter, IChatComponent _string, int _id) { 18 | super(_counter, _string, _id); 19 | if (_string == null) { 20 | _string = new ChatComponentText(""); 21 | } 22 | 23 | this.chatComponent = _string; 24 | } 25 | 26 | /** 27 | * Only used by vanilla, tabbychat itself should use {@link #getChatComponent()} instead 28 | */ 29 | @Override 30 | @Deprecated 31 | public IChatComponent func_151461_a() { 32 | return getChatComponent(); 33 | } 34 | 35 | public IChatComponent getChatComponent() { 36 | return this.chatComponent; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/tabbychat_at.cfg: -------------------------------------------------------------------------------- 1 | # TabbyChat 2 | public net.minecraft.client.gui.GuiChat field_146415_a # inputField 3 | protected net.minecraft.client.gui.GuiScreen field_146290_a # selectedButton 4 | protected net.minecraft.client.gui.GuiChat field_146416_h # sentHistoryCursor 5 | protected net.minecraft.client.gui.GuiChat field_146411_u # clickedURI 6 | protected net.minecraft.client.gui.GuiChat func_146407_a(Ljava/net/URI;)V # func_146407_a 7 | protected net.minecraft.client.gui.GuiNewChat func_146235_b(Ljava/lang/String;)Ljava/lang/String; # func_146235_b 8 | public net.minecraft.client.gui.GuiChat field_146409_v # defaultInputFieldText 9 | protected net.minecraft.client.gui.GuiNewChat func_146237_a(Lnet/minecraft/util/IChatComponent;IIZ)V # func_146237_a 10 | protected net.minecraft.client.gui.ChatLine field_74543_a # updateCounterCreated 11 | protected net.minecraft.client.gui.ChatLine field_74542_c # chatLineID 12 | public-f net.minecraft.client.gui.GuiNewChat field_146248_g # sentMessages 13 | -------------------------------------------------------------------------------- /src/main/resources/assets/tabbychat/lang/de_DE.lang: -------------------------------------------------------------------------------- 1 | # Language file for de_DE 2 | # Last update: Fri July 21 2023 By @Laerorneth 3 | colors.aqua=Aquamarin 4 | colors.black=Schwarz 5 | colors.brightgreen=Hellgrün 6 | colors.darkaqua=Dunkelaquamarin 7 | colors.darkblue=Dunkelblau 8 | colors.darkgray=Dunkelgrau 9 | colors.darkgreen=Dunkelgrün 10 | colors.darkred=Dunkelrot 11 | colors.default=Standard 12 | colors.gold=Gold 13 | colors.gray=Grau 14 | colors.indigo=Indigo 15 | colors.pink=Rosa 16 | colors.purple=Violett 17 | colors.red=Rot 18 | colors.white=Weiß 19 | colors.yellow=Gelb 20 | 21 | delims.angles= 22 | delims.anglesbracketscombo=<[Kombination]Pl.> 23 | delims.anglesparenscombo=<(Kombination)Pl.> 24 | delims.braces={Geschweifte Klammern} 25 | delims.brackets=[Eckige Klammern] 26 | delims.parenthesis=(Runde Klammern) 27 | 28 | formats.bold=Fett 29 | formats.default=Standard 30 | formats.italic=Kursiv 31 | formats.magic=Magic 32 | formats.striked=Durchgestrichen 33 | formats.underline=Unterstrichen 34 | 35 | messages.update1=Ein Update ist verfügbar (Momentane Version ist 36 | messages.update2=, neueste ist 37 | messages.update3=Besuche die TabbyChat Seiten auf Modrinth oder Gihub zum Herunterladen des Updates 38 | 39 | settings.advanced.chatboxunfocheight=Höhe ohne Fokus 40 | settings.advanced.chatfadeticks=Anzeigezeit einer Nachricht (in Ticks) 41 | settings.advanced.chatscrollhistory=Chat Historie speichern (Zeilen) 42 | settings.advanced.convertunicodetext=Unicode syntax konvertieren 43 | settings.advanced.forceunicode=Erzwinge Unicode Chat Anzeige 44 | settings.advanced.maxlengthchannelname=Maximale Länge Channelname 45 | settings.advanced.multichatdelay=Multi-Chat Sendeverzögerung (ms) 46 | settings.advanced.name=Erweiterte 47 | settings.advanced.textignoreopacity=Text ignoriert Opazitätseinstellungen 48 | 49 | settings.cancel=Abbrechen 50 | settings.delete=Löschen 51 | settings.new=Neu 52 | settings.save=Speichern 53 | 54 | settings.channel.alias=Alias 55 | settings.channel.cmdprefix=Chat-Commando Prefix 56 | settings.channel.hideprefix=Prefix während des Schreibens verbergen 57 | settings.channel.notificationson=Ungelesene Benachrichtigungen 58 | settings.channel.of=von 59 | settings.channel.position=Position 60 | 61 | settings.filters.audionotificationbool=Audio Benachrichtigung 62 | settings.filters.audionotificationsound=Ton 63 | settings.filters.casesensitive=Groß-/Kleinschreibung 64 | settings.filters.expressionstring=Ausdruck 65 | settings.filters.filtername=Filtername 66 | settings.filters.highlightbool=Treffer hervorheben 67 | settings.filters.highlightcolor=Farbe 68 | settings.filters.highlightformat=Formatierung 69 | settings.filters.inversematch=Invertierter Treffer 70 | settings.filters.name=Filter 71 | settings.filters.removematches=Treffer verbergen 72 | settings.filters.sendtoalltabs=Alle Tabs 73 | settings.filters.sendtotabbool=Sende Treffer an Tabs 74 | settings.filters.sendtotabname=Tab Name 75 | 76 | settings.general.groupspam=Spam zusammenfassen 77 | settings.general.name=Allgemeine 78 | settings.general.savechatlog=Chat in Logdatei speichern 79 | settings.spelling.spellcheckenable=Enable Spell-checking 80 | settings.general.splitchatlog=Log nach Channels aufteilen 81 | settings.general.tabbychatenable=TabbyChat aktiv 82 | settings.general.timestampcolor=Zeitstempel - Farbe 83 | settings.general.timestampenable=Zeitstempel aktivieren 84 | settings.general.timestampstyle=Zeitstempel - Stil 85 | settings.general.unreadflashing=Standardhinweis bei ungelesenen Benachrichtigungen 86 | settings.general.updatecheckenable=Nach Updates suchen 87 | 88 | settings.server.autochannelsearch=Automatische Suche nach neuen Channels 89 | settings.server.autopmsearch=Enable PM tabs 90 | settings.server.defaultchannels=Standard Channel 91 | settings.server.delimcolorbool=Separator - Farbe 92 | settings.server.delimformatbool=Separator - Format 93 | settings.server.delimiterchars=Channel Separator 94 | settings.server.ignoredchannels=Ignorierte Channel 95 | settings.server.name=Server 96 | settings.server.regexignorebool=Use patterns 97 | settings.server.pmtabregex.tome=PM Regex To Me 98 | settings.server.pmtabregex.fromme=PM Regex From Me 99 | 100 | settings.spelling.name=Spelling 101 | settings.spelling.userdictionary=User Dictionary 102 | settings.spelling.opendictionary=Open Dictionary 103 | settings.spelling.reloaddictionary=Neu laden 104 | 105 | sounds.anvil=Amboss 106 | sounds.bass=Bass 107 | sounds.bat=Fledermaus 108 | sounds.blast=Explosion 109 | sounds.blaze=Blaze 110 | sounds.bowhit=Bogen-Treffer 111 | sounds.break=Zerbrechen 112 | sounds.cat=Katze 113 | sounds.chicken=Hühnchen 114 | sounds.click=Klick 115 | sounds.cow=Kuh 116 | sounds.dragon=Drache 117 | sounds.endermen=Enderman 118 | sounds.ghast=Ghast 119 | sounds.glass=Glas 120 | sounds.harp=Harfe 121 | sounds.orb=EP-Kugel 122 | sounds.pig=Schwein 123 | sounds.pling=Pling 124 | sounds.splash=Spritzer 125 | sounds.swim=Schwimmen 126 | sounds.wolf=Wolf 127 | -------------------------------------------------------------------------------- /src/main/resources/assets/tabbychat/lang/en_US.lang: -------------------------------------------------------------------------------- 1 | #Language file for en_US 2 | #Wed May 21 19:58:20 EDT 2014 3 | colors.aqua=Aqua 4 | colors.black=Black 5 | colors.brightgreen=Bright Green 6 | colors.darkaqua=Dark Aqua 7 | colors.darkblue=Dark Blue 8 | colors.darkgray=Dark Gray 9 | colors.darkgreen=Dark Green 10 | colors.darkred=Dark Red 11 | colors.default=Default 12 | colors.gold=Gold 13 | colors.gray=Gray 14 | colors.indigo=Indigo 15 | colors.pink=Pink 16 | colors.purple=Purple 17 | colors.red=Red 18 | colors.white=White 19 | colors.yellow=Yellow 20 | 21 | delims.angles= 22 | delims.anglesbracketscombo=<[Combo]Pl.> 23 | delims.anglesparenscombo=<(Combo)Pl.> 24 | delims.braces={Braces} 25 | delims.brackets=[Brackets] 26 | delims.parenthesis=(Parenthesis) 27 | 28 | formats.bold=Bold 29 | formats.default=Default 30 | formats.italic=Italic 31 | formats.magic=Magic 32 | formats.striked=Striked 33 | formats.underline=Underlined 34 | 35 | messages.update1=An update is available! (Current version is 36 | messages.update2=, newest is 37 | messages.update3=Visit the mod page on Modrinth or Github to download 38 | 39 | settings.advanced.chatboxunfocheight=Unfocused Height 40 | settings.advanced.chatfadeticks=Chat fade time (ticks) 41 | settings.advanced.chatscrollhistory=Chat history to retain (lines) 42 | settings.advanced.convertunicodetext=Convert unicode syntax 43 | settings.advanced.forceunicode=Force Unicode Chat Rendering 44 | settings.advanced.maxlengthchannelname=Channel name max. length 45 | settings.advanced.multichatdelay=Multi-chat send delay (ms) 46 | settings.advanced.name=Advanced 47 | settings.advanced.textignoreopacity=Text ignores opacity setting 48 | 49 | settings.cancel=Cancel 50 | settings.delete=Delete 51 | settings.new=New 52 | settings.save=Save 53 | 54 | settings.channel.alias=Alias 55 | settings.channel.cmdprefix=Chat command prefix 56 | settings.channel.hideprefix=Hide prefix while typing 57 | settings.channel.notificationson=Unread Notifications 58 | settings.channel.of=of 59 | settings.channel.position=Position\: 60 | 61 | settings.filters.audionotificationbool=Audio notification 62 | settings.filters.audionotificationsound=Sound 63 | settings.filters.casesensitive=Case sensitive 64 | settings.filters.expressionstring=Expression 65 | settings.filters.filtername=Filter Name 66 | settings.filters.highlightbool=Highlight matches 67 | settings.filters.highlightcolor=Color 68 | settings.filters.highlightformat=Format 69 | settings.filters.inversematch=Inverse match 70 | settings.filters.name=Filters 71 | settings.filters.removematches=Hide matches from chat 72 | settings.filters.sendtoalltabs=All tabs 73 | settings.filters.sendtotabbool=Send matches to tab 74 | settings.filters.sendtotabname=Tab Name 75 | settings.filters.globalfilter=Global filter 76 | 77 | settings.general.groupspam=Consolidate spammed chat 78 | settings.general.name=General 79 | settings.general.savechatlog=Log chat to file 80 | settings.spelling.spellcheckenable=Enable Spell-checking 81 | settings.general.splitchatlog=Split log by channel 82 | settings.general.tabbychatenable=TabbyChat Enabled 83 | settings.general.timestampcolor=Timestamp color 84 | settings.general.timestampenable=Timestamp chat 85 | settings.general.timestampstyle=Timestamp style 86 | settings.general.unreadflashing=Default unread notification flashing 87 | settings.general.updatecheckenable=Check for Updates 88 | 89 | settings.server.autochannelsearch=Enable channel tabs 90 | settings.server.autopmsearch=Enable PM tabs 91 | settings.server.defaultchannels=Default channels 92 | settings.server.delimcolorbool=Colored delimiters 93 | settings.server.delimformatbool=Formatted delimiters 94 | settings.server.delimiterchars=Chat-channel delimiters 95 | settings.server.ignoredchannels=Ignored channels 96 | settings.server.name=Server 97 | settings.server.regexignorebool=Use patterns 98 | settings.server.pmtabregex.tome=PM Regex To Me 99 | settings.server.pmtabregex.fromme=PM Regex From Me 100 | 101 | settings.spelling.name=Spelling 102 | settings.spelling.userdictionary=User Dictionary 103 | settings.spelling.opendictionary=Open Dictionary 104 | settings.spelling.reloaddictionary=Reload 105 | 106 | sounds.anvil=Anvil 107 | sounds.bass=Bass 108 | sounds.bat=Bat 109 | sounds.blast=Blast 110 | sounds.blaze=Blaze 111 | sounds.bowhit=Bow Hit 112 | sounds.break=Break 113 | sounds.cat=Cat 114 | sounds.chicken=Chicken 115 | sounds.click=Click 116 | sounds.cow=Cow 117 | sounds.dragon=Dragon 118 | sounds.endermen=Endermen 119 | sounds.ghast=Ghast 120 | sounds.glass=Glass 121 | sounds.harp=Harp 122 | sounds.orb=Orb 123 | sounds.pig=Pig 124 | sounds.pling=Pling 125 | sounds.splash=Splash 126 | sounds.swim=Swim 127 | sounds.wolf=Wolf 128 | -------------------------------------------------------------------------------- /src/main/resources/assets/tabbychat/lang/es_ES.lang: -------------------------------------------------------------------------------- 1 | # Language file for es_ES 2 | # Wed May 21 19:58:20 EDT 2014 3 | colors.aqua=Agua 4 | colors.black=Black 5 | colors.brightgreen=Verde Claro 6 | colors.darkaqua=Agua Oscuro 7 | colors.darkblue=Azul Oscuro 8 | colors.darkgray=Gris Oscuro 9 | colors.darkgreen=Verde Oscuro 10 | colors.darkred=Rojo Oscuro 11 | colors.default=Normal 12 | colors.gold=Oro 13 | colors.gray=Gris 14 | colors.indigo=Añil 15 | colors.pink=Rosa 16 | colors.purple=Morado 17 | colors.red=Rojo 18 | colors.white=Blanco 19 | colors.yellow=Amarillo 20 | 21 | delims.angles=<Ángulos> 22 | delims.anglesbracketscombo=<[Combo]Y> 23 | delims.anglesparenscombo=<(Combo)Y> 24 | delims.braces={Llaves} 25 | delims.brackets=[Corchetes] 26 | delims.parenthesis=(Paréntesis) 27 | 28 | formats.bold=Negrita 29 | formats.default=Normal 30 | formats.italic=Cursiva 31 | formats.magic=Magic 32 | formats.striked=Tachado 33 | formats.underline=Subrayado 34 | 35 | messages.update1=¡Una nueva actualización\! (La versión actual es 36 | messages.update2=, la nueva es 37 | messages.update3=Visita el foro de TabbyChat en minecraftforum.net para descargar 38 | 39 | settings.advanced.chatboxunfocheight=Altura desenfocada 40 | settings.advanced.chatfadeticks=Tiempo de desaparición (ticks) 41 | settings.advanced.chatscrollhistory=Historial del chat (líneas) 42 | settings.advanced.convertunicodetext=Convert unicode syntax 43 | settings.advanced.forceunicode=Forzar renderizado Unicode 44 | settings.advanced.maxlengthchannelname=Maxima longitud de un canal 45 | settings.advanced.multichatdelay=Tiempo de espera para Multi-Chat (ms) 46 | settings.advanced.name=Avanzada 47 | settings.advanced.textignoreopacity=Text ignores opacity setting 48 | 49 | settings.cancel=Cancelar 50 | settings.delete=Borrar 51 | settings.new=Nuevo 52 | settings.save=Guardar 53 | 54 | settings.channel.alias=Alias 55 | settings.channel.cmdprefix=Prefijo del comando 56 | settings.channel.hideprefix=Hide prefix while typing 57 | settings.channel.notificationson=Notificaciones sin leer 58 | settings.channel.of=de 59 | settings.channel.position=Posición\: 60 | 61 | settings.filters.audionotificationbool=Notificacion de sonido 62 | settings.filters.audionotificationsound=Sonido 63 | settings.filters.casesensitive=Sensible a mayúsculas 64 | settings.filters.expressionstring=Expresión 65 | settings.filters.filtername=Filtrar Nombre 66 | settings.filters.highlightbool=Destacar coincidencias 67 | settings.filters.highlightcolor=Color 68 | settings.filters.highlightformat=Formato 69 | settings.filters.inversematch=Coincidencia inversa 70 | settings.filters.name=Filtros 71 | settings.filters.removematches=Ocultar coincidencias del chat 72 | settings.filters.sendtoalltabs=Todas las pestañas 73 | settings.filters.sendtotabbool=Enviar coincidencias a la pestaña 74 | settings.filters.sendtotabname=Nombre de pestaña 75 | 76 | settings.general.groupspam=Juntar mensajes iguales 77 | settings.general.name=General 78 | settings.general.savechatlog=Copiar chat a un archivo 79 | settings.spelling.spellcheckenable=Enable Spell-checking 80 | settings.general.splitchatlog=Split log by channel 81 | settings.general.tabbychatenable=TabbyChat Activado 82 | settings.general.timestampcolor=Color de hora 83 | settings.general.timestampenable=Mostrar hora 84 | settings.general.timestampstyle=Estilo de hora 85 | settings.general.unreadflashing=Notificación de mensajes no leídos 86 | settings.general.updatecheckenable=Check for Updates 87 | 88 | settings.server.autochannelsearch=Buscar canales automaticamente 89 | settings.server.autopmsearch=Enable PM tabs 90 | settings.server.defaultchannels=Canales Predeterminados 91 | settings.server.delimcolorbool=Separadores coloreados 92 | settings.server.delimformatbool=Separadores con formato 93 | settings.server.delimiterchars=Separadores de Chat-Canal 94 | settings.server.ignoredchannels=Canales Ignorados 95 | settings.server.name=Server 96 | settings.server.regexignorebool=Use patterns 97 | settings.server.pmtabregex.tome=PM Regex To Me 98 | settings.server.pmtabregex.fromme=PM Regex From Me 99 | 100 | settings.spelling.name=Spelling 101 | settings.spelling.userdictionary=User Dictionary 102 | settings.spelling.opendictionary=Open Dictionary 103 | settings.spelling.reloaddictionary=Reload 104 | 105 | sounds.anvil=Yunque 106 | sounds.bass=Bajo 107 | sounds.bat=Murciélago 108 | sounds.blast=Explosión 109 | sounds.blaze=Llama 110 | sounds.bowhit=Flecha 111 | sounds.break=Romper 112 | sounds.cat=Gato 113 | sounds.chicken=Gallina 114 | sounds.click=Click 115 | sounds.cow=Vaca 116 | sounds.dragon=Dragón 117 | sounds.endermen=Enderman 118 | sounds.ghast=Ghast 119 | sounds.glass=Cristal 120 | sounds.harp=Arpa 121 | sounds.orb=Experiencia 122 | sounds.pig=Cerdo 123 | sounds.pling=Pling 124 | sounds.splash=Salpicadura 125 | sounds.swim=Nadar 126 | sounds.wolf=Lobo 127 | -------------------------------------------------------------------------------- /src/main/resources/assets/tabbychat/lang/et_EE.lang: -------------------------------------------------------------------------------- 1 | # Language file for et_EE 2 | # Wed May 21 19:58:20 EDT 2014 3 | colors.aqua=Meresinine 4 | colors.black=Black 5 | colors.brightgreen=Erkroheline 6 | colors.darkaqua=Tume meresinine 7 | colors.darkblue=Tumesinine 8 | colors.darkgray=Tumehall 9 | colors.darkgreen=Tumeroheline 10 | colors.darkred=Tumepunane 11 | colors.default=Tavaline 12 | colors.gold=Kuldne 13 | colors.gray=Hall 14 | colors.indigo=Indigosinine 15 | colors.pink=Roosa 16 | colors.purple=Lilla 17 | colors.red=Punane 18 | colors.white=Valge 19 | colors.yellow=Kollane 20 | 21 | delims.angles= 22 | delims.anglesbracketscombo=<[Kombinatsioon]Mä.> 23 | delims.anglesparenscombo=<(Kombinatsioon)Mä.> 24 | delims.braces={Looksulud} 25 | delims.brackets=[Kantsulud] 26 | delims.parenthesis=(Ümarsulud) 27 | 28 | formats.bold=Paks 29 | formats.default=Tavaline 30 | formats.italic=Kursiiv 31 | formats.magic=Magic 32 | formats.striked=Läbikriipsutus 33 | formats.underline=Allakriipsutus 34 | 35 | messages.update1=Uuendus on saadaval\! (Praegune versioon on 36 | messages.update2=, uusim on 37 | messages.update3=Külasta TabbyChat'i foorumi teemat aadressil minecraftforum.net, et alla laadida. 38 | 39 | settings.advanced.chatboxunfocheight=Fokuseerimata vestluse kõrgus 40 | settings.advanced.chatfadeticks=Vestluse hajumisaeg (tick'i) 41 | settings.advanced.chatscrollhistory=Säilitatav vestluse ajalugu (rida) 42 | settings.advanced.convertunicodetext=Convert unicode syntax 43 | settings.advanced.forceunicode=Sunni teksti kuvamine Unicode vormingus 44 | settings.advanced.maxlengthchannelname=Kanali nime maksimaalne pikkus (märki) 45 | settings.advanced.multichatdelay=Multisõnumi saatmise viivitus (ms) 46 | settings.advanced.name=Täpsemad sätted 47 | settings.advanced.textignoreopacity=Text ignores opacity setting 48 | 49 | settings.cancel=Loobu 50 | settings.delete=Kustuta 51 | settings.new=Uus 52 | settings.save=Salvesta 53 | 54 | settings.channel.alias=Hüüdnimi 55 | settings.channel.cmdprefix=Vestluse käsu eesliide 56 | settings.channel.hideprefix=Peida eesliide kirjutamise ajal 57 | settings.channel.notificationson=Lugemata sõnumite korral teata 58 | settings.channel.of=/ 59 | settings.channel.position=Asukoht\: 60 | 61 | settings.filters.audionotificationbool=Heliteade 62 | settings.filters.audionotificationsound=Heli 63 | settings.filters.casesensitive=Tõstutundlik 64 | settings.filters.expressionstring=Regular Expression 65 | settings.filters.filtername=Filtri nimi 66 | settings.filters.highlightbool=Tõsta tulemused esile 67 | settings.filters.highlightcolor=Värv 68 | settings.filters.highlightformat=Vorming 69 | settings.filters.inversematch=Vastandtulemused 70 | settings.filters.name=Kohandatud filtrid 71 | settings.filters.removematches=Peida tulemused vestlusest 72 | settings.filters.sendtoalltabs=Kõik vahekaardid 73 | settings.filters.sendtotabbool=Saada tulemused vahekaardile 74 | settings.filters.sendtotabname=Vahekaardi nimi 75 | 76 | settings.general.groupspam=Ühenda korratud sõnumid 77 | settings.general.name=Põhilised sätted 78 | settings.general.savechatlog=Logi vestlus faili 79 | settings.spelling.spellcheckenable=Enable Spell-checking 80 | settings.general.splitchatlog=Split log by channel 81 | settings.general.tabbychatenable=TabbyChat lubatud 82 | settings.general.timestampcolor=Ajatempli värv 83 | settings.general.timestampenable=Ajatembelda vestlus 84 | settings.general.timestampstyle=Ajatempli vorming 85 | settings.general.unreadflashing=Lugemata teadete korral vilguta 86 | settings.general.updatecheckenable=Check for Updates 87 | 88 | settings.server.autochannelsearch=Otsi automaatselt uusi kanaleid 89 | settings.server.autopmsearch=Otsi automaatselt uusi privaatsõnumeid 90 | settings.server.defaultchannels=Vaikimisi kanalid 91 | settings.server.delimcolorbool=Eraldajate värv 92 | settings.server.delimformatbool=Eraldajate vorming 93 | settings.server.delimiterchars=Vestluskanalite eraldajad 94 | settings.server.ignoredchannels=Ignoreeritud kanalid 95 | settings.server.name=Serveri sätted 96 | settings.server.regexignorebool=Use patterns 97 | settings.server.pmtabregex.tome=PM Regex To Me 98 | settings.server.pmtabregex.fromme=PM Regex From Me 99 | 100 | settings.spelling.name=Spelling 101 | settings.spelling.userdictionary=User Dictionary 102 | settings.spelling.opendictionary=Open Dictionary 103 | settings.spelling.reloaddictionary=Reload 104 | 105 | sounds.anvil=Alasi 106 | sounds.bass=Bass 107 | sounds.bat=Nahkhiir 108 | sounds.blast=Plahvatus 109 | sounds.blaze=Leek 110 | sounds.bowhit=Vibu tabamus 111 | sounds.break=Purunemine 112 | sounds.cat=Kass 113 | sounds.chicken=Kana 114 | sounds.click=Klõps 115 | sounds.cow=Lehm 116 | sounds.dragon=Lõpudraakon 117 | sounds.endermen=Lõpumees 118 | sounds.ghast=Kammitus 119 | sounds.glass=Klaas 120 | sounds.harp=Harf 121 | sounds.orb=XP ring 122 | sounds.pig=Siga 123 | sounds.pling=Plõnn 124 | sounds.splash=Sulpsatus 125 | sounds.swim=Ujumine 126 | sounds.wolf=Hunt 127 | -------------------------------------------------------------------------------- /src/main/resources/assets/tabbychat/lang/fi_FI.lang: -------------------------------------------------------------------------------- 1 | # Language file for fi_FI 2 | # Wed May 21 19:58:20 EDT 2014 3 | colors.aqua=Meriveden Sininen 4 | colors.black=Black 5 | colors.brightgreen=Vaaleanvihreä 6 | colors.darkaqua=Meriveden Tumma 7 | colors.darkblue=Tummansininen 8 | colors.darkgray=Tummanharmaa 9 | colors.darkgreen=Tummanvihreä 10 | colors.darkred=Tummanpunainen 11 | colors.default=Tavallinen 12 | colors.gold=Kultainen 13 | colors.gray=Harmaa 14 | colors.indigo=Syvän Sininen 15 | colors.pink=Vaaleanpunainen 16 | colors.purple=Purppura 17 | colors.red=Punainen 18 | colors.white=Valkoinen 19 | colors.yellow=Keltainen 20 | 21 | delims.angles= 22 | delims.anglesbracketscombo=<[Yhdistelmä]> 23 | delims.anglesparenscombo=<(Yhdistelmä)> 24 | delims.braces={Aaltosulkeet} 25 | delims.brackets=[Sulkeet] 26 | delims.parenthesis=(Kaarisulkeet) 27 | 28 | formats.bold=Lihava 29 | formats.default=Tavallinen 30 | formats.italic=Kursivoitu 31 | formats.magic=Magic 32 | formats.striked=Yliviivattu 33 | formats.underline=Alleviivattu 34 | 35 | messages.update1=Uusi päivitys on saatavissa\! (Tämän hetkinen versio on 36 | messages.update2=, uusin on 37 | messages.update3=Käy katsomassa TabbyChat forumi minecraftforum.net\:ssä lataaksesi sen 38 | 39 | settings.advanced.chatboxunfocheight=Huomioimattomien korkeus (rivit) 40 | settings.advanced.chatfadeticks=Keskustelun haalistumis aika (tickit) 41 | settings.advanced.chatscrollhistory=Keskustelun säilytetty historia (rivit) 42 | settings.advanced.convertunicodetext=Convert unicode syntax 43 | settings.advanced.forceunicode=Pakota Unicode Keskustelun näyttäminen 44 | settings.advanced.maxlengthchannelname=Kanavan nimen maksimi pituus 45 | settings.advanced.multichatdelay=Monen viestin välissä oleva aika (ms) 46 | settings.advanced.name=Edistynyt 47 | settings.advanced.textignoreopacity=Text ignores opacity setting 48 | 49 | settings.cancel=Peruuta 50 | settings.delete=Poista 51 | settings.new=Uusi 52 | settings.save=Tallenna 53 | 54 | settings.channel.alias=Toiselta nimeltään 55 | settings.channel.cmdprefix=Keskustellun komennon etuliite 56 | settings.channel.hideprefix=Hide prefix while typing 57 | settings.channel.notificationson=Lukemattomat muistiinpanot 58 | settings.channel.of= 59 | settings.channel.position=Sijainti\: 60 | 61 | settings.filters.audionotificationbool=Ääni huomautus 62 | settings.filters.audionotificationsound=Ääni 63 | settings.filters.casesensitive=Yhteensopiva 64 | settings.filters.expressionstring=Ilmaisu 65 | settings.filters.filtername=Suodattimen nimi 66 | settings.filters.highlightbool=Korosta osumat 67 | settings.filters.highlightcolor=Väri 68 | settings.filters.highlightformat=Muotoilu 69 | settings.filters.inversematch=Käänteinen osuma 70 | settings.filters.name=Suodattimet 71 | settings.filters.removematches=Piilota osumat keskustelusta 72 | settings.filters.sendtoalltabs=Kaikki välilehdet 73 | settings.filters.sendtotabbool=Lähetä osumat välilehteen 74 | settings.filters.sendtotabname=Välilehden nimi 75 | 76 | settings.general.groupspam=Tallenna spämmätty keskustelu 77 | settings.general.name=Yleiset 78 | settings.general.savechatlog=Merkitse keskustelu tiedostoon 79 | settings.spelling.spellcheckenable=Enable Spell-checking 80 | settings.general.splitchatlog=Split log by channel 81 | settings.general.tabbychatenable=TabbyChat päällä 82 | settings.general.timestampcolor=Aikaleiman väri 83 | settings.general.timestampenable=Aikaleima juttelussa 84 | settings.general.timestampstyle=Aikaleiman tyyli 85 | settings.general.unreadflashing=Tavallinen lukemattoman viestin välkkyminen 86 | settings.general.updatecheckenable=Check for Updates 87 | 88 | settings.server.autochannelsearch=Etsi automaattisesti uusia kanavia 89 | settings.server.autopmsearch=Enable PM tabs 90 | settings.server.defaultchannels=Tavalliset kanavat 91 | settings.server.delimcolorbool=Värilliset eroittimet 92 | settings.server.delimformatbool=Muotoillut eroittimet 93 | settings.server.delimiterchars=Keskustelu kanavien eroittelu 94 | settings.server.ignoredchannels=Sivuutetut kanavat 95 | settings.server.name=Palvelin 96 | settings.server.regexignorebool=Use patterns 97 | settings.server.pmtabregex.tome=PM Regex To Me 98 | settings.server.pmtabregex.fromme=PM Regex From Me 99 | 100 | settings.spelling.name=Spelling 101 | settings.spelling.userdictionary=User Dictionary 102 | settings.spelling.opendictionary=Open Dictionary 103 | settings.spelling.reloaddictionary=Reload 104 | 105 | sounds.anvil=Alasin 106 | sounds.bass=Basso 107 | sounds.bat=Lepakko 108 | sounds.blast=Räjähdys 109 | sounds.blaze=Roihu 110 | sounds.bowhit=Jousen Osuma 111 | sounds.break=Rikkuminen 112 | sounds.cat=Kissa 113 | sounds.chicken=Kana 114 | sounds.click=Napsahdus 115 | sounds.cow=Lehmä 116 | sounds.dragon=Lohikäärme 117 | sounds.endermen=Ääreläinen 118 | sounds.ghast=Hornanhenki 119 | sounds.glass=Lasi 120 | sounds.harp=Harppu 121 | sounds.orb=Xp 122 | sounds.pig=Sika 123 | sounds.pling=Pling 124 | sounds.splash=Roiske 125 | sounds.swim=Uinti 126 | sounds.wolf=Susi 127 | -------------------------------------------------------------------------------- /src/main/resources/assets/tabbychat/lang/fr_FR.lang: -------------------------------------------------------------------------------- 1 | # Language file for fr_FR 2 | # Last Update: 21/07/2023 3 | # By @Keodrop 4 | colors.aqua=Bleu Ciel 5 | colors.black=Noir 6 | colors.brightgreen=Vert Clair 7 | colors.darkaqua=Cyan 8 | colors.darkblue=Bleu Foncé 9 | colors.darkgray=Gris Foncé 10 | colors.darkgreen=Vert Foncé 11 | colors.darkred=Rouge Foncé 12 | colors.default=Défaut 13 | colors.gold=Doré 14 | colors.gray=Gris 15 | colors.indigo=Bleu 16 | colors.pink=Rose 17 | colors.purple=Violet 18 | colors.red=Rouge 19 | colors.white=Blanc 20 | colors.yellow=Jaune 21 | 22 | delims.angles= 23 | delims.anglesbracketscombo=<[Combo]Pl.> 24 | delims.anglesparenscombo=<(Combo)Pl.> 25 | delims.braces={Accolades} 26 | delims.brackets=[Crochets] 27 | delims.parenthesis=(Parenthèses) 28 | 29 | formats.bold=Gras 30 | formats.default=Défaut 31 | formats.italic=Italique 32 | formats.magic=Magique 33 | formats.striked=Barré 34 | formats.underline=Souligné 35 | 36 | messages.update1=Une mise à jour est disponible ! (Version actuelle: 37 | messages.update2=, la nouvelle: 38 | messages.update3=Allez sur la page de TabbyChat sur Modrinth ou Github pour la télécharger 39 | 40 | settings.advanced.chatboxunfocheight=Hauteur sans focus 41 | settings.advanced.chatfadeticks=Temps fondu du chat (ticks) 42 | settings.advanced.chatscrollhistory=Historique à conserver (lignes) 43 | settings.advanced.convertunicodetext=Convertir la syntaxe unicode 44 | settings.advanced.forceunicode=Forcer l'affichage Unicode dans le chat 45 | settings.advanced.maxlengthchannelname=Longueur max. du nom d'un canal 46 | settings.advanced.multichatdelay=Délai d'envoi Chat-Multi (ms) 47 | settings.advanced.name=Avancé 48 | settings.advanced.textignoreopacity=Le texte ignore le paramètre d'opacité 49 | 50 | settings.cancel=Annuler 51 | settings.delete=Effacer 52 | settings.new=Nouveau 53 | settings.save=Sauvegarder 54 | 55 | settings.channel.alias=Alias 56 | settings.channel.cmdprefix=Préfixe de la commande de chat 57 | settings.channel.hideprefix=Cacher le préfixe lors de la frappe 58 | settings.channel.notificationson=Notifications non-lues 59 | settings.channel.of=de 60 | settings.channel.position=Position : 61 | 62 | settings.filters.audionotificationbool=Notification Audio 63 | settings.filters.audionotificationsound=Son 64 | settings.filters.casesensitive=Sensible à la casse 65 | settings.filters.expressionstring=Expression 66 | settings.filters.filtername=Nom du Filtre 67 | settings.filters.highlightbool=Surligner les correspondances 68 | settings.filters.highlightcolor=Couleur 69 | settings.filters.highlightformat=Format 70 | settings.filters.inversematch=Inverser les correspondances 71 | settings.filters.name=Filtres 72 | settings.filters.removematches=Cacher les correspondances du chat 73 | settings.filters.sendtoalltabs=Tous les onglets 74 | settings.filters.sendtotabbool=Envoyer les correspondances à l'onglet 75 | settings.filters.sendtotabname=Nom : 76 | 77 | settings.general.groupspam=Renforcer le spam du chat 78 | settings.general.name=General 79 | settings.general.savechatlog=Stocker le chat 80 | settings.spelling.spellcheckenable=Activer la vérification orthographique 81 | settings.general.splitchatlog=Diviser les logs par canal 82 | settings.general.tabbychatenable=TabbyChat Activé 83 | settings.general.timestampcolor=Couleur de l'heure 84 | settings.general.timestampenable=Heure dans le chat 85 | settings.general.timestampstyle=Style de l'heure 86 | settings.general.unreadflashing=Affichage par défaut des notifications non-lues 87 | settings.general.updatecheckenable=Vérifier les mises à jour 88 | 89 | settings.server.autochannelsearch=Activer les onglets canaux 90 | settings.server.autopmsearch=Activer les onglets de message privé 91 | settings.server.defaultchannels=Canaux par défaut 92 | settings.server.delimcolorbool=Délimiteurs colorés 93 | settings.server.delimformatbool=Délimiteurs formatés 94 | settings.server.delimiterchars=Délimiteurs Chat-Canaux 95 | settings.server.ignoredchannels=Canaux ignorés 96 | settings.server.name=Serveur 97 | settings.server.regexignorebool=Utiliser des modèles 98 | settings.server.pmtabregex.tome=Me MP les Regex 99 | settings.server.pmtabregex.fromme=Me MP les Regex 100 | 101 | settings.spelling.name=Orthographe 102 | settings.spelling.userdictionary=Dictionnaire de l'utilisateur 103 | settings.spelling.opendictionary=Ouvrir dictionnaire 104 | settings.spelling.reloaddictionary=Actualiser 105 | 106 | sounds.anvil=Enclume 107 | sounds.bass=Basse 108 | sounds.bat=Chauve-Souris 109 | sounds.blast=Explosion 110 | sounds.blaze=Blaze 111 | sounds.bowhit=Arc 112 | sounds.break=Casser 113 | sounds.cat=Chat 114 | sounds.chicken=Poulet 115 | sounds.click=Clic 116 | sounds.cow=Vache 117 | sounds.dragon=Dragon 118 | sounds.endermen=Endermen 119 | sounds.ghast=Ghast 120 | sounds.glass=Verre 121 | sounds.harp=Harpe 122 | sounds.orb=Orbe 123 | sounds.pig=Cochon 124 | sounds.pling=Pling 125 | sounds.splash=Éclaboussure 126 | sounds.swim=Nage 127 | sounds.wolf=Loup 128 | -------------------------------------------------------------------------------- /src/main/resources/assets/tabbychat/lang/ru_RU.lang: -------------------------------------------------------------------------------- 1 | # Language file for ru_RU 2 | # Wed May 21 19:58:20 EDT 2014 3 | colors.aqua=Голубой 4 | colors.black=Black 5 | colors.brightgreen=Лаймовый 6 | colors.darkaqua=Темно-голубой 7 | colors.darkblue=Темно-синий 8 | colors.darkgray=Темно-серый 9 | colors.darkgreen=Темно-зеленый 10 | colors.darkred=Темно-красный 11 | colors.default=Обычный 12 | colors.gold=Золотой 13 | colors.gray=Серый 14 | colors.indigo=Индиго 15 | colors.pink=Розовый 16 | colors.purple=Фиолетовый 17 | colors.red=Красный 18 | colors.white=Белый 19 | colors.yellow=Желтый 20 | 21 | delims.angles=<Углы> 22 | delims.anglesbracketscombo=<[Комбо]Pl.> 23 | delims.anglesparenscombo=<(Комбо)Pl.> 24 | delims.braces={Фигурные} 25 | delims.brackets=[Квадратные] 26 | delims.parenthesis=(Круглые) 27 | 28 | formats.bold=Жирный 29 | formats.default=Обычный 30 | formats.italic=Курсив 31 | formats.magic=Magic 32 | formats.striked=Зачекрнутый 33 | formats.underline=Подчеркнутый 34 | 35 | messages.update1=Найдено обновление! (Текущая версия 36 | messages.update2=, новая 37 | messages.update3=Посетите тему на minecraftforum.net для скачки обновления. 38 | 39 | settings.advanced.chatboxunfocheight=Высота неактивного чата 40 | settings.advanced.chatfadeticks=Время исчезновения (Тик) 41 | settings.advanced.chatscrollhistory=История чата (линии) 42 | settings.advanced.convertunicodetext=Convert unicode syntax 43 | settings.advanced.forceunicode=Юникод рендеринг 44 | settings.advanced.maxlengthchannelname=Макс. длина имени канала 45 | settings.advanced.multichatdelay=Отправка сообщений, мультичат (Мс) 46 | settings.advanced.name=Дополнительно 47 | settings.advanced.textignoreopacity=Text ignores opacity setting 48 | 49 | settings.cancel=Отмена 50 | settings.delete=Удалить 51 | settings.new=Новый 52 | settings.save=Сохр. 53 | 54 | settings.channel.alias=Алиас 55 | settings.channel.cmdprefix=Префикс в чате 56 | settings.channel.hideprefix=Hide prefix while typing 57 | settings.channel.notificationson=Уведомления 58 | settings.channel.of=из 59 | settings.channel.position=Позиция\: 60 | 61 | settings.filters.audionotificationbool=Аудио уведомления 62 | settings.filters.audionotificationsound=Звук 63 | settings.filters.casesensitive=Учитывать регистр 64 | settings.filters.expressionstring=Слова для поиска 65 | settings.filters.filtername=Имя фильтра 66 | settings.filters.highlightbool=Подсвечивать совпадения 67 | settings.filters.highlightcolor=Цвет 68 | settings.filters.highlightformat=Формат 69 | settings.filters.inversematch=Инвентировать 70 | settings.filters.name=Фильтры 71 | settings.filters.removematches=Скрывать совпадения 72 | settings.filters.sendtoalltabs=Во всех 73 | settings.filters.sendtotabbool=Показывать во вкладках 74 | settings.filters.sendtotabname=Отдельная 75 | 76 | settings.general.groupspam=Группировать одинаковые сообщения 77 | settings.general.name=Главное 78 | settings.general.savechatlog=Логировать чат 79 | settings.spelling.spellcheckenable=Enable Spell-checking 80 | settings.general.splitchatlog=Split log by channel 81 | settings.general.tabbychatenable=TabbyChat включен 82 | settings.general.timestampcolor=Цвет 83 | settings.general.timestampenable=Пометка времени 84 | settings.general.timestampstyle=Стиль 85 | settings.general.unreadflashing=Уведомления по-умолчанию 86 | settings.general.updatecheckenable=Check for Updates 87 | 88 | settings.server.autochannelsearch=Авто-поиск новых каналов 89 | settings.server.autopmsearch=Enable PM tabs 90 | settings.server.defaultchannels=Каналы по-умолчанию 91 | settings.server.delimcolorbool=Цвет 92 | settings.server.delimformatbool=Формат 93 | settings.server.delimiterchars=Разделители каналов 94 | settings.server.ignoredchannels=Игнорируемые каналы 95 | settings.server.name=Сервер 96 | settings.server.regexignorebool=Use patterns 97 | settings.server.pmtabregex.tome=PM Regex To Me 98 | settings.server.pmtabregex.fromme=PM Regex From Me 99 | 100 | settings.spelling.name=Spelling 101 | settings.spelling.userdictionary=User Dictionary 102 | settings.spelling.opendictionary=Open Dictionary 103 | settings.spelling.reloaddictionary=Reload 104 | 105 | sounds.anvil=Наковальня 106 | sounds.bass=Басс 107 | sounds.bat=Летучая мышь 108 | sounds.blast=Взрыв 109 | sounds.blaze=Ифрит 110 | sounds.bowhit=Стрела 111 | sounds.break=Сломал 112 | sounds.cat=Кот 113 | sounds.chicken=Курица 114 | sounds.click=Клик 115 | sounds.cow=Корова 116 | sounds.dragon=Дракон 117 | sounds.endermen=Эндерман 118 | sounds.ghast=Гаст 119 | sounds.glass=Стекло 120 | sounds.harp=Арфа 121 | sounds.orb=Опыт 122 | sounds.pig=Свинья 123 | sounds.pling=Pling 124 | sounds.splash=Всплеск 125 | sounds.swim=Спрут 126 | sounds.wolf=Волк 127 | -------------------------------------------------------------------------------- /src/main/resources/assets/tabbychat/lang/sv_SE.lang: -------------------------------------------------------------------------------- 1 | # Language file for sv_SE 2 | # Wed May 21 19:58:20 EDT 2014 3 | colors.aqua=Aqua 4 | colors.black=Black 5 | colors.brightgreen=Ljusgrön 6 | colors.darkaqua=Mörk Aqua 7 | colors.darkblue=Mörkblå 8 | colors.darkgray=Mörkgrå 9 | colors.darkgreen=Mörkgrön 10 | colors.darkred=Mörkröd 11 | colors.default=Standard 12 | colors.gold=Guld 13 | colors.gray=Grå 14 | colors.indigo=Indigo 15 | colors.pink=Rosa 16 | colors.purple=Lila 17 | colors.red=Röd 18 | colors.white=Vit 19 | colors.yellow=Gul 20 | 21 | delims.angles= 22 | delims.anglesbracketscombo=<[Kombo]Pl.> 23 | delims.anglesparenscombo=<(Kombo)Pl.> 24 | delims.braces={Klammrar} 25 | delims.brackets=[Konsoler] 26 | delims.parenthesis=(Parenteser) 27 | 28 | formats.bold=Fetstil 29 | formats.default=Standard 30 | formats.italic=Kursiv 31 | formats.magic=Magic 32 | formats.striked=Genomstrykt 33 | formats.underline=Understruket 34 | 35 | messages.update1=En uppdatering är tillgänglig\! (Nuvarande version är 36 | messages.update2=, nyaste är 37 | messages.update3=Besök TabbyChat forum tråden på minecraftforum.net för att ladda ner 38 | 39 | settings.advanced.chatboxunfocheight=Ofokuserad höjd 40 | settings.advanced.chatfadeticks=Chatt borttonings tid (ticks) 41 | settings.advanced.chatscrollhistory=Chatt historik att spara (rader) 42 | settings.advanced.convertunicodetext=Convert unicode syntax 43 | settings.advanced.forceunicode=Tvinga Unicode Chatt Rendering 44 | settings.advanced.maxlengthchannelname=Kanalnamn max. längd 45 | settings.advanced.multichatdelay=Multi-chatt skickningsfördröjning (ms) 46 | settings.advanced.name=Avancerat 47 | settings.advanced.textignoreopacity=Text ignores opacity setting 48 | 49 | settings.cancel=Avbryt 50 | settings.delete=Ta bort 51 | settings.new=Ny 52 | settings.save=Spara 53 | 54 | settings.channel.alias=Alias 55 | settings.channel.cmdprefix=Chatt kommando prefix 56 | settings.channel.hideprefix=Göm prefix medans du skriver 57 | settings.channel.notificationson=Olästa meddelanden 58 | settings.channel.of=av 59 | settings.channel.position=Position\: 60 | 61 | settings.filters.audionotificationbool=Ljudnotifiering 62 | settings.filters.audionotificationsound=Ljud 63 | settings.filters.casesensitive=Skiftlägeskänsligt 64 | settings.filters.expressionstring=Uttryck 65 | settings.filters.filtername=Filter Namn 66 | settings.filters.highlightbool=Markera matcher 67 | settings.filters.highlightcolor=Färg 68 | settings.filters.highlightformat=Format 69 | settings.filters.inversematch=Invers match 70 | settings.filters.name=Filter 71 | settings.filters.removematches=Göm matcher från chatten 72 | settings.filters.sendtoalltabs=Alla flikar 73 | settings.filters.sendtotabbool=Skicka matcher till flik 74 | settings.filters.sendtotabname=Fliknamn 75 | 76 | settings.general.groupspam=Konsolidera spammad chat 77 | settings.general.name=Allmänt 78 | settings.general.savechatlog=Logga chatt till fil 79 | settings.spelling.spellcheckenable=Enable Spell-checking 80 | settings.general.splitchatlog=Split log by channel 81 | settings.general.tabbychatenable=TabbyChat Aktiverad 82 | settings.general.timestampcolor=Tidsstämpelfärg 83 | settings.general.timestampenable=Tidsstämpla chatt 84 | settings.general.timestampstyle=Tidsstämpelstil 85 | settings.general.unreadflashing=Blinkade olästa meddelanden som standard 86 | settings.general.updatecheckenable=Check for Updates 87 | 88 | settings.server.autochannelsearch=Sök automatiskt efter nya kanaler 89 | settings.server.autopmsearch=Sök automatiskt efter nya PMs 90 | settings.server.defaultchannels=Standard kanaler 91 | settings.server.delimcolorbool=Färgare avgränsare 92 | settings.server.delimformatbool=Formaterade avgränsare 93 | settings.server.delimiterchars=Chatt-kanals avgränsare 94 | settings.server.ignoredchannels=Ignorerade kanaler 95 | settings.server.name=Server 96 | settings.server.regexignorebool=Use patterns 97 | settings.server.pmtabregex.tome=PM Regex To Me 98 | settings.server.pmtabregex.fromme=PM Regex From Me 99 | 100 | settings.spelling.name=Spelling 101 | settings.spelling.userdictionary=User Dictionary 102 | settings.spelling.opendictionary=Open Dictionary 103 | settings.spelling.reloaddictionary=Reload 104 | 105 | sounds.anvil=Städ 106 | sounds.bass=Bas 107 | sounds.bat=Fladdermus 108 | sounds.blast=Explosion 109 | sounds.blaze=Brännare 110 | sounds.bowhit=Pilbågsträff 111 | sounds.break=Bryning 112 | sounds.cat=Katt 113 | sounds.chicken=Kyckling 114 | sounds.click=Klick 115 | sounds.cow=Ko 116 | sounds.dragon=Drake 117 | sounds.endermen=Endermen 118 | sounds.ghast=Ghast 119 | sounds.glass=Glas 120 | sounds.harp=Harpa 121 | sounds.orb=Erfarenhetsklot 122 | sounds.pig=Gris 123 | sounds.pling=Pling 124 | sounds.splash=Skvätt 125 | sounds.swim=Simma 126 | sounds.wolf=Varg 127 | -------------------------------------------------------------------------------- /src/main/resources/assets/tabbychat/lang/uk_UA.lang: -------------------------------------------------------------------------------- 1 | # Language file for uk_UA 2 | # Wed May 21 19:58:20 EDT 2014 3 | colors.aqua=Голубий 4 | colors.black=Black 5 | colors.brightgreen=Сітло Зелений 6 | colors.darkaqua=Темно Голубий 7 | colors.darkblue=Темно Синій 8 | colors.darkgray=Темно Сірий 9 | colors.darkgreen=Темно Зелений 10 | colors.darkred=Темно Червоний 11 | colors.default=По замовч. 12 | colors.gold=Золотий 13 | colors.gray=Сірий 14 | colors.indigo=Індіго 15 | colors.pink=Рожевий 16 | colors.purple=Фіолетовий 17 | colors.red=Червоний 18 | colors.white=Білий 19 | colors.yellow=Жовтий 20 | 21 | delims.angles=<Кути> 22 | delims.anglesbracketscombo=<(Комбо)Pl.> 23 | delims.anglesparenscombo=<(Комбо)Pl.> 24 | delims.braces={Фігурні} 25 | delims.brackets=[Квадратні] 26 | delims.parenthesis=(Круглі) 27 | 28 | formats.bold=Жирний 29 | formats.default=По замовч. 30 | formats.italic=Курсив 31 | formats.magic=Magic 32 | formats.striked=Закреслений 33 | formats.underline=Підскреслений 34 | 35 | messages.update1=Знайдено оновлення\! (Поточна версія 36 | messages.update2=, нова 37 | messages.update3=Відвідайте форум TabbyChat на minecraftforum.net для оновлення. 38 | 39 | settings.advanced.chatboxunfocheight=Висота неактивного чату 40 | settings.advanced.chatfadeticks=Час зникнення (тік) 41 | settings.advanced.chatscrollhistory=Історія чату (лінії) 42 | settings.advanced.convertunicodetext=Convert unicode syntax 43 | settings.advanced.forceunicode=Юнікод рендеринг 44 | settings.advanced.maxlengthchannelname=Макс. довжина імені каналу 45 | settings.advanced.multichatdelay=Затримка відправлення у мультичат (Мс) 46 | settings.advanced.name=Додатково 47 | settings.advanced.textignoreopacity=Text ignores opacity setting 48 | 49 | settings.cancel=Відміна 50 | settings.delete=Видалити 51 | settings.new=Новий 52 | settings.save=Зберегти 53 | 54 | settings.channel.alias=Аліаси 55 | settings.channel.cmdprefix=Префікс команд чату 56 | settings.channel.hideprefix=Hide prefix while typing 57 | settings.channel.notificationson=Непрочитані повідомлення 58 | settings.channel.of=з 59 | settings.channel.position=Позиція\: 60 | 61 | settings.filters.audionotificationbool=Аудіо сповіщення 62 | settings.filters.audionotificationsound=Звук 63 | settings.filters.casesensitive=Враховувати регістр 64 | settings.filters.expressionstring=Вираз 65 | settings.filters.filtername=Ім'я Фільтру 66 | settings.filters.highlightbool=Підсвічувати співпадання 67 | settings.filters.highlightcolor=Колір 68 | settings.filters.highlightformat=Формат 69 | settings.filters.inversematch=Інвертувати 70 | settings.filters.name=Фільтри 71 | settings.filters.removematches=Ховати співпадання з чату 72 | settings.filters.sendtoalltabs=Всі вкладки 73 | settings.filters.sendtotabbool=Надсилати співпадання у вкладку 74 | settings.filters.sendtotabname=Ім'я Вкладки 75 | 76 | settings.general.groupspam=Групувати однакові повідомлення 77 | settings.general.name=Головне 78 | settings.general.savechatlog=Лог чату у файл 79 | settings.spelling.spellcheckenable=Enable Spell-checking 80 | settings.general.splitchatlog=Split log by channel 81 | settings.general.tabbychatenable=TabbyChat включений 82 | settings.general.timestampcolor=Колір відмітки часу 83 | settings.general.timestampenable=Відмітка часу чату 84 | settings.general.timestampstyle=Стиль відмітки часу 85 | settings.general.unreadflashing=Повідомлення про непрочитане 86 | settings.general.updatecheckenable=Check for Updates 87 | 88 | settings.server.autochannelsearch=Авто пошук нових каналів 89 | settings.server.autopmsearch=Enable PM tabs 90 | settings.server.defaultchannels=Канали по замовчуванні 91 | settings.server.delimcolorbool=Кольорові роздільники 92 | settings.server.delimformatbool=Форматовані роздільники 93 | settings.server.delimiterchars=Роздільник каналів 94 | settings.server.ignoredchannels=Канали, що ігноруються 95 | settings.server.name=Сервер 96 | settings.server.regexignorebool=Use patterns 97 | settings.server.pmtabregex.tome=PM Regex To Me 98 | settings.server.pmtabregex.fromme=PM Regex From Me 99 | 100 | settings.spelling.name=Spelling 101 | settings.spelling.userdictionary=User Dictionary 102 | settings.spelling.opendictionary=Open Dictionary 103 | settings.spelling.reloaddictionary=Reload 104 | 105 | sounds.anvil=Ковадло 106 | sounds.bass=Бас 107 | sounds.bat=Летюча Миша 108 | sounds.blast=Вибух 109 | sounds.blaze=Блейз 110 | sounds.bowhit=Стріла 111 | sounds.break=Зламав 112 | sounds.cat=Кіт 113 | sounds.chicken=Курка 114 | sounds.click=Клік 115 | sounds.cow=Корова 116 | sounds.dragon=Дракон 117 | sounds.endermen=Ендерман 118 | sounds.ghast=Гаст 119 | sounds.glass=Скло 120 | sounds.harp=Арфа 121 | sounds.orb=Досвід 122 | sounds.pig=Свиня 123 | sounds.pling=Pling 124 | sounds.splash=Сплеск 125 | sounds.swim=Спрут 126 | sounds.wolf=Вовк 127 | -------------------------------------------------------------------------------- /src/main/resources/assets/tabbychat/textures/gui/icons/copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mist475/tabbychat/bcda1aed7344a0a617cde55f8bd44a7fdfe5e3b4/src/main/resources/assets/tabbychat/textures/gui/icons/copy.png -------------------------------------------------------------------------------- /src/main/resources/assets/tabbychat/textures/gui/icons/cut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mist475/tabbychat/bcda1aed7344a0a617cde55f8bd44a7fdfe5e3b4/src/main/resources/assets/tabbychat/textures/gui/icons/cut.png -------------------------------------------------------------------------------- /src/main/resources/assets/tabbychat/textures/gui/icons/paste.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mist475/tabbychat/bcda1aed7344a0a617cde55f8bd44a7fdfe5e3b4/src/main/resources/assets/tabbychat/textures/gui/icons/paste.png -------------------------------------------------------------------------------- /src/main/resources/mcmod.info: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "modid": "${modId}", 4 | "name": "${modName}", 5 | "version": "${modVersion}", 6 | "mcversion": "${minecraftVersion}", 7 | "description": "SMP Chat Overhaul 8 | - Split chat into tabs 9 | - Custom filters w/ highlighting & sounds 10 | - Send multi-line messages 11 | - Add timestamps to chat 12 | - Log chat to file - Hide Spam 13 | - Customize chatbox size 14 | - Unread chat notifications", 15 | "url": "https://github.com/mist475/tabbychat", 16 | "authorList": ["RocketMan10404"], 17 | "credits": "Dykam and Killjoy1221 for updating to 1.7, mist475 for build script update", 18 | "logoFile": "", 19 | "screenshots": [] 20 | } 21 | ] 22 | --------------------------------------------------------------------------------