├── logo.png ├── gradle ├── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties └── libs.versions.toml ├── mod └── src │ └── main │ ├── java │ └── io │ │ └── github │ │ └── homchom │ │ └── recode │ │ ├── sys │ │ ├── file │ │ │ ├── ISave.java │ │ │ ├── ILoader.java │ │ │ ├── FileUtil.java │ │ │ └── ExternalFile.java │ │ ├── networking │ │ │ └── websocket │ │ │ │ └── client │ │ │ │ ├── type │ │ │ │ ├── SocketItem.java │ │ │ │ ├── TemplateItem.java │ │ │ │ ├── RawTemplateItem.java │ │ │ │ └── NbtItem.java │ │ │ │ └── WebsocketServer.java │ │ ├── util │ │ │ ├── TimerUtil.java │ │ │ └── SoundUtil.java │ │ ├── hypercube │ │ │ ├── codeaction │ │ │ │ ├── Types.java │ │ │ │ ├── TagOption.java │ │ │ │ ├── CodeBlock.java │ │ │ │ ├── Tag.java │ │ │ │ └── Action.java │ │ │ └── templates │ │ │ │ ├── TemplateItem.java │ │ │ │ └── CompressionUtil.java │ │ ├── player │ │ │ ├── chat │ │ │ │ ├── ChatType.java │ │ │ │ ├── MessageGrabberTask.java │ │ │ │ └── color │ │ │ │ │ ├── ColorUtil.java │ │ │ │ │ └── HSBColor.java │ │ │ └── DFInfo.java │ │ └── renderer │ │ │ ├── IMenu.java │ │ │ ├── ToasterUtil.java │ │ │ ├── widgets │ │ │ ├── ItemGridPanel.java │ │ │ ├── CText.java │ │ │ ├── ClickableGiveItem.java │ │ │ ├── CColoredRectangle.java │ │ │ ├── ItemScrollablePanel.java │ │ │ ├── CButton.java │ │ │ └── CColorPreset.java │ │ │ └── RenderUtil.java │ │ ├── mod │ │ ├── config │ │ │ ├── structure │ │ │ │ ├── IAdvancedSetting.java │ │ │ │ ├── IRawKey.java │ │ │ │ ├── IRawTranslation.java │ │ │ │ └── ConfigGroup.java │ │ │ ├── types │ │ │ │ ├── IConfigEnum.java │ │ │ │ ├── IConfigDropdownEnum.java │ │ │ │ ├── list │ │ │ │ │ ├── StringListSetting.java │ │ │ │ │ └── ListSetting.java │ │ │ │ ├── SoundSetting.java │ │ │ │ ├── LongSetting.java │ │ │ │ ├── FloatSetting.java │ │ │ │ ├── DoubleSetting.java │ │ │ │ ├── BooleanSetting.java │ │ │ │ ├── IntegerSetting.java │ │ │ │ ├── TextDescription.java │ │ │ │ ├── DynamicStringSetting.java │ │ │ │ ├── StringSetting.java │ │ │ │ ├── hud │ │ │ │ │ ├── HudData.java │ │ │ │ │ └── PositionSetting.java │ │ │ │ ├── DropdownSetting.java │ │ │ │ └── EnumSetting.java │ │ │ ├── internal │ │ │ │ ├── DestroyItemResetType.java │ │ │ │ ├── ITranslatable.java │ │ │ │ ├── ConfigInstruction.java │ │ │ │ └── gson │ │ │ │ │ └── types │ │ │ │ │ ├── EnumSerializer.java │ │ │ │ │ ├── SoundSerializer.java │ │ │ │ │ ├── list │ │ │ │ │ └── StringListSerializer.java │ │ │ │ │ ├── DynamicStringSerializer.java │ │ │ │ │ ├── StringSerializer.java │ │ │ │ │ ├── BooleanSerializer.java │ │ │ │ │ ├── LongSerializer.java │ │ │ │ │ ├── FloatSerializer.java │ │ │ │ │ ├── DoubleSerializer.java │ │ │ │ │ └── IntegerSerializer.java │ │ │ ├── ModMenuIntegration.java │ │ │ └── impl │ │ │ │ ├── KeybindsGroup.java │ │ │ │ ├── AutomationGroup.java │ │ │ │ ├── HidingGroup.java │ │ │ │ ├── CommandsGroup.java │ │ │ │ ├── SidedChatGroup.java │ │ │ │ ├── HighlightGroup.java │ │ │ │ └── MiscellaneousGroup.java │ │ ├── features │ │ │ ├── commands │ │ │ │ ├── nbs │ │ │ │ │ └── exceptions │ │ │ │ │ │ └── OutdatedNBSException.java │ │ │ │ ├── recode │ │ │ │ │ ├── LegacyFeature.java │ │ │ │ │ └── Contributor.java │ │ │ │ ├── image │ │ │ │ │ └── ParticleImage.java │ │ │ │ └── TemplatesMenu.java │ │ │ ├── streamer │ │ │ │ └── StreamerModeMessageCheck.java │ │ │ ├── social │ │ │ │ └── chat │ │ │ │ │ ├── message │ │ │ │ │ ├── finalizers │ │ │ │ │ │ ├── MessageGrabberFinalizer.java │ │ │ │ │ │ ├── DebugFinalizer.java │ │ │ │ │ │ └── StreamerModeFinalizer.java │ │ │ │ │ ├── checks │ │ │ │ │ │ ├── AdminCheck.java │ │ │ │ │ │ ├── SilentPunishmentCheck.java │ │ │ │ │ │ ├── SpiesCheck.java │ │ │ │ │ │ ├── StreamerModeRegexCheck.java │ │ │ │ │ │ ├── ModerationCheck.java │ │ │ │ │ │ ├── SupportCheck.java │ │ │ │ │ │ ├── JoinFailCheck.java │ │ │ │ │ │ ├── PlotAdCheck.java │ │ │ │ │ │ ├── PlotBoostCheck.java │ │ │ │ │ │ ├── TeleportCheck.java │ │ │ │ │ │ ├── ScanningCheck.java │ │ │ │ │ │ ├── SupportAnswerCheck.java │ │ │ │ │ │ ├── IncomingReportCheck.java │ │ │ │ │ │ ├── SupportQuestionCheck.java │ │ │ │ │ │ ├── BuycraftXUpdateCheck.java │ │ │ │ │ │ └── DirectMessageCheck.java │ │ │ │ │ ├── MessageFinalizer.java │ │ │ │ │ └── LegacyMessageType.java │ │ │ │ │ └── ConversationTimer.java │ │ │ └── keybinds │ │ │ │ └── FlightSpeedToggle.java │ │ ├── commands │ │ │ ├── arguments │ │ │ │ ├── StringReaders.java │ │ │ │ ├── ArgBuilder.java │ │ │ │ └── types │ │ │ │ │ ├── PlayerArgumentType.java │ │ │ │ │ └── ChoiceArgumentType.java │ │ │ ├── IManager.java │ │ │ └── impl │ │ │ │ ├── image │ │ │ │ └── AbstractImageCommand.java │ │ │ │ ├── other │ │ │ │ ├── PingCommand.java │ │ │ │ └── RecodeCommand.java │ │ │ │ ├── text │ │ │ │ └── CopyTextCommand.java │ │ │ │ └── item │ │ │ │ ├── TemplatesCommand.java │ │ │ │ ├── CodeVaultCommand.java │ │ │ │ └── template │ │ │ │ └── AbstractTemplateCommand.java │ │ ├── mixin │ │ │ ├── render │ │ │ │ ├── MScreen.java │ │ │ │ ├── MStitcher.java │ │ │ │ ├── MWindow.java │ │ │ │ ├── MChatScreen.java │ │ │ │ └── MChestRenderer.java │ │ │ ├── game │ │ │ │ └── MMinecraftClient.java │ │ │ ├── message │ │ │ │ └── MReceivedSound.java │ │ │ └── inventory │ │ │ │ ├── MItemCreative.java │ │ │ │ └── MItemInsert.java │ │ └── events │ │ │ ├── impl │ │ │ ├── LegacyReceiveSoundEvent.java │ │ │ ├── LegacyJoinEvent.java │ │ │ └── LegacyChangeStateEvent.java │ │ │ └── LegacyEventHandler.java │ │ ├── io │ │ └── OperatingSystem.kt │ │ ├── feature │ │ ├── meta │ │ │ └── DebugMode.kt │ │ ├── visual │ │ │ ├── MessageStacking.kt │ │ │ ├── SignRenderDistance.kt │ │ │ ├── BuiltInResourcePacks.kt │ │ │ └── CodeSearch.kt │ │ └── Feature.kt │ │ ├── hypercube │ │ ├── BukkitFunctions.kt │ │ ├── state │ │ │ ├── Permissions.kt │ │ │ └── Ranks.kt │ │ ├── HypercubeConstants.kt │ │ └── DFMiniMessage.kt │ │ ├── multiplayer │ │ ├── MultiplayerRegex.kt │ │ └── CommandQueue.kt │ │ ├── util │ │ ├── TraitInterfaces.kt │ │ ├── std │ │ │ ├── CollectionsFunctions.kt │ │ │ └── StdlibFunctions.kt │ │ ├── regex │ │ │ ├── RegexFunctions.kt │ │ │ ├── DynamicRegex.kt │ │ │ └── RegexModifiers.kt │ │ ├── math │ │ │ ├── Measurements.kt │ │ │ └── Arithmetic.kt │ │ ├── GenericWrappers.kt │ │ ├── WordCases.kt │ │ ├── coroutines │ │ │ ├── CoroutinesFunctions.kt │ │ │ └── Continuations.kt │ │ ├── Computation.kt │ │ └── Matcher.kt │ │ ├── mixin │ │ ├── game │ │ │ └── ItemStackAccessor.java │ │ ├── ui │ │ │ └── FontInvoker.java │ │ ├── ConditionalMixins.kt │ │ ├── render │ │ │ ├── MWindow.java │ │ │ ├── MBlockEntityRenderDispatcher.java │ │ │ ├── chat │ │ │ │ └── MChatScreen.java │ │ │ └── MGui.java │ │ ├── MMinecraft.java │ │ ├── multiplayer │ │ │ └── MConnection.java │ │ └── MixinConfig.kt │ │ ├── CommonGlobals.kt │ │ ├── render │ │ ├── StaticSkinRender.kt │ │ ├── text │ │ │ ├── FormattedCharSequenceManipulation.kt │ │ │ └── FormattedCharSequenceExtensions.kt │ │ ├── Blaze3DExtensions.kt │ │ ├── RenderDucks.kt │ │ └── ScreenEvents.kt │ │ ├── ModConstants.kt │ │ ├── ui │ │ ├── screen │ │ │ └── DummyScreen.kt │ │ └── text │ │ │ └── MiniMessageFunctions.kt │ │ ├── event │ │ ├── EventWrapper.kt │ │ ├── Validation.kt │ │ └── EventTransformations.kt │ │ ├── game │ │ ├── GameEvents.kt │ │ ├── ItemExtensions.kt │ │ ├── NBTExtensions.kt │ │ └── GameTime.kt │ │ ├── CodeInitializer.java │ │ ├── Logging.kt │ │ └── config │ │ └── Config.kt │ └── resources │ ├── assets │ ├── recode │ │ └── textures │ │ │ ├── gui │ │ │ ├── recode.png │ │ │ └── sprites │ │ │ │ └── icon │ │ │ │ └── df.png │ │ │ └── font │ │ │ └── puaa_8x8.png │ └── minecraft │ │ └── font │ │ └── default.json │ ├── resourcepacks │ └── better_unicode │ │ ├── pack.png │ │ ├── pack.mcmeta │ │ └── assets │ │ └── minecraft │ │ └── textures │ │ └── font │ │ ├── bu_arrows.png │ │ ├── bu_chess.png │ │ ├── bu_zodiac.png │ │ ├── bu_planetary.png │ │ ├── bu_page5_12x12.png │ │ ├── bu_page5_9x12.png │ │ ├── bu_page7_12x12.png │ │ └── bu_page7_9x12.png │ ├── high_contrast │ └── assets │ │ └── recode │ │ └── textures │ │ └── gui │ │ └── sprites │ │ └── icon │ │ └── df.png │ ├── recode.mixins.json │ ├── recodeLegacy.mixins.json │ └── fabric_mod_json_template.txt ├── ATTRIBUTION.md ├── .gitignore ├── settings.gradle.kts ├── CHANGELOG.md ├── .github └── workflows │ └── build.yml └── gradle.properties /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/homchom/recode/HEAD/logo.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/homchom/recode/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/file/ISave.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.file; 2 | 3 | public interface ISave { 4 | void save(); 5 | } 6 | -------------------------------------------------------------------------------- /mod/src/main/resources/assets/recode/textures/gui/recode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/homchom/recode/HEAD/mod/src/main/resources/assets/recode/textures/gui/recode.png -------------------------------------------------------------------------------- /mod/src/main/resources/resourcepacks/better_unicode/pack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/homchom/recode/HEAD/mod/src/main/resources/resourcepacks/better_unicode/pack.png -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/file/ILoader.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.file; 2 | 3 | public interface ILoader { 4 | void load(); 5 | } 6 | -------------------------------------------------------------------------------- /mod/src/main/resources/assets/recode/textures/font/puaa_8x8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/homchom/recode/HEAD/mod/src/main/resources/assets/recode/textures/font/puaa_8x8.png -------------------------------------------------------------------------------- /mod/src/main/resources/assets/recode/textures/gui/sprites/icon/df.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/homchom/recode/HEAD/mod/src/main/resources/assets/recode/textures/gui/sprites/icon/df.png -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/structure/IAdvancedSetting.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.structure; 2 | 3 | public interface IAdvancedSetting { 4 | } 5 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/types/IConfigEnum.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.types; 2 | 3 | public interface IConfigEnum { 4 | 5 | String getKey(); 6 | } 7 | -------------------------------------------------------------------------------- /mod/src/main/resources/high_contrast/assets/recode/textures/gui/sprites/icon/df.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/homchom/recode/HEAD/mod/src/main/resources/high_contrast/assets/recode/textures/gui/sprites/icon/df.png -------------------------------------------------------------------------------- /mod/src/main/resources/resourcepacks/better_unicode/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "pack_format": 22, 4 | "description": "vanilla-style unicode symbols.\n§8BetterUnicode by Electrosolt" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/io/OperatingSystem.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.io 2 | 3 | import oshi.PlatformEnum 4 | import oshi.SystemInfo 5 | 6 | val platform: PlatformEnum get() = SystemInfo.getCurrentPlatform() -------------------------------------------------------------------------------- /mod/src/main/resources/resourcepacks/better_unicode/assets/minecraft/textures/font/bu_arrows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/homchom/recode/HEAD/mod/src/main/resources/resourcepacks/better_unicode/assets/minecraft/textures/font/bu_arrows.png -------------------------------------------------------------------------------- /mod/src/main/resources/resourcepacks/better_unicode/assets/minecraft/textures/font/bu_chess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/homchom/recode/HEAD/mod/src/main/resources/resourcepacks/better_unicode/assets/minecraft/textures/font/bu_chess.png -------------------------------------------------------------------------------- /mod/src/main/resources/resourcepacks/better_unicode/assets/minecraft/textures/font/bu_zodiac.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/homchom/recode/HEAD/mod/src/main/resources/resourcepacks/better_unicode/assets/minecraft/textures/font/bu_zodiac.png -------------------------------------------------------------------------------- /mod/src/main/resources/resourcepacks/better_unicode/assets/minecraft/textures/font/bu_planetary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/homchom/recode/HEAD/mod/src/main/resources/resourcepacks/better_unicode/assets/minecraft/textures/font/bu_planetary.png -------------------------------------------------------------------------------- /mod/src/main/resources/resourcepacks/better_unicode/assets/minecraft/textures/font/bu_page5_12x12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/homchom/recode/HEAD/mod/src/main/resources/resourcepacks/better_unicode/assets/minecraft/textures/font/bu_page5_12x12.png -------------------------------------------------------------------------------- /mod/src/main/resources/resourcepacks/better_unicode/assets/minecraft/textures/font/bu_page5_9x12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/homchom/recode/HEAD/mod/src/main/resources/resourcepacks/better_unicode/assets/minecraft/textures/font/bu_page5_9x12.png -------------------------------------------------------------------------------- /mod/src/main/resources/resourcepacks/better_unicode/assets/minecraft/textures/font/bu_page7_12x12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/homchom/recode/HEAD/mod/src/main/resources/resourcepacks/better_unicode/assets/minecraft/textures/font/bu_page7_12x12.png -------------------------------------------------------------------------------- /mod/src/main/resources/resourcepacks/better_unicode/assets/minecraft/textures/font/bu_page7_9x12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/homchom/recode/HEAD/mod/src/main/resources/resourcepacks/better_unicode/assets/minecraft/textures/font/bu_page7_9x12.png -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/types/IConfigDropdownEnum.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.types; 2 | 3 | public interface IConfigDropdownEnum { 4 | 5 | String getName(); 6 | 7 | T[] getValues(); 8 | } 9 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/commands/nbs/exceptions/OutdatedNBSException.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.commands.nbs.exceptions; 2 | 3 | public class OutdatedNBSException extends Exception { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/streamer/StreamerModeMessageCheck.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.streamer; 2 | 3 | public interface StreamerModeMessageCheck { 4 | 5 | boolean streamerHideEnabled(); 6 | } 7 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/feature/meta/DebugMode.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.feature.meta 2 | 3 | import io.github.homchom.recode.config.Setting 4 | 5 | object FDebugMode : Setting { 6 | override val configString = "debugMode" 7 | } -------------------------------------------------------------------------------- /ATTRIBUTION.md: -------------------------------------------------------------------------------- 1 | The following file contains attribution not inherently found elsewhere in the project. 2 | 3 | ### Textures 4 | 5 | - 16x16 DiamondFire logo by baconiumo, based on a logo by MrGarretto 6 | - recode unicode character by Electrosolt, based on a logo by bignutty -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/feature/visual/MessageStacking.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.feature.visual 2 | 3 | import io.github.homchom.recode.config.Setting 4 | 5 | object FMessageStacking : Setting { 6 | override val configString = "stackDuplicateMsgs" 7 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/hypercube/BukkitFunctions.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.hypercube 2 | 3 | import io.github.homchom.recode.game.getCompoundOrNull 4 | import net.minecraft.nbt.CompoundTag 5 | 6 | val CompoundTag.publicBukkitValues get() = getCompoundOrNull("PublicBukkitValues") -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Gradle 2 | .gradle/ 3 | build/ 4 | out/ 5 | classes/ 6 | gradle/wrapper/gradle-wrapper.properties 7 | 8 | # IDEA 9 | .idea/ 10 | *.iml 11 | *.ipr 12 | *.iws 13 | 14 | # VSCode 15 | .settings/ 16 | .vscode/ 17 | bin/ 18 | .classpath 19 | .project 20 | 21 | # Fabric 22 | run/ 23 | logs/ 24 | *.launch 25 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/multiplayer/MultiplayerRegex.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.multiplayer 2 | 3 | import io.github.homchom.recode.util.regex.RegexPatternBuilder 4 | 5 | fun RegexPatternBuilder.username(string: String? = null) = 6 | if (string.isNullOrEmpty()) wordChar * (3..16) else str(string) -------------------------------------------------------------------------------- /mod/src/main/resources/assets/minecraft/font/default.json: -------------------------------------------------------------------------------- 1 | { 2 | "providers": [ 3 | { 4 | "type": "bitmap", 5 | "file": "recode:font/puaa_8x8.png", 6 | "height": 8, 7 | "ascent": 7, 8 | "chars": [ 9 | "\udb9c\ude65" 10 | ] 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/hypercube/state/Permissions.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.hypercube.state 2 | 3 | class PermissionGroup(ranks: Iterable) { 4 | val ranks = ranks.toSet() 5 | 6 | inline operator fun contains(rankPermission: P) 7 | where P : Rank, P : Comparable

= 8 | ranks.any { it is P && it >= rankPermission } 9 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/util/TraitInterfaces.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.util 2 | 3 | /** 4 | * A wrapper for a [value] of type [T] that can be unboxed with [invoke]. 5 | */ 6 | interface InvokableWrapper { 7 | val value: T 8 | 9 | /** 10 | * Unboxes and returns [value]. 11 | */ 12 | operator fun invoke() = value 13 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/util/std/CollectionsFunctions.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.util.std 2 | 3 | /** 4 | * Maps this list into an [Array]. 5 | * 6 | * @see map 7 | */ 8 | inline fun Collection.mapToArray(transform: (T) -> R): Array { 9 | val iterator = iterator() 10 | return Array(size) { transform(iterator.next()) } 11 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/structure/IRawKey.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.structure; 2 | 3 | import java.util.Optional; 4 | 5 | public interface IRawKey { 6 | default T setKeyName(String key) { 7 | return null; 8 | } 9 | 10 | default Optional getKeyName() { 11 | return Optional.empty(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/types/list/StringListSetting.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.types.list; 2 | 3 | public class StringListSetting extends ListSetting { 4 | public StringListSetting() { 5 | } 6 | 7 | public StringListSetting(String key, String... defaultValue) { 8 | super(key, defaultValue); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/util/regex/RegexFunctions.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.util.regex 2 | 3 | /** 4 | * Gets the value of this MatchResult's group with name [name]. For consistency with [MatchResult.groupValues], 5 | * if a group with this name does not exist, an empty string is returned instead. 6 | */ 7 | fun MatchResult.groupValue(name: String) = groups[name]?.value ?: "" -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/types/SoundSetting.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.types; 2 | 3 | import io.github.homchom.recode.mod.config.ConfigSounds; 4 | 5 | public class SoundSetting extends DropdownSetting { 6 | 7 | public SoundSetting(String key) { 8 | super(key, DropdownSetting.fromEnum(ConfigSounds.NONE)); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/networking/websocket/client/type/SocketItem.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.networking.websocket.client.type; 2 | 3 | import net.minecraft.world.item.ItemStack; 4 | 5 | public abstract class SocketItem { 6 | 7 | public abstract String getIdentifier(); 8 | 9 | public abstract ItemStack getItem(String data) throws Exception; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/types/LongSetting.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.types; 2 | 3 | import io.github.homchom.recode.mod.config.structure.ConfigSetting; 4 | 5 | public class LongSetting extends ConfigSetting { 6 | public LongSetting() { 7 | } 8 | 9 | public LongSetting(String key, Long defaultValue) { 10 | super(key, defaultValue); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/types/FloatSetting.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.types; 2 | 3 | import io.github.homchom.recode.mod.config.structure.ConfigSetting; 4 | 5 | public class FloatSetting extends ConfigSetting { 6 | public FloatSetting() { 7 | } 8 | 9 | public FloatSetting(String key, Float defaultValue) { 10 | super(key, defaultValue); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/types/DoubleSetting.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.types; 2 | 3 | import io.github.homchom.recode.mod.config.structure.ConfigSetting; 4 | 5 | public class DoubleSetting extends ConfigSetting { 6 | public DoubleSetting() { 7 | } 8 | 9 | public DoubleSetting(String key, Double defaultValue) { 10 | super(key, defaultValue); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/commands/arguments/StringReaders.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.commands.arguments; 2 | 3 | import com.mojang.brigadier.StringReader; 4 | 5 | public class StringReaders { 6 | public static String readRemaining(StringReader reader) { 7 | final String text = reader.getRemaining(); 8 | reader.setCursor(reader.getTotalLength()); 9 | return text; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/internal/DestroyItemResetType.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.internal; 2 | 3 | import io.github.homchom.recode.mod.config.types.IConfigEnum; 4 | 5 | public enum DestroyItemResetType implements IConfigEnum { 6 | OFF, 7 | STANDARD, 8 | COMPACT; 9 | 10 | @Override 11 | public String getKey() { 12 | return "destroyitemresettype"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/types/BooleanSetting.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.types; 2 | 3 | import io.github.homchom.recode.mod.config.structure.ConfigSetting; 4 | 5 | public class BooleanSetting extends ConfigSetting { 6 | public BooleanSetting() { 7 | } 8 | 9 | public BooleanSetting(String key, Boolean defaultValue) { 10 | super(key, defaultValue); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/types/IntegerSetting.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.types; 2 | 3 | import io.github.homchom.recode.mod.config.structure.ConfigSetting; 4 | 5 | public class IntegerSetting extends ConfigSetting { 6 | public IntegerSetting() { 7 | } 8 | 9 | public IntegerSetting(String key, Integer defaultValue) { 10 | super(key, defaultValue); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/types/TextDescription.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.types; 2 | 3 | import io.github.homchom.recode.mod.config.structure.ConfigSetting; 4 | import net.minecraft.network.chat.Component; 5 | 6 | public class TextDescription extends ConfigSetting { 7 | 8 | public TextDescription(String key) { 9 | super(key, Component.literal("")); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/hypercube/state/Ranks.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.hypercube.state 2 | 3 | import io.github.homchom.recode.hypercube.DIAMOND 4 | 5 | sealed interface Rank { 6 | val displayName: String 7 | } 8 | 9 | enum class DonorRank(override val displayName: String) : Rank { 10 | NOBLE("Noble"), 11 | EMPEROR("Emperor"), 12 | MYTHIC("Mythic"), 13 | OVERLORD("${DIAMOND}Overlord${DIAMOND}") 14 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/internal/ITranslatable.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.internal; 2 | 3 | import net.minecraft.network.chat.Component; 4 | 5 | public interface ITranslatable { 6 | default Component getTranslation(String key) { 7 | return ITranslatable.get(key); 8 | } 9 | 10 | static Component get(String key) { 11 | return Component.translatable(key); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/util/math/Measurements.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.util.math 2 | 3 | import kotlin.time.Duration 4 | 5 | /** 6 | * Creates a [Frequency]. 7 | */ 8 | infix fun Int.per(interval: Duration) = Frequency(this, interval) 9 | 10 | /** 11 | * A data structure that represents a frequency of [occurrences] occurrences per [interval]. 12 | */ 13 | data class Frequency(val occurrences: Int, val interval: Duration) -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/networking/websocket/client/type/TemplateItem.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.networking.websocket.client.type; 2 | 3 | public class TemplateItem extends AbstractTemplateItem { 4 | 5 | @Override 6 | public String getIdentifier() { 7 | return "template"; 8 | } 9 | 10 | @Override 11 | public String parseJsonData(String templateData) { 12 | return templateData; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/hypercube/HypercubeConstants.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("HypercubeConstants") 2 | 3 | package io.github.homchom.recode.hypercube 4 | 5 | const val SERVER_ADDRESS = "mcdiamondfire.com" 6 | 7 | const val DIAMOND = '◆' 8 | const val MAIN_ARROW = '»' 9 | const val RIGHT_ARROW = '→' 10 | const val SUPPORT_ARROW = '▶' 11 | const val BOOSTER_ARROW = '⏵' 12 | 13 | const val TOKEN_NOTCH_CHAR = '□' 14 | 15 | const val LAGSLAYER_PREFIX = """[LagSlayer]""" -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/types/DynamicStringSetting.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.types; 2 | 3 | public class DynamicStringSetting extends StringSetting { 4 | public DynamicStringSetting() { 5 | } 6 | 7 | public DynamicStringSetting(String key) { 8 | super(key, ""); 9 | } 10 | 11 | public DynamicStringSetting(String key, String defaultValue) { 12 | super(key, defaultValue); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/util/TimerUtil.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.util; 2 | 3 | public class TimerUtil { 4 | 5 | public static void setTimeout(Runnable runnable, int delay){ 6 | new Thread(() -> { 7 | try { 8 | Thread.sleep(delay); 9 | runnable.run(); 10 | } 11 | catch (Exception e){ 12 | e.printStackTrace(); 13 | } 14 | }).start(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/hypercube/codeaction/Types.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.hypercube.codeaction; 2 | 3 | public class Types { 4 | private final String id; 5 | private final String color; 6 | 7 | Types(String id, String color){ 8 | this.id = id; 9 | this.color = color; 10 | } 11 | 12 | public String getColor() { 13 | return color; 14 | } 15 | 16 | public String getName() { 17 | return id; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/ModMenuIntegration.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config; 2 | 3 | import com.terraformersmc.modmenu.api.ConfigScreenFactory; 4 | import com.terraformersmc.modmenu.api.ModMenuApi; 5 | import io.github.homchom.recode.mod.config.menu.ConfigScreen; 6 | 7 | public class ModMenuIntegration implements ModMenuApi { 8 | @Override 9 | public ConfigScreenFactory getModConfigScreenFactory() { 10 | return ConfigScreen::getScreen; 11 | } 12 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/file/FileUtil.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.file; 2 | 3 | import java.io.IOException; 4 | import java.nio.charset.Charset; 5 | import java.nio.file.Files; 6 | import java.nio.file.Paths; 7 | 8 | public class FileUtil { 9 | public static String readFile(String path, Charset encoding) 10 | throws IOException { 11 | byte[] encoded = Files.readAllBytes(Paths.get(path)); 12 | return new String(encoded, encoding); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mixin/game/ItemStackAccessor.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mixin.game; 2 | 3 | import net.minecraft.network.chat.Style; 4 | import net.minecraft.world.item.ItemStack; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.gen.Accessor; 7 | 8 | @Mixin(ItemStack.class) 9 | public interface ItemStackAccessor { 10 | @Accessor("LORE_STYLE") 11 | static Style getLoreVanillaStyle() { 12 | throw new AssertionError(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mixin/ui/FontInvoker.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mixin.ui; 2 | 3 | import net.minecraft.client.gui.Font; 4 | import net.minecraft.client.gui.font.FontSet; 5 | import net.minecraft.resources.ResourceLocation; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.gen.Invoker; 8 | 9 | @Mixin(Font.class) 10 | public interface FontInvoker { 11 | @Invoker("getFontSet") 12 | FontSet invokeGetFontSet(ResourceLocation resourceLocation); 13 | } 14 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/types/StringSetting.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.types; 2 | 3 | import io.github.homchom.recode.mod.config.structure.ConfigSetting; 4 | 5 | public class StringSetting extends ConfigSetting { 6 | public StringSetting() { 7 | } 8 | 9 | public StringSetting(String key) { 10 | super(key, ""); 11 | } 12 | 13 | public StringSetting(String key, String defaultValue) { 14 | super(key, defaultValue); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | val modName: String by settings 2 | 3 | rootProject.name = modName 4 | 5 | include("mod") 6 | 7 | pluginManagement { 8 | repositories { 9 | mavenCentral() 10 | gradlePluginPortal() 11 | } 12 | } 13 | 14 | // https://github.com/FabricMC/fabric-loom/issues/1122 and https://github.com/gradle/gradle/issues/1370 15 | buildscript { 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | classpath("com.google.code.gson:gson:2.10.1") 22 | } 23 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/commands/recode/LegacyFeature.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.commands.recode; 2 | 3 | public class LegacyFeature { 4 | private final String name; 5 | private final String description; 6 | 7 | public LegacyFeature(String name, String description) { 8 | this.name = name; 9 | this.description = description; 10 | } 11 | 12 | public String getName() { 13 | return name; 14 | } 15 | 16 | public String getDescription() { 17 | return description; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/types/hud/HudData.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.types.hud; 2 | 3 | public class HudData { 4 | private int x; 5 | private int y; 6 | 7 | public HudData(int x, int y) { 8 | 9 | this.x = x; 10 | this.y = y; 11 | } 12 | 13 | public int getX() { 14 | return x; 15 | } 16 | 17 | public void setX(int x) { 18 | this.x = x; 19 | } 20 | 21 | public int getY() { 22 | return y; 23 | } 24 | 25 | public void setY(int y) { 26 | this.y = y; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/util/GenericWrappers.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.util 2 | 3 | /** 4 | * A wrapper for [T]. Useful in generic contexts of a non-nullable upper bound. 5 | */ 6 | data class Case(val content: T) { 7 | companion object { 8 | val ofNull = Case(null) 9 | } 10 | 11 | /** 12 | * Unwraps and returns [content]. 13 | */ 14 | operator fun invoke() = content 15 | } 16 | 17 | /** 18 | * @see Case 19 | */ 20 | data class MutableCase(var content: T) { 21 | /** 22 | * Unwraps and returns [content]. 23 | */ 24 | operator fun invoke() = content 25 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/hypercube/codeaction/TagOption.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.hypercube.codeaction; 2 | 3 | import com.google.gson.JsonObject; 4 | 5 | public class TagOption { 6 | private final String name; 7 | private final DisplayItem icon; 8 | 9 | TagOption(JsonObject jsonObject){ 10 | this.name = jsonObject.get("name").getAsString(); 11 | this.icon = new DisplayItem(jsonObject.getAsJsonObject("icon")); 12 | } 13 | 14 | public String getName() { 15 | return name; 16 | } 17 | 18 | public DisplayItem getIcon() { 19 | return icon; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/CommonGlobals.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("Globals") 2 | 3 | package io.github.homchom.recode 4 | 5 | import io.github.homchom.recode.config.Config 6 | import io.github.homchom.recode.feature.meta.FDebugMode 7 | import net.minecraft.SharedConstants 8 | import net.minecraft.client.Minecraft 9 | 10 | val mc: Minecraft get() = Minecraft.getInstance() 11 | 12 | // TODO: should this be built into a higher level extension function instead? 13 | val currentDataVersion get() = SharedConstants.getCurrentVersion().dataVersion.version 14 | 15 | // TODO: remove false positives during config rework 16 | val debug: Boolean get() = Config[FDebugMode] ?: true -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/player/chat/ChatType.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.player.chat; 2 | 3 | public enum ChatType { 4 | SUCCESS("§a§l»", 'f'), 5 | FAIL("§4§l»", 'c'), 6 | INFO_YELLOW("§6§l»", 'e'), 7 | INFO_BLUE("§9§l»", 'b'); 8 | 9 | private final String prefix; 10 | private final char trailing; 11 | 12 | ChatType(String prefix, char trailing) { 13 | this.prefix = prefix; 14 | this.trailing = trailing; 15 | } 16 | 17 | public String getString() { 18 | return this.prefix; 19 | } 20 | 21 | public char getTrailing() { 22 | return trailing; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/structure/IRawTranslation.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.structure; 2 | 3 | import net.minecraft.network.chat.Component; 4 | 5 | import java.util.Optional; 6 | 7 | public interface IRawTranslation extends IRawKey { 8 | default T setRawKey(String key) { 9 | return null; 10 | } 11 | 12 | default Optional getRawKey() { 13 | return Optional.empty(); 14 | } 15 | 16 | default T setRawTooltip(String key) { 17 | return null; 18 | } 19 | 20 | default Optional getRawTooltip() { 21 | return Optional.empty(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/mixin/render/MScreen.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.mixin.render; 2 | 3 | import io.github.homchom.recode.LegacyRecode; 4 | import net.minecraft.client.gui.screens.Screen; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.injection.At; 7 | import org.spongepowered.asm.mixin.injection.Inject; 8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 9 | 10 | @Mixin(Screen.class) 11 | public class MScreen { 12 | 13 | @Inject(method = "onClose", at = @At("HEAD")) 14 | private void onClose(CallbackInfo ci) { 15 | LegacyRecode.signText = new String[0]; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/finalizers/MessageGrabberFinalizer.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message.finalizers; 2 | 3 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessage; 4 | import io.github.homchom.recode.mod.features.social.chat.message.MessageFinalizer; 5 | import io.github.homchom.recode.sys.player.chat.MessageGrabber; 6 | 7 | public class MessageGrabberFinalizer extends MessageFinalizer { 8 | 9 | @Override 10 | protected void receive(LegacyMessage message) { 11 | if (MessageGrabber.isActive()) { 12 | MessageGrabber.supply(message); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/util/std/StdlibFunctions.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("BasicTypeExtensions") 2 | 3 | package io.github.homchom.recode.util.std 4 | 5 | // booleans 6 | 7 | /** 8 | * @return [Unit] if this boolean is true, or `null` otherwise. 9 | */ 10 | fun Boolean.unitOrNull() = if (this) Unit else null 11 | 12 | // strings 13 | 14 | /** 15 | * @see Character.toString 16 | */ 17 | fun String.Companion.fromCodePoint(codePoint: Int): String = Character.toString(codePoint) 18 | 19 | /** 20 | * Appends multiple [substrings] to this [StringBuilder]. 21 | */ 22 | fun StringBuilder.interpolate(vararg substrings: String) = apply { 23 | for (substring in substrings) append(substring) 24 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/mixin/render/MStitcher.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.mixin.render; 2 | 3 | import net.minecraft.client.renderer.texture.Stitcher; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.Shadow; 6 | import org.spongepowered.asm.mixin.injection.At; 7 | import org.spongepowered.asm.mixin.injection.Inject; 8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 9 | 10 | @Mixin(Stitcher.class) 11 | public class MStitcher { 12 | @Shadow private int storageY; 13 | 14 | @Inject(method = "stitch", at = @At("RETURN")) 15 | private void stitch(CallbackInfo ci) { 16 | storageY *= 2; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/internal/ConfigInstruction.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.internal; 2 | 3 | import io.github.homchom.recode.mod.config.structure.ConfigSetting; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | public class ConfigInstruction { 9 | private final Map> settingMap = new HashMap<>(); 10 | 11 | public boolean isEmpty() { 12 | return settingMap.isEmpty(); 13 | } 14 | 15 | public void put(String key, ConfigSetting value) { 16 | this.settingMap.put(key, value); 17 | } 18 | 19 | public Map> getSettingMap() { 20 | return settingMap; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/internal/gson/types/EnumSerializer.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.internal.gson.types; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.JsonPrimitive; 5 | import com.google.gson.JsonSerializationContext; 6 | import com.google.gson.JsonSerializer; 7 | import io.github.homchom.recode.mod.config.types.EnumSetting; 8 | 9 | import java.lang.reflect.Type; 10 | 11 | public class EnumSerializer implements JsonSerializer> { 12 | @Override 13 | public JsonElement serialize(EnumSetting src, Type typeOfSrc, JsonSerializationContext context) { 14 | return new JsonPrimitive(src.getValue().toString()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/internal/gson/types/SoundSerializer.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.internal.gson.types; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.JsonPrimitive; 5 | import com.google.gson.JsonSerializationContext; 6 | import com.google.gson.JsonSerializer; 7 | import io.github.homchom.recode.mod.config.types.SoundSetting; 8 | 9 | import java.lang.reflect.Type; 10 | 11 | public class SoundSerializer implements JsonSerializer { 12 | 13 | @Override 14 | public JsonElement serialize(SoundSetting src, Type typeOfSrc, 15 | JsonSerializationContext context) { 16 | return new JsonPrimitive(src.getSelected()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/util/WordCases.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.util 2 | 3 | import io.github.homchom.recode.util.regex.regex 4 | 5 | private val humpRegex = regex { 6 | none("A-Z") 7 | any("A-Z") 8 | } 9 | 10 | /** 11 | * Splits this string into a list of words separated by "humps" (boundaries between a lowercase and uppercase 12 | * letter A-Z, as in camel case strings). 13 | */ 14 | fun String.splitByHumps() = buildList { 15 | var substringStart = 0 16 | for (match in humpRegex.findAll(this@splitByHumps)) { 17 | val next = match.range.last 18 | add(substring(substringStart, next)) 19 | substringStart = next 20 | } 21 | add(substring(substringStart, length)) 22 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mixin/ConditionalMixins.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mixin 2 | 3 | import net.fabricmc.loader.api.FabricLoader 4 | 5 | // TODO: is there a better way to do all of this? 6 | 7 | /** 8 | * Mixins with this annotation will only be applied if: 9 | * 1. The mod with ID [modID] is loaded. 10 | * 2. None of the mods with IDs in [disjointWith] are loaded. 11 | */ 12 | internal annotation class MixinConditional(val modID: String, val disjointWith: Array = []) 13 | 14 | internal val MixinConditional.shouldApplyMixin get() = when { 15 | !FabricLoader.getInstance().isModLoaded(modID) -> false 16 | disjointWith.any(FabricLoader.getInstance()::isModLoaded) -> false 17 | else -> true 18 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/commands/image/ParticleImage.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.commands.image; 2 | 3 | public class ParticleImage { 4 | final String[] imageData; 5 | final int imageWidth; 6 | final int imageHeight; 7 | 8 | public ParticleImage(String[] imageData, int imageWidth, int imageHeight) { 9 | this.imageData = imageData; 10 | this.imageWidth = imageWidth; 11 | this.imageHeight = imageHeight; 12 | } 13 | 14 | public String[] getData() { 15 | return imageData; 16 | } 17 | 18 | public int getWidth() { 19 | return imageWidth; 20 | } 21 | 22 | public int getHeight() { 23 | return imageHeight; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/render/StaticSkinRender.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.render 2 | 3 | import com.mojang.authlib.GameProfile 4 | import net.minecraft.Util 5 | import net.minecraft.client.Minecraft 6 | import net.minecraft.client.player.RemotePlayer 7 | import net.minecraft.client.resources.PlayerSkin 8 | import net.minecraft.world.entity.player.PlayerModelPart 9 | 10 | /** 11 | * An entity to be used only for rendering arbitrary player skins statically. 12 | */ 13 | class StaticSkinRender(client: Minecraft, private val skin: PlayerSkin) : RemotePlayer( 14 | client.level!!, 15 | GameProfile(Util.NIL_UUID, "") 16 | ) { 17 | override fun getSkin() = skin 18 | override fun isModelPartShown(part: PlayerModelPart) = true 19 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/internal/gson/types/list/StringListSerializer.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.internal.gson.types.list; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.JsonPrimitive; 5 | import com.google.gson.JsonSerializationContext; 6 | import com.google.gson.JsonSerializer; 7 | import io.github.homchom.recode.mod.config.types.list.StringListSetting; 8 | 9 | import java.lang.reflect.Type; 10 | 11 | public class StringListSerializer implements JsonSerializer { 12 | 13 | @Override 14 | public JsonElement serialize(StringListSetting setting, Type type, JsonSerializationContext context) { 15 | return new JsonPrimitive(setting.getSelected()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/ModConstants.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("ModConstants") 2 | 3 | package io.github.homchom.recode 4 | 5 | import net.minecraft.resources.ResourceLocation 6 | import kotlin.time.Duration.Companion.seconds 7 | 8 | const val MOD_ID = "recode" 9 | const val MOD_NAME = "recode" 10 | 11 | const val MOD_LOGO_CHAR = "\udb9c\ude65" 12 | 13 | const val ROOT_PACKAGE = "io.github.homchom.recode" 14 | //const val FEATURE_PACKAGE = "$ROOT_PACKAGE.feature" 15 | 16 | // TODO: add this as config setting (in some form) 17 | val DEFAULT_TIMEOUT_DURATION = 60.seconds 18 | 19 | // the Application ID given to recode by the Discord Developer Portal 20 | const val DISCORD_APP_ID = 1105614492534059020 21 | 22 | fun id(string: String) = ResourceLocation(MOD_ID, string) -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/internal/gson/types/DynamicStringSerializer.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.internal.gson.types; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.JsonPrimitive; 5 | import com.google.gson.JsonSerializationContext; 6 | import com.google.gson.JsonSerializer; 7 | import io.github.homchom.recode.mod.config.types.DynamicStringSetting; 8 | 9 | import java.lang.reflect.Type; 10 | 11 | public class DynamicStringSerializer implements JsonSerializer { 12 | 13 | @Override 14 | public JsonElement serialize(DynamicStringSetting src, Type typeOfSrc, 15 | JsonSerializationContext context) { 16 | return new JsonPrimitive(src.getValue()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/render/text/FormattedCharSequenceManipulation.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("FormattedCharSequenceTransformations") 2 | 3 | package io.github.homchom.recode.render.text 4 | 5 | import net.minecraft.util.FormattedCharSequence 6 | 7 | /** 8 | * @see CharSequence.subSequence 9 | */ 10 | fun FormattedCharSequence.subSequence(startIndex: Int, endIndex: Int) = FormattedCharSequence { sink -> 11 | acceptWithAbsoluteIndex { index, style, codePoint -> 12 | if (index in startIndex.. Minecraft.getInstance().setScreen(new CottonClientScreen(gui))); 13 | }catch(Exception e){ 14 | e.printStackTrace(); 15 | } 16 | } 17 | 18 | void open(String... args) throws CommandSyntaxException; 19 | } 20 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/renderer/ToasterUtil.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.renderer; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.gui.components.toasts.SystemToast; 5 | import net.minecraft.network.chat.Component; 6 | import net.minecraft.network.chat.MutableComponent; 7 | 8 | public class ToasterUtil { 9 | 10 | public static void sendToaster(String title, String description, SystemToast.SystemToastId type) { 11 | sendToaster(Component.literal(title), Component.literal(description), type); 12 | } 13 | 14 | public static void sendToaster(MutableComponent title, MutableComponent description, SystemToast.SystemToastId type) { 15 | Minecraft.getInstance().getToasts().addToast(new SystemToast(type, title, description)); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/types/DropdownSetting.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.types; 2 | 3 | import io.github.homchom.recode.mod.config.types.list.StringListSetting; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class DropdownSetting & IConfigDropdownEnum> extends StringListSetting { 9 | 10 | public DropdownSetting(String key, String... defaultValue) { 11 | super(key, defaultValue); 12 | } 13 | 14 | public static & IConfigDropdownEnum> String[] fromEnum(T anEnum) { 15 | List result = new ArrayList<>(); 16 | for (T value : anEnum.getValues()) { 17 | result.add(value.getName()); 18 | } 19 | return result.toArray(new String[0]); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/player/chat/MessageGrabberTask.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.player.chat; 2 | 3 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessageType; 4 | import net.minecraft.network.chat.Component; 5 | 6 | import java.util.List; 7 | import java.util.function.Consumer; 8 | 9 | public class MessageGrabberTask { 10 | 11 | public int messages; 12 | public Consumer> consumer; 13 | public boolean silent; 14 | public LegacyMessageType filter; 15 | 16 | public MessageGrabberTask(int messages, Consumer> consumer, boolean silent, LegacyMessageType filter) { 17 | this.messages = messages; 18 | this.consumer = consumer; 19 | this.silent = silent; 20 | this.filter = filter; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/player/chat/color/ColorUtil.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.player.chat.color; 2 | 3 | import java.awt.*; 4 | import java.util.ArrayList; 5 | 6 | public class ColorUtil { 7 | public static ArrayList recentColors = new ArrayList<>(); //for colors gui 8 | 9 | public static Color invertColor(Color color){ 10 | return new Color(255 - color.getRed(), 255 - color.getGreen(), 255 - color.getBlue()); 11 | } 12 | 13 | public static HSBColor toHSB(Color color){ 14 | return new HSBColor(Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null)); 15 | } 16 | 17 | public static String toMC(Color c) { 18 | return "§x" + String.format("%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue()).replaceAll("(.)", "§$1"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/util/coroutines/CoroutinesFunctions.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.util.coroutines 2 | 3 | import kotlinx.coroutines.CoroutineScope 4 | import kotlinx.coroutines.Job 5 | import kotlinx.coroutines.job 6 | import kotlin.coroutines.CoroutineContext 7 | import kotlin.coroutines.EmptyCoroutineContext 8 | 9 | /** 10 | * Constructs a [CoroutineScope] with context and a new [Job] derived from [parent]. 11 | * 12 | * @param context Any additional context to combine. 13 | */ 14 | fun derivedCoroutineScope(parent: CoroutineScope, context: CoroutineContext = EmptyCoroutineContext) = 15 | CoroutineScope(parent.coroutineContext + Job(parent.coroutineContext.job) + context) 16 | 17 | /** 18 | * Whether this [Job] has any children [Job]s. 19 | */ 20 | val Job.hasChildren get() = children.firstOrNull() != null -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/hypercube/codeaction/CodeBlock.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.hypercube.codeaction; 2 | 3 | import com.google.gson.JsonObject; 4 | 5 | public class CodeBlock { 6 | private final String name; 7 | private final String identifier; 8 | private final DisplayItem item; 9 | 10 | CodeBlock(JsonObject jsonObject){ 11 | this.name = jsonObject.get("name").getAsString(); 12 | this.identifier = jsonObject.get("identifier").getAsString(); 13 | this.item = new DisplayItem(jsonObject.getAsJsonObject("item")); 14 | } 15 | 16 | public String getName() { 17 | return name; 18 | } 19 | 20 | public DisplayItem getItem() { 21 | return item; 22 | } 23 | 24 | public String getIdentifier() { 25 | return identifier; 26 | } 27 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/ui/screen/DummyScreen.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.ui.screen 2 | 3 | import io.github.homchom.recode.ui.text.toVanilla 4 | import net.kyori.adventure.text.Component 5 | import net.minecraft.client.gui.GuiGraphics 6 | import net.minecraft.client.gui.screens.Screen 7 | 8 | /** 9 | * A dummy [Screen] whose sole purpose is to release the mouse. This is, for example, useful in conjunction 10 | * with native IO functions like [io.github.homchom.recode.io.pickFile]. 11 | */ 12 | class DummyScreen( 13 | title: Component, 14 | private val renderBackground: Boolean = true 15 | ) : Screen(title.toVanilla()) { 16 | override fun render(guiGraphics: GuiGraphics, mouseX: Int, mouseY: Int, tickDelta: Float) { 17 | if (renderBackground) renderBackground(guiGraphics, mouseX, mouseY, tickDelta) 18 | } 19 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/render/Blaze3DExtensions.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("Blaze3DExtensions") 2 | 3 | package io.github.homchom.recode.render 4 | 5 | import com.mojang.blaze3d.vertex.VertexMultiConsumer 6 | import io.github.homchom.recode.mc 7 | import net.minecraft.client.renderer.MultiBufferSource 8 | 9 | @JvmName("withOutline") 10 | fun MultiBufferSource.withOutline(color: RGBA) = MultiBufferSource { type -> 11 | val buffer = getBuffer(type) 12 | val outline = type.outline() 13 | if (outline.isPresent) { 14 | val outlineSource = mc.renderBuffers().outlineBufferSource() 15 | outlineSource.setColor(color.red(), color.green(), color.blue(), color.alpha()) 16 | val outlineBuffer = outlineSource.getBuffer(outline.get()) 17 | VertexMultiConsumer.create(outlineBuffer, buffer) 18 | } else { 19 | buffer 20 | } 21 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/impl/KeybindsGroup.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.impl; 2 | 3 | import io.github.homchom.recode.mod.config.structure.ConfigGroup; 4 | import io.github.homchom.recode.mod.config.structure.ConfigSubGroup; 5 | import io.github.homchom.recode.mod.config.types.IntegerSetting; 6 | 7 | public class KeybindsGroup extends ConfigGroup { 8 | public KeybindsGroup(String name) { 9 | super(name); 10 | } 11 | 12 | @Override 13 | public void initialize() { 14 | // Keybinds 15 | ConfigSubGroup keybinds = new ConfigSubGroup("flightspeed"); 16 | keybinds.register(new IntegerSetting("fsNormal", 100)); 17 | keybinds.register(new IntegerSetting("fsMed", 300)); 18 | keybinds.register(new IntegerSetting("fsFast", 1000)); 19 | this.register(keybinds); 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/hypercube/codeaction/Tag.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.hypercube.codeaction; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.JsonObject; 5 | 6 | public class Tag { 7 | private final String name; 8 | private final TagOption[] options; 9 | 10 | Tag(JsonObject jsonObject){ 11 | this.name = jsonObject.get("name").getAsString(); 12 | this.options = new TagOption[jsonObject.getAsJsonArray("options").size()]; 13 | int i = 0; 14 | for(JsonElement option : jsonObject.getAsJsonArray("options")){ 15 | this.options[i] = new TagOption(option.getAsJsonObject()); 16 | i++; 17 | } 18 | } 19 | 20 | public String getName() { 21 | return name; 22 | } 23 | 24 | public TagOption[] getOptions() { 25 | return options; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/renderer/widgets/ItemGridPanel.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.renderer.widgets; 2 | 3 | import io.github.cottonmc.cotton.gui.widget.WPlainPanel; 4 | import io.github.cottonmc.cotton.gui.widget.WWidget; 5 | import net.minecraft.world.item.ItemStack; 6 | 7 | import java.util.List; 8 | 9 | public class ItemGridPanel extends WPlainPanel { 10 | public ItemGridPanel() { 11 | super(); 12 | } 13 | 14 | public void addItem(ItemStack item) { 15 | int index = getItems().size(); 16 | add(new ClickableGiveItem(item), index % 14 * 17, index / 14 * 18); 17 | } 18 | 19 | public void addItem(CItem item) { 20 | int index = getItems().size(); 21 | add(item, index % 14 * 17, index / 14 * 18, 17, 18); 22 | } 23 | 24 | public List getItems() { 25 | return this.children; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/types/hud/PositionSetting.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.types.hud; 2 | 3 | import io.github.homchom.recode.mod.config.structure.ConfigSetting; 4 | import io.github.homchom.recode.mod.config.structure.IAdvancedSetting; 5 | 6 | public class PositionSetting extends ConfigSetting implements IAdvancedSetting { 7 | public PositionSetting() { 8 | } 9 | 10 | public PositionSetting(String key, HudData defaultValue) { 11 | super(key, defaultValue); 12 | } 13 | 14 | public int getX() { 15 | return this.defaultValue.getX(); 16 | } 17 | 18 | public void setX(int x) { 19 | this.defaultValue.setX(x); 20 | } 21 | 22 | public int getY() { 23 | return this.defaultValue.getY(); 24 | } 25 | 26 | public void setY(int y) { 27 | this.defaultValue.setY(y); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/util/SoundUtil.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.util; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.sounds.SoundEvent; 5 | import net.minecraft.sounds.SoundSource; 6 | import net.minecraft.world.entity.player.Player; 7 | 8 | public class SoundUtil { 9 | public static void playSound(SoundEvent soundEvent) { 10 | Minecraft mc = Minecraft.getInstance(); 11 | Player player = mc.player; 12 | if (mc.level != null && player != null) { 13 | mc.level.playLocalSound( 14 | player.getX(), 15 | player.getY(), 16 | player.getZ(), 17 | soundEvent, 18 | SoundSource.PLAYERS, 19 | 1f, 20 | 1f, 21 | false 22 | ); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/event/EventWrapper.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.event 2 | 3 | import io.github.homchom.recode.PowerSink 4 | import net.fabricmc.fabric.api.event.Event 5 | 6 | /** 7 | * Wraps an existing Fabric [Event] into a [Listenable], using [transform] to map recode listeners to its 8 | * specification. 9 | */ 10 | fun wrapFabricEvent( 11 | event: Event, 12 | transform: (EventInvoker) -> L 13 | ): WrappedEvent { 14 | val async = createEvent() 15 | event.register(transform(async::run)) 16 | return EventWrapper(event, async) 17 | } 18 | 19 | private class EventWrapper( 20 | private val fabricEvent: Event, 21 | private val async: CustomEvent 22 | ) : WrappedEvent, PowerSink by async { 23 | override val notifications by async::notifications 24 | 25 | override val invoker: L get() = fabricEvent.invoker() 26 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/renderer/widgets/CText.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.renderer.widgets; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import io.github.cottonmc.cotton.gui.widget.WText; 5 | import net.minecraft.client.gui.GuiGraphics; 6 | import net.minecraft.network.chat.Component; 7 | 8 | public class CText extends WText { 9 | 10 | public CText(Component text) { 11 | super(text); 12 | } 13 | 14 | public CText(Component text, int color) { 15 | super(text, color); 16 | } 17 | 18 | @Override 19 | public void paint(GuiGraphics guiGraphics, int x, int y, int mouseX, int mouseY) { 20 | x /= 2; 21 | y /= 2; 22 | PoseStack matrices = guiGraphics.pose(); 23 | matrices.scale(2, 2, 0); 24 | super.paint(guiGraphics, x, y, mouseX, mouseY); 25 | matrices.scale(0.5f, 0.5f, 0); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/keybinds/FlightSpeedToggle.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.keybinds; 2 | 3 | import io.github.homchom.recode.mod.config.LegacyConfig; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.player.LocalPlayer; 6 | 7 | import java.util.Objects; 8 | 9 | public class FlightSpeedToggle { 10 | public void toggleFlightSpeed(int percent) { 11 | LocalPlayer player = Minecraft.getInstance().player; 12 | Objects.requireNonNull(player); 13 | 14 | float current = player.getAbilities().getFlyingSpeed(); 15 | int target = current == normalFlightSpeed() ? percent : LegacyConfig.getInteger("fsNormal"); 16 | player.connection.sendUnsignedCommand("fs " + target); 17 | } 18 | 19 | private float normalFlightSpeed() { 20 | return 0.05f * LegacyConfig.getInteger("fsNormal") / 100; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/renderer/widgets/ClickableGiveItem.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.renderer.widgets; 2 | 3 | import io.github.cottonmc.cotton.gui.widget.data.InputResult; 4 | import io.github.homchom.recode.sys.util.ItemUtil; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.sounds.SoundEvents; 7 | import net.minecraft.sounds.SoundSource; 8 | import net.minecraft.world.item.ItemStack; 9 | 10 | public class ClickableGiveItem extends CItem { 11 | 12 | public ClickableGiveItem(ItemStack stack) { 13 | super(stack); 14 | } 15 | 16 | @Override 17 | public InputResult onClick(int x, int y, int button) { 18 | Minecraft mc = Minecraft.getInstance(); 19 | ItemUtil.giveCreativeItem(getItems().get(0), true); 20 | mc.player.playNotifySound(SoundEvents.ITEM_PICKUP, SoundSource.PLAYERS, 2, 1); 21 | return InputResult.IGNORED; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/internal/gson/types/StringSerializer.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.internal.gson.types; 2 | 3 | import com.google.gson.*; 4 | import io.github.homchom.recode.mod.config.types.StringSetting; 5 | 6 | import java.lang.reflect.Type; 7 | 8 | public class StringSerializer implements JsonSerializer, JsonDeserializer { 9 | @Override 10 | public StringSetting deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) { 11 | String value = jsonElement.getAsString(); 12 | StringSetting stringSetting = new StringSetting(); 13 | stringSetting.setValue(value); 14 | return stringSetting; 15 | 16 | } 17 | 18 | @Override 19 | public JsonElement serialize(StringSetting setting, Type type, JsonSerializationContext context) { 20 | return new JsonPrimitive(setting.getValue()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /mod/src/main/resources/recode.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "package": "io.github.homchom.recode.mixin", 4 | "compatibilityLevel": "JAVA_17", 5 | "mixins": [], 6 | "client": [ 7 | "MMinecraft", 8 | "game.ItemStackAccessor", 9 | "multiplayer.MChatListener", 10 | "multiplayer.MClientPacketListener", 11 | "multiplayer.MConnection", 12 | "multiplayer.MJoinMultiplayerScreen", 13 | "optional.sodium.MSodiumWorldRenderer", 14 | "render.MBlockEntityRenderDispatcher", 15 | "render.MGui", 16 | "render.MLevelRenderer", 17 | "render.MWindow", 18 | "render.chat.MChatComponent", 19 | "render.chat.MChatScreen", 20 | "render.chat.MCommandSuggestions", 21 | "ui.FontInvoker" 22 | ], 23 | "server": [], 24 | "plugin": "io.github.homchom.recode.mixin.MixinPluginRecode", 25 | "injectors": { 26 | "defaultRequire": 1 27 | } 28 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/internal/gson/types/BooleanSerializer.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.internal.gson.types; 2 | 3 | import com.google.gson.*; 4 | import io.github.homchom.recode.mod.config.types.BooleanSetting; 5 | 6 | import java.lang.reflect.Type; 7 | 8 | public class BooleanSerializer implements JsonSerializer, JsonDeserializer { 9 | @Override 10 | public BooleanSetting deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) { 11 | boolean value = jsonElement.getAsBoolean(); 12 | BooleanSetting booleanSetting = new BooleanSetting(); 13 | booleanSetting.setValue(value); 14 | return booleanSetting; 15 | 16 | } 17 | 18 | @Override 19 | public JsonElement serialize(BooleanSetting setting, Type type, JsonSerializationContext context) { 20 | return new JsonPrimitive(setting.getValue()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/internal/gson/types/LongSerializer.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.internal.gson.types; 2 | 3 | import com.google.gson.*; 4 | import io.github.homchom.recode.mod.config.types.LongSetting; 5 | 6 | import java.lang.reflect.Type; 7 | 8 | public class LongSerializer implements JsonSerializer, JsonDeserializer { 9 | @Override 10 | public LongSetting deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) { 11 | Number number = jsonElement.getAsNumber(); 12 | long value = number.longValue(); 13 | LongSetting longSetting = new LongSetting(); 14 | longSetting.setValue(value); 15 | return longSetting; 16 | } 17 | 18 | @Override 19 | public JsonElement serialize(LongSetting setting, Type type, JsonSerializationContext context) { 20 | return new JsonPrimitive(setting.getValue()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/events/impl/LegacyReceiveSoundEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.events.impl; 2 | 3 | import io.github.homchom.recode.event.SimpleValidated; 4 | import io.github.homchom.recode.game.GameEvents; 5 | import net.minecraft.network.protocol.game.ClientboundSoundPacket; 6 | 7 | public class LegacyReceiveSoundEvent { 8 | private static int cancelNextSounds; 9 | 10 | public LegacyReceiveSoundEvent() { 11 | GameEvents.getPlaySoundEvent().register(this::run); 12 | } 13 | 14 | private void run(SimpleValidated context) { 15 | if (cancelNextSounds > 0) { 16 | cancelNextSounds--; 17 | context.invalidate(); 18 | } 19 | } 20 | 21 | public static void cancelNextSounds(int amount) { 22 | cancelNextSounds = amount; 23 | } 24 | 25 | public static void cancelNextSound() { 26 | cancelNextSounds(1); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /mod/src/main/resources/recodeLegacy.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "package": "io.github.homchom.recode.mod.mixin", 4 | "compatibilityLevel": "JAVA_8", 5 | "mixins": [ 6 | "game.MMinecraftClient", 7 | "inventory.MHeldItemTooltip", 8 | "inventory.MItemCreative", 9 | "inventory.MItemInsert", 10 | "inventory.MItemStack", 11 | "message.MMessageListener", 12 | "message.MPlayerSendMessage", 13 | "message.MReceivedSound", 14 | "render.MChatScreen", 15 | "render.MChestBlock", 16 | "render.MChestRenderer", 17 | "render.MContainerScreen", 18 | "render.MInGameHUD", 19 | "render.MMouseHandler", 20 | "render.MScreen", 21 | "render.MStitcher", 22 | "render.MWindow", 23 | "render.screen.MCreativeInventoryScreen", 24 | "render.screen.MOptionsScreen" 25 | ], 26 | "client": [ 27 | "render.MAbstractContainerScreen" 28 | ], 29 | "server": [], 30 | "injectors": { 31 | "defaultRequire": 1 32 | } 33 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/internal/gson/types/FloatSerializer.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.internal.gson.types; 2 | 3 | import com.google.gson.*; 4 | import io.github.homchom.recode.mod.config.types.FloatSetting; 5 | 6 | import java.lang.reflect.Type; 7 | 8 | public class FloatSerializer implements JsonSerializer, JsonDeserializer { 9 | @Override 10 | public FloatSetting deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) { 11 | Number number = jsonElement.getAsNumber(); 12 | float value = number.floatValue(); 13 | FloatSetting floatSetting = new FloatSetting(); 14 | floatSetting.setValue(value); 15 | return floatSetting; 16 | } 17 | 18 | @Override 19 | public JsonElement serialize(FloatSetting setting, Type type, JsonSerializationContext context) { 20 | return new JsonPrimitive(setting.getValue()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/networking/websocket/client/type/NbtItem.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.networking.websocket.client.type; 2 | 3 | import com.mojang.brigadier.StringReader; 4 | import com.mojang.brigadier.exceptions.CommandSyntaxException; 5 | import net.minecraft.nbt.TagParser; 6 | import net.minecraft.world.item.ItemStack; 7 | 8 | import java.io.IOException; 9 | 10 | public class NbtItem extends SocketItem { 11 | 12 | @Override 13 | public String getIdentifier() { 14 | return "nbt"; 15 | } 16 | 17 | @Override 18 | public ItemStack getItem(String data) throws Exception { 19 | ItemStack stack; 20 | try { 21 | stack = ItemStack.of(new TagParser(new StringReader(data)).readStruct()); 22 | } catch (RuntimeException | CommandSyntaxException e) { 23 | throw new IOException("Failed to parse provided NBT data."); 24 | } 25 | 26 | return stack; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/events/impl/LegacyJoinEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.events.impl; 2 | 3 | import io.github.homchom.recode.hypercube.state.DF; 4 | import io.github.homchom.recode.mod.features.streamer.StreamerModeHandler; 5 | import io.github.homchom.recode.sys.util.TimerUtil; 6 | import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; 7 | import net.fabricmc.fabric.api.networking.v1.PacketSender; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.client.multiplayer.ClientPacketListener; 10 | 11 | public class LegacyJoinEvent { 12 | public LegacyJoinEvent() { 13 | ClientPlayConnectionEvents.JOIN.register(this::run); 14 | } 15 | 16 | private void run(ClientPacketListener clientPacketListener, PacketSender packetSender, Minecraft minecraft) { 17 | if (DF.isOnDF()) { 18 | TimerUtil.setTimeout(StreamerModeHandler::handleServerJoin, 2500); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/mixin/message/MReceivedSound.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.mixin.message; 2 | 3 | import io.github.homchom.recode.event.SimpleValidated; 4 | import io.github.homchom.recode.game.GameEvents; 5 | import net.minecraft.client.multiplayer.ClientPacketListener; 6 | import net.minecraft.network.protocol.game.ClientboundSoundPacket; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | 12 | @Mixin(ClientPacketListener.class) 13 | public class MReceivedSound { 14 | @Inject(method = "handleSoundEvent", at = @At("HEAD"), cancellable = true) 15 | private void handleSoundEvent(ClientboundSoundPacket packet, CallbackInfo ci) { 16 | if (!GameEvents.getPlaySoundEvent().run(new SimpleValidated<>(packet))) { 17 | ci.cancel(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/internal/gson/types/DoubleSerializer.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.internal.gson.types; 2 | 3 | import com.google.gson.*; 4 | import io.github.homchom.recode.mod.config.types.DoubleSetting; 5 | 6 | import java.lang.reflect.Type; 7 | 8 | public class DoubleSerializer implements JsonSerializer, JsonDeserializer { 9 | @Override 10 | public DoubleSetting deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) { 11 | Number number = jsonElement.getAsNumber(); 12 | double value = number.doubleValue(); 13 | DoubleSetting doubleSetting = new DoubleSetting(); 14 | doubleSetting.setValue(value); 15 | return doubleSetting; 16 | 17 | } 18 | 19 | @Override 20 | public JsonElement serialize(DoubleSetting setting, Type type, JsonSerializationContext context) { 21 | return new JsonPrimitive(setting.getValue()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/util/Computation.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.util 2 | 3 | import io.github.homchom.recode.util.Computation.Failure 4 | import io.github.homchom.recode.util.Computation.Success 5 | 6 | /** 7 | * A computed result that can either be a [Success] or [Failure], like the 8 | * [Either](https://docs.rs/either/latest/either/enum.Either.html) type found in many functional languages. 9 | */ 10 | sealed interface Computation { 11 | fun successOrNull() = this as? Success 12 | fun failureOrNull() = this as? Failure 13 | 14 | class Success(override val value: T) : Computation, InvokableWrapper 15 | class Failure(override val value: T) : Computation, InvokableWrapper 16 | } 17 | 18 | inline fun Computation.map(transform: (S) -> R): Computation = 19 | when (this) { 20 | is Success -> Success(transform(value)) 21 | is Failure -> Failure(value) 22 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/internal/gson/types/IntegerSerializer.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.internal.gson.types; 2 | 3 | import com.google.gson.*; 4 | import io.github.homchom.recode.mod.config.types.IntegerSetting; 5 | 6 | import java.lang.reflect.Type; 7 | 8 | public class IntegerSerializer implements JsonSerializer, JsonDeserializer { 9 | @Override 10 | public IntegerSetting deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) { 11 | Number number = jsonElement.getAsNumber(); 12 | int value = number.intValue(); 13 | IntegerSetting integerSetting = new IntegerSetting(); 14 | integerSetting.setValue(value); 15 | return integerSetting; 16 | 17 | } 18 | 19 | @Override 20 | public JsonElement serialize(IntegerSetting setting, Type type, JsonSerializationContext context) { 21 | return new JsonPrimitive(setting.getValue()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | For Minecraft 1.20.2, Fabric API 0.90.7 or newer 2 | 3 | ### Additions 4 | - Completely overhauled Syntax Highlighting, which now highlights the chat input box directly 5 | - Syntax Highlighting now includes MiniMessage highlighting 6 | 7 | ### Changes 8 | - Updated to Minecraft 1.20.2 9 | - Formatting changes and fixes to Chest Preview (#60, thanks Electric131) 10 | 11 | ### Fixes 12 | - Holding Game Values can no longer crash the game (thanks ShadowEmpress_) 13 | - Kicks for "out-of-order chat packets" are now much less common 14 | - Message stacking once again works for multi-line messages 15 | - Code Search is now compatible with Sodium 0.5 (for real this time!) 16 | - The check for DiamondFire IP addresses is now case-insensitive 17 | - `/dfgive clipboard` now trims extraneous whitespace (#61, thanks Electric131) 18 | - More obscure fixes to location overlay and state-related features (thanks ShadowEmpress_) 19 | 20 | ### Removals 21 | - Removed `/schem` (#65) 22 | - Removed `/gradient` in favor of `` -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/render/RenderDucks.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.render 2 | 3 | import net.minecraft.core.SectionPos 4 | import net.minecraft.world.level.block.entity.BlockEntity 5 | 6 | /** 7 | * An [net.minecraft.client.renderer.LevelRenderer] that is augmented by recode. 8 | */ 9 | @Suppress("FunctionName") 10 | interface DRecodeLevelRenderer { 11 | /** 12 | * @returns A filtered list of block entities that should still be rendered. 13 | */ 14 | fun `recode$runBlockEntityEvents`( 15 | blockEntities: Collection, 16 | sectionPos: SectionPos? 17 | ): List 18 | 19 | /** 20 | * Gets and returns the RGBA hex of [blockEntity]'s outline, or `null` if it will not be outlined. 21 | */ 22 | fun `recode$getBlockEntityOutlineColor`(blockEntity: BlockEntity): Int? 23 | 24 | /** 25 | * Processes all unprocessed entity and block entity outlines. 26 | */ 27 | fun `recode$processOutlines`(partialTick: Float) 28 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/types/EnumSetting.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.types; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import io.github.homchom.recode.mod.config.structure.ConfigSetting; 5 | 6 | public class EnumSetting & IConfigEnum> extends ConfigSetting { 7 | Class eClass; 8 | 9 | public EnumSetting(String key, Class eClass, E defaultValue) { 10 | super(key, defaultValue); 11 | 12 | this.eClass = eClass; 13 | } 14 | 15 | public Class getEnumClass() { 16 | return eClass; 17 | } 18 | 19 | public void setFromString(String string) { 20 | this.setValue(Enum.valueOf(eClass,string)); 21 | } 22 | 23 | public enum TestEnum { 24 | @SerializedName("ONE") 25 | ONE, 26 | @SerializedName("TWO") 27 | TWO, 28 | @SerializedName("THREE") 29 | THREE 30 | } 31 | 32 | public enum TestEnum2 { 33 | A, 34 | B, 35 | C 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/util/coroutines/Continuations.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.util.coroutines 2 | 3 | import kotlin.coroutines.AbstractCoroutineContextElement 4 | import kotlin.coroutines.Continuation 5 | import kotlin.coroutines.ContinuationInterceptor 6 | 7 | /** 8 | * Returns a new [ContinuationInterceptor] that invokes [onResume] before each successful resumption. 9 | */ 10 | // we don't optimize with Delay because CancellableContinuation is very internal 11 | fun ContinuationInterceptor.withNotifications(onResume: () -> Unit): ContinuationInterceptor = 12 | object : AbstractCoroutineContextElement(ContinuationInterceptor), ContinuationInterceptor { 13 | override fun interceptContinuation(continuation: Continuation) = 14 | Continuation(continuation.context) { result -> 15 | if (result.isSuccess) onResume() 16 | val intercepted = this@withNotifications.interceptContinuation(continuation) 17 | intercepted.resumeWith(result) 18 | } 19 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/game/GameEvents.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("GameEvents") 2 | 3 | package io.github.homchom.recode.game 4 | 5 | import io.github.homchom.recode.event.createEvent 6 | import io.github.homchom.recode.event.createValidatedEvent 7 | import io.github.homchom.recode.event.run 8 | import io.github.homchom.recode.event.wrapFabricEvent 9 | import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents 10 | import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents 11 | import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents.EndTick 12 | import net.minecraft.network.protocol.game.ClientboundSoundPacket 13 | 14 | val AfterClientTickEvent = wrapFabricEvent(ClientTickEvents.END_CLIENT_TICK) { EndTick(it) } 15 | 16 | val PlaySoundEvent = createValidatedEvent() 17 | 18 | /** 19 | * An event that runs when the client stops, including crashes. 20 | */ 21 | val GameStopEvent = createEvent().also { event -> 22 | ClientLifecycleEvents.CLIENT_STOPPING.register { event.run() } 23 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/commands/arguments/ArgBuilder.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.commands.arguments; 2 | 3 | import com.mojang.brigadier.arguments.ArgumentType; 4 | import com.mojang.brigadier.builder.LiteralArgumentBuilder; 5 | import com.mojang.brigadier.builder.RequiredArgumentBuilder; 6 | import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; 7 | 8 | // These argument classes will eventually become our own command dispatcher, removing the dependency for Cotton Clients Commands. 9 | public final class ArgBuilder { 10 | // TODO: nice exception handler - maybe custom client commands impl? 11 | 12 | private ArgBuilder() { 13 | } 14 | 15 | public static LiteralArgumentBuilder literal(String name) { 16 | return LiteralArgumentBuilder.literal(name); 17 | } 18 | 19 | public static RequiredArgumentBuilder argument(String name, ArgumentType type) { 20 | return RequiredArgumentBuilder.argument(name, type); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/events/impl/LegacyChangeStateEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.events.impl; 2 | 3 | import io.github.homchom.recode.hypercube.state.DFState; 4 | import io.github.homchom.recode.hypercube.state.DFStateDetectors; 5 | import io.github.homchom.recode.mod.features.StateOverlayHandler; 6 | import io.github.homchom.recode.mod.features.streamer.StreamerModeHandler; 7 | import io.github.homchom.recode.sys.player.chat.MessageGrabber; 8 | import io.github.homchom.recode.util.Case; 9 | 10 | public class LegacyChangeStateEvent { 11 | public LegacyChangeStateEvent() { 12 | DFStateDetectors.INSTANCE.register(this::run); 13 | } 14 | 15 | private void run(Case stateCase) { 16 | var state = stateCase.getContent(); 17 | StreamerModeHandler.handleStateChange(state); 18 | 19 | if (state == null) MessageGrabber.reset(); 20 | 21 | try { 22 | StateOverlayHandler.setState(state); 23 | } catch(Exception e) { 24 | e.printStackTrace(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/networking/websocket/client/WebsocketServer.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.networking.websocket.client; 2 | 3 | import org.java_websocket.WebSocket; 4 | import org.java_websocket.handshake.ClientHandshake; 5 | import org.java_websocket.server.WebSocketServer; 6 | 7 | import java.net.InetSocketAddress; 8 | 9 | public class WebsocketServer extends WebSocketServer { 10 | public WebsocketServer(InetSocketAddress address) { 11 | super(address); 12 | } 13 | 14 | @Override 15 | public void onOpen(WebSocket conn, ClientHandshake handshake) {} 16 | 17 | @Override 18 | public void onClose(WebSocket conn, int code, String reason, boolean remote) {} 19 | 20 | @Override 21 | public void onMessage(WebSocket conn, String message) { 22 | String res = Clients.acceptData(message); 23 | if (res != null) conn.send(res); 24 | } 25 | 26 | @Override 27 | public void onError(WebSocket conn, Exception ex) { 28 | System.out.println(); 29 | } 30 | 31 | @Override 32 | public void onStart() {} 33 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/hypercube/templates/TemplateItem.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.hypercube.templates; 2 | 3 | import net.minecraft.world.item.ItemStack; 4 | 5 | import java.util.Objects; 6 | 7 | public class TemplateItem { 8 | 9 | final String code; 10 | final ItemStack stack; 11 | 12 | public TemplateItem(ItemStack stack) { 13 | this.code = TemplateUtil.read(stack).get("code").getAsString(); 14 | this.stack = stack; 15 | } 16 | 17 | public TemplateItem(String code, ItemStack stack) { 18 | this.code = code; 19 | this.stack = stack; 20 | } 21 | 22 | @Override 23 | public boolean equals(Object o) { 24 | if (this == o) return true; 25 | if (o == null || getClass() != o.getClass()) return false; 26 | TemplateItem that = (TemplateItem) o; 27 | return Objects.equals(code, that.code); 28 | } 29 | 30 | @Override 31 | public int hashCode() { 32 | return Objects.hash(code); 33 | } 34 | 35 | public ItemStack getStack() { 36 | return stack; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [libraries] 2 | 3 | # required; change versions every minecraft update 4 | minecraft = { module = "com.mojang:minecraft", version = "1.20.4" } 5 | fabric-api = { module = "net.fabricmc.fabric-api:fabric-api", version = "0.96.1+1.20.4" } 6 | 7 | adventure-platform-fabric = { module = "net.kyori:adventure-platform-fabric", version = "5.12.0" } 8 | libgui = { module = "io.github.cottonmc:LibGui", version = "9.2.2+1.20.2" } 9 | clothConfig = { module = "me.shedaniel.cloth:cloth-config-fabric", version = "13.0.121" } 10 | 11 | # optional; change versions every minecraft update 12 | modmenu = { module = "com.terraformersmc:modmenu", version = "9.0.0" } 13 | sodium = { module = "maven.modrinth:sodium", version = "mc1.20.4-0.5.8" } 14 | 15 | # change versions as needed 16 | fabric-loader = { module = "net.fabricmc:fabric-loader", version = "0.15.2" } 17 | fabric-language-kotlin = { module = "net.fabricmc:fabric-language-kotlin", version = "1.11.0+kotlin.2.0.0" } 18 | 19 | [plugins] 20 | kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version = "2.0.0" } 21 | fabric-loom = { id = "fabric-loom", version = "1.7-SNAPSHOT" } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/multiplayer/CommandQueue.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("CommandQueue") 2 | 3 | package io.github.homchom.recode.multiplayer 4 | 5 | import io.github.homchom.recode.RecodeDispatcher 6 | import io.github.homchom.recode.game.waitTicks 7 | import io.github.homchom.recode.mc 8 | import kotlinx.coroutines.DelicateCoroutinesApi 9 | import kotlinx.coroutines.GlobalScope 10 | import kotlinx.coroutines.launch 11 | 12 | // https://github.com/PaperMC/Velocity/issues/909 13 | private val queue = ArrayDeque() 14 | 15 | @OptIn(DelicateCoroutinesApi::class) 16 | fun unsafelySendCommand(command: String) { 17 | // https://github.com/PaperMC/Velocity/issues/909 TODO: remove queue when fixed 18 | queue += command 19 | if (queue.size == 1) GlobalScope.launch(RecodeDispatcher) { 20 | try { 21 | do { 22 | val next = queue.removeFirst() 23 | mc.player?.connection?.sendUnsignedCommand(next) ?: break 24 | waitTicks(1) 25 | } while (queue.isNotEmpty()) 26 | } finally { 27 | queue.clear() 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/commands/IManager.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.commands; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Allows initialization functionality and keeps track of 7 | * registered objects of specified type. 8 | * 9 | * @param Object type. 10 | */ 11 | public interface IManager { 12 | /** 13 | * Initializes all objects. 14 | */ 15 | void initialize(); 16 | 17 | /** 18 | * Registers an object and inserts it 19 | * into a list. 20 | * 21 | * @param object Object to register. 22 | */ 23 | void register(T object); 24 | 25 | /** 26 | * Returns list of all registered objects. 27 | * 28 | * @return List of registered objects. 29 | */ 30 | List getRegistered(); 31 | 32 | /** 33 | * Removes an object from the manager's list. 34 | * 35 | * @param object Object to be removed. 36 | * @return True if was removed, false if not. 37 | * @see List#remove(Object) 38 | */ 39 | default boolean unregister(T object) { 40 | return this.getRegistered().remove(object); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/commands/impl/image/AbstractImageCommand.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.commands.impl.image; 2 | 3 | import com.mojang.brigadier.tree.ArgumentCommandNode; 4 | import io.github.homchom.recode.mod.commands.Command; 5 | import io.github.homchom.recode.mod.commands.arguments.ArgBuilder; 6 | import io.github.homchom.recode.mod.commands.arguments.types.PathArgumentType; 7 | import io.github.homchom.recode.sys.file.ExternalFile; 8 | import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; 9 | 10 | import java.nio.file.Path; 11 | import java.util.function.Function; 12 | 13 | public abstract class AbstractImageCommand extends Command { 14 | protected ArgumentCommandNode fileArgument(Function executor) { 15 | return ArgBuilder.argument("file", PathArgumentType.folder(ExternalFile.IMAGE_FILES.getPath(), true)) 16 | .executes(ctx -> { 17 | Path path = PathArgumentType.getPath(ctx, "file"); 18 | 19 | return executor.apply(path); 20 | }) 21 | .build(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/events/LegacyEventHandler.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.events; 2 | 3 | import io.github.homchom.recode.mod.commands.IManager; 4 | import io.github.homchom.recode.mod.events.impl.*; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class LegacyEventHandler implements IManager { 10 | private final List registeredEvents = new ArrayList<>(); 11 | 12 | @Override 13 | public void initialize() { 14 | register( 15 | new LegacyAfterScreenInitEvent(), 16 | new LegacyChangeStateEvent(), 17 | new LegacyReceiveChatMessageEvent(), 18 | new LegacyReceiveSoundEvent(), 19 | new LegacyJoinEvent() 20 | ); 21 | } 22 | 23 | @Override 24 | public void register(Object object) { 25 | registeredEvents.add(object); 26 | } 27 | 28 | public void register(Object... objects) { 29 | for (Object object : objects) register(object); 30 | } 31 | 32 | @Override 33 | public List getRegistered() { 34 | return registeredEvents; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/commands/recode/Contributor.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.commands.recode; 2 | 3 | import net.minecraft.resources.ResourceLocation; 4 | 5 | public class Contributor { 6 | private final String name; 7 | private final int id; 8 | private final int contributions; 9 | private final String avatarUrl; 10 | private ResourceLocation avatar; 11 | 12 | public Contributor(String name, int id, int contributions, String avatarUrl) { 13 | this.name = name; 14 | this.id = id; 15 | this.contributions = contributions; 16 | this.avatarUrl = avatarUrl; 17 | } 18 | 19 | public ResourceLocation getAvatar() { 20 | return avatar; 21 | } 22 | 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | public int getId() { 28 | return id; 29 | } 30 | 31 | public int getContributions() { 32 | return contributions; 33 | } 34 | 35 | public String getAvatarUrl() { 36 | return avatarUrl; 37 | } 38 | 39 | public void setAvatar(ResourceLocation avatar) { 40 | this.avatar = avatar; 41 | } 42 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/checks/AdminCheck.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message.checks; 2 | 3 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessage; 4 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessageType; 5 | import io.github.homchom.recode.mod.features.social.chat.message.MessageCheck; 6 | import io.github.homchom.recode.mod.features.streamer.StreamerModeHandler; 7 | import io.github.homchom.recode.mod.features.streamer.StreamerModeMessageCheck; 8 | 9 | public class AdminCheck extends MessageCheck implements StreamerModeMessageCheck { 10 | 11 | @Override 12 | public LegacyMessageType getType() { 13 | return LegacyMessageType.ADMIN; 14 | } 15 | 16 | @Override 17 | public boolean check(LegacyMessage message, String stripped) { 18 | return stripped.startsWith("[ADMIN]"); 19 | } 20 | 21 | @Override 22 | public void onReceive(LegacyMessage message) { 23 | 24 | } 25 | 26 | @Override 27 | public boolean streamerHideEnabled() { 28 | return StreamerModeHandler.hideAdmin(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/mixin/inventory/MItemCreative.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.mixin.inventory; 2 | 3 | import io.github.homchom.recode.sys.hypercube.templates.TemplateStorageHandler; 4 | import io.github.homchom.recode.sys.hypercube.templates.TemplateUtil; 5 | import net.minecraft.network.protocol.game.ServerboundSetCreativeModeSlotPacket; 6 | import net.minecraft.server.network.ServerGamePacketListenerImpl; 7 | import net.minecraft.world.item.ItemStack; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Inject; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 12 | 13 | @Mixin(ServerGamePacketListenerImpl.class) 14 | public class MItemCreative { 15 | @Inject(method = "handleSetCreativeModeSlot", at = @At("HEAD")) 16 | public void handleSetCreativeModeSlot(ServerboundSetCreativeModeSlotPacket packet, CallbackInfo ci) { 17 | ItemStack stack = packet.getItem(); 18 | if (TemplateUtil.isTemplate(stack)) { 19 | TemplateStorageHandler.addTemplate(stack); 20 | } 21 | } 22 | } 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/commands/arguments/types/PlayerArgumentType.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.commands.arguments.types; 2 | 3 | import com.mojang.brigadier.StringReader; 4 | import com.mojang.brigadier.arguments.ArgumentType; 5 | import com.mojang.brigadier.context.CommandContext; 6 | import com.mojang.brigadier.suggestion.Suggestions; 7 | import com.mojang.brigadier.suggestion.SuggestionsBuilder; 8 | import net.minecraft.commands.SharedSuggestionProvider; 9 | 10 | import java.util.concurrent.CompletableFuture; 11 | 12 | public class PlayerArgumentType implements ArgumentType { 13 | 14 | private PlayerArgumentType() { 15 | } 16 | 17 | public static PlayerArgumentType player() { 18 | return new PlayerArgumentType(); 19 | } 20 | 21 | public String parse(StringReader stringReader) { 22 | return stringReader.readUnquotedString(); 23 | } 24 | 25 | public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { 26 | return SharedSuggestionProvider.suggest(((SharedSuggestionProvider) context.getSource()).getOnlinePlayerNames(), builder); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/renderer/widgets/CColoredRectangle.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.renderer.widgets; 2 | 3 | import io.github.cottonmc.cotton.gui.client.LibGui; 4 | import io.github.cottonmc.cotton.gui.widget.WWidget; 5 | import io.github.homchom.recode.sys.renderer.RenderUtil; 6 | import net.minecraft.client.gui.GuiGraphics; 7 | 8 | import java.awt.*; 9 | 10 | public class CColoredRectangle extends WWidget { 11 | 12 | private Color color; 13 | private Color darkmodeColor; 14 | 15 | public CColoredRectangle(Color color, Color darkmodecolor){ 16 | this.color = color; 17 | this.darkmodeColor = darkmodecolor; 18 | } 19 | 20 | @Override 21 | public void paint(GuiGraphics guiGraphics, int x, int y, int mouseX, int mouseY) { 22 | RenderUtil.drawRect(guiGraphics, x, y, x+this.width, y+this.height, LibGui.isDarkMode() ? this.darkmodeColor : this.color); 23 | } 24 | 25 | @Override 26 | public boolean canResize() { 27 | return true; 28 | } 29 | 30 | public void setColor(Color color, Color darkmodecolor){ 31 | this.color = color; 32 | this.darkmodeColor = darkmodecolor; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/game/ItemExtensions.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("ItemExtensions") 2 | 3 | package io.github.homchom.recode.game 4 | 5 | import io.github.homchom.recode.mixin.game.ItemStackAccessor 6 | import io.github.homchom.recode.ui.text.mergeStyleIfAbsent 7 | import io.github.homchom.recode.ui.text.toAdventure 8 | import net.kyori.adventure.text.Component 9 | import net.kyori.adventure.text.serializer.json.JSONComponentSerializer 10 | import net.minecraft.nbt.Tag 11 | import net.minecraft.world.item.ItemStack 12 | 13 | /** 14 | * @return this [ItemStack]'s "lore" (description), found in its tooltip, as a list of [Component]s. 15 | */ 16 | fun ItemStack.lore(): List { 17 | val loreTag = tag 18 | ?.getCompoundOrNull("display") 19 | ?.getListOrNull("Lore", Tag.TAG_STRING) 20 | ?: return emptyList() 21 | 22 | return buildList(loreTag.size) { 23 | for (index in 0.. manager) { 21 | this.add(new IManager[]{manager}); 22 | } 23 | 24 | public void add(ILoader loader) { 25 | this.add(new ILoader[]{loader}); 26 | } 27 | 28 | public void add(ILoader... loaders) { 29 | Arrays.stream(loaders).forEach(ILoader::load); 30 | } 31 | 32 | public void add(IManager... managers) { 33 | Arrays.stream(managers).forEach(IManager::initialize); 34 | } 35 | 36 | public void addIf(ILoader loader, boolean b) { 37 | if (b) loader.load(); 38 | } 39 | 40 | public void addIf(IManager manager, boolean b) { 41 | if (b) manager.initialize(); 42 | } 43 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/player/DFInfo.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.player; 2 | 3 | public class DFInfo { 4 | public static String patchId = "5.3"; 5 | 6 | public static boolean isPatchNewer(String base, String target) { 7 | String[] baseSplit = base.split("\\.", 0); 8 | String[] targetSplit = target.split("\\.", 0); 9 | 10 | boolean oldNumberFound = false; 11 | 12 | int l = baseSplit.length; 13 | if (targetSplit.length > baseSplit.length) l = targetSplit.length; 14 | 15 | for (int i = 0; i < l; i++) { 16 | String currentBase = "0"; 17 | String currentTarget = "0"; 18 | 19 | if (baseSplit.length > i) currentBase = baseSplit[i]; 20 | if (targetSplit.length > i) currentTarget = targetSplit[i]; 21 | 22 | if (Integer.parseInt(currentBase) > Integer.parseInt(currentTarget)) { 23 | return true; 24 | } else { 25 | if (Integer.parseInt(currentBase) < Integer.parseInt(currentTarget)) { 26 | oldNumberFound = true; 27 | } 28 | } 29 | } 30 | return !oldNumberFound; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/util/math/Arithmetic.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.util.math 2 | 3 | /** 4 | * Returns the square of this Int. 5 | */ 6 | fun Int.squared() = this * this 7 | 8 | /** 9 | * Returns the square of this Long. 10 | */ 11 | fun Long.squared() = this * this 12 | 13 | /** 14 | * Returns the square of this Float. 15 | */ 16 | fun Float.squared() = this * this 17 | 18 | /** 19 | * Returns the square of this Double. 20 | */ 21 | fun Double.squared() = this * this 22 | 23 | /** 24 | * @return the [floor modulo](https://en.wikipedia.org/wiki/Modulo#Variants_of_the_definition) 25 | * of this Int and [other]. 26 | */ 27 | infix fun Int.mod(other: Int) = Math.floorMod(this, other) 28 | 29 | /** 30 | * @return the [floor modulo](https://en.wikipedia.org/wiki/Modulo#Variants_of_the_definition) 31 | * of this Long and [other]. 32 | */ 33 | infix fun Long.mod(other: Long) = Math.floorMod(this, other) 34 | 35 | /** 36 | * @return the greatest common divisor of [a] and [b] using the 37 | * [Euclidean algorithm](https://en.wikipedia.org/wiki/Euclidean_algorithm). 38 | */ 39 | tailrec fun greatestCommonDivisor(a: Int, b: Int): Int = 40 | if (b == 0) a else greatestCommonDivisor(b, a % b) -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/checks/SilentPunishmentCheck.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message.checks; 2 | 3 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessage; 4 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessageType; 5 | import io.github.homchom.recode.mod.features.social.chat.message.MessageCheck; 6 | import io.github.homchom.recode.mod.features.streamer.StreamerModeHandler; 7 | import io.github.homchom.recode.mod.features.streamer.StreamerModeMessageCheck; 8 | 9 | public class SilentPunishmentCheck extends MessageCheck implements StreamerModeMessageCheck { 10 | 11 | @Override 12 | public LegacyMessageType getType() { 13 | return LegacyMessageType.SILENT_PUNISHMENT; 14 | } 15 | 16 | @Override 17 | public boolean check(LegacyMessage message, String stripped) { 18 | return stripped.startsWith("[Silent]"); 19 | } 20 | 21 | @Override 22 | public void onReceive(LegacyMessage message) { 23 | 24 | } 25 | 26 | @Override 27 | public boolean streamerHideEnabled() { 28 | return StreamerModeHandler.hideModeration(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/renderer/widgets/ItemScrollablePanel.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.renderer.widgets; 2 | 3 | import io.github.cottonmc.cotton.gui.widget.WScrollPanel; 4 | import net.minecraft.world.item.ItemStack; 5 | 6 | import java.util.List; 7 | 8 | public class ItemScrollablePanel extends WScrollPanel { 9 | 10 | private final ItemGridPanel itemGrid; 11 | 12 | private ItemScrollablePanel(ItemGridPanel grid, List items) { 13 | super(grid); 14 | this.itemGrid = grid; 15 | 16 | for (ItemStack stack : items) { 17 | itemGrid.addItem(stack); 18 | } 19 | } 20 | 21 | public static ItemScrollablePanel with(List items) { 22 | return new ItemScrollablePanel(new ItemGridPanel(), items); 23 | } 24 | 25 | public void setItems(List items) { 26 | itemGrid.getItems().clear(); 27 | itemGrid.setSize(0, 0); 28 | horizontalScrollBar.setValue(0); 29 | 30 | for (ItemStack item : items) { 31 | itemGrid.addItem(item); 32 | } 33 | layout(); 34 | } 35 | 36 | public ItemGridPanel getItemGrid() { 37 | return itemGrid; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/checks/SpiesCheck.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message.checks; 2 | 3 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessage; 4 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessageType; 5 | import io.github.homchom.recode.mod.features.social.chat.message.MessageCheck; 6 | import io.github.homchom.recode.mod.features.streamer.StreamerModeHandler; 7 | import io.github.homchom.recode.mod.features.streamer.StreamerModeMessageCheck; 8 | 9 | public class SpiesCheck extends MessageCheck implements StreamerModeMessageCheck { 10 | 11 | @Override 12 | public LegacyMessageType getType() { 13 | return LegacyMessageType.SPIES; 14 | } 15 | 16 | @Override 17 | public boolean check(LegacyMessage message, String stripped) { 18 | // Hide spies (Session spy, Muted spy, DM spy) 19 | return stripped.startsWith("*"); 20 | } 21 | 22 | @Override 23 | public void onReceive(LegacyMessage message) { 24 | 25 | } 26 | 27 | @Override 28 | public boolean streamerHideEnabled() { 29 | return StreamerModeHandler.hideSpies(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/types/list/ListSetting.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.types.list; 2 | 3 | import io.github.homchom.recode.mod.config.structure.ConfigSetting; 4 | import io.github.homchom.recode.mod.config.types.IConfigDropdownEnum; 5 | 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | public class ListSetting extends ConfigSetting> { 10 | private Type selected; 11 | 12 | public ListSetting() { 13 | } 14 | 15 | @SuppressWarnings("unchecked") 16 | public ListSetting(String key, Type... defaultValue) { 17 | super(key, Arrays.asList(defaultValue)); 18 | } 19 | 20 | public Type getSelected() { 21 | return selected; 22 | } 23 | 24 | public ListSetting setSelected(Type selected) { 25 | this.selected = selected; 26 | return this; 27 | } 28 | 29 | @SuppressWarnings("unchecked") 30 | public > ListSetting setSelected(T selected) { 31 | this.selected = (Type) selected.getName(); 32 | return this; 33 | } 34 | 35 | @Override 36 | public boolean isString() { 37 | return this instanceof StringListSetting; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/checks/StreamerModeRegexCheck.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message.checks; 2 | 3 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessage; 4 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessageType; 5 | import io.github.homchom.recode.mod.features.social.chat.message.MessageCheck; 6 | import io.github.homchom.recode.mod.features.streamer.StreamerModeHandler; 7 | import io.github.homchom.recode.mod.features.streamer.StreamerModeMessageCheck; 8 | 9 | public class StreamerModeRegexCheck extends MessageCheck implements StreamerModeMessageCheck { 10 | 11 | @Override 12 | public LegacyMessageType getType() { 13 | return LegacyMessageType.STREAMER_MODE_REGEX; 14 | } 15 | 16 | @Override 17 | public boolean check(LegacyMessage message, String stripped) { 18 | return stripped.matches(StreamerModeHandler.hideRegex()); 19 | } 20 | 21 | @Override 22 | public void onReceive(LegacyMessage message) { 23 | 24 | } 25 | 26 | @Override 27 | public boolean streamerHideEnabled() { 28 | return StreamerModeHandler.hideRegexEnabled(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/checks/ModerationCheck.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message.checks; 2 | 3 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessage; 4 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessageType; 5 | import io.github.homchom.recode.mod.features.social.chat.message.MessageCheck; 6 | import io.github.homchom.recode.mod.features.streamer.StreamerModeHandler; 7 | import io.github.homchom.recode.mod.features.streamer.StreamerModeMessageCheck; 8 | 9 | public class ModerationCheck extends MessageCheck implements StreamerModeMessageCheck { 10 | @Override 11 | public LegacyMessageType getType() { 12 | return LegacyMessageType.MODERATION; 13 | } 14 | 15 | @Override 16 | public boolean check(LegacyMessage message, String stripped) { 17 | // General moderation messages (Broadcast, AntiX, etc.) 18 | return stripped.startsWith("[MOD]"); 19 | } 20 | 21 | @Override 22 | public void onReceive(LegacyMessage message) { 23 | 24 | } 25 | 26 | @Override 27 | public boolean streamerHideEnabled() { 28 | return StreamerModeHandler.hideModeration(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/mixin/inventory/MItemInsert.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.mixin.inventory; 2 | 3 | import io.github.homchom.recode.sys.hypercube.templates.TemplateStorageHandler; 4 | import io.github.homchom.recode.sys.hypercube.templates.TemplateUtil; 5 | import net.minecraft.client.multiplayer.ClientPacketListener; 6 | import net.minecraft.network.protocol.game.ClientboundContainerSetContentPacket; 7 | import net.minecraft.world.item.ItemStack; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Inject; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 12 | 13 | @Mixin(ClientPacketListener.class) 14 | public class MItemInsert { 15 | @Inject(method = "handleContainerContent", at = @At("HEAD")) 16 | public void handleContainerContent(ClientboundContainerSetContentPacket packet, CallbackInfo ci) { 17 | if (packet.getContainerId() == 0) { 18 | for (ItemStack stack : packet.getItems()) { 19 | if (TemplateUtil.isTemplate(stack)) { 20 | TemplateStorageHandler.addTemplate(stack); 21 | } 22 | } 23 | } 24 | } 25 | 26 | 27 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/checks/SupportCheck.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message.checks; 2 | 3 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessage; 4 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessageType; 5 | import io.github.homchom.recode.mod.features.social.chat.message.MessageCheck; 6 | import io.github.homchom.recode.mod.features.streamer.StreamerModeHandler; 7 | import io.github.homchom.recode.mod.features.streamer.StreamerModeMessageCheck; 8 | 9 | public class SupportCheck extends MessageCheck implements StreamerModeMessageCheck { 10 | 11 | @Override 12 | public LegacyMessageType getType() { 13 | return LegacyMessageType.SUPPORT; 14 | } 15 | 16 | @Override 17 | public boolean check(LegacyMessage message, String stripped) { 18 | // General support messages (Broadcast, session requests and completion, etc.) 19 | return stripped.startsWith("[SUPPORT]"); 20 | } 21 | 22 | @Override 23 | public void onReceive(LegacyMessage message) { 24 | 25 | } 26 | 27 | @Override 28 | public boolean streamerHideEnabled() { 29 | return StreamerModeHandler.hideSupport(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mixin/MMinecraft.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mixin; 2 | 3 | import io.github.homchom.recode.RecodeDispatcher; 4 | import io.github.homchom.recode.game.GameEvents; 5 | import kotlin.Unit; 6 | import net.minecraft.client.Minecraft; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | 12 | @Mixin(Minecraft.class) 13 | public abstract class MMinecraft { 14 | @Inject(method = "runTick", at = @At(value = "INVOKE", 15 | target = "Lnet/minecraft/client/Minecraft;runAllTasks()V", 16 | shift = At.Shift.BEFORE 17 | )) 18 | private void runRecodeTasksNormally(CallbackInfo ci) { 19 | RecodeDispatcher.INSTANCE.expedite(); // ensure tasks are run on runTick if not elsewhere 20 | } 21 | 22 | @Inject(method = "crash", at = @At("HEAD")) 23 | private static void handleCrashes(CallbackInfo ci) { 24 | try { 25 | GameEvents.getGameStopEvent().run(Unit.INSTANCE); 26 | } catch (Exception ignored) { 27 | // no need to use the exception because this is already during a crash 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: [pull_request, push] 3 | 4 | jobs: 5 | build: 6 | strategy: 7 | matrix: 8 | # use these Java versions 9 | java: [ 10 | 17 # current Java LTS & minimum supported by Minecraft 11 | ] 12 | # and run on both Linux and Windows 13 | os: [ubuntu-20.04, windows-2022] 14 | runs-on: ${{ matrix.os }} 15 | steps: 16 | - name: checkout repository 17 | uses: actions/checkout@v2 18 | - name: validate gradle wrapper 19 | uses: gradle/wrapper-validation-action@v1 20 | - name: setup jdk ${{ matrix.java }} 21 | uses: actions/setup-java@v3 22 | with: 23 | java-version: ${{ matrix.java }} 24 | distribution: "microsoft" 25 | cache: "gradle" 26 | - name: make gradle wrapper executable 27 | if: ${{ runner.os != 'Windows' }} 28 | run: chmod +x ./gradlew 29 | - name: build 30 | run: ./gradlew build --no-daemon 31 | - name: upload latest build 32 | # only upload jars built from latest java on one OS 33 | if: ${{ runner.os == 'Linux' && matrix.java == '17' }} 34 | uses: actions/upload-artifact@v2 35 | with: 36 | name: latest build 37 | path: build/libs/ 38 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/commands/impl/other/PingCommand.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.commands.impl.other; 2 | 3 | 4 | import com.mojang.brigadier.CommandDispatcher; 5 | import io.github.homchom.recode.mod.commands.Command; 6 | import io.github.homchom.recode.mod.commands.arguments.ArgBuilder; 7 | import io.github.homchom.recode.sys.player.chat.ChatUtil; 8 | import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; 9 | import net.minecraft.client.Minecraft; 10 | import net.minecraft.commands.CommandBuildContext; 11 | 12 | public class PingCommand extends Command { 13 | @Override 14 | public void register(Minecraft mc, CommandDispatcher cd, CommandBuildContext context) { 15 | cd.register(ArgBuilder.literal("ping") 16 | .executes(ctx -> { 17 | ChatUtil.sendMessage("§aℹ §7Your ping: §6" + mc.getConnection().getPlayerInfo(mc.player.getUUID()).getLatency() + "ms"); 18 | return 1; 19 | }) 20 | ); 21 | } 22 | 23 | @Override 24 | public String getDescription() { 25 | return "[blue]/ping[reset]\n\nShows your current ping in milliseconds."; 26 | } 27 | 28 | @Override 29 | public String getName() { 30 | return "/ping"; 31 | } 32 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mixin/render/MBlockEntityRenderDispatcher.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mixin.render; 2 | 3 | import io.github.homchom.recode.render.Blaze3DExtensions; 4 | import io.github.homchom.recode.render.DRecodeLevelRenderer; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.client.renderer.MultiBufferSource; 7 | import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher; 8 | import net.minecraft.world.level.block.entity.BlockEntity; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.ModifyVariable; 12 | 13 | @Mixin(value = BlockEntityRenderDispatcher.class) 14 | public abstract class MBlockEntityRenderDispatcher { 15 | @ModifyVariable(method = "render", at = @At("HEAD"), ordinal = 0, argsOnly = true) 16 | private MultiBufferSource outlineBlockEntities(MultiBufferSource multiBufferSource, BlockEntity blockEntity) { 17 | var processor = (DRecodeLevelRenderer) Minecraft.getInstance().levelRenderer; 18 | var outlineColor = processor.recode$getBlockEntityOutlineColor(blockEntity); 19 | if (outlineColor != null) { 20 | return Blaze3DExtensions.withOutline(multiBufferSource, outlineColor); 21 | } 22 | return multiBufferSource; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/checks/JoinFailCheck.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message.checks; 2 | 3 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessage; 4 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessageType; 5 | import io.github.homchom.recode.mod.features.social.chat.message.MessageCheck; 6 | import io.github.homchom.recode.mod.features.streamer.StreamerModeHandler; 7 | import io.github.homchom.recode.mod.features.streamer.StreamerModeMessageCheck; 8 | 9 | public class JoinFailCheck extends MessageCheck implements StreamerModeMessageCheck { 10 | 11 | private static final String JOIN_FAIL_REGEX = "^([^ ]{3,}) tried to join, but is banned \\(.*\\)!$"; 12 | 13 | @Override 14 | public LegacyMessageType getType() { 15 | return LegacyMessageType.JOIN_FAIL; 16 | } 17 | 18 | @Override 19 | public boolean check(LegacyMessage message, String stripped) { 20 | return stripped.matches(JOIN_FAIL_REGEX); 21 | } 22 | 23 | @Override 24 | public void onReceive(LegacyMessage message) { 25 | 26 | } 27 | 28 | @Override 29 | public boolean streamerHideEnabled() { 30 | return StreamerModeHandler.hideModeration(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/Logging.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("Logging") 2 | 3 | package io.github.homchom.recode 4 | 5 | import kotlinx.coroutines.CoroutineScope 6 | import kotlinx.coroutines.cancel 7 | import org.slf4j.LoggerFactory 8 | 9 | private val logger = LoggerFactory.getLogger(MOD_ID) 10 | 11 | /** 12 | * @see org.slf4j.Logger.info 13 | */ 14 | fun logInfo(message: String) = logger.info("[$MOD_NAME] $message") 15 | 16 | /** 17 | * @see org.slf4j.Logger.error 18 | */ 19 | @JvmOverloads 20 | fun logError(message: String, mentionBugReport: Boolean = false) { 21 | val bugString = if (mentionBugReport) { 22 | "\nIf you believe this is a bug, you can report it here: https://github.com/homchom/recode/issues)" 23 | } else "" 24 | logger.error("[$MOD_NAME] $message$bugString") 25 | } 26 | 27 | /** 28 | * Uses [logInfo] to log a debug message if [debug] is `true`. 29 | */ 30 | fun logDebug(message: String) = logDebug { message } 31 | 32 | /** 33 | * Uses [logInfo] to log a debug message if [debug] is `true`. 34 | */ 35 | inline fun logDebug(lazyMessage: () -> String) { 36 | if (debug) logInfo("[debug] ${lazyMessage()}") 37 | } 38 | 39 | /** 40 | * @see cancel 41 | * @see logDebug 42 | */ 43 | fun CoroutineScope.cancelAndLog(message: String) { 44 | logDebug(message) 45 | cancel(message) 46 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/player/chat/color/HSBColor.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.player.chat.color; 2 | 3 | public class HSBColor { 4 | private float hue; 5 | private float saturation; 6 | private float brightness; 7 | 8 | public HSBColor(int h, int s, int b) { 9 | this.hue = h; 10 | this.saturation = s; 11 | this.brightness = b; 12 | } 13 | 14 | public HSBColor(float[] hsb) { 15 | this.hue = hsb[0]; 16 | this.saturation = hsb[1]; 17 | this.brightness = hsb[2]; 18 | } 19 | 20 | public String toString() { 21 | return "HSB(" + hue + ", " + saturation + ", " + brightness + ")"; 22 | } 23 | 24 | public boolean isGrayscale() { 25 | return saturation == 0 || brightness == 0; 26 | } 27 | 28 | public float getBrightness() { 29 | return brightness; 30 | } 31 | 32 | public float getHue() { 33 | return hue; 34 | } 35 | 36 | public float getSaturation() { 37 | return saturation; 38 | } 39 | 40 | public void setBrightness(float b) { 41 | this.brightness = b; 42 | } 43 | 44 | public void setHue(float h) { 45 | this.hue = h; 46 | } 47 | 48 | public void setSaturation(float s) { 49 | this.saturation = s; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/commands/impl/other/RecodeCommand.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.commands.impl.other; 2 | 3 | 4 | import com.mojang.brigadier.CommandDispatcher; 5 | import io.github.homchom.recode.mod.commands.Command; 6 | import io.github.homchom.recode.mod.commands.arguments.ArgBuilder; 7 | import io.github.homchom.recode.mod.features.commands.recode.RecodeUI; 8 | import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; 9 | import net.minecraft.client.Minecraft; 10 | import net.minecraft.commands.CommandBuildContext; 11 | 12 | public class RecodeCommand extends Command { 13 | @Override 14 | public void register(Minecraft mc, CommandDispatcher cd, CommandBuildContext context) { 15 | cd.register(ArgBuilder.literal("recode") 16 | .executes(ctx -> { 17 | RecodeUI gui = new RecodeUI(); 18 | gui.scheduleOpenGui(gui); 19 | return 1; 20 | }) 21 | ); 22 | } 23 | 24 | @Override 25 | public String getDescription() { 26 | return "[blue]/recode[reset]\n\nShows information about this mod, such as this help menu, mod contributors, etc."; 27 | } 28 | 29 | @Override 30 | public String getName() { 31 | return "/recode"; 32 | } 33 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/ui/text/MiniMessageFunctions.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.ui.text 2 | 3 | import net.kyori.adventure.text.Component 4 | import net.kyori.adventure.text.minimessage.Context 5 | import net.kyori.adventure.text.minimessage.MiniMessage 6 | import net.kyori.adventure.text.minimessage.tag.Tag 7 | import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue 8 | import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver 9 | 10 | // https://github.com/KyoriPowered/adventure/issues/998 11 | /** 12 | * Escapes [MiniMessage] tags and escape characters in [input]. 13 | * 14 | * @return The escaped string. 15 | */ 16 | fun MiniMessage.escapeAll(input: String) = serialize(Component.text(input)) 17 | 18 | /** 19 | * @return A new [TagResolver] that resolves like this TagResolver but excludes [disabledTags]. 20 | */ 21 | fun TagResolver.without(vararg disabledTags: TagResolver) = object : TagResolver { 22 | override fun resolve(name: String, arguments: ArgumentQueue, ctx: Context): Tag? { 23 | if (disabledTags.any { it.has(name) }) return null 24 | return this@without.resolve(name, arguments, ctx) 25 | } 26 | 27 | override fun has(name: String): Boolean { 28 | if (disabledTags.any { it.has(name) }) return false 29 | return this@without.has(name) 30 | } 31 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/checks/PlotAdCheck.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message.checks; 2 | 3 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessage; 4 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessageType; 5 | import io.github.homchom.recode.mod.features.social.chat.message.MessageCheck; 6 | import io.github.homchom.recode.mod.features.streamer.StreamerModeHandler; 7 | import io.github.homchom.recode.mod.features.streamer.StreamerModeMessageCheck; 8 | 9 | import java.util.regex.Pattern; 10 | 11 | public class PlotAdCheck extends MessageCheck implements StreamerModeMessageCheck { 12 | 13 | private static final Pattern PLOT_AD_REGEX = Pattern.compile(" {32}\\[ Plot Ad ] {32}\\n(.+)\\n {78}"); 14 | 15 | @Override 16 | public LegacyMessageType getType() { 17 | return LegacyMessageType.PLOT_AD; 18 | } 19 | 20 | @Override 21 | public boolean check(LegacyMessage message, String stripped) { 22 | return PLOT_AD_REGEX.matcher(stripped).matches(); 23 | } 24 | 25 | @Override 26 | public void onReceive(LegacyMessage message) { 27 | 28 | } 29 | 30 | @Override 31 | public boolean streamerHideEnabled() { 32 | return StreamerModeHandler.hidePlotAds(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/event/Validation.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.event 2 | 3 | import io.github.homchom.recode.util.InvokableWrapper 4 | import io.github.homchom.recode.util.math.MixedInt 5 | 6 | /** 7 | * Creates a [SimpleValidated] event. 8 | */ 9 | fun createValidatedEvent() = createEvent, Boolean> { it.isValid } 10 | 11 | /** 12 | * A type that is validated by a [Listenable], mutating and returning [validity]. 13 | */ 14 | interface Validated { 15 | /** 16 | * The validity of this context, where positive values represent "valid". 17 | */ 18 | var validity: MixedInt 19 | 20 | val isValid get() = validity > 0 21 | 22 | fun validate(weight: MixedInt) { 23 | validity += weight 24 | } 25 | 26 | fun invalidate(weight: MixedInt) { 27 | validity -= weight 28 | } 29 | 30 | fun validate() = validate(MixedInt(1)) 31 | fun invalidate() = invalidate(MixedInt(1)) 32 | } 33 | 34 | /** 35 | * @property value 36 | * @property validity 37 | * 38 | * @see createValidatedEvent 39 | */ 40 | data class SimpleValidated @JvmOverloads constructor( 41 | override val value: T, 42 | override var validity: MixedInt = MixedInt(1) 43 | ) : Validated, InvokableWrapper 44 | 45 | fun Iterable>.mapValid() = mapNotNull { if (it.isValid) it.value else null } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/checks/PlotBoostCheck.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message.checks; 2 | 3 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessage; 4 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessageType; 5 | import io.github.homchom.recode.mod.features.social.chat.message.MessageCheck; 6 | import io.github.homchom.recode.mod.features.streamer.StreamerModeHandler; 7 | import io.github.homchom.recode.mod.features.streamer.StreamerModeMessageCheck; 8 | 9 | import java.util.regex.Pattern; 10 | 11 | public class PlotBoostCheck extends MessageCheck implements StreamerModeMessageCheck { 12 | 13 | private static final Pattern PLOT_BOOST_REGEX = Pattern.compile("\n {78}\n(.+)\n {29}\u200c→ Click to join!\n {78}"); 14 | 15 | @Override 16 | public LegacyMessageType getType() { 17 | return LegacyMessageType.PLOT_BOOST; 18 | } 19 | 20 | @Override 21 | public boolean check(LegacyMessage message, String stripped) { 22 | return PLOT_BOOST_REGEX.matcher(stripped).matches(); 23 | } 24 | 25 | @Override 26 | public void onReceive(LegacyMessage message) { 27 | 28 | } 29 | 30 | @Override 31 | public boolean streamerHideEnabled() { 32 | return StreamerModeHandler.hidePlotBoosts(); 33 | } 34 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/impl/AutomationGroup.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.impl; 2 | 3 | import io.github.homchom.recode.mod.config.structure.ConfigGroup; 4 | import io.github.homchom.recode.mod.config.structure.ConfigSubGroup; 5 | import io.github.homchom.recode.mod.config.types.BooleanSetting; 6 | import io.github.homchom.recode.mod.config.types.LongSetting; 7 | 8 | public class AutomationGroup extends ConfigGroup { 9 | public AutomationGroup(String name) { 10 | super(name); 11 | } 12 | 13 | @Override 14 | public void initialize() { 15 | 16 | // Time 17 | ConfigSubGroup time = new ConfigSubGroup("time"); 18 | time.register(new BooleanSetting("autotime", false)); 19 | time.register(new LongSetting("autotimeval", 0L)); 20 | this.register(time); 21 | 22 | // Other non sub-grouped 23 | this.register(new BooleanSetting("autowand", false)); 24 | this.register(new BooleanSetting("autoRC", false)); 25 | this.register(new BooleanSetting("autonightvis", false)); 26 | this.register(new BooleanSetting("autolagslayer", false)); 27 | this.register(new BooleanSetting("autoChatLocal", false)); 28 | this.register(new BooleanSetting("autoClickEditMsgs", true)); 29 | this.register(new BooleanSetting("autoTip", true)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/checks/TeleportCheck.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message.checks; 2 | 3 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessage; 4 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessageType; 5 | import io.github.homchom.recode.mod.features.social.chat.message.MessageCheck; 6 | import io.github.homchom.recode.mod.features.streamer.StreamerModeHandler; 7 | import io.github.homchom.recode.mod.features.streamer.StreamerModeMessageCheck; 8 | 9 | import java.util.regex.Pattern; 10 | 11 | public class TeleportCheck extends MessageCheck implements StreamerModeMessageCheck { 12 | 13 | private static final Pattern TELEPORTING_REGEX = Pattern.compile("^\\[([^ ]{3,}): Teleported ([^ ]{3,}) to ([^ ]{3,})]$"); 14 | 15 | @Override 16 | public LegacyMessageType getType() { 17 | return LegacyMessageType.TELEPORTING; 18 | } 19 | 20 | @Override 21 | public boolean check(LegacyMessage message, String stripped) { 22 | return TELEPORTING_REGEX.matcher(stripped).matches(); 23 | } 24 | 25 | @Override 26 | public void onReceive(LegacyMessage message) { 27 | 28 | } 29 | 30 | @Override 31 | public boolean streamerHideEnabled() { 32 | return StreamerModeHandler.hideModeration(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/MessageFinalizer.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message; 2 | 3 | import io.github.homchom.recode.mod.features.social.chat.message.finalizers.DebugFinalizer; 4 | import io.github.homchom.recode.mod.features.social.chat.message.finalizers.MessageGrabberFinalizer; 5 | import io.github.homchom.recode.mod.features.social.chat.message.finalizers.StreamerModeFinalizer; 6 | 7 | /** 8 | * Before a message is sent to the client, and after the message checks have been evaluated, 9 | * plus a check was accepted, all finalizers will be evaluated. The {@link MessageCheck} instance 10 | * accepted for this message can be retrieved using {@link LegacyMessage#getCheck()}. 11 | */ 12 | public abstract class MessageFinalizer { 13 | 14 | private static final MessageFinalizer[] finalizers = new MessageFinalizer[]{ 15 | new StreamerModeFinalizer(), 16 | new DebugFinalizer(), 17 | new MessageGrabberFinalizer() 18 | }; 19 | 20 | /** 21 | * Use {@link LegacyMessage#cancel()} to cancel the message 22 | */ 23 | protected abstract void receive(LegacyMessage message); 24 | 25 | public static void run(LegacyMessage message) { 26 | for (MessageFinalizer finalizer : finalizers) { 27 | finalizer.receive(message); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/checks/ScanningCheck.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message.checks; 2 | 3 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessage; 4 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessageType; 5 | import io.github.homchom.recode.mod.features.social.chat.message.MessageCheck; 6 | import io.github.homchom.recode.mod.features.streamer.StreamerModeHandler; 7 | import io.github.homchom.recode.mod.features.streamer.StreamerModeMessageCheck; 8 | 9 | import java.util.regex.Pattern; 10 | 11 | public class ScanningCheck extends MessageCheck implements StreamerModeMessageCheck { 12 | 13 | private static final Pattern SCANNING_REGEX = Pattern.compile("^Scanning \\w+(.|\n)*\\[Online] \\[Offline] \\[(IP|)Banned]\1*$"); 14 | 15 | @Override 16 | public LegacyMessageType getType() { 17 | return LegacyMessageType.SCANNING; 18 | } 19 | 20 | @Override 21 | public boolean check(LegacyMessage message, String stripped) { 22 | return SCANNING_REGEX.matcher(stripped).matches(); 23 | } 24 | 25 | @Override 26 | public void onReceive(LegacyMessage message) { 27 | 28 | } 29 | 30 | @Override 31 | public boolean streamerHideEnabled() { 32 | return StreamerModeHandler.hideModeration(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs = -Xmx1G 2 | 3 | # https://fabricmc.net/develop/ 4 | 5 | modName = recode 6 | mavenGroup = io.github.homchom 7 | 8 | # the mod version, without metadata 9 | modVersion = 0.1.0-beta.10 10 | 11 | # the current supported Minecraft version 12 | minecraftVersion = 1.20.4 13 | 14 | # the minimum version of Fabric Loader required by recode. update only as needed 15 | loaderVersion = 0.15.2 16 | 17 | # every version below this should be changed every Minecraft update 18 | # ideally, pick versions without bugs but not versions with unused features (for compatibility) 19 | 20 | fabricVersion = 0.96.1+1.20.4 21 | flkVersion = 1.11.0+kotlin.2.0.0 22 | 23 | # required dependency mods 24 | required.adventure-platform-fabric.artifact = net.kyori:adventure-platform-fabric 25 | required.adventure-platform-fabric.version = 5.12.0 26 | required.adventure-platform-fabric.versionSpec = ~ 27 | 28 | required.libgui.artifact = io.github.cottonmc:LibGui 29 | required.libgui.version = 9.2.2+1.20.2 30 | 31 | required.cloth-config.artifact = me.shedaniel.cloth:cloth-config-fabric 32 | required.cloth-config.version = 13.0.121 33 | required.cloth-config.versionSpec = >= 34 | 35 | # optional dependency mods 36 | optional.modmenu.artifact = com.terraformersmc:modmenu 37 | optional.modmenu.version = 9.0.0 38 | 39 | optional.sodium.artifact = maven.modrinth:sodium 40 | optional.sodium.version = mc1.20.4-0.5.8 -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/checks/SupportAnswerCheck.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message.checks; 2 | 3 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessage; 4 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessageType; 5 | import io.github.homchom.recode.mod.features.social.chat.message.MessageCheck; 6 | import io.github.homchom.recode.mod.features.streamer.StreamerModeHandler; 7 | import io.github.homchom.recode.mod.features.streamer.StreamerModeMessageCheck; 8 | 9 | import java.util.regex.Pattern; 10 | 11 | public class SupportAnswerCheck extends MessageCheck implements StreamerModeMessageCheck { 12 | 13 | private static final Pattern SUPPORT_ANSWER_REGEX = Pattern.compile("^.*\\n» \\w+ has answered \\w+'s question:\\n\\n.+\\n.*$"); 14 | 15 | @Override 16 | public LegacyMessageType getType() { 17 | return LegacyMessageType.SUPPORT_ANSWER; 18 | } 19 | 20 | @Override 21 | public boolean check(LegacyMessage message, String stripped) { 22 | return SUPPORT_ANSWER_REGEX.matcher(stripped).matches(); 23 | } 24 | 25 | @Override 26 | public void onReceive(LegacyMessage message) { 27 | 28 | } 29 | 30 | @Override 31 | public boolean streamerHideEnabled() { 32 | return StreamerModeHandler.hideSupport(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/checks/IncomingReportCheck.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message.checks; 2 | 3 | import io.github.homchom.recode.mod.config.LegacyConfig; 4 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessage; 5 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessageType; 6 | import io.github.homchom.recode.mod.features.social.chat.message.MessageCheck; 7 | import io.github.homchom.recode.mod.features.streamer.StreamerModeHandler; 8 | import io.github.homchom.recode.mod.features.streamer.StreamerModeMessageCheck; 9 | import io.github.homchom.recode.sys.player.chat.ChatUtil; 10 | 11 | public class IncomingReportCheck extends MessageCheck implements StreamerModeMessageCheck { 12 | 13 | @Override 14 | public LegacyMessageType getType() { 15 | return LegacyMessageType.INCOMING_REPORT; 16 | } 17 | 18 | @Override 19 | public boolean check(LegacyMessage message, String stripped) { 20 | return stripped.startsWith("! Incoming Report "); 21 | } 22 | 23 | @Override 24 | public void onReceive(LegacyMessage message) { 25 | ChatUtil.playSound(LegacyConfig.getSound("incomingReportSound")); 26 | } 27 | 28 | @Override 29 | public boolean streamerHideEnabled() { 30 | return StreamerModeHandler.hideModeration(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/feature/visual/SignRenderDistance.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.feature.visual 2 | 3 | import io.github.homchom.recode.Power 4 | import io.github.homchom.recode.event.listenEach 5 | import io.github.homchom.recode.feature.AddsFeature 6 | import io.github.homchom.recode.feature.registerFeature 7 | import io.github.homchom.recode.mc 8 | import io.github.homchom.recode.mod.config.LegacyConfig 9 | import io.github.homchom.recode.render.RenderBlockEntitiesEvent 10 | import net.minecraft.world.level.block.entity.SignBlockEntity 11 | 12 | @OptIn(AddsFeature::class) 13 | object FSignRenderDistance { 14 | init { 15 | registerFeature("Sign Render Distance") { 16 | onEnable { renderSigns() } 17 | } 18 | } 19 | 20 | private fun Power.renderSigns() { 21 | listenEach(RenderBlockEntitiesEvent) { context -> 22 | for (element in context) { 23 | val blockEntity = element.value 24 | if (blockEntity is SignBlockEntity) { 25 | val cameraPos = mc.cameraEntity!!.blockPosition() 26 | val distance = LegacyConfig.getInteger("signRenderDistance").toDouble() 27 | if (!blockEntity.getBlockPos().closerThan(cameraPos, distance)) { 28 | element.invalidate() 29 | } 30 | } 31 | } 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mixin/render/chat/MChatScreen.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mixin.render.chat; 2 | 3 | import com.llamalad7.mixinextras.injector.wrapoperation.Operation; 4 | import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; 5 | import io.github.homchom.recode.feature.social.DGuiWithSideChat; 6 | import net.minecraft.client.GuiMessageTag; 7 | import net.minecraft.client.Minecraft; 8 | import net.minecraft.client.gui.components.ChatComponent; 9 | import net.minecraft.client.gui.screens.ChatScreen; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | 13 | @Mixin(ChatScreen.class) 14 | public abstract class MChatScreen { 15 | @WrapOperation(method = "render", at = @At(value = "INVOKE", 16 | target = "Lnet/minecraft/client/gui/components/ChatComponent;getMessageTagAt(DD)Lnet/minecraft/client/GuiMessageTag;" 17 | )) 18 | private GuiMessageTag recognizeSideChatTags( 19 | ChatComponent mainChat, 20 | double screenX, 21 | double screenY, 22 | Operation operation 23 | ) { 24 | var mainTag = operation.call(mainChat, screenX, screenY); 25 | if (mainTag != null) return mainTag; 26 | var gui = (DGuiWithSideChat) Minecraft.getInstance().gui; 27 | return gui.getRecode$sideChat().getMessageTagAt(screenX, screenY); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/checks/SupportQuestionCheck.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message.checks; 2 | 3 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessage; 4 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessageType; 5 | import io.github.homchom.recode.mod.features.social.chat.message.MessageCheck; 6 | import io.github.homchom.recode.mod.features.streamer.StreamerModeHandler; 7 | import io.github.homchom.recode.mod.features.streamer.StreamerModeMessageCheck; 8 | 9 | import java.util.regex.Pattern; 10 | 11 | public class SupportQuestionCheck extends MessageCheck implements StreamerModeMessageCheck { 12 | 13 | private static final Pattern SUPPORT_QUESTION_REGEX = Pattern.compile("^.*?» Support Question: \\(Click to answer\\)\\nAsked by \\w+ \\[[a-zA-Z]+]\\n.+$"); 14 | 15 | @Override 16 | public LegacyMessageType getType() { 17 | return LegacyMessageType.SUPPORT_QUESTION; 18 | } 19 | 20 | @Override 21 | public boolean check(LegacyMessage message, String stripped) { 22 | return SUPPORT_QUESTION_REGEX.matcher(stripped).matches(); 23 | } 24 | 25 | @Override 26 | public void onReceive(LegacyMessage message) { 27 | 28 | } 29 | 30 | @Override 31 | public boolean streamerHideEnabled() { 32 | return StreamerModeHandler.hideSupport(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/game/NBTExtensions.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused") 2 | 3 | package io.github.homchom.recode.game 4 | 5 | import net.minecraft.nbt.CompoundTag 6 | 7 | fun CompoundTag.getByteOrNull(key: String) = getNullable(key, this::getByte) 8 | 9 | fun CompoundTag.getShortOrNull(key: String) = getNullable(key, this::getShort) 10 | 11 | fun CompoundTag.getIntOrNull(key: String) = getNullable(key, this::getInt) 12 | 13 | fun CompoundTag.getLongOrNull(key: String) = getNullable(key, this::getLong) 14 | 15 | fun CompoundTag.getFloatOrNull(key: String) = getNullable(key, this::getFloat) 16 | 17 | fun CompoundTag.getDoubleOrNull(key: String) = getNullable(key, this::getDouble) 18 | 19 | fun CompoundTag.getStringOrNull(key: String) = getNullable(key, this::getString) 20 | 21 | fun CompoundTag.getByteArrayOrNull(key: String) = getNullable(key, this::getByteArray) 22 | 23 | fun CompoundTag.getIntArrayOrNull(key: String) = getNullable(key, this::getIntArray) 24 | 25 | fun CompoundTag.getLongArrayOrNull(key: String) = getNullable(key, this::getLongArray) 26 | 27 | fun CompoundTag.getCompoundOrNull(key: String) = getNullable(key, this::getCompound) 28 | 29 | fun CompoundTag.getListOrNull(key: String, elementType: Byte) = 30 | if (contains(key)) getList(key, elementType.toInt()) else null 31 | 32 | private inline fun CompoundTag.getNullable(key: String, getter: (String) -> R) = 33 | if (contains(key)) getter(key) else null -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/checks/BuycraftXUpdateCheck.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message.checks; 2 | 3 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessage; 4 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessageType; 5 | import io.github.homchom.recode.mod.features.social.chat.message.MessageCheck; 6 | import io.github.homchom.recode.mod.features.streamer.StreamerModeHandler; 7 | import io.github.homchom.recode.mod.features.streamer.StreamerModeMessageCheck; 8 | 9 | import java.util.regex.Pattern; 10 | 11 | public class BuycraftXUpdateCheck extends MessageCheck implements StreamerModeMessageCheck { 12 | 13 | private static final Pattern BUYCRAFT_UPDATE_REGEX = Pattern.compile("^A new version of BuycraftX \\([0-9.]+\\) is available\\. Go to your server panel at https://server.tebex.io/plugins to download the update\\.$"); 14 | 15 | @Override 16 | public LegacyMessageType getType() { 17 | return null; 18 | } 19 | 20 | @Override 21 | public boolean check(LegacyMessage message, String stripped) { 22 | return BUYCRAFT_UPDATE_REGEX.matcher(stripped).matches(); 23 | } 24 | 25 | @Override 26 | public void onReceive(LegacyMessage message) { 27 | 28 | } 29 | 30 | @Override 31 | public boolean streamerHideEnabled() { 32 | return StreamerModeHandler.hideBuycraftUpdate(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mixin/multiplayer/MConnection.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mixin.multiplayer; 2 | 3 | import io.github.homchom.recode.multiplayer.MultiplayerEvents; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.network.Connection; 6 | import net.minecraft.network.PacketListener; 7 | import net.minecraft.network.PacketSendListener; 8 | import net.minecraft.network.protocol.Packet; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 13 | 14 | @Mixin(Connection.class) 15 | public abstract class MConnection { 16 | @Inject(method = "genericsFtw", at = @At("HEAD")) 17 | private static void runReceivePacketEvent( 18 | Packet packet, 19 | PacketListener packetListener, 20 | CallbackInfo ci 21 | ) { 22 | Minecraft.getInstance().execute(() -> MultiplayerEvents.getReceivePacketEvent().run(packet)); 23 | } 24 | 25 | @Inject(method = "sendPacket", at = @At("HEAD")) 26 | private void runSendPacketEvent( 27 | Packet packet, 28 | PacketSendListener packetSendListener, 29 | boolean flush, 30 | CallbackInfo ci 31 | ) { 32 | Minecraft.getInstance().execute(() -> MultiplayerEvents.getSendPacketEvent().run(packet)); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/util/regex/DynamicRegex.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.util.regex 2 | 3 | import io.github.homchom.recode.util.MutableCase 4 | 5 | /** 6 | * Creates a [RegexFactory] of [Regex] patterns based on a given input. For performance, patterns are 7 | * cached when the input is `null` or consecutively equal. 8 | * 9 | * @see regex 10 | */ 11 | fun dynamicRegex(builder: RegexPatternBuilder.(T) -> Unit): RegexFactory = 12 | NullCachedRegexFactory(builder) 13 | 14 | /** 15 | * @see dynamicRegex 16 | */ 17 | sealed interface RegexFactory { 18 | operator fun invoke(input: T): Regex 19 | } 20 | 21 | /** 22 | * @see dynamicRegex 23 | */ 24 | private class NullCachedRegexFactory( 25 | private val builder: RegexPatternBuilder.(input: T) -> Unit 26 | ) : RegexFactory { 27 | private var prevInput: MutableCase? = null 28 | private lateinit var prevResult: Regex 29 | private lateinit var nullDefault: Regex 30 | 31 | override fun invoke(input: T): Regex { 32 | if (input == null) { 33 | if (!::nullDefault.isInitialized) { 34 | nullDefault = regex { builder(input) } 35 | } 36 | return nullDefault 37 | } 38 | 39 | prevInput?.let { (content) -> 40 | if (input == content) return prevResult 41 | } 42 | prevInput = MutableCase(input) 43 | prevResult = regex { builder(input) } 44 | return prevResult 45 | } 46 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/impl/HidingGroup.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.impl; 2 | 3 | import io.github.homchom.recode.mod.config.structure.ConfigGroup; 4 | import io.github.homchom.recode.mod.config.structure.ConfigSubGroup; 5 | import io.github.homchom.recode.mod.config.types.BooleanSetting; 6 | import io.github.homchom.recode.mod.config.types.StringSetting; 7 | 8 | public class HidingGroup extends ConfigGroup { 9 | public HidingGroup(String name) { 10 | super(name); 11 | } 12 | 13 | @Override 14 | public void initialize() { 15 | // Non sub-grouped 16 | this.register(new BooleanSetting("hideJoinLeaveMessages", false)); 17 | this.register(new BooleanSetting("hideVarScopeMessages", false)); 18 | this.register(new BooleanSetting("hideScoreboardOnF3", true)); 19 | this.register(new BooleanSetting("stackDuplicateMsgs", false)); 20 | 21 | // Regular Expressions 22 | ConfigSubGroup regex = new ConfigSubGroup("regex"); 23 | regex.register(new BooleanSetting("hideMsgMatchingRegex", false)); 24 | regex.register(new StringSetting("hideMsgRegex", "")); 25 | this.register(regex); 26 | 27 | // Staff 28 | ConfigSubGroup staff = new ConfigSubGroup("staff"); 29 | staff.register(new BooleanSetting("hideSessionSpy", false)); 30 | staff.register(new BooleanSetting("hideMutedChat", false)); 31 | this.register(staff); 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/util/Matcher.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.util 2 | 3 | /** 4 | * A general-purpose function object that matches inputs of type [T] against a specification, returning matches 5 | * of type [R] or `null`. 6 | * 7 | * @see matcherOf 8 | */ 9 | fun interface Matcher { 10 | fun match(input: T): R? 11 | 12 | infix fun matches(input: T) = match(input) != null 13 | } 14 | 15 | /** 16 | * Creates a [MatcherList] with [initialPredicates]. 17 | */ 18 | fun matcherOf(vararg initialPredicates: Matcher) = 19 | MatcherList().apply { addAll(initialPredicates) } 20 | 21 | /** 22 | * Creates a [MatcherList] with [initialPredicates]. 23 | */ 24 | fun > matcherOf(initialPredicates: Collection) = 25 | MatcherList().apply { addAll(initialPredicates) } 26 | 27 | /** 28 | * A [List]-backed implementation of [Matcher] that yields the first successful match among its elements. 29 | */ 30 | @JvmInline 31 | value class MatcherList private constructor( 32 | private val elements: MutableList> 33 | ) : Matcher, MutableList> by elements { 34 | constructor() : this(mutableListOf()) 35 | 36 | override fun match(input: T) = firstNotNullOfOrNull { 37 | try { 38 | it.match(input) 39 | } catch (npe: NullPointerException) { 40 | npe.printStackTrace() 41 | throw npe 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/util/regex/RegexModifiers.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.util.regex 2 | 3 | sealed interface InlineRegexOption { 4 | operator fun plus(modifier: InlineRegexOption): InlineRegexOption 5 | operator fun minus(modifier: InlineRegexOption): InlineRegexOption 6 | } 7 | 8 | enum class RegexModifier(private val character: Char) : InlineRegexOption { 9 | IgnoreCase('i'), 10 | MatchPerLine('m'), 11 | MatchLineBreaksInAny('s'); 12 | 13 | override fun plus(modifier: InlineRegexOption): InlineRegexOption = 14 | MutableRegexModifier("$character$modifier") 15 | 16 | override fun minus(modifier: InlineRegexOption): InlineRegexOption = 17 | MutableRegexModifier("$character-$modifier") 18 | 19 | override fun toString() = character.toString() 20 | } 21 | 22 | private class MutableRegexModifier(private val builder: StringBuilder) : InlineRegexOption { 23 | private val hasNegation get() = '-' in builder 24 | 25 | constructor(string: String) : this(StringBuilder(string)) 26 | 27 | override fun plus(modifier: InlineRegexOption) = apply { 28 | if (hasNegation) { 29 | builder.insert(0, modifier) 30 | } else { 31 | builder.append(modifier) 32 | } 33 | } 34 | 35 | override fun minus(modifier: InlineRegexOption) = apply { 36 | if (!hasNegation) builder.append('-') 37 | builder.append(modifier) 38 | } 39 | 40 | override fun toString() = builder.toString() 41 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/commands/TemplatesMenu.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.commands; 2 | 3 | import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription; 4 | import io.github.cottonmc.cotton.gui.widget.WPlainPanel; 5 | import io.github.cottonmc.cotton.gui.widget.data.Insets; 6 | import io.github.homchom.recode.sys.hypercube.templates.TemplateItem; 7 | import io.github.homchom.recode.sys.hypercube.templates.TemplateStorageHandler; 8 | import io.github.homchom.recode.sys.renderer.IMenu; 9 | import io.github.homchom.recode.sys.renderer.widgets.ItemScrollablePanel; 10 | import net.minecraft.world.item.ItemStack; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | public class TemplatesMenu extends LightweightGuiDescription implements IMenu { 16 | 17 | public TemplatesMenu() { 18 | } 19 | 20 | @Override 21 | public void open(String... args) { 22 | List items = new ArrayList<>(); 23 | for (TemplateItem item : TemplateStorageHandler.getInstance().getRegistered()) { 24 | items.add(item.getStack()); 25 | } 26 | WPlainPanel root = new WPlainPanel(); 27 | ItemScrollablePanel panel = ItemScrollablePanel.with(items); 28 | root.setSize(256, 90); 29 | panel.setSize(256, 90); 30 | 31 | root.add(panel, 0, 0, 256, 90); 32 | 33 | setRootPanel(root); 34 | root.validate(this); 35 | root.setInsets(Insets.ROOT_PANEL); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /mod/src/main/resources/fabric_mod_json_template.txt: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "recode", 4 | "version": "${version}", 5 | "name": "${modName}", 6 | "description": "a utility mod for DiamondFire to make development more fun", 7 | "contributors": ["homchom", "The CodeUtilities Team"], 8 | "contact": { 9 | "sources": "https://github.com/homchom/recode", 10 | "issues": "https://discord.gg/ndGVFutEHg" 11 | }, 12 | "environment": "client", 13 | "license": "LGPL-3.0", 14 | "icon": "assets/recode/textures/gui/recode.png", 15 | "entrypoints": { 16 | "client": [ 17 | { 18 | "adapter": "kotlin", 19 | "value": "io.github.homchom.recode.Recode" 20 | }, 21 | "io.github.homchom.recode.mod.features.keybinds.Keybinds" 22 | ], 23 | "modmenu": ["io.github.homchom.recode.mod.config.ModMenuIntegration"], 24 | "preLaunch": [], 25 | "main": [], 26 | "server": [] 27 | }, 28 | "mixins": [ 29 | "recode.mixins.json", 30 | "recodeLegacy.mixins.json" 31 | ], 32 | "depends": { 33 | "minecraft": "$minecraftVersion", 34 | "fabricloader": "^$loaderVersion", 35 | "fabric-api": "^$fabricVersion", 36 | "fabric-language-kotlin": "^$flkVersion", 37 | $dependencyMods 38 | }, 39 | "conflicts": { 40 | "optifabric": "*" 41 | }, 42 | "custom": { 43 | "modmenu:clientsideOnly": true 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/feature/visual/BuiltInResourcePacks.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.feature.visual 2 | 3 | import io.github.homchom.recode.MOD_ID 4 | import io.github.homchom.recode.Recode 5 | import io.github.homchom.recode.feature.AddsFeature 6 | import io.github.homchom.recode.feature.registerFeature 7 | import io.github.homchom.recode.id 8 | import io.github.homchom.recode.render.RGB 9 | import io.github.homchom.recode.ui.text.style 10 | import io.github.homchom.recode.ui.text.text 11 | import io.github.homchom.recode.ui.text.toVanillaComponent 12 | import net.fabricmc.fabric.api.resource.ResourceManagerHelper 13 | import net.fabricmc.fabric.api.resource.ResourcePackActivationType 14 | 15 | @OptIn(AddsFeature::class) 16 | object FBuiltInResourcePacks { 17 | init { 18 | registerFeature("Built-in Resource Packs") { 19 | registerPack("better_unicode", RGB(0x6770ff)) 20 | } 21 | } 22 | 23 | private fun registerPack( 24 | id: String, 25 | displayColor: RGB, 26 | activationType: ResourcePackActivationType = ResourcePackActivationType.DEFAULT_ENABLED 27 | ) { 28 | 29 | val packDescription = text { 30 | literal("[$MOD_ID] ") 31 | translate("resourcePack.recode.$id", style().color(displayColor)) 32 | } 33 | 34 | ResourceManagerHelper.registerBuiltinResourcePack( 35 | id(id), 36 | Recode, 37 | packDescription.toVanillaComponent(), 38 | activationType 39 | ) 40 | } 41 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/impl/CommandsGroup.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.impl; 2 | 3 | import io.github.homchom.recode.mod.config.structure.ConfigGroup; 4 | import io.github.homchom.recode.mod.config.structure.ConfigSubGroup; 5 | import io.github.homchom.recode.mod.config.types.BooleanSetting; 6 | import io.github.homchom.recode.mod.config.types.IntegerSetting; 7 | import io.github.homchom.recode.mod.config.types.LongSetting; 8 | 9 | public class CommandsGroup extends ConfigGroup { 10 | public CommandsGroup(String name) { 11 | super(name); 12 | } 13 | 14 | @Override 15 | public void initialize() { 16 | // top-level 17 | this.register(new BooleanSetting("dfCommands", true)); 18 | this.register(new BooleanSetting("errorSound", true)); 19 | this.register(new BooleanSetting("colorReplacePicker", false)); 20 | 21 | // auto /msg 22 | ConfigSubGroup autoMessage = new ConfigSubGroup("automsg"); 23 | autoMessage.register(new BooleanSetting("automsg", false)); 24 | autoMessage.register(new BooleanSetting("automsg_timeout", true)); 25 | autoMessage.register(new LongSetting("automsg_timeoutNumber", 300000L)); 26 | this.register(autoMessage); 27 | 28 | // heads 29 | ConfigSubGroup heads = new ConfigSubGroup("heads"); 30 | heads.register(new BooleanSetting("headsEnabled", false)); 31 | heads.register(new IntegerSetting("headMenuMaxRender", 1000)); 32 | this.register(heads); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/hypercube/codeaction/Action.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.hypercube.codeaction; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.JsonObject; 5 | import io.github.homchom.recode.sys.util.StringUtil; 6 | 7 | public class Action { 8 | private final String name; 9 | private final CodeBlock codeBlock; 10 | private final Tag[] tags; 11 | private final String[] aliases; 12 | private final DisplayItem icon; 13 | 14 | Action(JsonObject jsonObject){ 15 | this.name = jsonObject.get("name").getAsString(); 16 | this.codeBlock = ActionDump.getCodeBlock(jsonObject.get("codeblockName").getAsString()).get(0); 17 | this.tags = new Tag[jsonObject.getAsJsonArray("tags").size()]; 18 | int i = 0; 19 | for(JsonElement tag : jsonObject.getAsJsonArray("tags")){ 20 | this.tags[i] = new Tag(tag.getAsJsonObject()); 21 | i++; 22 | } 23 | this.aliases = StringUtil.toStringArray(jsonObject.get("aliases").getAsJsonArray()); 24 | this.icon = new DisplayItem(jsonObject.getAsJsonObject("icon")); 25 | } 26 | 27 | public String getName() { 28 | return name; 29 | } 30 | 31 | public CodeBlock getCodeBlock() { 32 | return codeBlock; 33 | } 34 | 35 | public DisplayItem getIcon() { 36 | return icon; 37 | } 38 | 39 | public String[] getAliases() { 40 | return aliases; 41 | } 42 | 43 | public Tag[] getTags() { 44 | return tags; 45 | } 46 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/commands/impl/text/CopyTextCommand.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.commands.impl.text; 2 | 3 | import com.mojang.brigadier.CommandDispatcher; 4 | import com.mojang.brigadier.arguments.StringArgumentType; 5 | import io.github.homchom.recode.mod.commands.Command; 6 | import io.github.homchom.recode.mod.commands.arguments.ArgBuilder; 7 | import io.github.homchom.recode.sys.player.chat.ChatType; 8 | import io.github.homchom.recode.sys.player.chat.ChatUtil; 9 | import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; 10 | import net.minecraft.client.Minecraft; 11 | import net.minecraft.commands.CommandBuildContext; 12 | 13 | public class CopyTextCommand extends Command { 14 | 15 | @Override 16 | public void register(Minecraft mc, CommandDispatcher cd, CommandBuildContext context) { 17 | cd.register(ArgBuilder.literal("copytxt") 18 | .then(ArgBuilder.argument("text", StringArgumentType.greedyString()) 19 | .executes(ctx -> { 20 | mc.keyboardHandler.setClipboard(ctx.getArgument("text", String.class)); 21 | ChatUtil.sendMessage("Copied text!", ChatType.INFO_BLUE); 22 | return 1; 23 | }) 24 | ) 25 | ); 26 | } 27 | 28 | @Override 29 | public String getDescription() { 30 | return null; 31 | } 32 | 33 | @Override 34 | public String getName() { 35 | return null; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/ConversationTimer.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat; 2 | 3 | import io.github.homchom.recode.mod.config.LegacyConfig; 4 | import io.github.homchom.recode.sys.file.ILoader; 5 | import io.github.homchom.recode.sys.player.chat.ChatType; 6 | import io.github.homchom.recode.sys.player.chat.ChatUtil; 7 | import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; 8 | 9 | public class ConversationTimer implements ILoader { 10 | public static boolean isTimerOn = false; 11 | public static String currentConversation = null; 12 | public static String conversationUpdateTime = null; 13 | 14 | @Override 15 | public void load() { 16 | ClientTickEvents.START_CLIENT_TICK.register(mc -> { 17 | if (currentConversation != null && !LegacyConfig.getBoolean("automsg")) { 18 | currentConversation = null; 19 | conversationUpdateTime = null; 20 | return; 21 | } 22 | if (!isTimerOn || !LegacyConfig.getBoolean("automsg_timeout")) return; 23 | if (System.currentTimeMillis() - LegacyConfig.getLong("automsg_timeoutNumber") >= Long.parseLong(conversationUpdateTime)) { 24 | ChatUtil.sendMessage("Your conversation with " + currentConversation + " was inactive and ended.", ChatType.INFO_BLUE); 25 | currentConversation = null; 26 | conversationUpdateTime = null; 27 | isTimerOn = false; 28 | } 29 | }); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/render/ScreenEvents.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("ScreenEvents") 2 | 3 | package io.github.homchom.recode.render 4 | 5 | import io.github.homchom.recode.event.wrapFabricEvent 6 | import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents.* 7 | import net.minecraft.client.Minecraft 8 | import net.minecraft.client.gui.GuiGraphics 9 | import net.minecraft.client.gui.screens.Screen 10 | 11 | val BeforeInitScreenEvent = wrapFabricEvent(BEFORE_INIT) { listener -> 12 | BeforeInit { client, screen, scaledWidth, scaledHeight -> 13 | listener(ScreenInitContext(client, screen, scaledWidth, scaledHeight)) 14 | } 15 | } 16 | 17 | val AfterInitScreenEvent = wrapFabricEvent(AFTER_INIT) { listener -> 18 | AfterInit { client, screen, scaledWidth, scaledHeight -> 19 | listener(ScreenInitContext(client, screen, scaledWidth, scaledHeight)) 20 | } 21 | } 22 | 23 | data class ScreenInitContext( 24 | val client: Minecraft, 25 | val screen: Screen, 26 | val scaledWidth: Int, 27 | val scaledHeight: Int 28 | ) 29 | 30 | fun Screen.afterRender() = wrapFabricEvent(afterRender(this)) { listener -> 31 | AfterRender { screen, drawContext, mouseX, mouseY, tickDelta -> 32 | listener(ScreenRenderContext(screen, drawContext, mouseX, mouseY, tickDelta)) 33 | } 34 | } 35 | 36 | data class ScreenRenderContext( 37 | val screen: Screen, 38 | val guiGraphics: GuiGraphics, 39 | val mouseX: Int, 40 | val mouseY: Int, 41 | val tickDelta: Float 42 | ) 43 | 44 | fun Screen.onRemove() = wrapFabricEvent(remove(this)) { Remove(it) } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/structure/ConfigGroup.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.structure; 2 | 3 | import io.github.homchom.recode.mod.commands.IManager; 4 | import net.minecraft.network.chat.Component; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.Optional; 9 | 10 | public abstract class ConfigGroup implements IManager, IRawTranslation { 11 | private final List> settings = new ArrayList<>(); 12 | private final List subGroups = new ArrayList<>(); 13 | private final String name; 14 | 15 | private Component rawKey = null; 16 | 17 | public ConfigGroup(String name) { 18 | this.name = name; 19 | } 20 | 21 | @Override 22 | public ConfigGroup setRawKey(String key) { 23 | this.rawKey = Component.literal(key); 24 | return this; 25 | } 26 | 27 | @Override 28 | public Optional getRawKey() { 29 | return Optional.ofNullable(rawKey); 30 | } 31 | 32 | public String getName() { 33 | return name; 34 | } 35 | 36 | public void register(ConfigSetting setting) { 37 | settings.add(setting); 38 | } 39 | 40 | @Override 41 | public void register(ConfigSubGroup object) { 42 | this.subGroups.add(object); 43 | } 44 | 45 | @Override 46 | public List getRegistered() { 47 | return subGroups; 48 | } 49 | 50 | public List> getSettings() { 51 | return settings; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/game/GameTime.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.game 2 | 3 | import io.github.homchom.recode.Power 4 | import io.github.homchom.recode.event.listen 5 | import io.github.homchom.recode.event.listenEach 6 | import kotlinx.coroutines.flow.collect 7 | import kotlinx.coroutines.flow.take 8 | import kotlinx.coroutines.flow.takeWhile 9 | 10 | /** 11 | * The current client tick. 12 | * 13 | * @see waitTicks 14 | * @see AfterClientTickEvent 15 | */ 16 | val currentTick get() = TickRecorder.currentTick 17 | 18 | /** 19 | * Suspends until [AfterClientTickEvent] runs [ticks] times. Unlike [kotlinx.coroutines.delay], this is 20 | * event-based and respects tick rates. 21 | */ 22 | suspend fun waitTicks(ticks: Int) = AfterClientTickEvent.notifications.take(ticks).collect() 23 | 24 | private object TickRecorder { 25 | var currentTick = 0L 26 | 27 | private val power = Power() 28 | 29 | init { 30 | power.listenEach(AfterClientTickEvent) { currentTick++ } 31 | } 32 | } 33 | 34 | class TickCountdown(private val duration: Int, private val onFinish: () -> Unit = {}) { 35 | val isActive get() = counter > 0 36 | 37 | private var counter = 0 38 | private val power = Power(startEnabled = true) 39 | 40 | fun wind() { 41 | val launch = !isActive 42 | counter = duration 43 | if (launch) power.listen(AfterClientTickEvent) { 44 | takeWhile { --counter > 0 } 45 | }.invokeOnCompletion { exception -> 46 | counter = 0 47 | if (exception == null) onFinish() 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/renderer/widgets/CButton.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.renderer.widgets; 2 | 3 | import io.github.cottonmc.cotton.gui.client.LibGui; 4 | import io.github.cottonmc.cotton.gui.client.ScreenDrawing; 5 | import io.github.cottonmc.cotton.gui.widget.WButton; 6 | import net.fabricmc.api.EnvType; 7 | import net.fabricmc.api.Environment; 8 | import net.minecraft.client.gui.GuiGraphics; 9 | 10 | public class CButton extends WButton { 11 | 12 | //paint method copied from wbutton and modified 13 | @Environment(EnvType.CLIENT) 14 | @Override 15 | public void paint(GuiGraphics guiGraphics, int x, int y, int mouseX, int mouseY) { 16 | boolean hovered = (mouseX >= 0 && mouseY >= 0 && mouseX < getWidth() 17 | && mouseY < getHeight()); 18 | int color = 0; 19 | if (hovered || isFocused()) { 20 | color = LibGui.isDarkMode() ? 0xff393E46 : 0xffdddddd; 21 | } 22 | if (!isEnabled()) { 23 | color = LibGui.isDarkMode() ? 0xaa00ADB5 : 0xff00ADB5; 24 | } 25 | 26 | int tcolor = LibGui.isDarkMode() ? 0xaaaaaa : 0x222222; 27 | 28 | if (getLabel() != null) { 29 | 30 | ScreenDrawing.coloredRect(guiGraphics, x,y+3, width, height, color); 31 | 32 | ScreenDrawing.drawString(guiGraphics, getLabel().getVisualOrderText(), alignment, x, 33 | y + ((20 - 8) / 2), width, tcolor); 34 | } 35 | } 36 | 37 | @Override 38 | public void setSize(int x, int y) { 39 | width = x; 40 | height = y; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mixin/render/MGui.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mixin.render; 2 | 3 | import com.llamalad7.mixinextras.injector.wrapoperation.Operation; 4 | import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; 5 | import io.github.homchom.recode.feature.social.DGuiWithSideChat; 6 | import io.github.homchom.recode.feature.social.SideChat; 7 | import net.minecraft.client.gui.Gui; 8 | import net.minecraft.client.gui.GuiGraphics; 9 | import net.minecraft.client.gui.components.ChatComponent; 10 | import org.jetbrains.annotations.NotNull; 11 | import org.spongepowered.asm.mixin.Mixin; 12 | import org.spongepowered.asm.mixin.Unique; 13 | import org.spongepowered.asm.mixin.injection.At; 14 | 15 | @Mixin(Gui.class) 16 | public abstract class MGui implements DGuiWithSideChat { 17 | @Unique 18 | private final SideChat sideChat = new SideChat(); 19 | 20 | @WrapOperation(method = "render", at = @At(value = "INVOKE", 21 | target = "Lnet/minecraft/client/gui/components/ChatComponent;render(Lnet/minecraft/client/gui/GuiGraphics;III)V" 22 | )) 23 | private void renderSideChat( 24 | ChatComponent mainChat, 25 | GuiGraphics graphics, 26 | int tickDelta, 27 | int x, 28 | int y, 29 | Operation operation 30 | ) { 31 | operation.call(mainChat, graphics, tickDelta, x, y); 32 | sideChat.render(graphics, tickDelta, x, y); 33 | } 34 | 35 | @NotNull 36 | @Override 37 | public SideChat getRecode$sideChat() { 38 | return sideChat; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/LegacyMessageType.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message; 2 | 3 | public enum LegacyMessageType { 4 | OTHER, 5 | 6 | // ---------------------------------- 7 | 8 | // General 9 | DIRECT_MESSAGE(true), 10 | PLOT_AD(true), 11 | PLOT_BOOST(true), 12 | 13 | // Support 14 | SUPPORT, 15 | SUPPORT_QUESTION(true), 16 | SUPPORT_ANSWER(true), 17 | 18 | // Moderation 19 | MODERATION, 20 | INCOMING_REPORT, 21 | SILENT_PUNISHMENT, 22 | SCANNING(2), 23 | TELEPORTING, 24 | JOIN_FAIL, 25 | 26 | // Admin 27 | SPIES, 28 | ADMIN, 29 | 30 | // Custom regex 31 | STREAMER_MODE_REGEX; 32 | 33 | // ---------------------------------- 34 | 35 | private final int messageAmount; 36 | private final boolean hasSound; 37 | 38 | LegacyMessageType() { 39 | this(1); 40 | } 41 | 42 | LegacyMessageType(int messageAmount) { 43 | this(messageAmount, false); 44 | } 45 | 46 | LegacyMessageType(boolean hasSound) { 47 | this(1, hasSound); 48 | } 49 | 50 | LegacyMessageType(int messageAmount, boolean hasSound) { 51 | this.messageAmount = messageAmount; 52 | this.hasSound = hasSound; 53 | } 54 | 55 | public int getMessageAmount() { 56 | return messageAmount; 57 | } 58 | 59 | public boolean hasSound() { 60 | return hasSound; 61 | } 62 | 63 | public boolean is(LegacyMessageType compareTo) { 64 | return this == compareTo; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/hypercube/templates/CompressionUtil.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.hypercube.templates; 2 | 3 | import java.io.*; 4 | import java.nio.charset.StandardCharsets; 5 | import java.util.Base64; 6 | import java.util.zip.GZIPInputStream; 7 | import java.util.zip.GZIPOutputStream; 8 | 9 | public class CompressionUtil { 10 | 11 | public static byte[] fromBase64(byte[] bytes) { 12 | return Base64.getDecoder().decode(bytes); 13 | } 14 | 15 | public static byte[] toBase64(byte[] bytes) { 16 | return Base64.getEncoder().encode(bytes); 17 | } 18 | 19 | public static byte[] fromGZIP(byte[] bytes) throws IOException { 20 | if (bytes == null) { 21 | return null; 22 | } 23 | 24 | GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(bytes)); 25 | BufferedReader bf = new BufferedReader(new InputStreamReader(gis, StandardCharsets.UTF_8)); 26 | StringBuilder outStr = new StringBuilder(); 27 | String line; 28 | while ((line = bf.readLine()) != null) { 29 | outStr.append(line); 30 | } 31 | 32 | return outStr.toString().getBytes(); 33 | } 34 | 35 | public static byte[] toGZIP(byte[] bytes) throws IOException { 36 | if (bytes == null) { 37 | return null; 38 | } 39 | ByteArrayOutputStream obj = new ByteArrayOutputStream(); 40 | GZIPOutputStream gzip = new GZIPOutputStream(obj); 41 | gzip.write(bytes); 42 | gzip.close(); 43 | 44 | return obj.toByteArray(); 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/impl/SidedChatGroup.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.impl; 2 | 3 | import io.github.homchom.recode.mod.config.ConfigSounds; 4 | import io.github.homchom.recode.mod.config.structure.ConfigGroup; 5 | import io.github.homchom.recode.mod.config.structure.ConfigSubGroup; 6 | import io.github.homchom.recode.mod.config.types.EnumSetting; 7 | import io.github.homchom.recode.mod.config.types.IntegerSetting; 8 | import io.github.homchom.recode.mod.config.types.SoundSetting; 9 | import io.github.homchom.recode.mod.config.types.StringSetting; 10 | import io.github.homchom.recode.sys.sidedchat.ChatRule; 11 | 12 | public class SidedChatGroup extends ConfigGroup { 13 | public SidedChatGroup(String name) { 14 | super(name); 15 | } 16 | 17 | @Override 18 | public void initialize() { 19 | this.register(new IntegerSetting("sidechat_width",0)); 20 | 21 | for (ChatRule chatRule : ChatRule.getChatRules()) { 22 | ConfigSubGroup chatRuleSubGroup = new ConfigSubGroup(chatRule.getInternalName()); 23 | 24 | if (chatRule.getChatRuleType() == ChatRule.ChatRuleType.CUSTOM) 25 | chatRuleSubGroup.register(new StringSetting("custom_filter")); 26 | 27 | chatRuleSubGroup.register(new EnumSetting<>(ChatRule.getChatRuleConfigSideName(chatRule), ChatRule.ChatSide.class, ChatRule.ChatSide.MAIN)); 28 | chatRuleSubGroup.register(new SoundSetting(ChatRule.getChatRuleConfigSoundName(chatRule)).setSelected(ConfigSounds.NONE)); 29 | this.register(chatRuleSubGroup); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mixin/MixinConfig.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mixin 2 | 3 | import org.objectweb.asm.tree.ClassNode 4 | import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin 5 | import org.spongepowered.asm.mixin.extensibility.IMixinInfo 6 | import org.spongepowered.asm.service.MixinService 7 | 8 | // recode's mixin configuration plugin, referenced in resources/recode.mixins.json 9 | class MixinPluginRecode : IMixinConfigPlugin { 10 | override fun shouldApplyMixin(targetClassName: String, mixinClassName: String): Boolean { 11 | // handle optional mixins 12 | val annotations = MixinService.getService() 13 | .bytecodeProvider 14 | .getClassNode(mixinClassName) 15 | .visibleAnnotations 16 | ?: return true 17 | annotations.filterIsInstance() 18 | .singleOrNull() 19 | ?.run { return shouldApplyMixin } 20 | 21 | return true 22 | } 23 | 24 | override fun onLoad(mixinPackage: String) {} 25 | override fun getRefMapperConfig() = null 26 | override fun acceptTargets(myTargets: MutableSet, otherTargets: MutableSet) {} 27 | override fun getMixins() = null 28 | 29 | override fun preApply( 30 | targetClassName: String, 31 | targetClass: ClassNode, 32 | mixinClassName: String, 33 | mixinInfo: IMixinInfo 34 | ) {} 35 | 36 | override fun postApply( 37 | targetClassName: String, 38 | targetClass: ClassNode, 39 | mixinClassName: String, 40 | mixinInfo: IMixinInfo 41 | ) {} 42 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/commands/impl/item/TemplatesCommand.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.commands.impl.item; 2 | 3 | import com.mojang.brigadier.CommandDispatcher; 4 | import io.github.homchom.recode.mod.commands.Command; 5 | import io.github.homchom.recode.mod.commands.arguments.ArgBuilder; 6 | import io.github.homchom.recode.mod.features.commands.TemplatesMenu; 7 | import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.commands.CommandBuildContext; 10 | 11 | public class TemplatesCommand extends Command { 12 | 13 | @Override 14 | public void register(Minecraft mc, CommandDispatcher cd, CommandBuildContext context) { 15 | cd.register(ArgBuilder.literal("templates") 16 | .executes(ctx -> { 17 | if (this.isCreative(mc)) { 18 | TemplatesMenu templateStorageUI = new TemplatesMenu(); 19 | templateStorageUI.scheduleOpenGui(templateStorageUI); 20 | } else { 21 | return -1; 22 | } 23 | return 1; 24 | }) 25 | ); 26 | } 27 | 28 | @Override 29 | public String getDescription() { 30 | return "[blue]/templates[reset]\n" 31 | + "\n" 32 | + "Shows a list of recently used code templates. Click on the item to get it in your inventory."; 33 | } 34 | 35 | @Override 36 | public String getName() { 37 | return "/templates"; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/commands/impl/item/CodeVaultCommand.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.commands.impl.item; 2 | 3 | import com.mojang.brigadier.CommandDispatcher; 4 | import io.github.homchom.recode.mod.commands.Command; 5 | import io.github.homchom.recode.mod.commands.arguments.ArgBuilder; 6 | import io.github.homchom.recode.mod.features.commands.CodeVaultMenu; 7 | import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.commands.CommandBuildContext; 10 | 11 | public class CodeVaultCommand extends Command { 12 | 13 | @Override 14 | public void register(Minecraft mc, CommandDispatcher cd, CommandBuildContext context) { 15 | cd.register(ArgBuilder.literal("codevault") 16 | .executes(ctx -> { 17 | if (isCreative(mc)) { 18 | CodeVaultMenu menu = new CodeVaultMenu(); 19 | menu.scheduleOpenGui(menu); 20 | } 21 | return 1; 22 | }) 23 | ); 24 | } 25 | 26 | @Override 27 | public String getDescription() { 28 | return "[blue]/codevault[reset]\n" 29 | + "\n" 30 | + "Browses the code templates uploaded by other people. Click the item in the menu to get the code template.\n" 31 | + "To add your own code templates, join the plot [green]Code Vault[reset] (ID:43780) and upload the templates there."; 32 | } 33 | 34 | @Override 35 | public String getName() { 36 | return "/codevault"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/renderer/widgets/CColorPreset.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.renderer.widgets; 2 | 3 | import io.github.cottonmc.cotton.gui.widget.WButton; 4 | import io.github.cottonmc.cotton.gui.widget.data.InputResult; 5 | import io.github.homchom.recode.sys.renderer.RenderUtil; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.client.gui.GuiGraphics; 8 | import net.minecraft.client.resources.sounds.SimpleSoundInstance; 9 | import net.minecraft.sounds.SoundEvents; 10 | 11 | import java.awt.*; 12 | 13 | public class CColorPreset extends WButton { 14 | 15 | private final Color color; 16 | private final CColorPicker picker; 17 | 18 | public CColorPreset(Color color, CColorPicker picker) { 19 | this.color = color; 20 | this.picker = picker; 21 | } 22 | 23 | @Override 24 | public void paint(GuiGraphics guiGraphics, int x, int y, int mouseX, int mouseY) { 25 | RenderUtil.drawRect(guiGraphics, x-1, y-1, x+11, y+11, Color.black); 26 | RenderUtil.drawRect(guiGraphics, x, y, x+10, y+10, this.color); 27 | } 28 | 29 | @Override 30 | public InputResult onClick(int x, int y, int button) { 31 | if (isEnabled() && isWithinBounds(x, y)) { 32 | Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F)); 33 | 34 | this.picker.setColor(this.color); 35 | } 36 | return InputResult.IGNORED; 37 | } 38 | 39 | @Override 40 | public void setSize(int x, int y) { 41 | this.width = x; 42 | this.height = y; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/impl/HighlightGroup.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.impl; 2 | 3 | import io.github.homchom.recode.mod.config.ConfigSounds; 4 | import io.github.homchom.recode.mod.config.structure.ConfigGroup; 5 | import io.github.homchom.recode.mod.config.structure.ConfigSubGroup; 6 | import io.github.homchom.recode.mod.config.types.BooleanSetting; 7 | import io.github.homchom.recode.mod.config.types.FloatSetting; 8 | import io.github.homchom.recode.mod.config.types.SoundSetting; 9 | import io.github.homchom.recode.mod.config.types.StringSetting; 10 | 11 | public class HighlightGroup extends ConfigGroup { 12 | public HighlightGroup(String name) { 13 | super(name); 14 | } 15 | 16 | @Override 17 | public void initialize() { 18 | // Non sub-grouped 19 | this.register(new BooleanSetting("highlight", false)); 20 | this.register(new BooleanSetting("highlightIgnoreSender", false)); 21 | 22 | // Text 23 | ConfigSubGroup text = new ConfigSubGroup("text"); 24 | text.register(new StringSetting("highlightMatcher", "{name}")); 25 | text.register(new StringSetting("highlightPrefix", "&e")); 26 | this.register(text); 27 | 28 | // Sound 29 | ConfigSubGroup sound = new ConfigSubGroup("sound"); 30 | sound.register(new SoundSetting("highlightSound") 31 | .setSelected(ConfigSounds.SHIELD_BLOCK)); 32 | sound.register(new FloatSetting("highlightSoundVolume", 3F)); 33 | sound.register(new BooleanSetting("highlightOwnSenderSound", false)); 34 | this.register(sound); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/mixin/render/MChatScreen.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.mixin.render; 2 | 3 | import io.github.homchom.recode.sys.sidedchat.ChatShortcut; 4 | import net.minecraft.client.gui.screens.ChatScreen; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.injection.At; 7 | import org.spongepowered.asm.mixin.injection.ModifyArg; 8 | 9 | @Mixin(ChatScreen.class) 10 | public class MChatScreen { 11 | @ModifyArg(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiGraphics;fill(IIIII)V"), index = 4) 12 | private int getTextboxColor(int defaultColour) { 13 | ChatShortcut currentChatShortcut = ChatShortcut.getCurrentChatShortcut(); 14 | 15 | // if there is one active - use it 16 | if (currentChatShortcut != null) { 17 | return currentChatShortcut.getColor().getRGB(); 18 | } 19 | // else use the default minecraft option 20 | else return defaultColour; 21 | } 22 | 23 | @ModifyArg(method = "keyPressed", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/ChatScreen;handleChatInput(Ljava/lang/String;Z)Z"), index = 0) 24 | private String insertPrefix(String interceptedMessage) { 25 | ChatShortcut currentChatShortcut = ChatShortcut.getCurrentChatShortcut(); 26 | 27 | if (currentChatShortcut != null) { 28 | // the prefix already includes the space 29 | return currentChatShortcut.getPrefix() + interceptedMessage; 30 | } 31 | // else just send the message 32 | else return interceptedMessage; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/commands/impl/item/template/AbstractTemplateCommand.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.commands.impl.item.template; 2 | 3 | import com.mojang.brigadier.CommandDispatcher; 4 | import io.github.homchom.recode.mod.commands.Command; 5 | import io.github.homchom.recode.mod.commands.arguments.ArgBuilder; 6 | import io.github.homchom.recode.sys.hypercube.templates.TemplateUtil; 7 | import io.github.homchom.recode.sys.player.chat.ChatType; 8 | import io.github.homchom.recode.sys.player.chat.ChatUtil; 9 | import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; 10 | import net.minecraft.client.Minecraft; 11 | import net.minecraft.commands.CommandBuildContext; 12 | import net.minecraft.world.item.ItemStack; 13 | 14 | public abstract class AbstractTemplateCommand extends Command { 15 | 16 | 17 | @Override 18 | public void register(Minecraft mc, CommandDispatcher cd, CommandBuildContext context) { 19 | cd.register(ArgBuilder.literal(getCmdName()) 20 | .executes(ctx -> { 21 | ItemStack item = mc.player.getMainHandItem(); 22 | if (TemplateUtil.isTemplate(item)) { 23 | withTemplate(item); 24 | return 1; 25 | } else { 26 | ChatUtil.sendMessage("This item is not a template!", ChatType.FAIL); 27 | return -1; 28 | } 29 | }) 30 | ); 31 | } 32 | 33 | protected abstract String getCmdName(); 34 | 35 | protected abstract void withTemplate(ItemStack stack); 36 | } 37 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/render/text/FormattedCharSequenceExtensions.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("FormattedCharSequenceExtensions") 2 | 3 | package io.github.homchom.recode.render.text 4 | 5 | import io.github.homchom.recode.util.std.fromCodePoint 6 | import net.minecraft.util.FormattedCharSequence 7 | import net.minecraft.util.FormattedCharSink 8 | 9 | /** 10 | * @return Whether this [FormattedCharSequence] and [other] yield the same styles and code points. 11 | */ 12 | infix fun FormattedCharSequence.looksLike(other: FormattedCharSequence): Boolean { 13 | val list = mutableListOf() // even indices are styles; odd indices are code points 14 | accept { _, style, codePoint -> 15 | list += style 16 | list += codePoint 17 | true 18 | } 19 | var index = 0 20 | val result = other.accept { _, style, codePoint -> 21 | if (index == list.size) return@accept false 22 | style == list[index++] && codePoint == list[index++] 23 | } 24 | return result && index == list.size 25 | } 26 | 27 | /** 28 | * [FormattedCharSequence.accept]s this [FormattedCharSequence], adjusting the `index` parameter 29 | * passed to [sink] to be absolute instead of relative. Surrogate pairs are handled but not validated. 30 | */ 31 | fun FormattedCharSequence.acceptWithAbsoluteIndex(sink: FormattedCharSink): Boolean { 32 | var absoluteIndex = 0 33 | return accept { _, style, codePoint -> 34 | val shouldContinue = sink.accept(absoluteIndex++, style, codePoint) 35 | if (String.fromCodePoint(codePoint)[0].isHighSurrogate()) { 36 | absoluteIndex++ 37 | } 38 | shouldContinue 39 | } 40 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/config/Config.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.config 2 | 3 | import io.github.homchom.recode.mod.config.LegacyConfig 4 | import io.github.homchom.recode.mod.config.structure.ConfigManager 5 | import io.github.homchom.recode.util.std.HeteroMap 6 | import io.github.homchom.recode.util.std.MutableHeteroMap 7 | 8 | // right now, this object just encapsulates LegacyConfig with a cache 9 | // TODO: with config refactor, make it in control of the config file and menu 10 | object Config { 11 | private val map = object : MutableHeteroMap>() { 12 | operator fun get(key: Setting) = getRaw(key) 13 | } 14 | 15 | private val updateMap = mutableMapOf Unit>() 16 | 17 | @JvmStatic 18 | operator fun get(setting: Setting): T? { 19 | map[setting]?.let { return it } 20 | 21 | val value = tryPut(setting) ?: return null 22 | val string = setting.configString 23 | if (!updateMap.containsKey(string)) { 24 | updateMap[string] = { tryPut(setting) } 25 | } 26 | return value 27 | } 28 | 29 | fun save() { 30 | for (updater in updateMap.values) updater() 31 | } 32 | 33 | private fun tryPut(setting: Setting): T? { 34 | val legacySetting = ConfigManager.getInstance().find(setting.configString) 35 | // see Config todo 36 | val legacyValue = LegacyConfig.getValue(legacySetting, Any::class.java) as T? 37 | if (legacyValue != null) map[setting] = legacyValue 38 | return legacyValue 39 | } 40 | } 41 | 42 | interface Setting : HeteroMap.Key { 43 | val configString: String 44 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/sys/renderer/RenderUtil.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.sys.renderer; 2 | 3 | import com.mojang.blaze3d.systems.RenderSystem; 4 | import com.mojang.blaze3d.vertex.*; 5 | import net.minecraft.client.gui.GuiGraphics; 6 | 7 | import java.awt.*; 8 | 9 | public class RenderUtil { 10 | public static void drawRect(GuiGraphics guiGraphics, int left, int top, int right, int bottom, Color color) 11 | { 12 | guiGraphics.fill(left, top, right, bottom, color.getRGB()); 13 | } 14 | 15 | public static void drawGradientRect(GuiGraphics guiGraphics, int xStart, int yStart, int xEnd, int yEnd, Color colorStart, Color colorEnd, int zOffset) { 16 | RenderSystem.enableBlend(); 17 | RenderSystem.disableDepthTest(); 18 | RenderSystem.defaultBlendFunc(); 19 | RenderSystem.blendEquation(7425); 20 | Tesselator tessellator = Tesselator.getInstance(); 21 | BufferBuilder bufferBuilder = tessellator.getBuilder(); 22 | bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); 23 | guiGraphics.fillGradient(xStart, yStart, xEnd, yEnd, zOffset, colorStart.getRGB(), colorEnd.getRGB()); 24 | tessellator.end(); 25 | RenderSystem.blendEquation(7424); 26 | RenderSystem.disableBlend(); 27 | RenderSystem.enableDepthTest(); 28 | } 29 | 30 | protected void drawGradientRect(GuiGraphics guiGraphics, BufferBuilder bufferBuilder, int xStart, int yStart, int xEnd, int yEnd, int z, int colorStart, int colorEnd) { 31 | guiGraphics.fillGradient(xStart, yStart, xEnd, yEnd, z, colorStart, colorEnd); 32 | } 33 | 34 | public static void drawBox(PoseStack matrixStack) { 35 | 36 | } 37 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/event/EventTransformations.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("EventTransformations") 2 | 3 | package io.github.homchom.recode.event 4 | 5 | import io.github.homchom.recode.Power 6 | import kotlinx.coroutines.flow.FlowCollector 7 | import kotlinx.coroutines.flow.flow 8 | import kotlinx.coroutines.flow.merge 9 | 10 | /** 11 | * @see kotlinx.coroutines.flow.transform 12 | */ 13 | inline fun Listenable.transform(crossinline transform: suspend FlowCollector.(T) -> Unit) = 14 | object : Listenable { 15 | override val notifications = flow { 16 | this@transform.notifications.collect { transform(it) } 17 | } 18 | 19 | override fun use(source: Power) = this@transform.use(source) 20 | } 21 | 22 | /** 23 | * @see kotlinx.coroutines.flow.map 24 | */ 25 | inline fun Listenable.map(crossinline transform: (T) -> R) = 26 | transform { emit(transform(it)) } 27 | 28 | /** 29 | * @see kotlinx.coroutines.flow.filter 30 | */ 31 | inline fun Listenable.filter(crossinline predicate: (T) -> Boolean) = 32 | transform { if (predicate(it)) emit(it) } 33 | 34 | /** 35 | * @see kotlinx.coroutines.flow.filterIsInstance 36 | */ 37 | inline fun Listenable<*>.filterIsInstance() = 38 | transform { if (it is R) emit(it) } 39 | 40 | /** 41 | * @see merge 42 | */ 43 | fun merge(vararg events: Listenable) = events.asList().merge() 44 | 45 | /** 46 | * @see Iterable.merge 47 | */ 48 | fun Iterable>.merge() = object : Listenable { 49 | override val notifications = this@merge.map { it.notifications }.merge() 50 | 51 | override fun use(source: Power) { 52 | for (event in this@merge) event.use(source) 53 | } 54 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/feature/visual/CodeSearch.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.feature.visual 2 | 3 | import io.github.homchom.recode.Power 4 | import io.github.homchom.recode.event.listenEach 5 | import io.github.homchom.recode.feature.AddsFeature 6 | import io.github.homchom.recode.feature.registerFeature 7 | import io.github.homchom.recode.hypercube.state.PlotMode 8 | import io.github.homchom.recode.hypercube.state.currentDFState 9 | import io.github.homchom.recode.hypercube.state.isInMode 10 | import io.github.homchom.recode.mc 11 | import io.github.homchom.recode.mod.features.commands.CodeSearcher 12 | import io.github.homchom.recode.render.OutlineBlockEntitiesEvent 13 | import io.github.homchom.recode.render.RGBA 14 | import net.minecraft.world.level.block.entity.SignBlockEntity 15 | import kotlin.math.sqrt 16 | 17 | @OptIn(AddsFeature::class) 18 | object FCodeSearch { 19 | init { 20 | registerFeature("Code Search") { 21 | onEnable { outlineBlockEntities() } 22 | } 23 | } 24 | 25 | private fun Power.outlineBlockEntities() = listenEach(OutlineBlockEntitiesEvent) { context -> 26 | if (!currentDFState.isInMode(PlotMode.Dev)) return@listenEach 27 | for (element in context) { 28 | val blockEntity = element.blockEntity 29 | if (blockEntity is SignBlockEntity && CodeSearcher.isSignMatch(blockEntity)) { 30 | val distance = sqrt(blockEntity.getBlockPos().distSqr(mc.cameraEntity!!.blockPosition())) 31 | // TODO: test if alpha actually makes a difference 32 | val alpha = (distance.coerceIn(1.0, 15.0) * 17).toInt() 33 | element.outlineColor = RGBA(255, 255, 255, alpha) 34 | } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/hypercube/DFMiniMessage.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.hypercube 2 | 3 | import io.github.homchom.recode.ui.text.literalText 4 | import net.kyori.adventure.text.minimessage.MiniMessage 5 | import net.kyori.adventure.text.minimessage.tag.Tag 6 | import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver 7 | import net.kyori.adventure.text.minimessage.tag.standard.StandardTags 8 | 9 | /** 10 | * A [MiniMessage] instance to match DiamondFire's MiniMessage behavior. 11 | */ 12 | val dfMiniMessage = MiniMessage.builder().run { 13 | tags(DFMiniMessageTags.all) 14 | build() 15 | } 16 | 17 | /** 18 | * An object providing access to DiamondFire's MiniMessage [TagResolver]s. 19 | * 20 | * @see dfMiniMessage 21 | * @see StandardTags 22 | */ 23 | @Suppress("MemberVisibilityCanBePrivate") 24 | object DFMiniMessageTags { 25 | private const val MAX_REPETITION_COUNT = 32 26 | 27 | // TODO: remove this when adventure 5.15.0 28 | inline val standard get() = StandardTags.defaults() 29 | 30 | val space = repetitionTagResolver("space", " ") 31 | val repeatableNewline = repetitionTagResolver("newline", "\n") 32 | 33 | val all = TagResolver.resolver(standard, space, repeatableNewline) 34 | 35 | private fun repetitionTagResolver(name: String, literal: String) = 36 | TagResolver.resolver(name) { args, context -> 37 | val count = if (args.hasNext()) { 38 | args.pop().asInt().orElseThrow { 39 | context.newException("Count must be a number") 40 | } 41 | } else 1 42 | 43 | val repeated = literal.repeat(count.coerceAtMost(MAX_REPETITION_COUNT)) 44 | Tag.selfClosingInserting(literalText(repeated)) 45 | } 46 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/feature/Feature.kt: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.feature 2 | 3 | import io.github.homchom.recode.Power 4 | import io.github.homchom.recode.PowerCallback 5 | import kotlinx.coroutines.DelicateCoroutinesApi 6 | import kotlinx.coroutines.GlobalScope 7 | import kotlinx.coroutines.launch 8 | 9 | @RequiresOptIn("Feature registration irreversibly mutates global state and should only occur in " + 10 | "init blocks of object declarations") 11 | annotation class AddsFeature 12 | 13 | /** 14 | * Registers a feature with [builder]. 15 | * 16 | * NOTE: Features have little special functionality at the moment, but should still be used as various refactors 17 | * progress. See the wiki for more information. 18 | * 19 | * @return This feature's [Power]. 20 | */ 21 | @AddsFeature 22 | @Suppress("UNUSED_PARAMETER") 23 | inline fun registerFeature(name: String, builder: FeatureBuilder.() -> Unit): Power { 24 | val feature = FeatureBuilder().apply(builder) 25 | 26 | val power = feature.buildPower() 27 | // temporary 28 | @OptIn(DelicateCoroutinesApi::class) 29 | GlobalScope.launch { power.up() } 30 | 31 | return power 32 | } 33 | 34 | @AddsFeature 35 | class FeatureBuilder { 36 | private val enableCallbacks = mutableListOf() 37 | private val disableCallbacks = mutableListOf() 38 | 39 | fun onEnable(callback: PowerCallback) { 40 | enableCallbacks += callback 41 | } 42 | 43 | fun onDisable(callback: PowerCallback) { 44 | disableCallbacks += callback 45 | } 46 | 47 | fun buildPower() = Power( 48 | onEnable = { 49 | for (callback in enableCallbacks) callback() 50 | }, 51 | onDisable = { 52 | for (callback in disableCallbacks) callback() 53 | } 54 | ) 55 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/config/impl/MiscellaneousGroup.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.config.impl; 2 | 3 | import io.github.homchom.recode.mod.config.ConfigSounds; 4 | import io.github.homchom.recode.mod.config.internal.DestroyItemResetType; 5 | import io.github.homchom.recode.mod.config.structure.ConfigGroup; 6 | import io.github.homchom.recode.mod.config.structure.ConfigSubGroup; 7 | import io.github.homchom.recode.mod.config.types.BooleanSetting; 8 | import io.github.homchom.recode.mod.config.types.DoubleSetting; 9 | import io.github.homchom.recode.mod.config.types.EnumSetting; 10 | import io.github.homchom.recode.mod.config.types.SoundSetting; 11 | 12 | public class MiscellaneousGroup extends ConfigGroup { 13 | public MiscellaneousGroup(String name) { 14 | super(name); 15 | } 16 | 17 | @Override 18 | public void initialize() { 19 | // Non sub-grouped 20 | this.register(new BooleanSetting("itemApi", true)); 21 | this.register(new EnumSetting<>("destroyItemReset", DestroyItemResetType.class, DestroyItemResetType.OFF)); 22 | this.register(new SoundSetting("incomingReportSound") 23 | .setSelected(ConfigSounds.FLUTE)); 24 | this.register(new BooleanSetting("debugMode", false)); 25 | 26 | // Quick Number Change 27 | ConfigSubGroup quickNum = new ConfigSubGroup("quicknum"); 28 | quickNum.register(new BooleanSetting("quicknum", true)); 29 | quickNum.register(new BooleanSetting("quicknumSound", true)); 30 | quickNum.register(new DoubleSetting("quicknumPrimaryAmount", 1.0)); 31 | quickNum.register(new DoubleSetting("quicknumSecondaryAmount", 10d)); 32 | quickNum.register(new DoubleSetting("quicknumTertiaryAmount", 0.1)); 33 | this.register(quickNum); 34 | 35 | } 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/checks/DirectMessageCheck.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message.checks; 2 | 3 | import io.github.homchom.recode.mod.features.social.chat.ConversationTimer; 4 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessage; 5 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessageType; 6 | import io.github.homchom.recode.mod.features.social.chat.message.MessageCheck; 7 | import io.github.homchom.recode.mod.features.streamer.StreamerModeHandler; 8 | import io.github.homchom.recode.mod.features.streamer.StreamerModeMessageCheck; 9 | 10 | public class DirectMessageCheck extends MessageCheck implements StreamerModeMessageCheck { 11 | 12 | private static final String DIRECT_MESSAGE_REGEX = "^\\[(\\w{3,16}) → You] .+$"; 13 | 14 | @Override 15 | public LegacyMessageType getType() { 16 | return LegacyMessageType.DIRECT_MESSAGE; 17 | } 18 | 19 | @Override 20 | public boolean check(LegacyMessage message, String stripped) { 21 | return stripped.matches(DIRECT_MESSAGE_REGEX); 22 | } 23 | 24 | @Override 25 | public void onReceive(LegacyMessage message) { 26 | // update conversation end timer 27 | if (ConversationTimer.currentConversation != null && usernameMatches(message, ConversationTimer.currentConversation)) { 28 | ConversationTimer.conversationUpdateTime = String.valueOf(System.currentTimeMillis()); 29 | } 30 | } 31 | 32 | @Override 33 | public boolean streamerHideEnabled() { 34 | return StreamerModeHandler.hideDMs(); 35 | } 36 | 37 | public static boolean usernameMatches(LegacyMessage message, String username) { 38 | return message.getStripped().matches("^\\["+ username +" → You] .+$"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/commands/arguments/types/ChoiceArgumentType.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.commands.arguments.types; 2 | 3 | import com.mojang.brigadier.StringReader; 4 | import com.mojang.brigadier.arguments.ArgumentType; 5 | import com.mojang.brigadier.context.CommandContext; 6 | import com.mojang.brigadier.exceptions.CommandSyntaxException; 7 | import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; 8 | import com.mojang.brigadier.suggestion.Suggestions; 9 | import com.mojang.brigadier.suggestion.SuggestionsBuilder; 10 | import net.minecraft.commands.SharedSuggestionProvider; 11 | import net.minecraft.network.chat.Component; 12 | 13 | import java.util.Arrays; 14 | import java.util.concurrent.CompletableFuture; 15 | 16 | public class ChoiceArgumentType implements ArgumentType { 17 | public static final SimpleCommandExceptionType UNKNOWN_TYPE_EXCEPTION = new SimpleCommandExceptionType(Component.literal("Unknown type")); 18 | private final String[] suggestions; 19 | 20 | private ChoiceArgumentType(String[] suggestions) { 21 | this.suggestions = suggestions; 22 | } 23 | 24 | public static ChoiceArgumentType choice(String[] suggestions) { 25 | return new ChoiceArgumentType(suggestions); 26 | } 27 | 28 | public String parse(StringReader stringReader) throws CommandSyntaxException { 29 | String string = stringReader.readUnquotedString(); 30 | 31 | if (!Arrays.asList(this.suggestions).contains(string)) { 32 | throw UNKNOWN_TYPE_EXCEPTION.createWithContext(stringReader); 33 | } 34 | 35 | return string; 36 | } 37 | 38 | public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { 39 | return SharedSuggestionProvider.suggest(this.suggestions, builder); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/mixin/render/MChestRenderer.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.mixin.render; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import io.github.homchom.recode.mod.config.LegacyConfig; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.client.renderer.MultiBufferSource; 7 | import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; 8 | import net.minecraft.client.renderer.blockentity.ChestRenderer; 9 | import net.minecraft.world.level.block.Blocks; 10 | import net.minecraft.world.level.block.entity.BlockEntity; 11 | import net.minecraft.world.level.block.entity.ChestBlockEntity; 12 | import net.minecraft.world.level.block.entity.LidBlockEntity; 13 | import net.minecraft.world.level.block.state.BlockState; 14 | import org.spongepowered.asm.mixin.Mixin; 15 | import org.spongepowered.asm.mixin.injection.At; 16 | import org.spongepowered.asm.mixin.injection.Inject; 17 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 18 | 19 | @Mixin(ChestRenderer.class) 20 | public abstract class MChestRenderer implements BlockEntityRenderer { 21 | @Inject(method = "render(Lnet/minecraft/world/level/block/entity/BlockEntity;FLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;II)V", at = @At("HEAD"), cancellable = true) 22 | public void render(T entity, float tickDelta, PoseStack poseStack, MultiBufferSource multiBufferSource, int light, int overlay, CallbackInfo ci) { 23 | if (LegacyConfig.getBoolean("chestReplacement") && entity instanceof ChestBlockEntity) { 24 | ci.cancel(); 25 | 26 | BlockState state = Blocks.BARREL.defaultBlockState(); 27 | Minecraft.getInstance().getBlockRenderer().renderSingleBlock(state, poseStack, multiBufferSource, light, overlay); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /mod/src/main/java/io/github/homchom/recode/mod/features/social/chat/message/finalizers/StreamerModeFinalizer.java: -------------------------------------------------------------------------------- 1 | package io.github.homchom.recode.mod.features.social.chat.message.finalizers; 2 | 3 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessage; 4 | import io.github.homchom.recode.mod.features.social.chat.message.LegacyMessageType; 5 | import io.github.homchom.recode.mod.features.social.chat.message.MessageCheck; 6 | import io.github.homchom.recode.mod.features.social.chat.message.MessageFinalizer; 7 | import io.github.homchom.recode.mod.features.social.chat.message.checks.DirectMessageCheck; 8 | import io.github.homchom.recode.mod.features.streamer.StreamerModeMessageCheck; 9 | 10 | public class StreamerModeFinalizer extends MessageFinalizer { 11 | 12 | private static final String[] HIDE_DMS_EXEMPTIONS = new String[]{ 13 | "RyanLand", 14 | "Vattendroppen236", 15 | "Reasonless" 16 | }; 17 | 18 | @Override 19 | protected void receive(LegacyMessage message) { 20 | MessageCheck check = message.getCheck(); 21 | 22 | if ( 23 | check instanceof StreamerModeMessageCheck 24 | && ((StreamerModeMessageCheck) check).streamerHideEnabled() 25 | && !matchesDirectMessageExemptions(message) 26 | ) { 27 | message.cancel(); 28 | } 29 | } 30 | 31 | private static boolean matchesDirectMessageExemptions(LegacyMessage message) { 32 | if (message.typeIs(LegacyMessageType.DIRECT_MESSAGE)) { 33 | String stripped = message.getStripped(); 34 | 35 | for (String username : HIDE_DMS_EXEMPTIONS) { 36 | if (DirectMessageCheck.usernameMatches(message, username)) { 37 | return true; 38 | } 39 | } 40 | } 41 | return false; 42 | } 43 | } 44 | --------------------------------------------------------------------------------