Repository: isXander/Debugify Branch: main Commit: e6d218185202 Files: 255 Total size: 398.5 KB Directory structure: gitextract_dituu3lz/ ├── .bugs ├── .editorconfig ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug-report.yml │ │ ├── config.yml │ │ └── patch-request.yml │ └── workflows/ │ ├── check-bug-fixes.yml │ ├── gradle.yml │ └── publish.yml ├── .gitignore ├── GUIDELINES.md ├── LICENSE ├── PATCHED.md ├── README.md ├── build.gradle.kts ├── changelogs/ │ ├── 1.18.2/ │ │ ├── 1.0.0.md │ │ ├── 1.1.0.md │ │ ├── 1.10.0.md │ │ ├── 1.11.0.md │ │ ├── 1.2.0.md │ │ ├── 1.2.1.md │ │ ├── 1.2.2.md │ │ ├── 1.3.0.md │ │ ├── 1.4.0.md │ │ ├── 1.4.1.md │ │ ├── 1.5.0.md │ │ ├── 1.6.0.md │ │ ├── 1.7.0.md │ │ ├── 1.7.1.md │ │ ├── 1.7.2.md │ │ ├── 1.8.0.md │ │ ├── 1.8.1.md │ │ └── 1.9.0.md │ ├── 1.19/ │ │ ├── 2.0.0.md │ │ ├── 2.1.0.md │ │ ├── 2.2.0.md │ │ ├── 2.3.0.md │ │ ├── 2.3.1.md │ │ └── 2.3.2.md │ ├── 1.19.1/ │ │ ├── 2.3.3.md │ │ ├── 2.3.4.md │ │ └── 2.4.0.md │ ├── 1.19.2/ │ │ ├── 2.4.1.md │ │ ├── 2.5.0.md │ │ ├── 2.6.0.md │ │ ├── 2.6.1.md │ │ ├── 2.6.2.md │ │ ├── 2.7.0.md │ │ ├── 2.7.1.md │ │ └── 2.8.0.md │ ├── 1.19.3/ │ │ ├── 1.19.3+1.0.md │ │ ├── 1.19.3+1.1.md │ │ └── 1.19.3+1.2.md │ ├── 1.19.4/ │ │ ├── 1.19.4+1.0.md │ │ ├── 1.19.4+1.1.md │ │ ├── 1.19.4+2.0.md │ │ ├── 1.19.4+2.1.md │ │ └── 1.19.4+2.2.md │ ├── 1.20/ │ │ ├── 1.20+1.0.md │ │ └── 1.20+1.1.md │ ├── 1.20.1/ │ │ ├── 1.20.1+1.0.md │ │ ├── 1.20.1+1.1.md │ │ └── 1.20.1+2.0.md │ ├── 1.20.2/ │ │ └── 1.20.2+1.0.md │ ├── 1.20.3/ │ │ ├── 1.20.3+1.0.md │ │ └── 1.20.3+1.1.md │ ├── 1.20.4/ │ │ ├── 1.20.4+1.0.md │ │ └── 1.20.4+1.1.md │ ├── 1.21/ │ │ └── 1.21+1.0.md │ ├── 1.21.1/ │ │ └── 1.21.1+1.0.md │ ├── 1.21.10/ │ │ ├── 1.21.10+1.0.md │ │ └── 1.21.10+1.1.md │ ├── 1.21.11/ │ │ └── 1.21.11+1.0.md │ ├── 1.21.3/ │ │ └── 1.21.3+1.0.md │ ├── 1.21.4/ │ │ ├── 1.21.4+1.0.md │ │ └── 1.21.4+1.1.md │ ├── 1.21.5/ │ │ └── 1.21.5+1.0.md │ ├── 1.21.7/ │ │ └── 1.21.7+1.0.md │ ├── 1.21.8/ │ │ └── 1.21.8+1.0.md │ ├── 26.1.2/ │ │ ├── 26.1.2+1.0.md │ │ └── 26.1.2.2.md │ └── header.md ├── crowdin.yml ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── modstitch.ct ├── scripts/ │ └── check_bug_fixes.py ├── settings.gradle.kts └── src/ ├── client/ │ ├── java/ │ │ └── dev/ │ │ └── isxander/ │ │ └── debugify/ │ │ └── client/ │ │ ├── DebugifyClient.java │ │ ├── gui/ │ │ │ ├── BugFixController.java │ │ │ ├── ConfigGuiHelper.java │ │ │ └── NoYACLScreen.java │ │ ├── helpers/ │ │ │ ├── mc118740/ │ │ │ │ └── LocalPlayerDuck.java │ │ │ ├── mc122477/ │ │ │ │ └── KeyboardPollCounter.java │ │ │ ├── mc147605/ │ │ │ │ └── TextFieldHolder.java │ │ │ ├── mc197260/ │ │ │ │ └── DebugifyLightProvider.java │ │ │ ├── mc237493/ │ │ │ │ ├── DebugifyTelemetry.java │ │ │ │ └── DebugifyTelemetryAccessor.java │ │ │ └── mc26757/ │ │ │ └── TooltipWrapper.java │ │ ├── integrations/ │ │ │ └── ModMenuIntegration.java │ │ ├── mixins/ │ │ │ ├── basic/ │ │ │ │ ├── mc105068/ │ │ │ │ │ └── LivingEntityMixin.java │ │ │ │ ├── mc115092/ │ │ │ │ │ └── SquidRendererMixin.java │ │ │ │ ├── mc116379/ │ │ │ │ │ └── FishingHookRendererMixin.java │ │ │ │ ├── mc118740/ │ │ │ │ │ ├── GuiMixin.java │ │ │ │ │ ├── LocalPlayerMixin.java │ │ │ │ │ └── PlayerMixin.java │ │ │ │ ├── mc122477/ │ │ │ │ │ ├── EditBoxMixin.java │ │ │ │ │ └── MinecraftMixin.java │ │ │ │ ├── mc122627/ │ │ │ │ │ └── CommandSuggestionsMixin.java │ │ │ │ ├── mc127970/ │ │ │ │ │ └── ItemInHandRendererMixin.java │ │ │ │ ├── mc143474/ │ │ │ │ │ └── ClientPacketListenerMixin.java │ │ │ │ ├── mc165305/ │ │ │ │ │ └── RenderPipelinesMixin.java │ │ │ │ ├── mc165381/ │ │ │ │ │ └── LocalPlayerMixin.java │ │ │ │ ├── mc176559/ │ │ │ │ │ ├── ItemStackAccessor.java │ │ │ │ │ └── MultiPlayerGameModeMixin.java │ │ │ │ ├── mc188359/ │ │ │ │ │ ├── CakeBlockMixin.java │ │ │ │ │ └── ConsumableMixin.java │ │ │ │ ├── mc197260/ │ │ │ │ │ ├── ArmorStandRendererMixin.java │ │ │ │ │ └── LivingEntityRendererMixin.java │ │ │ │ ├── mc206540/ │ │ │ │ │ └── EntityMixin.java │ │ │ │ ├── mc210318/ │ │ │ │ │ └── BookSignScreenMixin.java │ │ │ │ ├── mc211561/ │ │ │ │ │ └── FishingHookRendererMixin.java │ │ │ │ ├── mc215531/ │ │ │ │ │ └── GuiMixin.java │ │ │ │ ├── mc217716/ │ │ │ │ │ └── GameRendererMixin.java │ │ │ │ ├── mc237493/ │ │ │ │ │ ├── OptionsMixin.java │ │ │ │ │ ├── TelemetryEventInstanceMixin.java │ │ │ │ │ ├── TelemetryEventWidgetMixin.java │ │ │ │ │ └── TelemetryInfoScreenMixin.java │ │ │ │ ├── mc242809/ │ │ │ │ │ ├── DirectJoinServerScreenMixin.java │ │ │ │ │ └── ManageServerScreenMixin.java │ │ │ │ ├── mc251068/ │ │ │ │ │ └── WorldSelectionListMixin.java │ │ │ │ ├── mc259512/ │ │ │ │ │ └── LivingEntityMixin.java │ │ │ │ ├── mc267376/ │ │ │ │ │ └── CameraMixin.java │ │ │ │ ├── mc268420/ │ │ │ │ │ └── GuiMixin.java │ │ │ │ ├── mc280220/ │ │ │ │ │ └── DolphinCarryingItemLayerMixin.java │ │ │ │ ├── mc298225/ │ │ │ │ │ └── CameraMixin.java │ │ │ │ ├── mc298558/ │ │ │ │ │ └── AtmosphericFogEnvironmentMixin.java │ │ │ │ ├── mc35361/ │ │ │ │ │ └── MinecraftMixin.java │ │ │ │ ├── mc4490/ │ │ │ │ │ └── FishingHookRendererMixin.java │ │ │ │ ├── mc46737/ │ │ │ │ │ └── GameRendererMixin.java │ │ │ │ ├── mc46766/ │ │ │ │ │ └── MinecraftMixin.java │ │ │ │ ├── mc57057/ │ │ │ │ │ └── GuardianAttackSoundInstanceMixin.java │ │ │ │ ├── mc577/ │ │ │ │ │ └── AbstractContainerScreenMixin.java │ │ │ │ ├── mc59810/ │ │ │ │ │ └── MouseHandlerMixin.java │ │ │ │ ├── mc61489/ │ │ │ │ │ ├── BookEditScreenMixin.java │ │ │ │ │ └── BookViewScreenMixin.java │ │ │ │ ├── mc79545/ │ │ │ │ │ └── ExperienceBarRendererMixin.java │ │ │ │ ├── mc80859/ │ │ │ │ │ └── AbstractContainerScreenMixin.java │ │ │ │ ├── mc90683/ │ │ │ │ │ └── ClientPacketListenerMixin.java │ │ │ │ └── mc93384/ │ │ │ │ └── LivingEntityMixin.java │ │ │ └── gameplay/ │ │ │ ├── mc159163/ │ │ │ │ └── ClientPacketListenerMixin.java │ │ │ └── mc231097/ │ │ │ └── LocalPlayerMixin.java │ │ └── utils/ │ │ └── ClientUtils.java │ └── resources/ │ └── debugify.client.mixins.json ├── gametest/ │ ├── java/ │ │ └── dev/ │ │ └── isxander/ │ │ └── debugify/ │ │ └── test/ │ │ ├── DebugifyApiTest.java │ │ ├── DebugifyTestUtils.java │ │ └── suites/ │ │ ├── MC100991.java │ │ ├── MC30391.java │ │ ├── MC72151.java │ │ ├── MC8187.java │ │ └── MC93018.java │ └── resources/ │ ├── data/ │ │ └── debugify/ │ │ └── gametest/ │ │ └── structures/ │ │ └── mc-8187.snbt │ └── fabric.mod.json └── main/ ├── java/ │ └── dev/ │ └── isxander/ │ └── debugify/ │ ├── Debugify.java │ ├── api/ │ │ └── DebugifyApi.java │ ├── config/ │ │ └── DebugifyConfig.java │ ├── error/ │ │ ├── CrashReportInjector.java │ │ ├── DebugifyErrorHandler.java │ │ ├── ErrorStage.java │ │ └── MixinErrorEntry.java │ ├── fixes/ │ │ ├── BugFix.java │ │ ├── BugFixData.java │ │ ├── FixCategory.java │ │ └── OS.java │ ├── mixinplugin/ │ │ ├── BugFixDataCache.java │ │ ├── DebugifyDebugFlags.java │ │ └── MixinPlugin.java │ └── mixins/ │ ├── basic/ │ │ ├── mc100991/ │ │ │ └── FishingHookMixin.java │ │ ├── mc119754/ │ │ │ └── FireworkRocketEntityMixin.java │ │ ├── mc121706/ │ │ │ └── RangedBowAttackGoalMixin.java │ │ ├── mc121903/ │ │ │ └── MinecraftCommandBlockMixin.java │ │ ├── mc123450/ │ │ │ └── ItemFrameMixin.java │ │ ├── mc129909/ │ │ │ └── ServerPlayerMixin.java │ │ ├── mc131562/ │ │ │ └── ServerGamePacketListenerImplMixin.java │ │ ├── mc132878/ │ │ │ └── ArmorStandMixin.java │ │ ├── mc133218/ │ │ │ └── ServerPlayerMixin.java │ │ ├── mc134110/ │ │ │ └── ChestBlockMixin.java │ │ ├── mc139041/ │ │ │ └── FishingRodItemMixin.java │ │ ├── mc147659/ │ │ │ └── CatSpawnerMixin.java │ │ ├── mc153010/ │ │ │ └── FoxMixin.java │ │ ├── mc155509/ │ │ │ └── PufferfishMixin.java │ │ ├── mc158900/ │ │ │ └── PlayerListMixin.java │ │ ├── mc159283/ │ │ │ └── DensityFunctionsMixin.java │ │ ├── mc160095/ │ │ │ └── CactusBlockMixin.java │ │ ├── mc168573/ │ │ │ └── BlocksAttacksMixin.java │ │ ├── mc170462/ │ │ │ └── MobEffectsMixin.java │ │ ├── mc176806/ │ │ │ └── RespawnAnchorBlockMixin.java │ │ ├── mc177381/ │ │ │ └── LocateCommandMixin.java │ │ ├── mc179072/ │ │ │ └── SwellGoalMixin.java │ │ ├── mc183990/ │ │ │ └── MobMixin.java │ │ ├── mc187100/ │ │ │ └── EnderDragonMixin.java │ │ ├── mc200418/ │ │ │ └── ZombieVillagerMixin.java │ │ ├── mc201374/ │ │ │ └── CampfireBlockMixin.java │ │ ├── mc202637/ │ │ │ └── FoodPropertiesMixin.java │ │ ├── mc206922/ │ │ │ ├── EntityMixin.java │ │ │ └── ItemEntityMixin.java │ │ ├── mc215530/ │ │ │ └── ServerPlayerMixin.java │ │ ├── mc221257/ │ │ │ └── ShulkerBulletMixin.java │ │ ├── mc223153/ │ │ │ └── BlocksMixin.java │ │ ├── mc224729/ │ │ │ └── ChunkMapMixin.java │ │ ├── mc226961/ │ │ │ └── ExperienceOrbMixin.java │ │ ├── mc227008/ │ │ │ └── EnderManMixin.java │ │ ├── mc227337/ │ │ │ └── ShulkerBulletMixin.java │ │ ├── mc231743/ │ │ │ └── FlowerPotBlockMixin.java │ │ ├── mc232869/ │ │ │ └── StriderMixin.java │ │ ├── mc245394/ │ │ │ └── RaidMixin.java │ │ ├── mc263999/ │ │ │ └── BreakDoorGoalMixin.java │ │ ├── mc264285/ │ │ │ └── CreeperMixin.java │ │ ├── mc264979/ │ │ │ └── SettingsMixin.java │ │ ├── mc267125/ │ │ │ └── PlayerListMixin.java │ │ ├── mc268617/ │ │ │ └── FileUtilMixin.java │ │ ├── mc271899/ │ │ │ └── StructureTemplateMixin.java │ │ ├── mc272431/ │ │ │ └── EnderDragonMixin.java │ │ ├── mc297837/ │ │ │ └── WaypointTransmitterMixin.java │ │ ├── mc298066/ │ │ │ └── LivingEntityMixin.java │ │ ├── mc30391/ │ │ │ └── LivingEntityMixin.java │ │ ├── mc44654/ │ │ │ └── EntityMixin.java │ │ ├── mc7569/ │ │ │ └── RconConsoleSourceMixin.java │ │ ├── mc82263/ │ │ │ └── EnderDragonMixin.java │ │ ├── mc84661/ │ │ │ └── MobEffectsMixin.java │ │ ├── mc88371/ │ │ │ └── DragonLandingPhaseMixin.java │ │ ├── mc89146/ │ │ │ └── ChunkAccessMixin.java │ │ ├── mc93018/ │ │ │ └── AnimalMixin.java │ │ └── mc94054/ │ │ └── WallClimberNavigationMixin.java │ ├── errorhandler/ │ │ └── CrashReportMixin.java │ └── gameplay/ │ ├── mc136249/ │ │ └── LivingEntityMixin.java │ └── mc8187/ │ └── TreeFeatureMixin.java ├── resources/ │ ├── assets/ │ │ └── debugify/ │ │ └── lang/ │ │ ├── el_gr.json │ │ ├── en_us.json │ │ ├── es_ar.json │ │ ├── es_mx.json │ │ ├── fr_fr.json │ │ ├── it_it.json │ │ ├── pt_br.json │ │ ├── ru_ru.json │ │ ├── tr_tr.json │ │ ├── uk_ua.json │ │ ├── vi_vn.json │ │ ├── zh_cn.json │ │ └── zh_tw.json │ └── debugify.mixins.json └── templates/ └── fabric.mod.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .bugs ================================================ # This file is used to generate PATCHED.md # Please run `./gradlew generatePatchedTable` to update PATCHED.md based on this file # Try not to re-order this file (it sorts itself!), put additions at the end of each section - this helps with git conflicts patched 577 client basic patched 4490 client basic patched 12062 client basic patched 35361 client basic patched 46737 client basic patched 46766 client basic patched 57057 client basic patched 59810 client basic patched 61489 client basic patched 79545 client basic patched 80859 client basic patched 90683 client basic patched 93384 client basic patched 105068 client basic patched 115092 client basic patched 116379 client basic patched 116510 client basic patched 118740 client basic patched 122627 client basic patched 122477 client basic patched 127970 client basic patched 143474 client basic patched 159163 client gameplay patched 165306 client basic patched 165381 client basic patched 168573 client basic patched 176559 client basic patched 188359 client basic patched 197260 client basic patched 206540 client basic patched 210318 client basic patched 211561 client basic patched 215531 client basic patched 217716 client basic patched 231097 client gameplay patched 237493 client basic patched 242809 client basic patched 259512 client basic patched 267376 client basic patched 268420 client basic patched 280220 client basic patched 298225 client basic patched 298558 client basic patched 7569 server basic patched 8187 server gameplay patched 30391 server basic patched 81773 server basic patched 82263 server basic patched 84661 server basic patched 88371 server basic patched 89146 server basic patched 93018 server basic patched 94054 server basic patched 100991 server basic patched 119754 server basic patched 121706 server basic patched 121903 server basic patched 123450 server basic patched 129909 server basic patched 132878 server basic patched 134110 server basic patched 136249 server gameplay patched 139041 server basic patched 147659 server basic patched 155509 server basic patched 159283 server basic patched 160095 server basic patched 170462 server basic patched 176806 server basic patched 177381 server basic patched 179072 server basic patched 183990 server basic patched 187100 server basic patched 200418 server basic patched 201374 server basic patched 202637 server basic patched 206705 server basic patched 206922 server basic patched 214147 server basic patched 215530 server basic patched 221257 server basic patched 223153 server basic patched 224729 server basic patched 226961 server basic patched 227008 server basic patched 227337 server basic patched 231743 server basic patched 232869 server basic patched 245394 server basic patched 251068 server basic patched 267125 server basic patched 268617 server basic patched 271899 server basic patched 272431 server basic patched 298066 server basic patched 263999 server basic patched 153010 server basic patched 44654 server basic patched 264979 server basic patched 264285 server basic patched 131562 server basic patched 133218 server basic patched 158900 server basic previous 2025 17w47a previous 53312 22w17a previous 72687 22w24a previous 148149 1.19.1-pre6 previous 235035 22w15a previous 26757 22w42a previous 135973 22w42a previous 145748 22w42a previous 84873 22w43a previous 147605 22w46a previous 151412 22w46a previous 233042 22w46a previous 249059 22w46a previous 228976 1.19.3-pre3 previous 165595 23w03a previous 162253 23w16a previous 121772 23w31a previous 140646 23w31a previous 90084 23w31a previous 72151 24w06a previous 193343 24w18a previous 14923 24w19a previous 124177 24w20a previous 31819 24w21a previous 227169 24w33a previous 135971 24w33a previous 12829 24w44a previous 55347 24w44a previous 111516 24w44a previous 263865 25w04a previous 112730 25w21a previous 183776 25w31a previous 46503 25w33a previous 69216 25w33a previous 119417 25w33a previous 147784 25w34a previous 299115 25w34a previous 267469 1.21.9 previous 201723 1.21.9 previous 22882 25w41a previous 199467 25w45a previous 219981 26.1-snapshot-1 previous 123605 26.1-snapshot-6 ================================================ FILE: .editorconfig ================================================ root = true [*] end_of_line = lf insert_final_newline = true charset = utf-8 trim_trailing_whitespace = true ================================================ FILE: .github/FUNDING.yml ================================================ ko_fi: isxander ================================================ FILE: .github/ISSUE_TEMPLATE/bug-report.yml ================================================ name: Bug Report description: Let us know of an incompatibility with a mod or crashes etc. title: "[Bug] Summary of bug" labels: [bug] body: - type: textarea id: bug attributes: label: Bug Description description: A clear and concise description of what the bug is. validations: required: true - type: textarea id: how-to-reproduce attributes: label: How to Reproduce? description: Steps to reproduce the behavior placeholder: | 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error validations: required: false - type: textarea id: expected-behavior attributes: label: Expected Behavior description: A clear and concise description of what you expected to happen. validations: required: false - type: input id: version attributes: label: Version description: What version of the mod are you on? placeholder: 1.0.0 validations: required: true - type: input id: loader-version attributes: label: Fabric/Quilt Loader Version description: What version of the mod loader are you on? placeholder: 0.14.8 for 1.19.1 validations: required: true - type: textarea id: logs-extra-context attributes: label: Logs or additional context description: Please copy and paste any relevant log output into a paste website such as [Hastebin](https://hst.sh) and then link them here. You may also give any additional information here too. - type: checkboxes id: has-not-been-reported attributes: label: Has not been reported. description: You made sure this bug hasn't already been reported. options: - label: I made sure this bug hasn't already been reported. required: true - type: checkboxes id: is-up-to-date attributes: label: Is on most update to date version. description: You made sure that you are on the most recent version of the fabric/quilt loader and the mod. options: - label: I made sure I am using the most up to date fabric/quilt loader and mod version. required: true ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ blank_issues_enabled: true ================================================ FILE: .github/ISSUE_TEMPLATE/patch-request.yml ================================================ name: Patch Request description: Propose adding a patch for a Minecraft bug. title: "[Patch Request] MC-123456" labels: [patch request] body: - type: input id: mc-id attributes: label: Mojang Bug Report ID description: What bug report would you like to be patched? placeholder: MC-123456 validations: required: true - type: checkboxes id: adheres-to-guidelines attributes: label: Bug adhere to the guidelines. description: You made sure that the bug adheres to the [guidelines](https://github.com/isXander/Debugify/blob/1.19/GUIDELINES.md). options: - label: I made sure that this bug adheres to the guidelines. required: true - type: checkboxes id: not-already-requested attributes: label: Has not already been requested. description: You made sure that the patch has not already been requested. options: - label: I am certain this patch has not already been requested. required: true - type: checkboxes id: not-already-implemented attributes: label: Has not already been implemented. description: You made sure that the patch has not already been implemented. options: - label: I know that this patch isn't already in the latest version of the mod. required: true - type: input id: existing-implementation attributes: label: Existing implementation description: Link here if a mod for this fix already exists. validations: required: false ================================================ FILE: .github/workflows/check-bug-fixes.yml ================================================ name: Bug Status Check on: push: branches: - '*' paths: - 'PATCHED.md' schedule: - cron: 0 0 * * * workflow_dispatch: jobs: build: runs-on: ubuntu-latest name: Check bug status steps: - uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.x' - name: Install pip requirements run: pip install requests packaging - name: Run script run: python scripts/check_bug_fixes.py ================================================ FILE: .github/workflows/gradle.yml ================================================ name: Gradle CI on: push: branches: - '*' paths-ignore: - 'README.md' - 'PATCHED.md' - 'GUIDELINES.md' - 'LICENSE' - '.gitignore' - '.editorconfig' - 'changelogs/**' pull_request: branches: - '*' paths-ignore: - 'README.md' - 'LICENSE' - '.gitignore' - '.editorconfig' - 'changelogs/**' workflow_dispatch: jobs: build: runs-on: ubuntu-latest name: Build with gradle steps: - uses: actions/checkout@v4 - name: Set up JDK uses: actions/setup-java@v4 with: java-version: 21 distribution: temurin - uses: actions/cache@v3 with: path: | ~/.gradle/caches ~/.gradle/wrapper ./.gradle/loom-cache key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} restore-keys: | ${{ runner.os }}-gradle- - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build with Gradle run: ./gradlew build --no-daemon - uses: actions/upload-artifact@v4 with: name: debugify-artifacts path: build/libs/*.jar ================================================ FILE: .github/workflows/publish.yml ================================================ name: Publish Debugify on: workflow_dispatch jobs: publish: if: contains('["isXander"]', github.actor) runs-on: ubuntu-latest name: Publish to all platforms steps: - uses: actions/checkout@v3 - name: Set up JDK uses: actions/setup-java@v2.3.1 with: java-version: 17 distribution: temurin - uses: actions/cache@v3 with: path: | ~/.gradle/caches ~/.gradle/wrapper ./.gradle/loom-cache key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} restore-keys: | ${{ runner.os }}-gradle- - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Publish to All Platforms run: ./gradlew publishDebugify --no-daemon env: xander-api.username: wyvest xander-api.password: ${{ secrets.XANDER_API_PASS }} modrinth.token: ${{ secrets.MODRINTH_XANDER_TOKEN }} curseforge.token: ${{ secrets.CURSEFORGE_CI_TOKEN }} github.token: ${{ secrets.GITHUB_TOKEN }} ================================================ FILE: .gitignore ================================================ /.idea .gradle/ build/ run/ !*/.gitkeep /venv ================================================ FILE: GUIDELINES.md ================================================ # MC Bug Checklist * Must be a bug in a stable release (not in a snapshot, future release, etc) * Must have a meaningful impact to a player or admin. (even a niche one) * Before trying to fix a bug, make sure you can reproduce it. * Must be a bug that has been confirmed by mojang or community consensus and open in the bug tracker. ================================================ FILE: LICENSE ================================================ GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. ================================================ FILE: PATCHED.md ================================================ # List of Patched Bugs ## Unpatched in vanilla ### Client side | Type | Bug ID | Name | |------|--------|------| | Basic | [MC-577](https://mojira.dev/MC-577) | Mouse buttons block all inventory controls that are not default | | Basic | [MC-4490](https://mojira.dev/MC-4490) | Fishing line not attached to fishing rod in third person while crouching | | Basic | [MC-12062](https://mojira.dev/MC-12062) | Hotbar selection resets to the far left when exiting the end | | Basic | [MC-35361](https://mojira.dev/MC-35361) | Inventory opening is detected while in Nether Portal | | Basic | [MC-46737](https://mojira.dev/MC-46737) | Entities' shaders are applied when beginning to spectate them in third person | | Basic | [MC-46766](https://mojira.dev/MC-46766) | Breaking particles, sounds, and block cracks can be created in spectator mode | | Basic | [MC-57057](https://mojira.dev/MC-57057) | Guardian laser attack sound ignores distance | | Basic | [MC-59810](https://mojira.dev/MC-59810) | | | Basic | [MC-61489](https://mojira.dev/MC-61489) | | | Basic | [MC-79545](https://mojira.dev/MC-79545) | The experience bar disappears when too many levels are given to the player | | Basic | [MC-80859](https://mojira.dev/MC-80859) | Starting to drag item stacks over other compatible stacks makes the latter invisible until appearance change (stack size increases) | | Basic | [MC-90683](https://mojira.dev/MC-90683) | "Received unknown passenger" - Entities with differing render distances as passengers outputs error | | Basic | [MC-93384](https://mojira.dev/MC-93384) | Bubbles appear at the feet of drowning mobs | | Basic | [MC-105068](https://mojira.dev/MC-105068) | Attacking a shield-blocking player always plays the player hurts sound | | Basic | [MC-115092](https://mojira.dev/MC-115092) | Squid/glow squid named "Dinnerbone" or "Grumm" is not upside-down | | Basic | [MC-116379](https://mojira.dev/MC-116379) | Punching with a cast fishing rod in the off-hand detaches fishing line from rod | | Basic | [MC-116510](https://mojira.dev/MC-116510) | Attack indicator doesn't indicate (most of the time) that breaking instantly-mineable blocks resets your attack | | Basic | [MC-118740](https://mojira.dev/MC-118740) | Performing any right-click action silently resets the attack cooldown | | Basic | [MC-122477](https://mojira.dev/MC-122477) | Linux/GNU: Opening chat sometimes writes 't' | | Basic | [MC-122627](https://mojira.dev/MC-122627) | Tab suggestion box has missing padding on right side | | Basic | [MC-127970](https://mojira.dev/MC-127970) | Using Riptide on a trident with an item in your off-hand causes visual glitch with said item | | Basic | [MC-143474](https://mojira.dev/MC-143474) | Respawning causes your hotbar to reset to the first space | | Gameplay | [MC-159163](https://mojira.dev/MC-159163) | Quickly pressing the sneak key causes the sneak animation to play twice | | Basic | [MC-165306](https://mojira.dev/MC-165306) | | | Basic | [MC-165381](https://mojira.dev/MC-165381) | Block breaking can be delayed by dropping/throwing the tool while breaking a block | | Basic | [MC-168573](https://mojira.dev/MC-168573) | After breaking a shield, the player's off-hand can't finish using some items | | Basic | [MC-176559](https://mojira.dev/MC-176559) | Breaking process resets when a pickaxe enchanted with Mending mends by XP / Mending slows down breaking blocks again | | Basic | [MC-188359](https://mojira.dev/MC-188359) | Burp sound does not play after drinking or after eating cake | | Basic | [MC-197260](https://mojira.dev/MC-197260) | Armor Stand renders itself and armor dark if its head is in a solid block | | Basic | [MC-206540](https://mojira.dev/MC-206540) | Increased input delay when riding an entity | | Basic | [MC-210318](https://mojira.dev/MC-210318) | Maximum length of book title changed from 16 to 15 characters | | Basic | [MC-211561](https://mojira.dev/MC-211561) | Fishing line appears in opposite hand when switching slots | | Basic | [MC-215531](https://mojira.dev/MC-215531) | The carved pumpkin overlay is rendered in spectator mode | | Basic | [MC-217716](https://mojira.dev/MC-217716) | The green nausea overlay isn't removed when switching into spectator mode | | Basic | [MC-231097](https://mojira.dev/MC-231097) | Holding the "Use" button continues to slow down the player even after the used item has been dropped | | Basic | [MC-237493](https://mojira.dev/MC-237493) | Telemetry cannot be disabled | | Basic | [MC-242809](https://mojira.dev/MC-242809) | | | Basic | [MC-259512](https://mojira.dev/MC-259512) | Horizontal camera rotation lags when riding | | Basic | [MC-267376](https://mojira.dev/MC-267376) | You can view through blocks on small scales (near plane clipping) | | Basic | [MC-268420](https://mojira.dev/MC-268420) | Cooldown indicator flashes when switching items with high attack speed attribute | | Basic | [MC-280220](https://mojira.dev/MC-280220) | When a Dolphin holds an item, it is rendered upside-down | | Basic | [MC-298225](https://mojira.dev/MC-298225) | Shapes appear in the end sky with certain distance settings | | Basic | [MC-298558](https://mojira.dev/MC-298558) | Rain fog calculation can overshoot while game is unresponsive | ### Server side (both) | Type | Bug ID | Name | |------|--------|------| | Basic | [MC-7569](https://mojira.dev/MC-7569) | RCON output has newlines removed | | Gameplay | [MC-8187](https://mojira.dev/MC-8187) | Two-by-two arrangements of jungle or spruce saplings cannot grow when there are adjacent blocks located north or west of the sapling formation | | Basic | [MC-30391](https://mojira.dev/MC-30391) | Chickens, blazes and the wither emit particles when landing from a height, despite falling slowly | | Basic | [MC-44654](https://mojira.dev/MC-44654) | Some entities don't update position to the client when teleported | | Basic | [MC-81773](https://mojira.dev/MC-81773) | Bows, crossbows, and tridents drawn in survival/creative/adventure mode can be released in spectator mode | | Basic | [MC-82263](https://mojira.dev/MC-82263) | Ender dragon produces regular hurt sound on final hit | | Basic | [MC-84661](https://mojira.dev/MC-84661) | Glowing is considered a positive effect in potion item tooltips | | Basic | [MC-88371](https://mojira.dev/MC-88371) | Ender Dragon flies down in the void when the exit portal is destroyed | | Basic | [MC-89146](https://mojira.dev/MC-89146) | Pistons forget update when being reloaded | | Basic | [MC-93018](https://mojira.dev/MC-93018) | Wild wolves show breeding hearts but do not breed | | Basic | [MC-94054](https://mojira.dev/MC-94054) | Cave spiders and spiders with small scale attribute spin around when walking | | Basic | [MC-100991](https://mojira.dev/MC-100991) | Killing entities with a fishing rod doesn't count as a kill | | Basic | [MC-119754](https://mojira.dev/MC-119754) | Firework boosting on elytra continues in spectator mode | | Basic | [MC-121706](https://mojira.dev/MC-121706) | Skeletons and illusioners aren't looking up / down at their target while strafing | | Basic | [MC-121903](https://mojira.dev/MC-121903) | Command block minecarts do not save execution cooldown to NBT | | Basic | [MC-123450](https://mojira.dev/MC-123450) | Item frames play sounds when the item within them is read from NBT | | Basic | [MC-129909](https://mojira.dev/MC-129909) | Players in spectator mode continue to consume foods and liquids shortly after switching game modes | | Basic | [MC-131562](https://mojira.dev/MC-131562) | Pressing the "Done" button in empty command block minecarts prints the message "Command set:" in chat | | Basic | [MC-132878](https://mojira.dev/MC-132878) | Armor stands destroyed by explosions/lava/fire don't produce particles | | Basic | [MC-133218](https://mojira.dev/MC-133218) | Usable items continue to be used on the death screen after dying when the "keepInventory" gamerule is set to "true" | | Basic | [MC-134110](https://mojira.dev/MC-134110) | Structure mirroring breaking apart double chests | | Basic | [MC-136249](https://mojira.dev/MC-136249) | Wearing boots enchanted with depth strider decreases the strength of the riptide enchantment | | Basic | [MC-139041](https://mojira.dev/MC-139041) | The sounds of fishing bobbers aren't controlled by the "Players" sound slider | | Basic | [MC-147659](https://mojira.dev/MC-147659) | Some witch huts spawn the incorrect cat | | Basic | [MC-153010](https://mojira.dev/MC-153010) | doMobLoot gamerule doesn't prevent foxes from dropping their items | | Basic | [MC-155509](https://mojira.dev/MC-155509) | Dying puffed pufferfish can still sting players | | Basic | [MC-158900](https://mojira.dev/MC-158900) | "bad packet id 26" upon connecting after tempban expire | | Basic | [MC-159283](https://mojira.dev/MC-159283) | The End terrain does not generate in multiple rings centered around the world center | | Basic | [MC-160095](https://mojira.dev/MC-160095) | Partial blocks break cactus when moved by pistons | | Basic | [MC-170462](https://mojira.dev/MC-170462) | Bad Omen is considered a positive effect in potion item tooltips | | Basic | [MC-176806](https://mojira.dev/MC-176806) | Scoreboard criteria for using glowstone doesn't increase score when charging a respawn anchor | | Basic | [MC-177381](https://mojira.dev/MC-177381) | The game does not calculate the distance correctly when a structure more than 46340 blocks away is located | | Basic | [MC-179072](https://mojira.dev/MC-179072) | Creepers do not defuse when switching from Survival to Creative/Spectator | | Basic | [MC-183990](https://mojira.dev/MC-183990) | Group AI of some mobs breaks when their target dies | | Basic | [MC-187100](https://mojira.dev/MC-187100) | End crystals try to heal dying Ender dragons | | Basic | [MC-200418](https://mojira.dev/MC-200418) | Cured baby zombie villagers stay as jockey variant | | Basic | [MC-201374](https://mojira.dev/MC-201374) | Wrong position passed to getCollisionShape from CampfireBlock#isSmokingBlockAt | | Basic | [MC-202637](https://mojira.dev/MC-202637) | Last sound clip of eating will still play when Players volume is set to 0% | | Basic | [MC-206705](https://mojira.dev/MC-206705) | Spyglasses stay in use in spectator mode | | Basic | [MC-206922](https://mojira.dev/MC-206922) | Items dropped by entities that are killed by lightning instantly disappear | | Basic | [MC-214147](https://mojira.dev/MC-214147) | Skeletons wearing leather armor still convert to strays in powder snow | | Basic | [MC-215530](https://mojira.dev/MC-215530) | | | Basic | [MC-221257](https://mojira.dev/MC-221257) | Shulker bullets don't produce bubble particles when moving through water | | Basic | [MC-223153](https://mojira.dev/MC-223153) | Block of Raw Copper uses stone sounds instead of copper sounds | | Basic | [MC-224729](https://mojira.dev/MC-224729) | Partially generated chunks are not saved in some situations | | Basic | [MC-226961](https://mojira.dev/MC-226961) | Experience orbs treat flowing lava as a full block | | Basic | [MC-227008](https://mojira.dev/MC-227008) | Endermen constantly try to teleport when in a boat or a minecart under daylight | | Basic | [MC-227337](https://mojira.dev/MC-227337) | When a shulker bullet hits an entity, the explosion sound is not played and particles are not produced | | Basic | [MC-231743](https://mojira.dev/MC-231743) | "minecraft.used:minecraft." doesn't increase when placing plants into flower pots | | Basic | [MC-232869](https://mojira.dev/MC-232869) | Adult striders can spawn with saddles in peaceful mode | | Basic | [MC-245394](https://mojira.dev/MC-245394) | The sounds of raid horns blaring aren't controlled by the correct sound slider | | Basic | [MC-251068](https://mojira.dev/MC-251068) | If you delete your only world, then you are no longer automatically thrown into the menu of creating a new world | | Basic | [MC-263999](https://mojira.dev/MC-263999) | Zombies breaking doors do not show break particles | | Basic | [MC-264285](https://mojira.dev/MC-264285) | | | Basic | [MC-264979](https://mojira.dev/MC-264979) | Fresh installations print NoSuchFileException for server.properties | | Basic | [MC-267125](https://mojira.dev/MC-267125) | Command suggestions for reloadable content are not affected by /reload. | | Basic | [MC-268617](https://mojira.dev/MC-268617) | Structures can't be saved if the game directory is named in a certain way | | Basic | [MC-271899](https://mojira.dev/MC-271899) | StructureTemplate Palette's caches are not thread safe | | Basic | [MC-272431](https://mojira.dev/MC-272431) | Ender Dragon incorrect vertical velocity causes erratic behavior | | Basic | [MC-298066](https://mojira.dev/MC-298066) | Directly entering a bed from a mount places the player in the wrong place | ## Previously patched Bugs that this mod has patched in the past, but has since been fixed by a vanilla update. | Bug ID | Name | Fixed Version | |--------|------|---------------| | [MC-2025](https://mojira.dev/MC-2025) | Mobs going out of fenced areas/suffocate in blocks when loading chunks | 17w47a | | [MC-12829](https://mojira.dev/MC-12829) | Flying through climbable blocks in creative mode slows you down | 24w44a | | [MC-14923](https://mojira.dev/MC-14923) | Players can be kicked for spamming in a singleplayer world with cheats disabled | 24w19a | | [MC-22882](https://mojira.dev/MC-22882) | Ctrl + Q doesn't work on Mac | 25w41a | | [MC-26757](https://mojira.dev/MC-26757) | Large item tooltips can get cut off at the edges of the screen | 22w42a | | [MC-31819](https://mojira.dev/MC-31819) | Hunger saturation depletes on peaceful difficulty | 24w21a | | [MC-46503](https://mojira.dev/MC-46503) | You can retain entities' shaders by running the "/kill" command while in spectator mode | 25w33a | | [MC-53312](https://mojira.dev/MC-53312) | Illager/(zombie) villager/witch robes don't render the last two rows of pixels | 22w17a | | [MC-55347](https://mojira.dev/MC-55347) | Title with long duration shows in other world | 24w44a | | [MC-69216](https://mojira.dev/MC-69216) | Switching to spectator mode while fishing keeps rod cast | 25w33a | | [MC-72151](https://mojira.dev/MC-72151) | Snow Golem's snowballs damage wolves instead of pushing them | 24w06a | | [MC-72687](https://mojira.dev/MC-72687) | There are no shadows on text displayed within the action bar | 22w24a | | [MC-84873](https://mojira.dev/MC-84873) | DeathTime values 20+ cause corrupted mobs | 22w43a | | [MC-90084](https://mojira.dev/MC-90084) | When sitting in boats and boats with chest mobs legs penetrate the hull | 23w31a | | [MC-111516](https://mojira.dev/MC-111516) | Player flickers/turns invisible when flying at high speeds | 24w44a | | [MC-112730](https://mojira.dev/MC-112730) | Beacon beam and structure block render twice per frame | 25w21a | | [MC-119417](https://mojira.dev/MC-119417) | A spectator can occupy a bed if they enter it and then are switched to spectator mode | 25w33a | | [MC-121772](https://mojira.dev/MC-121772) | Can't scroll while holding SHIFT on macOS | 23w31a | | [MC-123605](https://mojira.dev/MC-123605) | Debug world still sets clear weather time instead of deactivating gamerule doWeatherCycle | 26.1-snapshot-6 | | [MC-124177](https://mojira.dev/MC-124177) | Teleporting to another dimension loses some client states | 24w20a | | [MC-135971](https://mojira.dev/MC-135971) | Can't use CTRL+Q in crafting table | 24w33a | | [MC-135973](https://mojira.dev/MC-135973) | Can't hold Q to drop items rapidly from container inventories | 22w42a | | [MC-140646](https://mojira.dev/MC-140646) | Text fields don't scroll while selecting text with Shift | 23w31a | | [MC-145748](https://mojira.dev/MC-145748) | Clicking a settings button when there's a slider under the mouse in the next screen plays the click sound twice | 22w42a | | [MC-147605](https://mojira.dev/MC-147605) | Text cursors can exist in multiple fields | 22w46a | | [MC-147784](https://mojira.dev/MC-147784) | Fletching table flashes crafting table's GUI for about a second upon right-clicking it in spectator mode | 25w34a | | [MC-148149](https://mojira.dev/MC-148149) | | 1.19.1-pre6 | | [MC-151412](https://mojira.dev/MC-151412) | "Edit Server Info" window does not focus "Server Name" text field automatically | 22w46a | | [MC-162253](https://mojira.dev/MC-162253) | Lag spike when crossing certain chunk borders | 23w16a | | [MC-165595](https://mojira.dev/MC-165595) | Guardian beam does not render when over a certain "Time" in level.dat | 23w03a | | [MC-183776](https://mojira.dev/MC-183776) | After switching game modes using F3+F4, you need to press F3 twice to toggle the debug screen | 25w31a | | [MC-193343](https://mojira.dev/MC-193343) | Soul Speed effect remains after switching to spectator mode | 24w18a | | [MC-199467](https://mojira.dev/MC-199467) | Certain entity animations stop after they've existed in world for too long | 25w45a | | [MC-201723](https://mojira.dev/MC-201723) | Statistics sprites don't look pressed when clicked | 1.21.9 | | [MC-219981](https://mojira.dev/MC-219981) | Leader zombie-type mobs spawn with 20 health despite having an increased maximum health | 26.1-snapshot-1 | | [MC-227169](https://mojira.dev/MC-227169) | The main hand is positioned incorrectly when holding a loaded crossbow in your offhand | 24w33a | | [MC-228976](https://mojira.dev/MC-228976) | Entity collision is run on render thread | 1.19.3-pre3 | | [MC-233042](https://mojira.dev/MC-233042) | Server Address field isn't focused when Direct Connection menu is opened | 22w46a | | [MC-235035](https://mojira.dev/MC-235035) | Sleeping in a custom dimension with "natural" set to false causes crash | 22w15a | | [MC-249059](https://mojira.dev/MC-249059) | Loading terrain screen cannot close before 2 seconds have passed | 22w46a | | [MC-263865](https://mojira.dev/MC-263865) | Fullscreen state isn't saved | 25w04a | | [MC-267469](https://mojira.dev/MC-267469) | GUI List Entry highlight border not always aligned properly | 1.21.9 | | [MC-299115](https://mojira.dev/MC-299115) | | 25w34a | ================================================ FILE: README.md ================================================
# Debugify #### Debugify is a project that fixes **over 70** bugs found on the bug tracker in Minecraft. (and does nothing more!) [![wakatime](https://wakatime.com/badge/github/W-OVERFLOW/Debugify.svg?style=for-the-badge)](https://wakatime.com/badge/github/W-OVERFLOW/Debugify) ![Lines of Code](https://img.shields.io/tokei/lines/github/isXander/Debugify?color=%23ff4747&label=Lines%20of%20code&style=for-the-badge) [![](https://www.bisecthosting.com/partners/custom-banners/08bbd3ff-5c0d-4480-8738-de0f070a04dd.png)](https://bisecthosting.com/xander)
## What does this mod replace? This mod replaces many mods and implements fixes from some others - **[BetterShields](https://modrinth.com/mod/bettershields)** - **[Shift-Scroll Fix](https://www.curseforge.com/minecraft/mc-mods/shift-scroll-fix)** - **[ForgetMeChunk](https://www.curseforge.com/minecraft/mc-mods/forgetmechunk)** - **[ChunkSavingFix](https://www.curseforge.com/minecraft/mc-mods/chunk-saving-fix)** - **[force-close-world-loading-screen](https://modrinth.com/mod/forcecloseworldloadingscreen)**: Missing option to remove menu fully (as it isn't a bug) - **[No Telemetry](https://www.curseforge.com/minecraft/mc-mods/no-telemetry/)** - **[ToolTipFix](https://www.curseforge.com/minecraft/mc-mods/tooltipfix)** - **[Title Fix Mod](https://modrinth.com/mod/title-fix-mod)** - **[Entity Collision FPS Fix Refabricated](https://www.curseforge.com/minecraft/mc-mods/entity-collision-fps-fix-fabric)** - **[Ctrl Q](https://www.curseforge.com/minecraft/mc-mods/ctrl-q)**: Missing other QOL features that aren't bugs. - **[Skeleton Aiming Fix](https://www.curseforge.com/minecraft/mc-mods/skeleton-aiming-fix)** - **[2x2 Surrounded Saplings Fix](https://modrinth.com/mod/8187)** **These superseded mods are not hard conflicts and can be used in conjunction with Debugify for any additional advanced features.** ## Links and other info [GitHub](https://github.com/isXander/Debugify) • [Curseforge](https://curseforge.com/minecraft/mc-mods/debugify) • [Modrinth](https://modrinth.com/mod/debugify) • [Patched bug list](https://github.com/isXander/Debugify/blob/1.19/PATCHED.md) • [Discord](https://short.isxander.dev/discord) ## What if I want to enable some bug fixes, but not others? Debugify has a configuration GUI accessible by Fabric's [Mod Menu](https://modrinth.com/mod/modmenu). If you don't want to it, there is always the configuration file located at `.minecraft/config/debugify.json` ![configuration menu](https://user-images.githubusercontent.com/43245524/191992486-4ba9bd8f-db37-4021-b302-7f54701d8b08.png) ## Client, or Server? Debugify includes many fixes for both the client and server (all server fixes also apply to client). So you should definitely use it on both. ## Can I include this in my modpack? Yes! Of course! I even added a little feature in the mod for you! The constant updates may be exhausting to maintain, so I added a config option that defaults new bug fixes to off, until you get round to looking at it. ## Credits - [**isXander**](https://github.com/isXander) - Founder of project - [**Contributors**](https://github.com/isXander/Debugify/graphs/contributors) - For PRing new fixes! - [**MoonTidez**](https://github.com/MoonTidez) - Creating an awesome logo! ### Translators - [**RaptaG**](https://github.com/RaptaG) - Greek - [**Altegar**](https://github.com/Altegar) - Ukrainian - [**ttrafford7**](https://github.com/ttrafford7) - Ukrainian - [**GodGun968**](https://github.com/GodGun968) - Chinese - [**Agentew04**](https://github.com/Agentew04) - Portuguese - [**localfossa**](https://github.com/localfossa) - Turkish - [**xMikux**](https://github.com/xMikux) - Traditional Chinese ================================================ FILE: build.gradle.kts ================================================ import java.time.LocalDateTime import java.time.format.DateTimeFormatter plugins { id("dev.isxander.modstitch.base") version "0.8.4" id("me.modmuss50.mod-publish-plugin") version "0.8.4" `maven-publish` signing id("dev.isxander.secrets") version "0.1.0" id("org.ajoberstar.grgit") version "5.3.2" id("com.gradleup.nmcp.aggregation") version "1.4.3" id("com.gradleup.nmcp") version "1.4.3" } modstitch { minecraftVersion = property("minecraftVersion")!!.toString() modLoaderVersion = "0.18.6" metadata { modVersion = providers.gradleProperty("modVersion") modId = "debugify" modName = "Debugify" modDescription = "Fixes Minecraft bugs found on the bug tracker" modCredits = """ j-Tai's TieFix - Code used licensed under LGPLv3 FlashyReese's Sodium Extra - Code used licensed under LGPLv3 Ampflower's 2x2 Surrounded Saplings Fix - Code used licensed under Zlib NoahvdAa's Thorium - Code used licensed under LGPLv3 Moulberry's MoulberryTweaks - Code used licensed under MIT """.trimIndent() } mixin { addMixinsToModManifest = true configs.register("debugify") configs.register("debugify.client") { side = CLIENT } } loom { configureLoom { splitEnvironmentSourceSets() val gametest by sourceSets.registering { compileClasspath += sourceSets.main.get().compileClasspath runtimeClasspath += sourceSets.main.get().runtimeClasspath compileClasspath += sourceSets["client"].compileClasspath runtimeClasspath += sourceSets["client"].runtimeClasspath } createProxyConfigurations(gametest.get()) mods.register("debugify") { sourceSet(sourceSets["main"]) sourceSet(sourceSets["client"]) } runs { register("gametest") { client() ideConfigGenerated(true) name("Game Test") source(gametest.get()) } listOf(named("client"), named("server")).forEach { it { vmArg("-Ddebugify.forceMacFixes=true") vmArg("-Ddebugify.forceLinuxFixes=true") vmArg("-Ddebugify.forceWindowsFixes=true") } } } } } } repositories { exclusiveContent { forRepository { maven("https://maven.terraformersmc.com/releases") } filter { includeGroup("com.terraformersmc") } } maven("https://maven.isxander.dev/releases") } val fabricApiVersion: String by project val yaclVersion: String by project val mixinExtrasVersion: String by project val modMenuVersion: String by project dependencies { implementation("net.fabricmc.fabric-api:fabric-api:$fabricApiVersion") "clientImplementation"("dev.isxander:yet-another-config-lib:$yaclVersion") "clientImplementation"("com.terraformersmc:modmenu:$modMenuVersion") "gametestImplementation"(sourceSets.main.get().output) "gametestImplementation"(sourceSets["client"].output) nmcpAggregation(project) } java { withSourcesJar() withJavadocJar() } tasks.javadoc { isFailOnError = false } publishMods { displayName = modstitch.metadata.modVersion.map { "Debugify $it" } version = modstitch.metadata.modVersion file = modstitch.finalJarTask.flatMap { it.archiveFile } type = STABLE modLoaders.add("fabric") changelog = modstitch.minecraftVersion.zip(modstitch.metadata.modVersion) { mcVersion, modVersion -> val header = file("changelogs/header.md") .takeIf { it.exists() } ?.readText() file("changelogs/$mcVersion/$modVersion.md") .takeIf { it.exists() } ?.readText() ?.let { if (header != null) "$header\n\n$it" else it } } modrinth { projectId = providers.gradleProperty("pub.modrinthId") accessToken = secrets.gradleProperty("modrinth.accessToken") minecraftVersions.add(modstitch.minecraftVersion) requires { slug.set("yacl") } requires { slug.set("fabric-api") } optional { slug.set("modmenu") } } curseforge { projectId = providers.gradleProperty("pub.curseforgeId") projectSlug = providers.gradleProperty("pub.curseforgeSlug") accessToken = secrets.gradleProperty("curseforge.accessToken") minecraftVersions.add(modstitch.minecraftVersion) requires { slug.set("yacl") } requires { slug.set("fabric-api") } optional { slug.set("modmenu") } } github { repository = providers.gradleProperty("githubProject") accessToken = secrets.gradleProperty("github.accessToken") commitish = grgit.branch.current().name } } publishing { publications { create("mod") { from(components["java"]) groupId = "dev.isxander" artifactId = "debugify" version = modstitch.metadata.modVersion.get() pom { name = modstitch.metadata.modName description = modstitch.metadata.modDescription url = "https://www.isxander.dev/projects/debugify" licenses { license { name = "LGPL-3.0-or-later" url = "https://www.gnu.org/licenses/lgpl-3.0.en.html" } } developers { developer { id = "isXander" name = "Xander" email = "business@isxander.dev" } } scm { url = "https://github.com/isXander/Debugify" connection = "scm:git:git//github.com/isXander/Debugify.git" developerConnection = "scm:git:ssh://git@github.com/isXander/Debugify.git" } } } } } val signingKeyProvider = secrets.gradleProperty("signing.secretKey") val signingPasswordProvider = secrets.gradleProperty("signing.password") signing { sign(publishing.publications["mod"]) } // not configuration cache friendly, but neither is the whole of signing plugin // this plugin does not support lazy configuration of signing keys gradle.taskGraph.whenReady { val willSign = allTasks.any { it.name.startsWith("sign") } if (willSign) { signing { val signingKey = signingKeyProvider.orNull val signingPassword = signingPasswordProvider.orNull isRequired = signingKey != null && signingPassword != null if (isRequired) { useInMemoryPgpKeys(signingKey, signingPassword) } else { logger.error("Signing keys not found; skipping signing!") } } } } nmcpAggregation { centralPortal { username = secrets.gradleProperty("mcentral.username") password = secrets.gradleProperty("mcentral.password") publicationName = "debugify:$version" } } val generatePatchedTable by tasks.registering { val inputFile = rootProject.file(".bugs") inputs.file(inputFile) val outputFile = rootProject.file("PATCHED.md") outputs.file(outputFile) group = "debugify-utils" doLast { val inputContents = inputFile.readText() val entries = parsePatchedFile(inputContents) val patched = entries.filterIsInstance() val clientPatched = patched.filter { it.env == PatchedFileEntry.Patched.Environment.Client } val serverPatched = patched.filter { it.env == PatchedFileEntry.Patched.Environment.Server } fun generatePatchedRows(entries: List) = entries.joinToString("\n") { "- | ${it.type.friendlyName} | [${it.bugId}](https://mojira.dev/${it.bugId}) | ${getBugDescription(it.bugId)} |" } val previous = entries.filterIsInstance() val timestamp = LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME) val markdownTable = """ - - - # List of Patched Bugs - ## Unpatched in vanilla - ### Client side - | Type | Bug ID | Name | - |------|--------|------| ${generatePatchedRows(clientPatched)} - ### Server side (both) - | Type | Bug ID | Name | - |------|--------|------| ${generatePatchedRows(serverPatched)} - ## Previously patched - Bugs that this mod has patched in the past, but has since been fixed by a vanilla update. - | Bug ID | Name | Fixed Version | - |--------|------|---------------| ${previous.joinToString("\n") { "- | [${it.bugId}](https://mojira.dev/${it.bugId}) | ${getBugDescription(it.bugId)} | ${it.patchVersion} |" }} """.trimMargin("-") outputFile.parentFile.mkdirs() outputFile.writeText(markdownTable) } } data class MojiraBug( val key: String, val summary: String, val status: String, val confirmation_status: String, val resolution: String, val fix_versions: List ) { companion object { fun fetch(bugId: String): MojiraBug? { try { val url = "https://mojira.dev/api/v1/issues/$bugId" val response = `java.net`.URI(url).toURL().readText() return try { com.google.gson.Gson().fromJson(response, MojiraBug::class.java) } catch (e: com.google.gson.JsonSyntaxException) { throw IllegalStateException("Failed to parse Mojira response <$url>: \"$response\"", e) } } catch (e: Exception) { e.printStackTrace() return null } } } } sealed class PatchedFileEntry(val bugNumber: Int) { val bugId = "MC-$bugNumber" class Patched(bugNumber: Int, val env: Environment, val type: Type) : PatchedFileEntry(bugNumber) { enum class Environment(val friendlyName: String) { Client("Client"), Server("Server"); companion object { fun from(string: String): Environment? = when (string) { "client" -> Client "server" -> Server else -> null } } } enum class Type(val friendlyName: String) { Basic("Basic"), Gameplay("Gameplay"); companion object { fun from(string: String): Type? = when (string) { "basic" -> Basic "gameplay" -> Gameplay else -> null } } } } class Previous(bugNumber: Int, val patchVersion: String) : PatchedFileEntry(bugNumber) } fun parsePatchedFile(contents: String): List { return contents.lineSequence() .map { it.trim() } .filter { it.isNotBlank() && !it.startsWith("#") } .map { it.lowercase() } .map { it.split(" ") } .filter { it.size >= 2 } .map { words -> val command = words[0] val bugNumber = words[1].toInt() return@map when (command) { "patched" -> { if (words.size != 4) throw IllegalArgumentException("patched command must have exactly 4 words: got ${words.joinToString(" ")}") val env = PatchedFileEntry.Patched.Environment.from(words[2])!! val type = PatchedFileEntry.Patched.Type.from(words[3])!! PatchedFileEntry.Patched(bugNumber, env, type) } "previous" -> { if (words.size != 3) throw IllegalArgumentException("previous command must have exactly 3 words: got ${words.joinToString(" ")}") val fixVersion = words[2] PatchedFileEntry.Previous(bugNumber, fixVersion) } else -> throw IllegalArgumentException("Unknown command: $command") } } .toList() .sortedBy { it.bugNumber } } fun getBugDescription(bugId: String): String { val mojiraBug = MojiraBug.fetch(bugId) return mojiraBug?.summary ?: "" } ================================================ FILE: changelogs/1.18.2/1.0.0.md ================================================ Fixes 6 Bugs - [MC-234898](https://bugs.mojang.com/browse/MC-234898) - The "Get a trial!" button isn't consistently displayed within the realms menu - [MC-231743](https://bugs.mojang.com/browse/MC-231743) - minecraft.used:minecraft.POTTABLE_PLANT doesn't increase when placing plants into flower pots - [MC-231097](https://bugs.mojang.com/browse/MC-231097) - Holding the "Use" button continues to slow down the player even after the used item has been dropped - [MC-198464](https://bugs.mojang.com/browse/MC-198464) - snowy_butchers_shop_1 misplaced block - [MC-122627](https://bugs.mojang.com/browse/MC-122627) - Tab suggestion box has missing padding on right side - [MC-165381](https://bugs.mojang.com/browse/MC-165381) - Block breaking can be delayed by dropping/throwing the tool while breaking a block ================================================ FILE: changelogs/1.18.2/1.1.0.md ================================================ - [MC-176559](https://bugs.mojang.com/browse/MC-176559) - Breaking process resets when a pickaxe enchanted with Mending mends by XP / Mending slows down breaking blocks again *(fabric only)* - forge release! ================================================ FILE: changelogs/1.18.2/1.10.0.md ================================================ **Bug Fixes** - [MC-55347](https://bugs.mojang.com/browse/MC-55347) - Title with long duration shows in other world - [MC-26757](https://bugs.mojang.com/browse/MC-26757) - Large item tooltips can get cut off at the edges of the screen *(fabric only)* **Rebugify no more!** - Fix [MC-122477](https://bugs.mojang.com/browse/MC-122477) preventing some linux users from typing any characters in text boxes. **Misc** - On Quilt, require beta 15 or later because there is a crucial bug fix. - Mark all superseded mods as "conflicts" which make Fabric & Quilt log warnings. - Compress icon for smaller file size. - Fix some client mixins trying to load on servers. - Don't write disabled fixes to JSON when default disabled is enabled. ([#81](https://github.com/W-OVERFLOW/Debugify/issues/81)) - Don't run MC-237493 when no-telemetry is present, not tiefix. ================================================ FILE: changelogs/1.18.2/1.11.0.md ================================================ **Bug Fixes** - [MC-228976](https://bugs.mojang.com/browse/MC-228976) - Entity collision is run on render thread - [MC-112730](https://bugs.mojang.com/browse/MC-112730) - Beacon beam and structure block render twice per frame *(fabric only)* **Removals** - [MC-234898](https://bugs.mojang.com/browse/MC-234898) - More pain than it's worth. - [MC-249021](https://bugs.mojang.com/browse/MC-249021) - More pain than it's worth. **Misc** - Decrease file size by ~15% ================================================ FILE: changelogs/1.18.2/1.2.0.md ================================================ Patches - [MC-14923](https://bugs.mojang.com/browse/MC-14923) - Players can be kicked for spamming in a singleplayer world with cheats disabled - [MC-79545](https://bugs.mojang.com/browse/MC-79545) - The experience bar disappears when too many levels are given to the player - [MC-80859](https://bugs.mojang.com/browse/MC-80859) - Starting to drag item stacks over other compatible stacks makes the latter invisible until appearance change (stack size increases) Fixes - Fixed incompatibility with Sodium Extras ================================================ FILE: changelogs/1.18.2/1.2.1.md ================================================ - Added metric json toggle ================================================ FILE: changelogs/1.18.2/1.2.2.md ================================================ - Delete metrics - Add update checker ================================================ FILE: changelogs/1.18.2/1.3.0.md ================================================ - [MC-121903](https://bugs.mojang.com/browse/MC-121903) - Command block minecarts do not save execution cooldown to NBT - [MC-93018](https://bugs.mojang.com/browse/MC-93018) - Wild wolves show breeding hearts but do not breed - [MC-116379](https://bugs.mojang.com/browse/MC-116379) - Punching with a cast fishing rod in the off-hand detaches fishing line from rod - [MC-124177](https://bugs.mojang.com/browse/MC-124177) - Teleporting to another dimension loses some client states - [MC-127970](https://bugs.mojang.com/browse/MC-127970) - Using riptide on a trident with an item in your off-hand causes visual glitch with the item in your offhand - [MC-121772](https://bugs.mojang.com/browse/MC-121772) - Can't scroll while holding SHIFT on macOS ================================================ FILE: changelogs/1.18.2/1.4.0.md ================================================ - Add settings menu, allowing you to toggle on and off each bug fix - [MC-140646](https://bugs.mojang.com/browse/MC-140646) - Text fields don't scroll while selecting text with Shift - [MC-4490](https://bugs.mojang.com/browse/MC-4490) - Fishing line not attached to fishing rod in third person while crouching - [MC-53312](https://bugs.mojang.com/browse/MC-53312) - Illager/(zombie) villager/witch robes don't render the last two rows of pixels - [MC-111516](https://bugs.mojang.com/browse/MC-111516) - Player flickers/turns invisible when flying at high speeds - [MC-84873](https://bugs.mojang.com/browse/MC-84873) - DeathTime values 20+ cause corrupted mobs - [MC-235035](https://bugs.mojang.com/browse/MC-235035) - Sleeping in a custom dimension with "natural" set to false causes crash - [MC-162253](https://bugs.mojang.com/browse/MC-162253) - Lag spike when crossing certain chunk borders - **replaces [ForgetMeChunk](https://www.curseforge.com/minecraft/mc-mods/forgetmechunk)** - [MC-108948](https://bugs.mojang.com/browse/MC-108948) - Boat on top of slime blocks hover over block - [MC-93384](https://bugs.mojang.com/browse/MC-93384) - Bubbles appear at the feet of drowning mobs - [MC-132878](https://bugs.mojang.com/browse/MC-132878) - Armor stands destroyed by explosions/lava/fire don't produce particles - [MC-151412](https://bugs.mojang.com/browse/MC-151412) - "Edit Server Info" window does not focus "Server Name" text field automatically - [MC-233042](https://bugs.mojang.com/browse/MC-233042) - Server Address field isn't focused when Direct Connection menu is opened - [MC-200418](https://bugs.mojang.com/browse/MC-200418) - Cured baby zombie villagers stay as jockey variant - [MC-223153](https://bugs.mojang.com/browse/MC-223153) - Block of Raw Copper uses stone sounds instead of copper sounds - [MC-148149](https://bugs.mojang.com/browse/MC-148149) - Linux game crash when opening links - **replaces [FastOpenLinksAndFolders](https://www.curseforge.com/minecraft/mc-mods/fastopenlinksandfolders)** - [MC-132878](https://bugs.mojang.com/browse/MC-132878) - Armor stands destroyed by explosions/lava/fire don't produce particles - [MC-249059](https://bugs.mojang.com/browse/MC-249059) - Loading terrain screen cannot close before 2 seconds have passed - [MC-123739](https://bugs.mojang.com/browse/MC-123739) - Recipe book entries are not sorted in any meaningful manner ([aws404](https://github.com/aws404)) - [MC-122477](https://bugs.mojang.com/browse/MC-122477) - Linux/GNU: Opening chat sometimes writes 't' - [MC-46766](https://bugs.mojang.com/browse/MC-46766) - Mining a block in Survival, then changing to Spectator creates a breaking animation and sound - [MC-215531](https://bugs.mojang.com/browse/MC-215531) - The carved pumpkin overlay isn't removed when switching into spectator mode - [MC-217716](https://bugs.mojang.com/browse/MC-217716) - The green nausea overlay isn't removed when switching into spectator mode - [MC-69216](https://bugs.mojang.com/browse/MC-69216) - Switching to spectator mode while fishing keeps rod cast - [MC-119417](https://bugs.mojang.com/browse/MC-119417) - A spectator can occupy a bed if they enter it and then are switched to spectator mode - [MC-119754](https://bugs.mojang.com/browse/MC-119754) - Firework boosting on elytra continues in spectator mode - [MC-129909](https://bugs.mojang.com/browse/MC-129909) - Players in spectator mode continue to consume foods and liquids shortly after switching game modes - [MC-193343](https://bugs.mojang.com/browse/MC-193343) - Soul Speed effect remains after switching to spectator mode - [MC-215530](https://bugs.mojang.com/browse/MC-215530) - The freezing effect isn't immediately removed when switching into spectator mode - improve [MC-121772](https://bugs.mojang.com/browse/MC-121772) - improve [MC-231097](https://bugs.mojang.com/browse/MC-231097) ================================================ FILE: changelogs/1.18.2/1.4.1.md ================================================ - Fix crashing with MC-148149 ================================================ FILE: changelogs/1.18.2/1.5.0.md ================================================ - [MC-90084](https://bugs.mojang.com/browse/MC-90084) - When sitting in boats and boats with chest mobs legs penetrate the hull - [MC-159163](https://bugs.mojang.com/browse/MC-159163) - Quickly pressing the sneak key causes the sneak animation to play twice - [MC-199467](https://bugs.mojang.com/browse/MC-199467) - Certain entity animations stop after they've existed in world for too long ================================================ FILE: changelogs/1.18.2/1.6.0.md ================================================ **Bug Fixes** - [MC-88371](https://bugs.mojang.com/browse/MC-88371) - Ender Dragon flies down in the void when the exit portal is destroyed - [MC-100991](https://bugs.mojang.com/browse/MC-100991) - Killing entities with a fishing rod doesn't count as a kill - [MC-155509](https://bugs.mojang.com/browse/MC-155509) - Puffed pufferfish can hurt the player while dying - [MC-183776](https://bugs.mojang.com/browse/MC-183776) - After switching gamemodes using F3+F4, you need to press F3 twice to toggle the debug screen - [MC-183990](https://bugs.mojang.com/browse/MC-183990) - Group AI of some mobs breaks when their target dies - [MC-30391](https://bugs.mojang.com/browse/MC-30391) - Chickens, blazes and the wither emit particles when landing from a height, despite falling slowly - [MC-89146](https://bugs.mojang.com/browse/MC-89146) - Pistons forget update when being reloaded - [MC-214147](https://bugs.mojang.com/browse/MC-214147) - Skeletons wearing leather armor still convert to strays in powder snow - [MC-26757](https://bugs.mojang.com/browse/MC-26757) - Large item tooltips can get cut off at the edges of the screen - [MC-72151](https://bugs.mojang.com/browse/MC-72151) - Snow Golem's snowballs damage wolves instead of pushing them - [MC-7569](https://bugs.mojang.com/browse/MC-7569) - RCON output has newlines removed - [MC-206922](https://bugs.mojang.com/browse/MC-206922) - Items dropped by entities that are killed by lightning instantly disappear **Misc** - Add patched bugs link to modmenu entry - Mark shadowed action-bar as incompatible - Mark [shiftscrollfix](https://www.curseforge.com/minecraft/mc-mods/shift-scroll-fix) as incompatible - Improve MC-199467 ================================================ FILE: changelogs/1.18.2/1.7.0.md ================================================ **Bug Fixes** - [MC-2025](https://bugs.mojang.com/browse/MC-2025) - Mobs going out of fenced areas/suffocate in blocks when loading chunks - [MC-249021](https://bugs.mojang.com/browse/MC-249021) - The invitation and news buttons aren't consistently displayed within the realms menu - [MC-197260](https://bugs.mojang.com/browse/MC-197260) - Armor Stand renders itself and armor dark if its head is in a solid block - ([aws404](https://github.com/aws404)) - [MC-224729](https://bugs.mojang.com/browse/MC-224729) - Partially generated chunks are not saved in some situations - [MC-147605](https://bugs.mojang.com/browse/MC-147605) - Text cursors can exist in multiple fields - ([aws404](https://github.com/aws404)) - [MC-179072](https://bugs.mojang.com/browse/MC-179072) - Creepers do not defuse when switching from Survival to Creative/Spectator - [MC-145748](https://bugs.mojang.com/browse/MC-145748) - Clicking a settings button when there's a slider under the mouse in the next screen plays the click sound twice - [MC-160095](https://bugs.mojang.com/browse/MC-160095) - End Rods only break Cactus when moved by pistons **Misc** - Add descriptions to bug fixes buttons - Add opt-out setting for update checking - Removed [MC-26757](https://bugs.mojang.com/browse/MC-26757) as it was quite a bad implementation - Mark [force-close-world-loading-screen](https://modrinth.com/mod/forcecloseworldloadingscreen) as incompatible ================================================ FILE: changelogs/1.18.2/1.7.1.md ================================================ **Rebugify no more!** - Fix [MC-147605](https://bugs.mojang.com/browse/MC-147605) not allowing you to focus text fields if a widget is present. **Misc** - Add `default_disabled` config option into the GUI. ================================================ FILE: changelogs/1.18.2/1.7.2.md ================================================ **Rebugify no more!** - Fix unavoidable crash on Forge server environments - Avoid mixin warning with MC-147605 enabled - Fix bugfix MC-53312 only applying to villager-like entities not illagers or zombie villagers - Fix crash on gui on next launch if you forcibly stop the game at a really specific time - Fix misleading log message displaying total amount of bugs not current amount of enabled bugs ================================================ FILE: changelogs/1.18.2/1.8.0.md ================================================ **New Fixes** - Basic: [MC-135971](https://bugs.mojang.com/browse/MC-135971) - Can't use CTRL+Q in crafting table - Gameplay: [MC-12829](https://bugs.mojang.com/browse/MC-12829) - Flying through ladders/vines/scaffolding in creative mode slows you down - Gameplay: [MC-31819](https://bugs.mojang.com/browse/MC-31819) - Hunger saturation depletes on Peaceful **Features!** - Gameplay fixes! A new type of bug fix called Gameplay fixes have been added. By default, they are disabled in multiplayer however you can enable them. - Fixes have been visually split up into client-server categories **Rebugify no more!** - Fix not being able to name any items in an anvil. **Misc** - Migrate to quilt mappings ![new gui](https://i.imgur.com/sHvPlac.png) ================================================ FILE: changelogs/1.18.2/1.8.1.md ================================================ **Rebugify no more!** - Fix Debugify breaking any mods that modify Minecraft resources ================================================ FILE: changelogs/1.18.2/1.9.0.md ================================================ **Bug Fixes** - [MC-237493](https://bugs.mojang.com/browse/MC-237493) - Telemetry cannot be disabled - Continuation of: [MC-124177](https://bugs.mojang.com/browse/MC-124177) - Experience bar is not updated on TP **Rebugify no more!** - Fix crash when other mods modify `Text` ================================================ FILE: changelogs/1.19/2.0.0.md ================================================ ## Update to 1.19 ================================================ FILE: changelogs/1.19/2.1.0.md ================================================ ## New Patches - [MC-577](https://bugs.mojang.com/browse/MC-577) - Mouse buttons block all inventory controls that are not default - [MC-232869](https://bugs.mojang.com/browse/MC-232869) - Adult striders can spawn with saddles in peaceful mode - [MC-143474](https://bugs.mojang.com/browse/MC-143474) - Respawning causes your hotbar to reset to the first space # Bug Fixes - Fix incompatibility with MineLittlePony (yes [this is real](https://minelittlepony-mod.com)) - Fix [MC-7569](https://bugs.mojang.com/browse/MC-7569) not working since 2.0 - Fix default value for fixes in the gui always being true despite if the bug is disabled by default - Fix [MC-143474](https://bugs.mojang.com/browse/MC-143474) not applying since 1.10.0 ================================================ FILE: changelogs/1.19/2.2.0.md ================================================ ## New Patches - [MC-22882](https://bugs.mojang.com/browse/MC-22882) - Ctrl + Q won't work on Mac ## Bug Fixes - Fix compatibility with [VulkanMod](https://github.com/xCollateral/VulkanMod) when [MC-122477](https://bugs.mojang.com/browse/MC-122477) is enabled - Further improvements to [MC-26757](https://bugs.mojang.com/browse/MC-26757) (Better Tooltips) that keeps more of the tooltip readable ([see here for screenshots](https://github.com/isXander/Debugify/issues/106)) ================================================ FILE: changelogs/1.19/2.3.0.md ================================================ ## New Fixes - [MC-121706](https://bugs.mojang.com/browse/MC-121706) - Skeletons and illusioners aren't looking up / down at their target while strafing ## Bug Fixes - Fix player not colliding with other entities with [MC-228976](https://bugs.mojang.com/browse/MC-228976) (closes [#19](https://github.com/isXander/Debugify/issues/119)) - Fix camera and control deviations with [MC-199467](https://bugs.mojang.com/browse/MC-199467) (closes [#122](https://github.com/isXander/Debugify/issues/122)) ## Misc - Remove update checker as update API no longer maintained. ================================================ FILE: changelogs/1.19/2.3.1.md ================================================ - Fix crash with lithium mod ================================================ FILE: changelogs/1.19/2.3.2.md ================================================ - Fix fixes not being disabled when there is a mod conflict - Crash when debugify detects YOSBR handling debugify config ================================================ FILE: changelogs/1.19.1/2.3.3.md ================================================ - Update to 1.19.1 - Remove [MC-148149](https://bugs.mojang.com/browse/MC-148149) as it was fixed in 1.19.1 ================================================ FILE: changelogs/1.19.1/2.3.4.md ================================================ - Removed [MC-72687](https://bugs.mojang.com/browse/MC-72687) as it was fixed in a snapshot ================================================ FILE: changelogs/1.19.1/2.4.0.md ================================================ - Debugify is now fabric/quilt only! - Fix MC-147605 breaking modded text fields (EMI compatibility) ================================================ FILE: changelogs/1.19.2/2.4.1.md ================================================ - Support 1.19.2 ================================================ FILE: changelogs/1.19.2/2.5.0.md ================================================ - Add [MC-90683](https://bugs.mojang.com/browse/MC-90683) - "Received unknown passenger" - Entities with differing render distances as passengers outputs error - Add `Support me!` button in config menu. ================================================ FILE: changelogs/1.19.2/2.6.0.md ================================================ - Use [YetAnotherConfigLib](https://curseforge.com/minecraft/mc-mod/yacl) (you need to download it) instead of Cloth Config! ================================================ FILE: changelogs/1.19.2/2.6.1.md ================================================ - Disable configuring fixes that are force-disabled - Force disable macOS fixes on other operating systems ================================================ FILE: changelogs/1.19.2/2.6.2.md ================================================ - Fix description loading causing long load times ================================================ FILE: changelogs/1.19.2/2.7.0.md ================================================ ## New Fixes - [MC-59810](https://bugs.mojang.com/browse/MC-59810) - Cannot break blocks while sprinting (Ctrl+Click = right click on macOS) ## Other Changes - When conflicts or incompatible OSes are detected, Debugify no longer disables the fix permanently but only for that launch, so if you delete the mod / change OS it will automatically re-enable. - Change `Not fixed` for unavailable fixes to `Unavailable`. - Fix for [MC-577](https://bugs.mojang.com/browse/MC-577) wasn't handling drop mouse keybinds like the bug states. - Fixed [MC-200418](https://bugs.mojang.com/browse/MC-200418) dismounting zombie villagers even when they weren't a jockey. - Disable [MC-162253](https://bugs.mojang.com/browse/MC-162253) when Phosphor or Starlight are loaded, they fix it. - Disable [MC-165595](https://bugs.mojang.com/browse/MC-165595) when Sodium Extra is loaded, it fixes it. - Disable [MC-22882](https://bugs.mojang.com/browse/MC-22882) when Ctrl-Q is loaded, it fixes it. ================================================ FILE: changelogs/1.19.2/2.7.1.md ================================================ - Further improve [MC-26757](https://bugs.mojang.com/browse/MC-26757) (the tooltip going off-screen one) now Debugify can wrap tooltips only when even centering tooltips makes them going off-screen, maintaining parity with Bedrock AND completely fixing the issue altogether. - Better compatibility for some fixes - Techniques of modifying certain game code have been improved ================================================ FILE: changelogs/1.19.2/2.8.0.md ================================================ - [MC-227169](https://bugs.mojang.com/browse/MC-227169) - The main hand is broken when you hold a crossbow loaded into the secondary hand - [MC-135973](https://bugs.mojang.com/browse/MC-135973) - Can't hold Q to drop items rapidly from container inventories - Fix some LinkageErrors with other mods using MixinExtras - Resolve [#162](https://github.com/isXander/Debugify/issues/162) - Notice screen for config when YetAnotherConfigLib isn't loaded - Remove use of Fabric's access wideners ================================================ FILE: changelogs/1.19.3/1.19.3+1.0.md ================================================ # Updated to 1.19.3 ## New & improved Telemetry Fix New telemetry menu in 1.19.3 allows you to set telemetry from Minimal to Full, Debugify adds a third option, off, that fully turns off and prevents Minecraft from connecting to Mojang telemetry services. This also allows for a tooltip explaining each type of telemetry option. ### Technical Details Debugify adds another option in `options.txt` named `debugifyTelemetry` where 0 = off, 1 = minimal and 2 = full. Debugify internally sets the vanilla option to minimal if off or minimal so if you delete Debugify you would not be defaulted to full. ## Options GUI improvements You can now search for fixes using their descriptions as well as their bug ID. 'Server' fixes have been renamed to 'Main' fixes because previous wording was misleading that they only applied on a server. 'Main' and 'Client' are now categories instead of groups while 'Basic' and 'Gameplay' have taken their place as groups rather than categories. The gameplay warning and multiplayer toggle are mirrored in both categories. Fix groups are now expanded by default. ## New versioning system Due to how intertwined Debugify is with Minecraft versions, starting 1.19.3, a new versioning system for Debugify is being adopted. The version will reset on every Minecraft version bump, including patches. An example version is `1.19.3+1.0`, the major version will change when Debugify adds new fixes or any significant changes to the mod itself happens, the minor version will change if Debugify makes any small changes such as a bug fix or a text localisation update. This has been made because the current system was very confusing and wasn't clear when there should ever be a major bump. ## Removed bugs fixed in 1.19.3 | Bug ID | Name | Fixed in | |-------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------|-------------| | [MC-26757](https://bugs.mojang.com/browse/MC-26757) | Large item tooltips can get cut off at the edges of the screen | 22w42a | | [MC-135973](https://bugs.mojang.com/browse/MC-135973) | Can't hold Q to drop items rapidly from container inventories | 22w42a | | [MC-145748](https://bugs.mojang.com/browse/MC-145748) | Clicking a settings button when there's a slider under the mouse in the next screen plays the click sound twice | 22w42a | | [MC-84873](https://bugs.mojang.com/browse/MC-84873) | DeathTime values 20+ cause corrupted mobs | 22w43a | | [MC-147605](https://bugs.mojang.com/browse/MC-147605) | Text cursors can exist in multiple fields | 22w46a | | [MC-151412](https://bugs.mojang.com/browse/MC-151412) | "Edit Server Info" window does not focus "Server Name" text field automatically | 22w46a | | [MC-233042](https://bugs.mojang.com/browse/MC-233042) | Server Address field isn't focused when Direct Connection menu is opened | 22w46a | | [MC-249059](https://bugs.mojang.com/browse/MC-249059) | Loading terrain screen cannot close before 2 seconds have passed | 22w46a | | [MC-228976](https://bugs.mojang.com/browse/MC-228976) | Entity collision is run on render thread | 1.19.3-pre3 | ================================================ FILE: changelogs/1.19.3/1.19.3+1.1.md ================================================ - Re-compile with latest version of YetAnotherConfigLib as new version JAR isn't backwards compatible ================================================ FILE: changelogs/1.19.3/1.19.3+1.2.md ================================================ - Removed MC-214147 as it was deemed intended by me. ================================================ FILE: changelogs/1.19.4/1.19.4+1.0.md ================================================ - Update to 1.19.4 - Removed [MC-165595](https://bugs.mojang.com/browse/MC-165595) as it was fixed in 1.19.4 ================================================ FILE: changelogs/1.19.4/1.19.4+1.1.md ================================================ - Fixed issues with the MC-46766 fix - Fixed a lot of client bug fixes silently failing to be applied fully - MC-108948 - MC-127970 - MC-143474 - MC-162253 - MC-215531 - MC-217716 - MC-227169 - MC-22882 - MC-237493 - this fixes the telemetry fix not properly clearing the telemetry info screen - MC-577 - MC-59810 - MC-79545 - MC-90683 - MC-12829 - MC-140646 - Prevent mixins from failing silently in the future - Publish sources jar to maven - Add Traditional Chinese translation ================================================ FILE: changelogs/1.19.4/1.19.4+2.0.md ================================================ - Add fix explanations and effects to most bug fixes - Fix crash relating to MC-162253 - Improve MC-183990 to fix more mobs ================================================ FILE: changelogs/1.19.4/1.19.4+2.1.md ================================================ - Fix crash relating to MC-122477 on Linux ================================================ FILE: changelogs/1.19.4/1.19.4+2.2.md ================================================ - Fix crash when MC-59810 is enabled ================================================ FILE: changelogs/1.20/1.20+1.0.md ================================================ - Update to 1.20 - Removed [MC-162253](https://bugs.mojang.com/browse/MC-162253) as it was fixed in 1.20 snapshots. ================================================ FILE: changelogs/1.20/1.20+1.1.md ================================================ - Fix crash when opening chat menu with MC-122627 enabled ================================================ FILE: changelogs/1.20.1/1.20.1+1.0.md ================================================ - Added error handling to bug fixes to sometimes catch errors and continue loading. - Fixed issue with MC-176559 bugfix where continuously breaking blocks would glitch out. ([#247](https://github.com/isXander/Debugify/issues/247)) ================================================ FILE: changelogs/1.20.1/1.20.1+1.1.md ================================================ - Fix mixin conflict with Fabric API - Fix French translation not loading ================================================ FILE: changelogs/1.20.1/1.20.1+2.0.md ================================================ # Debugify 1.20.1+2.0 ## New Fixes - [MC-263865](https://bugs.mojang.com/browse/MC-263865) - Fullscreen state isn't saved when F11 is pressed - *by [Ampflower](https://github.com/isXander/Debugify/pull/259),* [MC-8187](https://bugs.mojang.com/browse/MC-8187) - Two-by-two arrangements of jungle or spruce saplings cannot grow when there are adjacent blocks located north or west of the sapling formation ================================================ FILE: changelogs/1.20.2/1.20.2+1.0.md ================================================ - Update to 1.20.2 - Remove MC-121772 as it was fixed - Remove MC-140646 as it was fixed - Remove MC-90084 as it was fixed ================================================ FILE: changelogs/1.20.3/1.20.3+1.0.md ================================================ - Update to 1.20.3 - Literally nothing changed since 1.20.3 ================================================ FILE: changelogs/1.20.3/1.20.3+1.1.md ================================================ - Fix MC-237493 - Telemetry mode couldn't be toggled to None anymore. ================================================ FILE: changelogs/1.20.4/1.20.4+1.0.md ================================================ - Update to 1.20.4 - Fabric Loader 0.15.0 or later required - Mixin extras is no longer bundled ================================================ FILE: changelogs/1.20.4/1.20.4+1.1.md ================================================ - Fix broken description cache ================================================ FILE: changelogs/1.21/1.21+1.0.md ================================================ # Debugify 1.21+1.0 ## Removed bug fixes These fixes have been fixed by vanilla and therefore have no use in this mod! - MC-14923 - Players can be kicked for spamming in a singleplayer world with cheats disabled - MC-124177 - Teleporting to another dimension loses some client states - MC-31819 - Hunger saturation depletes on Peaceful ================================================ FILE: changelogs/1.21.1/1.21.1+1.0.md ================================================ # Debugify 1.21.1+1.0 - Bumped fabric version constraint to 1.21.1 *This release was kindly PRed by [lospejos](https://github.com/lospejos)* ================================================ FILE: changelogs/1.21.10/1.21.10+1.0.md ================================================ # Debugify 1.21.10+1.0 As usual with a 1.0, all bug fixes that have been fixed in vanilla have been removed. ## Newly Patched Bugs - [MC-263999](https://mojira.dev/MC-263999) - Zombies breaking doors do not show break particles - by [Microcontrollers#476](https://github.com/isxander/debugify/pull/476) - [MC-153010](https://mojira.dev/MC-153010) - doMobLoot gamerule doesn't prevent foxes from dropping their items - by [Microcontrollers#478](https://github.com/isxander/debugify/pull/478) - [MC-44654](https://mojira.dev/MC-44654) - Some entities don't update position to the client when teleported - by [Microcontrollers#474](https://github.com/isxander/debugify/pull/474) - [MC-264979](https://mojira.dev/MC-264979) - Fresh installations print NoSuchFileException for server.properties - by [Microcontrollers#477](https://github.com/isxander/debugify/pull/477) - [MC-264285](https://mojira.dev/MC-264285) - Unbreakable flint and steels are completely consumed when igniting a creeper - by [Microcontrollers#480](https://github.com/isxander/debugify/pull/480) - [MC-133218](https://mojira.dev/MC-133218) - Usable items continue to be used on the death screen after dying when the "keepInventory" gamerule is set to "true" - by [Microcontrollers#471](https://github.com/isxander/debugify/pull/471) - [MC-158900](https://mojira.dev/MC-158900) - "bad packet id 26" upon connecting after tempban expire - [Microcontrollers#482](https://github.com/isxander/debugify/pull/482) ## Changes - Fixed [MC-168573](https://mojira.dev/MC-168573) patch - it broke shields blocking sounds - by [Microcontrollers#469](https://github.com/isxander/debugify/pull/469) - Disable [MC-61489](https://mojira.dev/MC-61489) patch by default - people may not like this alternative position - by [Riflusso#468](https://github.com/isxander/debugify/pull/468) - Mark [MC-61489](https://mojira.dev/MC-61489) patch as incompatible with Scribble mod - by [chrrs#493](https://github.com/isxander/debugify/pull/493) ================================================ FILE: changelogs/1.21.10/1.21.10+1.1.md ================================================ # Debugify 1.21.10+1.1 ## Changes - Fix crash with Controlify installed - The fix for MC-59810 was failing. This was not caught in testing because the fix applies specifically for macOS. - Attempted mixin failure recoveries are now logged within crash reports, like they are in latest.log ================================================ FILE: changelogs/1.21.11/1.21.11+1.0.md ================================================ # Debugify 1.21.11+1.0 As usual with a 1.0, all bug fixes that have been fixed in vanilla have been removed. ================================================ FILE: changelogs/1.21.3/1.21.3+1.0.md ================================================ # Debugify 1.21.3+1.0 - **This update was gracefully PRed by IMS, thank you IMS for updating Debugify to 1.21.3** - Add Vietnamese translation (by I_am_Vietnam) - Add Italian translation (VladAndreiMorariu) - Add Mexican Spanish Translation (Santiago Hernandez) - Update Russian translation (FurnyGo) - Fix insta-crash bug with MC-577 bug fix (howmanysmall) ================================================ FILE: changelogs/1.21.4/1.21.4+1.0.md ================================================ # Debugify 1.21.4+1.0 - Removed MC-12829 fix (resolved in 24w44a) - Removed MC-55347 fix (resolved in 24w44a) - Removed MC-111516 fix (resolved in 24w44a) ================================================ FILE: changelogs/1.21.4/1.21.4+1.1.md ================================================ # Debugify 1.21.4+1.1 - Fix crash when going into end dimension ([by rvbsm](https://github.com/isXander/Debugify/pull/379)) ================================================ FILE: changelogs/1.21.5/1.21.5+1.0.md ================================================ # Debugify 1.21.5+1.0 - Removed MC-108948 fix since it was extremely buggy - Move MC-159163 to a gameplay fix as some servers detected this as cheating ================================================ FILE: changelogs/1.21.7/1.21.7+1.0.md ================================================ # Debugify 1.21.7+1.0 - Make bug fix descriptions offline as the bug tracker migration broke the API - Removed MC-112730 as it was fixed by vanilla ================================================ FILE: changelogs/1.21.8/1.21.8+1.0.md ================================================ # Debugify 1.21.8+1.0 ## Bug Fixes * Fix [MC-35361](https://bugs.mojang.com/browse/MC-35361) – Inventory opening is detected while in Nether Portal (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/422)) * Fix [MC-46503](https://bugs.mojang.com/browse/MC-46503) – You can retain entities' shaders by running the “/kill” command while in spectator mode (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/407)) * Fix [MC-46737](https://bugs.mojang.com/browse/MC-46737) – Entities' shaders are applied when beginning to spectate them in third person (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/408)) * Fix [MC-57057](https://bugs.mojang.com/browse/MC-57057) – Guardian laser attack sound ignores distance (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/438)) * Fix [MC-61489](https://bugs.mojang.com/browse/MC-61489) – Book GUI is not vertically centred (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/433)) * Fix [MC-82263](https://bugs.mojang.com/browse/MC-82263) – Ender dragon produces regular hurt sound on final hit (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/447)) * Fix [MC-84661](https://bugs.mojang.com/browse/MC-84661) – Glowing is considered a positive effect in potion item tooltips (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/406)) * Fix [MC-94054](https://bugs.mojang.com/browse/MC-94054) – Cave spiders spin around when walking (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/420)) * Fix [MC-115092](https://bugs.mojang.com/browse/MC-115092) – Squid/glow squid named “Dinnerbone” or “Grumm” is not upside‑down (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/423)) * Fix [MC-116510](https://bugs.mojang.com/browse/MC-116510) – Attack indicator doesn't indicate (most of the time) that breaking instantly‑mineable blocks resets your attack (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/445)) * Fix [MC-118740](https://bugs.mojang.com/browse/MC-118740) – Performing any right‑click action silently resets the attack cooldown (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/445)) * Fix [MC-123450](https://bugs.mojang.com/browse/MC-123450) – Item frames play sounds when the item within them is read from NBT (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/424)) * Fix [MC-123605](https://bugs.mojang.com/browse/MC-123605) – Debug world still sets clear weather time instead of deactivating gamerule doWeatherCycle (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/409)) * Fix [MC-134110](https://bugs.mojang.com/browse/MC-134110) – Structure mirroring breaking apart double chests (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/417)) * Fix [MC-136249](https://bugs.mojang.com/browse/MC-136249) – Wearing boots enchanted with Depth Strider decreases the strength of the Riptide enchantment (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/449)) * Fix [MC-139041](https://bugs.mojang.com/browse/MC-139041) – The sounds of fishing bobbers aren't controlled by the “Players” sound slider (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/425)) * Fix [MC-147659](https://bugs.mojang.com/browse/MC-147659) – Some witch huts spawn the incorrect cat (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/414)) * Fix [MC-147784](https://bugs.mojang.com/browse/MC-147784) – Fletching table flashes crafting table’s GUI for about a second upon right‑clicking it in spectator mode (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/450)) * Fix [MC-159283](https://bugs.mojang.com/browse/MC-159283) – The End terrain does not generate in multiple rings centred around the world centre (from Thorium) (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/429)) * Fix [MC-165306](https://bugs.mojang.com/browse/MC-165306) – Beacon beams are transparent from the inside (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/448)) * Fix [MC-168573](https://bugs.mojang.com/browse/MC-168573) – After breaking a shield, the player’s off‑hand can’t finish using some items (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/412)) * Fix [MC-170462](https://bugs.mojang.com/browse/MC-170462) – Bad Omen is considered a positive effect in potion item tooltips (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/406)) * Fix [MC-176806](https://bugs.mojang.com/browse/MC-176806) – Scoreboard criteria for using glowstone doesn’t increase score when charging a respawn anchor (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/428)) * Fix [MC-177381](https://bugs.mojang.com/browse/MC-177381) – Game does not count the distance properly if you locate a structure from more than 46340 blocks away (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/410)) * Fix [MC-187100](https://bugs.mojang.com/browse/MC-187100) – End crystals try to heal dying Ender dragons (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/427)) * Fix [MC-187100](https://bugs.mojang.com/browse/MC-187100) – End crystals try to heal dying Ender dragons (fix missing BugFix and move to server side) (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/443)) * Fix [MC-188359](https://bugs.mojang.com/browse/MC-188359) – Burp sound does not play after drinking or after eating cake (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/437)) * Fix [MC-201374](https://bugs.mojang.com/browse/MC-201374) – Wrong position passed to getCollisionShape from CampfireBlock#isSmokingBlockAt (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/418)) * Fix [MC-201723](https://bugs.mojang.com/browse/MC-201723) – Statistics sprites don’t look pressed when clicked (from Thorium) (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/429)) * Fix [MC-202637](https://bugs.mojang.com/browse/MC-202637) – Last sound clip of eating will still play when Players volume is set to 0% (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/425)) * Fix [MC-206540](https://bugs.mojang.com/browse/MC-206540) – Increased input delay when riding an entity (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/432)) * Fix [MC-210318](https://bugs.mojang.com/browse/MC-210318) – Maximum length of book title changed from 16 to 15 characters (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/426)) * Fix [MC-211561](https://bugs.mojang.com/browse/MC-211561) – Fishing line appears in opposite hand when switching slots (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/435)) * Fix [MC-219981](https://bugs.mojang.com/browse/MC-219981) – If zombies spawned with max health over 20 (leader zombie bonus), they will have 20 health instead of their max health (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/434)) * Fix [MC-221257](https://bugs.mojang.com/browse/MC-221257) – Shulker bullets don’t produce bubble particles when moving through water (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/430)) * Fix [MC-226961](https://bugs.mojang.com/browse/MC-226961) – Experience Orbs treat flowing lava as a full block (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/461)) * Fix [MC-227008](https://bugs.mojang.com/browse/MC-227008) – Enderman constantly tries to teleport when in a boat or a minecart under daylight (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/460)) * Fix [MC-227337](https://bugs.mojang.com/browse/MC-227337) – When a shulker bullet hits an entity, the explosion sound is not played and particles are not produced (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/425)) * Fix [MC-242809](https://bugs.mojang.com/browse/MC-242809) – IP field in the multiplayer menu will not detect the IP if a space is put at the beginning/end of it (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/421)) * Fix [MC-245394](https://bugs.mojang.com/browse/MC-245394) – The sounds of raid horns blaring aren’t controlled by the correct sound slider (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/425)) * Fix [MC-251068](https://bugs.mojang.com/browse/MC-251068) – If you delete your only world, you are no longer automatically taken to the “Create New World” screen (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/415)) * Fix [MC-259512](https://bugs.mojang.com/browse/MC-259512) – Horizontal camera rotation lags when riding (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/432)) * Fix [MC-267125](https://bugs.mojang.com/browse/MC-267125) – Command suggestions for reloadable content are not affected by /reload (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/456)) * Fix [MC-267376](https://bugs.mojang.com/browse/MC-267376) – You can view through blocks on small scales (near‑plane clipping) (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/413)) * Fix [MC-267469](https://bugs.mojang.com/browse/MC-267469) – GUI list entry highlight border not always aligned properly (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/458)) * Fix [MC-268420](https://bugs.mojang.com/browse/MC-268420) – Cooldown indicator flashes when switching items with high attack‑speed attribute (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/436)) * Fix [MC-268617](https://bugs.mojang.com/browse/MC-268617) – Structures can’t be saved if the game directory name has certain patterns (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/439)) * Fix [MC-271899](https://bugs.mojang.com/browse/MC-271899) – StructureTemplate palette caches are not thread‑safe (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/419)) * Fix [MC-272431](https://bugs.mojang.com/browse/MC-272431) – Ender Dragon incorrect vertical velocity causes erratic behaviour (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/459)) * Fix [MC-280220](https://bugs.mojang.com/browse/MC-280220) – When a dolphin holds an item, it is rendered upside‑down and far from the mouth (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/462)) * Fix [MC-297837](https://bugs.mojang.com/browse/MC-297837) – Locator bar shows players above you as being below you when they are high enough (by [@isXander](https://github.com/isXander/Debugify/pull/465)) * Fix [MC-298066](https://bugs.mojang.com/browse/MC-298066) – Directly entering a bed from a mount places the player in the wrong place (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/454)) * Fix [MC-298225](https://bugs.mojang.com/browse/MC-298225) – Shapes appear in the End sky with certain distance settings (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/416)) * Fix [MC-298558](https://bugs.mojang.com/browse/MC-298558) – Rain fog calculation can overshoot while the game is unresponsive (by [@isXander](https://github.com/isXander/Debugify/pull/441)) * Fix [MC-299115](https://bugs.mojang.com/browse/MC-299115) – Arrow loses its owner tag when deflected while its owner is offline (by [@isXander](https://github.com/isXander/Debugify/pull/464)) ## Other Changes * Fix crash when opening inventory (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/444)) * Resolve Moonrise mixin error (by [@R00tB33rMan](https://github.com/isXander/Debugify/pull/405)) * Cleanup (by [@MicrocontrollersDev](https://github.com/isXander/Debugify/pull/446)) * 🌐 Add Argentine Spanish localisation (by [@Texaliuz](https://github.com/isXander/Debugify/pull/453)) * Bump org.ajoberstar.grgit from 5.0.0 to 5.3.2 (by [dependabot[bot]](https://github.com/isXander/Debugify/pull/440)) ================================================ FILE: changelogs/26.1.2/26.1.2+1.0.md ================================================ # Debugify 26.1.2+1.0 As usual with a 1.0, all bug fixes that have been fixed in vanilla have been removed. Some mixins have also been rewritten to be more optimal and compatible with other mods. ================================================ FILE: changelogs/26.1.2/26.1.2.2.md ================================================ # Debugify 26.1.2.2 Debugify now has a new versioning scheme! It is now similar to the versioning scheme of NeoForge. This version, `26.1.2.2`, refers to `26.1.2` Minecraft version, build `2` of Debugify. This change was made to make Debugify's version semantically parseable by Fabric. ## Changes - Move MC-136249 (Depth strider + riptide bug) to a gameplay fix, meaning it is disabled by default in multiplayer. - Move MC-231097 (Release item after dropping bug) to a gameplay fix, meaning it is disabled by default in multiplayer. Both of these fixes had been known to cause strict anti-cheats, such as the one found on `minemen.club`, to ban users of Debugify. As of this release, Debugify will no longer cause bans on `minemen.club`, as of this update, confirmed by dewgs. ================================================ FILE: changelogs/header.md ================================================ [![](https://www.bisecthosting.com/partners/custom-banners/08bbd3ff-5c0d-4480-8738-de0f070a04dd.png)](https://bisecthosting.com/xander) ================================================ FILE: crowdin.yml ================================================ files: - source: src/main/resources/assets/debugify/lang/en_us.json translation: /src/main/resources/assets/debugify/lang/%locale_with_underscore%.json ================================================ FILE: gradle/wrapper/gradle-wrapper.properties ================================================ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists ================================================ FILE: gradle.properties ================================================ org.gradle.jvmargs=-Xmx4G org.gradle.parallel=true org.gradle.parallel.threads=4 modstitch.platform=fabric-loom modVersion=26.1.2.2 pub.modrinthId=QwxR6Gcd pub.curseforgeId=596224 pub.curseforgeSlug=debugify githubProject=isXander/Debugify # Libraries minecraftVersion=26.1.2 fabricApiVersion=0.145.4+26.1.2 yaclVersion=3.9.2+26.1-fabric modMenuVersion=18.0.0-alpha.8 ================================================ FILE: gradlew ================================================ #!/bin/sh # # Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ############################################################################## # # Gradle start up script for POSIX generated by Gradle. # # Important for running: # # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is # noncompliant, but you have some other compliant shell such as ksh or # bash, then to run this script, type that shell name before the whole # command line, like: # # ksh Gradle # # Busybox and similar reduced shells will NOT work, because this script # requires all of these POSIX shell features: # * functions; # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», # «${var#prefix}», «${var%suffix}», and «$( cmd )»; # * compound commands having a testable exit status, especially «case»; # * various built-in commands including «command», «set», and «ulimit». # # Important for patching: # # (2) This script targets any POSIX shell, so it avoids extensions provided # by Bash, Ksh, etc; in particular arrays are avoided. # # The "traditional" practice of packing multiple parameters into a # space-separated string is a well documented source of bugs and security # problems, so this is (mostly) avoided, by progressively accumulating # options in "$@", and eventually passing that to Java. # # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; # see the in-line comments for details. # # There are tweaks for specific operating systems such as AIX, CygWin, # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. # ############################################################################## # Attempt to set APP_HOME # Resolve links: $0 may be a link app_path=$0 # Need this for daisy-chained symlinks. while APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path [ -h "$app_path" ] do ls=$( ls -ld "$app_path" ) link=${ls#*' -> '} case $link in #( /*) app_path=$link ;; #( *) app_path=$APP_HOME$link ;; esac done APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" APP_BASE_NAME=${0##*/} # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum warn () { echo "$*" } >&2 die () { echo echo "$*" echo exit 1 } >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false case "$( uname )" in #( CYGWIN* ) cygwin=true ;; #( Darwin* ) darwin=true ;; #( MSYS* | MINGW* ) msys=true ;; #( NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD=$JAVA_HOME/jre/sh/java else JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac fi # Collect all arguments for the java command, stacking in reverse order: # * args from the command line # * the main class name # * -classpath # * -D...appname settings # * --module-path (only if needed) # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) # Now convert the arguments - kludge to limit ourselves to /bin/sh for arg do if case $arg in #( -*) false ;; # don't mess with options #( /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath [ -e "$t" ] ;; #( *) false ;; esac then arg=$( cygpath --path --ignore --mixed "$arg" ) fi # Roll the args list around exactly as many times as the number of # args, so each arg winds up back in the position where it started, but # possibly modified. # # NB: a `for` loop captures its iteration list before it begins, so # changing the positional parameters here affects neither the number of # iterations, nor the values presented in `arg`. shift # remove old arg set -- "$@" "$arg" # push replacement arg done fi # Collect all arguments for the java command; # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # shell script including quotes and variable substitutions, so put them in # double quotes to make sure that they get re-expanded; and # * put everything else in single quotes, so that it's not re-expanded. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -classpath "$CLASSPATH" \ org.gradle.wrapper.GradleWrapperMain \ "$@" # Stop when "xargs" is not available. if ! command -v xargs >/dev/null 2>&1 then die "xargs is not available" fi # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. # # In Bash we could simply go: # # readarray ARGS < <( xargs -n1 <<<"$var" ) && # set -- "${ARGS[@]}" "$@" # # but POSIX shell has neither arrays nor command substitution, so instead we # post-process each arg (as a line of input to sed) to backslash-escape any # character that might be a shell metacharacter, then use eval to reverse # that process (while maintaining the separation between arguments), and wrap # the whole thing up as a single "set" statement. # # This will of course break if any of these variables contains a newline or # an unmatched quote. # eval "set -- $( printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | xargs -n1 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | tr '\n' ' ' )" '"$@"' exec "$JAVACMD" "$@" ================================================ FILE: gradlew.bat ================================================ @rem @rem Copyright 2015 the original author or authors. @rem @rem Licensed under the Apache License, Version 2.0 (the "License"); @rem you may not use this file except in compliance with the License. @rem You may obtain a copy of the License at @rem @rem https://www.apache.org/licenses/LICENSE-2.0 @rem @rem Unless required by applicable law or agreed to in writing, software @rem distributed under the License is distributed on an "AS IS" BASIS, @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Resolve any "." and ".." in APP_HOME to make it shorter. for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! set EXIT_CODE=%ERRORLEVEL% if %EXIT_CODE% equ 0 set EXIT_CODE=1 if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal :omega ================================================ FILE: modstitch.ct ================================================ accessWidener v2 named accessible class net/minecraft/client/Options$FieldAccess accessible class net/minecraft/client/gui/screens/telemetry/TelemetryEventWidget$ContentBuilder accessible class net/minecraft/client/gui/screens/telemetry/TelemetryEventWidget$Content accessible class net/minecraft/client/gui/screens/achievement/StatsScreen$ItemStatisticsList accessible class net/minecraft/world/level/levelgen/DensityFunctions$EndIslandDensityFunction accessible class net/minecraft/server/MinecraftServer$ReloadableResources ================================================ FILE: scripts/check_bug_fixes.py ================================================ import requests import sys import os abspath = os.path.abspath(__file__) dname = os.path.dirname(abspath) os.chdir(dname) version_list = requests.get("https://piston-meta.mojang.com/mc/game/version_manifest_v2.json").json()['versions'] def version_idx(version): return [(idx, ver) for idx, ver in enumerate(version_list) if ver['id'] == version] with open('../gradle.properties', 'r') as propfile: gradleProperties = dict([map(lambda side: side.strip(), i.split('=', maxsplit=1)) for i in filter(lambda line: len(line.strip()) > 2 and not line.lstrip().startswith('#'), propfile.readlines())]) minecraft_version = gradleProperties['minecraftVersion'] minecraft_version_idx = version_idx(minecraft_version) print(f'Minecraft Version: {minecraft_version}') with open('../.bugs', 'r') as f: bugs_lines = f.readlines() bugs = [] for line in bugs_lines: parts = line.split() if len(parts) >= 3 and parts[0] == 'patched': bugs.append((f'MC-{parts[1]}', parts[2])) resolved_count = 0 duplicate_count = 0 for bug, side in bugs: try: response = requests.get(f'https://mojira.dev/api/v1/issues/{bug}') except Exception as e: print(f'Failed to fetch {bug}: {e}') continue if not response.ok: print(f'Failed to fetch {bug}: HTTP {response.status_code} {response.text.strip()}') continue try: json_response = response.json() except Exception as e: text = response.text.strip() if '\n' not in text and len(text) < 100: print(f'\033[35m{bug} ({side}): {text}\033[0m') else: print(f'Failed to parse response for {bug} ({side}): {e}\n{text}') continue resolution = json_response['resolution'] fix_versions = [v.replace(' Pre-release ', '-pre').replace(' Release Candidate ', '-rc').replace(' Snapshot ', '-snapshot-').replace('Minecraft ', '') for v in (json_response.get('fix_versions') or [])] message_color = '' match resolution: case 'Fixed' | "Won't Fix" | 'Works As Intended': resolved_count += 1 bug_status = resolution message_color = '\033[91m' if len(fix_versions) > 0: bug_status += f' in {", ".join(fix_versions)}' if all(map(lambda v: version_idx(v) < minecraft_version_idx, fix_versions)) or any( map(lambda v: v == "Future Update", fix_versions)): message_color = '\033[33m' resolved_count -= 1 case 'Duplicate': duplicate_count += 1 bug_status = "Duplicate" message_color = '\033[33m' case _: bug_status = 'OK!' is_resolved = resolution in ('Fixed', "Won't Fix", 'Works As Intended') message = f"{message_color}{bug} ({side}): {bug_status}\033[0m" print(message, file=sys.stderr if is_resolved else sys.stdout) if resolved_count == 0 and duplicate_count == 0: print('\nNothing to report!') else: print() if duplicate_count > 0: print(f'\033[33m{duplicate_count} bug{"s have" if duplicate_count > 1 else " has"} been marked as duplicate!') if resolved_count > 0: print(f'\033[91m{resolved_count} bug{"s need" if resolved_count > 1 else " needs"} removing!') exit(-1) ================================================ FILE: settings.gradle.kts ================================================ pluginManagement { repositories { mavenCentral() gradlePluginPortal() maven("https://maven.fabricmc.net") maven("https://maven.quiltmc.org/repository/release") } } rootProject.name = "Debugify" ================================================ FILE: src/client/java/dev/isxander/debugify/client/DebugifyClient.java ================================================ package dev.isxander.debugify.client; public class DebugifyClient { public static void onInitializeClient() { } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/gui/BugFixController.java ================================================ package dev.isxander.debugify.client.gui; import dev.isxander.yacl3.api.Option; import dev.isxander.yacl3.api.utils.Dimension; import dev.isxander.yacl3.gui.AbstractWidget; import dev.isxander.yacl3.gui.YACLScreen; import dev.isxander.yacl3.gui.controllers.BooleanController; import net.minecraft.ChatFormatting; import net.minecraft.network.chat.Component; public class BugFixController extends BooleanController { public BugFixController(Option option, boolean errored) { super(option, state -> { if (errored) return Component.translatable("debugify.error.mixin_error.text").withStyle(ChatFormatting.RED); if (!option.available()) return Component.translatable("debugify.fix.unavailable"); return state ? Component.translatable("debugify.fix.enabled").withStyle(ChatFormatting.GREEN) : Component.translatable("debugify.fix.disabled").withStyle(ChatFormatting.RED); }, false); } @Override public AbstractWidget provideWidget(YACLScreen screen, Dimension widgetDimension) { return new BugFixControllerElement(this, screen, widgetDimension); } public static class BugFixControllerElement extends BooleanControllerElement { private String tooltipString; public BugFixControllerElement(BugFixController control, YACLScreen screen, Dimension dim) { super(control, screen, dim); control.option().addListener((opt, pending) -> recalculateTooltipString()); recalculateTooltipString(); } @Override public boolean matchesSearch(String query) { return super.matchesSearch(query) || tooltipString.contains(query.toLowerCase()); } private void recalculateTooltipString() { this.tooltipString = control.option().description().text().getString().toLowerCase(); } } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/gui/ConfigGuiHelper.java ================================================ package dev.isxander.debugify.client.gui; import dev.isxander.debugify.config.DebugifyConfig; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import dev.isxander.debugify.error.DebugifyErrorHandler; import dev.isxander.yacl3.api.*; import dev.isxander.yacl3.api.controller.BooleanControllerBuilder; import dev.isxander.yacl3.api.controller.TickBoxControllerBuilder; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.ChatFormatting; import net.minecraft.client.gui.screens.Screen; import net.minecraft.locale.Language; import net.minecraft.network.chat.Component; public class ConfigGuiHelper { public static Screen createConfigGui(DebugifyConfig config, Screen parent) { var yacl = YetAnotherConfigLib.createBuilder() .title(Component.translatable("debugify.name")) .save(config::save); var gameplayWarning = LabelOption.create(Component.translatable("debugify.gameplay.warning").withStyle(ChatFormatting.RED)); var gameplayInMultiplayer = Option.createBuilder() .name(Component.translatable("debugify.gameplay.enable_in_multiplayer")) .binding( false, () -> config.gameplayFixesInMultiplayer, value -> config.gameplayFixesInMultiplayer = value ) .controller(TickBoxControllerBuilder::create) .build(); for (BugFix.Env env : BugFix.Env.values()) { var categoryBuilder = ConfigCategory.createBuilder() .name(Component.translatable(env.getDisplayName())) .tooltip(Component.translatable(env.getDescriptionKey())); for (FixCategory fixCategory : FixCategory.values()) { var groupBuilder = OptionGroup.createBuilder() .name(Component.translatable(fixCategory.getDisplayName())); if (fixCategory == FixCategory.GAMEPLAY) { groupBuilder .option(gameplayWarning) .option(gameplayInMultiplayer); } config.getBugFixes().forEach((bug, enabled) -> { if (bug.env() == env && bug.category() == fixCategory) { var conflicts = bug.getActiveConflicts().stream().map(id -> FabricLoader.getInstance().getModContainer(id).orElseThrow().getMetadata().getName()).toList(); var satisfiesOS = bug.satisfiesOSRequirement(); var errored = DebugifyErrorHandler.hasErrored(bug); var unavailable = !conflicts.isEmpty() || !satisfiesOS || errored; var optionBuilder = Option.createBuilder() .name(Component.literal(bug.bugId())) .binding( bug.enabledByDefault(), () -> config.getBugFixes().get(bug), value -> config.getBugFixes().replace(bug, value) ) .customController(opt -> new BugFixController(opt, errored)) .available(!unavailable) .flag(OptionFlag.GAME_RESTART); OptionDescription.Builder descriptionBuilder = OptionDescription.createBuilder(); if (errored) { descriptionBuilder.text(Component.translatable("debugify.error.mixin_error", bug.bugId()).withStyle(ChatFormatting.RED, ChatFormatting.BOLD)); } for (String conflictMod : conflicts) { descriptionBuilder.text(Component.translatable("debugify.error.conflict", bug.bugId(), conflictMod).withStyle(ChatFormatting.RED)); } if (!satisfiesOS) descriptionBuilder.text(Component.translatable("debugify.error.os", bug.bugId(), Component.translatable(bug.requiredOs().getDisplayName())).withStyle(ChatFormatting.RED)); if (bug.description() != null) descriptionBuilder.text(Component.literal(bug.description())); String fixExplanationTooltipKey = "debugify.fix_explanation." + bug.bugId().toLowerCase(); if (Language.getInstance().has(fixExplanationTooltipKey)) descriptionBuilder.text(Component.translatable(fixExplanationTooltipKey).withStyle(ChatFormatting.GRAY)); String fixEffectTooltipKey = "debugify.fix_effect." + bug.bugId().toLowerCase(); if (Language.getInstance().has(fixEffectTooltipKey)) descriptionBuilder.text(Component.translatable(fixEffectTooltipKey).withStyle(ChatFormatting.GOLD)); optionBuilder.description(descriptionBuilder.build()); groupBuilder.option(optionBuilder.build()); } }); categoryBuilder.group(groupBuilder.build()); } yacl.category(categoryBuilder.build()); } yacl.category(ConfigCategory.createBuilder() .name(Component.translatable("debugify.misc")) .option(Option.createBuilder() .name(Component.translatable("debugify.misc.default_disabled")) .description(OptionDescription.of(Component.translatable("debugify.misc.default_disabled.description"))) .binding( false, () -> config.defaultDisabled, value -> config.defaultDisabled = value ) .controller(BooleanControllerBuilder::create) .build()) .build()); return yacl.build().generateScreen(parent); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/gui/NoYACLScreen.java ================================================ package dev.isxander.debugify.client.gui; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.AlertScreen; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.ClickEvent; import net.minecraft.network.chat.Component; import java.net.URI; public class NoYACLScreen extends AlertScreen { public NoYACLScreen(Screen parent) { super( () -> Minecraft.getInstance().setScreen(parent), Component.translatable("debugify.no_yacl.title").withStyle(ChatFormatting.BOLD), Component.translatable("debugify.no_yacl.description", Component.literal("YetAnotherConfigLib").withStyle(style -> style .withClickEvent(new ClickEvent.OpenUrl(URI.create("https://curseforge.com/minecraft/mc-mods/yacl"))) .applyFormats(ChatFormatting.BLUE, ChatFormatting.UNDERLINE)), Component.literal(".minecraft/config/debugify.json").withStyle(style -> style .withClickEvent(new ClickEvent.OpenFile(FabricLoader.getInstance().getConfigDir())) .applyFormats(ChatFormatting.BLUE, ChatFormatting.UNDERLINE))) ); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/helpers/mc118740/LocalPlayerDuck.java ================================================ package dev.isxander.debugify.client.helpers.mc118740; /** * Taken from MoulberrysTweaks * https://github.com/Moulberry/MoulberrysTweaks * under MIT license * * @author Moulberry */ public interface LocalPlayerDuck { float debugify$getVisualAttackStrengthScale(float partialTick); void debugify$resetVisualAttackStrengthScale(); void debugify$incrementVisualAttackStrengthScale(); } ================================================ FILE: src/client/java/dev/isxander/debugify/client/helpers/mc122477/KeyboardPollCounter.java ================================================ package dev.isxander.debugify.client.helpers.mc122477; public class KeyboardPollCounter { private static int count = 0; private static boolean requiresCount = false; public static void poll() { if (requiresCount) count++; } public static void startCounting() { requiresCount = true; } public static void stopCountingAndReset() { requiresCount = false; count = 0; } public static int getCount() { return count; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/helpers/mc147605/TextFieldHolder.java ================================================ package dev.isxander.debugify.client.helpers.mc147605; import net.minecraft.client.gui.components.EditBox; import org.jetbrains.annotations.Nullable; public interface TextFieldHolder { @Nullable EditBox getFocusedTextField(); void setFocusedTextField(@Nullable EditBox widget); } ================================================ FILE: src/client/java/dev/isxander/debugify/client/helpers/mc197260/DebugifyLightProvider.java ================================================ package dev.isxander.debugify.client.helpers.mc197260; import net.minecraft.client.renderer.entity.state.LivingEntityRenderState; public interface DebugifyLightProvider { default void debugify$modifyLightCoords(S livingEntityState) { } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/helpers/mc237493/DebugifyTelemetry.java ================================================ package dev.isxander.debugify.client.helpers.mc237493; import com.mojang.serialization.Codec; import java.util.Arrays; import java.util.Comparator; import java.util.function.IntFunction; import net.minecraft.network.chat.Component; import net.minecraft.util.ByIdMap; import net.minecraft.util.Mth; import net.minecraft.util.StringRepresentable; public enum DebugifyTelemetry { OFF(0, "options.telemetry.state.none", "debugify.mc_237493.tooltip.off"), MINIMAL(1, "options.telemetry.state.minimal", "debugify.mc_237493.tooltip.minimal"), ALL(2, "options.telemetry.state.all", "debugify.mc_237493.tooltip.all"); private static final IntFunction BY_ID = ByIdMap.continuous(value -> value.id, values(), ByIdMap.OutOfBoundsStrategy.WRAP); public static final Codec LEGACY_CODEC = Codec.INT.xmap(BY_ID::apply, value -> value.id); private final int id; private final Component caption; private final Component tooltip; DebugifyTelemetry(int id, final String key, final String translationKey) { this.id = id; this.caption = Component.translatable(key); this.tooltip = Component.translatable(translationKey); } public Component caption() { return this.caption; } public Component tooltip() { return this.tooltip; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/helpers/mc237493/DebugifyTelemetryAccessor.java ================================================ package dev.isxander.debugify.client.helpers.mc237493; import net.minecraft.client.OptionInstance; public interface DebugifyTelemetryAccessor { OptionInstance getTelemetryOption(); } ================================================ FILE: src/client/java/dev/isxander/debugify/client/helpers/mc26757/TooltipWrapper.java ================================================ package dev.isxander.debugify.client.helpers.mc26757; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; import net.minecraft.util.FormattedCharSequence; public class TooltipWrapper { public static List wrapTooltipLines(Screen screen, Font textRenderer, List lines) { int width = getMaxWidth(textRenderer, lines); int maxWidth = screen.width - 30; if (width <= maxWidth) return lines.stream().map(Component::getVisualOrderText).collect(Collectors.toList()); List wrapped = new ArrayList<>(); for (Component line : lines) { wrapped.addAll(textRenderer.split(line, maxWidth)); } return wrapped; } private static int getMaxWidth(Font textRenderer, List lines) { int maxWidth = 0; for (Component line : lines) { int width = textRenderer.width(line); if (width > maxWidth) maxWidth = width; } return maxWidth; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/integrations/ModMenuIntegration.java ================================================ package dev.isxander.debugify.client.integrations; import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ModMenuApi; import dev.isxander.debugify.Debugify; import dev.isxander.debugify.client.gui.ConfigGuiHelper; import dev.isxander.debugify.client.gui.NoYACLScreen; import net.fabricmc.loader.api.FabricLoader; public class ModMenuIntegration implements ModMenuApi { @Override public ConfigScreenFactory getModConfigScreenFactory() { return (parent) -> { if (!FabricLoader.getInstance().isModLoaded("yet_another_config_lib_v3")) return new NoYACLScreen(parent); return ConfigGuiHelper.createConfigGui(Debugify.CONFIG, parent); }; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc105068/LivingEntityMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc105068; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.level.Level; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-105068", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Attacking a shield-blocking player always plays the player hurts sound") @Mixin(LivingEntity.class) public abstract class LivingEntityMixin extends Entity { public LivingEntityMixin(EntityType variant, Level world) { super(variant, world); } @WrapOperation( method = "handleEntityEvent", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;playSound(Lnet/minecraft/sounds/SoundEvent;FF)V" ) ) private void beforeCond30(LivingEntity instance, SoundEvent soundEvent, float volume, float pitch, Operation original) { level().playLocalSound(getX(), getY(), getZ(), soundEvent, getSoundSource(), volume, pitch, false); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc115092/SquidRendererMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc115092; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Axis; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.renderer.entity.SquidRenderer; import net.minecraft.client.renderer.entity.state.SquidRenderState; import net.minecraft.world.entity.animal.squid.Squid; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-115092", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Squid/glow squid named \"Dinnerbone\" or \"Grumm\" is not upside-down") @Mixin(SquidRenderer.class) public class SquidRendererMixin { @Unique T squidEntity; @Inject( method = "extractRenderState(Lnet/minecraft/world/entity/animal/squid/Squid;Lnet/minecraft/client/renderer/entity/state/SquidRenderState;F)V", at = @At("TAIL") ) private void getSquidEntity(T entity, SquidRenderState state, float partialTicks, CallbackInfo ci) { squidEntity = entity; } @Inject( method = "setupRotations(Lnet/minecraft/client/renderer/entity/state/SquidRenderState;Lcom/mojang/blaze3d/vertex/PoseStack;FF)V", at = @At("TAIL") ) private void applyRotation(SquidRenderState state, PoseStack poseStack, float bodyRot, float entityScale, CallbackInfo ci) { String name = squidEntity.getName().getString(); if ("Dinnerbone".equals(name) || "Grumm".equals(name)) { poseStack.translate(0.0F, squidEntity.getBbHeight() + 0.1F, 0.0F); poseStack.mulPose(Axis.XP.rotationDegrees(180.0F)); } } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc116379/FishingHookRendererMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc116379; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.renderer.entity.FishingHookRenderer; import net.minecraft.world.entity.HumanoidArm; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.FishingHook; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-116379", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Punching with a cast fishing rod in the off-hand detaches fishing line from rod") @Mixin(FishingHookRenderer.class) public class FishingHookRendererMixin { @ModifyExpressionValue( method = "extractRenderState(Lnet/minecraft/world/entity/projectile/FishingHook;Lnet/minecraft/client/renderer/entity/state/FishingHookRenderState;F)V", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;getAttackAnim(F)F" ) ) private float modifyHandSwingProgress(float handSwingProgress, FishingHook entity) { Player player = entity.getPlayerOwner(); int j = player.getMainArm() == HumanoidArm.RIGHT ? 1 : -1; int j2 = j; ItemStack itemStack = player.getMainHandItem(); if (!itemStack.is(Items.FISHING_ROD)) { j = -j; } return j == j2 ? handSwingProgress : 0; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc118740/GuiMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc118740; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import dev.isxander.debugify.client.helpers.mc118740.LocalPlayerDuck; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.gui.Gui; import net.minecraft.client.player.LocalPlayer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; /** * Taken from MoulberrysTweaks * https://github.com/Moulberry/MoulberrysTweaks * under MIT license * * @author Moulberry */ @BugFix(id = "MC-118740", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, modConflicts = "moulberrystweaks", description = "Performing any right-click action silently resets the attack cooldown") @Mixin(Gui.class) public class GuiMixin { /** * This fixes both: * MC-118740 - Performing any right-click action silently resets the attack cooldown * MC-116510 - Attack indicator doesn't indicate (most of the time) that breaking instantly-mineable blocks resets your attack */ @WrapOperation( method = "extractCrosshair", at = @At( value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;getAttackStrengthScale(F)F" ) ) public float useFixedCooldown(LocalPlayer instance, float partialTick, Operation original) { if (instance instanceof LocalPlayerDuck localPlayer) { return localPlayer.debugify$getVisualAttackStrengthScale(partialTick); } else { return original.call(instance, partialTick); } } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc118740/LocalPlayerMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc118740; import com.mojang.authlib.GameProfile; import dev.isxander.debugify.client.helpers.mc118740.LocalPlayerDuck; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.player.LocalPlayer; import net.minecraft.util.Mth; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; /** * Taken from MoulberrysTweaks * under MIT license * * @author Moulberry */ @BugFix(id = "MC-118740", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, modConflicts = "moulberrystweaks", description = "Performing any right-click action silently resets the attack cooldown") @Mixin(LocalPlayer.class) public abstract class LocalPlayerMixin extends Player implements LocalPlayerDuck { @Unique private int visualAttackStrengthTicker = 0; public LocalPlayerMixin(Level level, GameProfile gameProfile) { super(level, gameProfile); } @Inject(method = "swing", at = @At("HEAD")) public void swing(InteractionHand hand, CallbackInfo ci) { this.visualAttackStrengthTicker = 0; } @Override public float debugify$getVisualAttackStrengthScale(float partialTick) { return Mth.clamp(((float)this.visualAttackStrengthTicker + partialTick) / this.getCurrentItemAttackStrengthDelay(), 0.0F, 1.0F); } @Override public void debugify$resetVisualAttackStrengthScale() { this.visualAttackStrengthTicker = 0; } @Override public void debugify$incrementVisualAttackStrengthScale() { this.visualAttackStrengthTicker += 1; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc118740/PlayerMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc118740; import dev.isxander.debugify.client.helpers.mc118740.LocalPlayerDuck; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.player.Player; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; /** * Taken from MoulberrysTweaks * under MIT license * * @author Moulberry */ @BugFix(id = "MC-118740", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, modConflicts = "moulberrystweaks", description = "Performing any right-click action silently resets the attack cooldown") @Mixin(Player.class) public class PlayerMixin { @Inject(method = "resetAttackStrengthTicker", at = @At("HEAD")) public void resetAttackStrengthTicker(CallbackInfo ci) { if (this instanceof LocalPlayerDuck localPlayerExt) { localPlayerExt.debugify$resetVisualAttackStrengthScale(); } } @Inject( method = "tick", at = @At( value = "INVOKE", // no specific reason to inject here, just an easy injection point before doing anything with attack indicator target = "Lnet/minecraft/world/entity/player/Player;getMainHandItem()Lnet/minecraft/world/item/ItemStack;", ordinal = 0 ) ) public void tick(CallbackInfo ci) { if (this instanceof LocalPlayerDuck localPlayerExt) { localPlayerExt.debugify$incrementVisualAttackStrengthScale(); } } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc122477/EditBoxMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc122477; import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import dev.isxander.debugify.client.helpers.mc122477.KeyboardPollCounter; import dev.isxander.debugify.fixes.OS; import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.input.CharacterEvent; import net.minecraft.util.Util; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @BugFix(id = "MC-122477", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, os = OS.LINUX, description = "Linux/GNU: Opening chat sometimes writes 't'") @Mixin(EditBox.class) public class EditBoxMixin { @Inject( method = "(Lnet/minecraft/client/gui/Font;IIIILnet/minecraft/client/gui/components/EditBox;Lnet/minecraft/network/chat/Component;)V", at = @At("RETURN") ) private void startPolling(CallbackInfo ci) { KeyboardPollCounter.startCounting(); } @WrapMethod(method = "charTyped") private boolean stopPolling(CharacterEvent event, Operation original) { if (Util.getPlatform() == Util.OS.LINUX) { if (KeyboardPollCounter.getCount() == 1) { return true; } if (KeyboardPollCounter.getCount() >= 1) { KeyboardPollCounter.stopCountingAndReset(); } } return original.call(event); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc122477/MinecraftMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc122477; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import dev.isxander.debugify.client.helpers.mc122477.KeyboardPollCounter; import dev.isxander.debugify.fixes.OS; import net.minecraft.client.Minecraft; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-122477", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, os = OS.LINUX, description = "Linux/GNU: Opening chat sometimes writes 't'") @Mixin(Minecraft.class) public class MinecraftMixin { @Inject(method = "run", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;pollEvents()V")) private void onPollEvents(CallbackInfo ci) { KeyboardPollCounter.poll(); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc122627/CommandSuggestionsMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc122627; import com.llamalad7.mixinextras.expression.Definition;import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.gui.components.CommandSuggestions; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; @BugFix(id = "MC-122627", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Tab suggestion box has missing padding on right side") @Mixin(CommandSuggestions.class) public class CommandSuggestionsMixin { /** * Minecraft renders the text at +1 on the x-axis * but does not compensate and add 1 to the width of the box */ @Definition(id = "fill", method = "Lnet/minecraft/client/gui/GuiGraphicsExtractor;fill(IIIII)V") @Definition(id = "commandUsagePosition", field = "Lnet/minecraft/client/gui/components/CommandSuggestions;commandUsagePosition:I") @Definition(id = "commandUsageWidth", field = "Lnet/minecraft/client/gui/components/CommandSuggestions;commandUsageWidth:I") @Expression("?.fill(?, ?, @(this.commandUsagePosition + this.commandUsageWidth + 1), ?, ?)") @ModifyExpressionValue(method = "extractUsage", at = @At("MIXINEXTRAS:EXPRESSION")) private int modifyX2(int x) { return x + 1; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc127970/ItemInHandRendererMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc127970; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.renderer.ItemInHandRenderer; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-127970", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Using Riptide on a trident with an item in your off-hand causes visual glitch with said item") @Mixin(ItemInHandRenderer.class) public class ItemInHandRendererMixin { @ModifyExpressionValue( method = "renderArmWithItem", at = @At( value = "INVOKE", target = "Lnet/minecraft/client/player/AbstractClientPlayer;isAutoSpinAttack()Z" ) ) private boolean isUsingRiptideHand(boolean original, @Local(argsOnly = true, name = "itemStack") ItemStack itemStack) { return original && itemStack.is(Items.TRIDENT); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc143474/ClientPacketListenerMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc143474; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientCommonPacketListenerImpl; import net.minecraft.client.multiplayer.ClientPacketListener; import net.minecraft.client.multiplayer.CommonListenerCookie; import net.minecraft.client.player.LocalPlayer; import net.minecraft.network.Connection; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-143474", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Respawning causes your hotbar to reset to the first space") @Mixin(ClientPacketListener.class) public abstract class ClientPacketListenerMixin extends ClientCommonPacketListenerImpl { protected ClientPacketListenerMixin(Minecraft client, Connection connection, CommonListenerCookie commonListenerCookie) { super(client, connection, commonListenerCookie); } @Inject( method = "handleRespawn", at = @At( value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/ClientPacketListener;startWaitingForNewLevel(Lnet/minecraft/client/player/LocalPlayer;Lnet/minecraft/client/multiplayer/ClientLevel;Lnet/minecraft/client/gui/screens/LevelLoadingScreen$Reason;)V" ) ) private void persistInventorySlot2( CallbackInfo ci, @Local(name = "oldPlayer") LocalPlayer oldPlayer, @Local(name = "newPlayer") LocalPlayer newPlayer ) { newPlayer.getInventory().setSelectedSlot(oldPlayer.getInventory().getSelectedSlot()); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc165305/RenderPipelinesMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc165305; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.mojang.blaze3d.pipeline.RenderPipeline; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.renderer.RenderPipelines; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-165306", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Beacon beams are transparent from the inside") @Mixin(RenderPipelines.class) public class RenderPipelinesMixin { @Definition(id = "BEACON_BEAM_OPAQUE", field = "Lnet/minecraft/client/renderer/RenderPipelines;BEACON_BEAM_OPAQUE:Lcom/mojang/blaze3d/pipeline/RenderPipeline;") @Definition(id = "build", method = "Lcom/mojang/blaze3d/pipeline/RenderPipeline$Builder;build()Lcom/mojang/blaze3d/pipeline/RenderPipeline;") @Definition(id = "register", method = "Lnet/minecraft/client/renderer/RenderPipelines;register(Lcom/mojang/blaze3d/pipeline/RenderPipeline;)Lcom/mojang/blaze3d/pipeline/RenderPipeline;") @Expression("BEACON_BEAM_OPAQUE = register(@(?.build()))") @WrapOperation(method = "", at = @At("MIXINEXTRAS:EXPRESSION")) private static RenderPipeline disableCull(RenderPipeline.Builder builder, Operation original) { return original.call(builder.withCull(false)); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc165381/LocalPlayerMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc165381; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @BugFix(id = "MC-165381", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Block breaking can be delayed by dropping/throwing the tool while breaking a block") @Mixin(LocalPlayer.class) public class LocalPlayerMixin { @Shadow @Final protected Minecraft minecraft; @Inject( method = "drop", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Inventory;removeFromSelected(Z)Lnet/minecraft/world/item/ItemStack;", shift = At.Shift.AFTER ) ) private void onDropItem(CallbackInfoReturnable cir) { minecraft.gameMode.stopDestroyBlock(); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc176559/ItemStackAccessor.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc176559; import net.minecraft.core.component.PatchedDataComponentMap; import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; @Mixin(ItemStack.class) public interface ItemStackAccessor { @Accessor PatchedDataComponentMap getComponents(); } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc176559/MultiPlayerGameModeMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc176559; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.core.component.PatchedDataComponentMap; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import java.util.Objects; import net.minecraft.client.multiplayer.MultiPlayerGameMode; import net.minecraft.world.item.ItemStack; @BugFix(id = "MC-176559", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Breaking process resets when a pickaxe enchanted with Mending mends by XP / Mending slows down breaking blocks again") @Mixin(value = MultiPlayerGameMode.class, priority = 1010) public class MultiPlayerGameModeMixin { // Fabric API also redirects here. WrapOperation is compatible @WrapOperation( method = "sameDestroyTarget", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;isSameItemSameComponents(Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/ItemStack;)Z" ) ) private boolean isSameItem(ItemStack a, ItemStack b, Operation original) { return isSameItemSameComponentsIgnoringDurability(a, b); } @Unique private boolean isSameItemSameComponentsIgnoringDurability(ItemStack stack1, ItemStack stack2) { if (!stack1.is(stack2.getItem())) { return false; } else if (stack1.isEmpty() && stack2.isEmpty()) { return true; } else { int damage1 = stack1.getDamageValue(); int damage2 = stack2.getDamageValue(); stack1.setDamageValue(0); stack2.setDamageValue(0); PatchedDataComponentMap components1 = ((ItemStackAccessor) (Object) stack1).getComponents(); PatchedDataComponentMap components2 = ((ItemStackAccessor) (Object) stack2).getComponents(); boolean comparison = Objects.equals(components1, components2); stack1.setDamageValue(damage1); stack2.setDamageValue(damage2); return comparison; } } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc188359/CakeBlockMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc188359; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.core.BlockPos; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.util.Mth; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.CakeBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @BugFix(id = "MC-188359", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Burp sound does not play after drinking or after eating cake") @Mixin(CakeBlock.class) public class CakeBlockMixin { @Inject( method = "useWithoutItem", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/level/block/CakeBlock;eat(Lnet/minecraft/world/level/LevelAccessor;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/entity/player/Player;)Lnet/minecraft/world/InteractionResult;", ordinal = 0 ) ) private void playBurpSound( CallbackInfoReturnable cir, @Local(argsOnly = true, name = "player") Player player, @Local(argsOnly = true, name = "level") Level level ) { level.playLocalSound( player.getX(), player.getY(), player.getZ(), SoundEvents.PLAYER_BURP, SoundSource.PLAYERS, 0.5F, Mth.randomBetween(player.getRandom(), 0.9F, 1.0F), false ); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc188359/ConsumableMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc188359; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.core.Holder; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.util.Mth; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.component.Consumable; import net.minecraft.world.level.Level; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @BugFix(id = "MC-188359", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Burp sound does not play after drinking or after eating cake") @Mixin(Consumable.class) public class ConsumableMixin { @Shadow @Final private Holder sound; @Inject( method = "onConsume", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;consume(ILnet/minecraft/world/entity/LivingEntity;)V" ) ) private void addBurpSound(Level level, LivingEntity user, ItemStack stack, CallbackInfoReturnable cir) { if (this.sound.is(SoundEvents.GENERIC_DRINK) && user.isAlwaysTicking()) { level.playLocalSound(user.getX(), user.getY(), user.getZ(), SoundEvents.PLAYER_BURP, SoundSource.PLAYERS, 0.5F, Mth.randomBetween(user.getRandom(), 0.9F, 1.0F), false); } } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc197260/ArmorStandRendererMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc197260; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.Lightmap; import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.state.ArmorStandRenderState; import net.minecraft.util.LightCoordsUtil; import org.spongepowered.asm.mixin.Mixin; import net.minecraft.client.model.object.armorstand.ArmorStandArmorModel; import net.minecraft.client.renderer.entity.ArmorStandRenderer; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.decoration.ArmorStand; import net.minecraft.world.level.LightLayer; @BugFix(id = "MC-197260", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Armor Stand renders itself and armor dark if its head is in a solid block") @Mixin(ArmorStandRenderer.class) public abstract class ArmorStandRendererMixin extends LivingEntityRendererMixin { protected ArmorStandRendererMixin(EntityRendererProvider.Context context) { super(context); } /** * Overrides the light level passed to the renderer, with the maximum of: *
    *
  • The block below the armor stand
  • *
  • Bottom of the armor stand
  • *
  • Top of the armor stand
  • *
  • The block above the armor stand
  • *
*/ @Override public void debugify$modifyLightCoords(ArmorStandRenderState livingEntity) { if (LightCoordsUtil.sky(livingEntity.lightCoords) >= 15 || LightCoordsUtil.block(livingEntity.lightCoords) >= 15) return; BlockPos mainPos = BlockPos.containing(livingEntity.x, livingEntity.y, livingEntity.z); ClientLevel level = Minecraft.getInstance().level; int maxSkyLight = 0; int maxBlockLight = 0; for (int offset : new int[] { -1, 0, 2, 3 }) { BlockPos pos = mainPos.offset(0, offset, 0); maxSkyLight = Math.max(maxSkyLight, level.getBrightness(LightLayer.SKY, pos)); maxBlockLight = Math.max(maxBlockLight, level.getBrightness(LightLayer.BLOCK, pos)); } livingEntity.lightCoords = LightCoordsUtil.pack(maxBlockLight, maxSkyLight); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc197260/LivingEntityRendererMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc197260; import com.mojang.blaze3d.vertex.PoseStack; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.model.EntityModel; import net.minecraft.client.renderer.SubmitNodeCollector; import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.LivingEntityRenderer; import net.minecraft.client.renderer.entity.RenderLayerParent; import net.minecraft.client.renderer.entity.state.LivingEntityRenderState; import net.minecraft.client.renderer.state.level.CameraRenderState; import net.minecraft.world.entity.LivingEntity; import dev.isxander.debugify.client.helpers.mc197260.DebugifyLightProvider; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-197260", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Armor Stand renders itself and armor dark if its head is in a solid block") @Mixin(LivingEntityRenderer.class) public abstract class LivingEntityRendererMixin> extends EntityRenderer implements RenderLayerParent, DebugifyLightProvider { protected LivingEntityRendererMixin(EntityRendererProvider.Context context) { super(context); } @Inject( method = "submit(Lnet/minecraft/client/renderer/entity/state/LivingEntityRenderState;Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/SubmitNodeCollector;Lnet/minecraft/client/renderer/state/level/CameraRenderState;)V", at = @At("HEAD") ) private void fixLightLevel(S state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera, CallbackInfo ci) { debugify$modifyLightCoords(state); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc206540/EntityMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc206540; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-206540", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, modConflicts = "ridingmousefix", description = "Increased input delay when riding an entity") @Mixin(Entity.class) public abstract class EntityMixin { @Shadow public abstract float getYRot(); /** * Code taken from {@link net.minecraft.world.entity.vehicle.boat.AbstractBoat} */ @Inject(method = "onPassengerTurned", at = @At("HEAD")) private void fixCameraMovement(Entity passenger, CallbackInfo ci) { if (passenger.isAlwaysTicking()) { passenger.setYBodyRot(this.getYRot()); float f = Mth.wrapDegrees(passenger.getYRot() - this.getYRot()); float g = Mth.clamp(f, -180.0F, 180.0F); passenger.yRotO += g - f; passenger.setYRot(passenger.getYRot() + g - f); passenger.setYHeadRot(passenger.getYRot()); } } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc210318/BookSignScreenMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc210318; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.gui.screens.inventory.BookSignScreen; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; @BugFix(id = "MC-210318", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Maximum length of book title changed from 16 to 15 characters") @Mixin(BookSignScreen.class) public class BookSignScreenMixin { @ModifyArg( method = "init", at = @At( value = "INVOKE", target = "Lnet/minecraft/client/gui/components/EditBox;setMaxLength(I)V" ) ) private int restoreBookTitleMaxLength(int length) { return 16; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc211561/FishingHookRendererMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc211561; import com.llamalad7.mixinextras.injector.ModifyReturnValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.renderer.entity.FishingHookRenderer; import net.minecraft.world.entity.HumanoidArm; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.FishingRodItem; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-211561", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Fishing line appears in opposite hand when switching slots") @Mixin(FishingHookRenderer.class) public class FishingHookRendererMixin { @ModifyReturnValue(method = "getHoldingArm", at = @At("RETURN")) private static HumanoidArm fixHoldingArm(HumanoidArm original, Player owner) { return owner.getOffhandItem().getItem() instanceof FishingRodItem ? original : owner.getMainArm(); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc215531/GuiMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc215531; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-215531", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "The carved pumpkin overlay is rendered in spectator mode") @Mixin(Gui.class) public class GuiMixin { @Shadow @Final private Minecraft minecraft; @ModifyExpressionValue(method = "extractCameraOverlays", at = @At(value = "INVOKE", target = "Ljava/util/Optional;isPresent()Z")) private boolean shouldRenderPumpkinOverlay(boolean pumpkinOnHead) { return pumpkinOnHead && !minecraft.player.isSpectator(); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc217716/GameRendererMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc217716; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GameRenderer; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-217716", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "The green nausea overlay isn't removed when switching into spectator mode") @Mixin(GameRenderer.class) public class GameRendererMixin { @Shadow @Final private Minecraft minecraft; // Naughty minecraft using references to player in `render`!! // This should be in extractOptions and we shouldn't be referencing player either here but // we have to because mojang gets the nausea blend factor here @Definition(id = "getEffectBlendFactor", method = "Lnet/minecraft/client/player/LocalPlayer;getEffectBlendFactor(Lnet/minecraft/core/Holder;F)F") @Definition(id = "NAUSEA", field = "Lnet/minecraft/world/effect/MobEffects;NAUSEA:Lnet/minecraft/core/Holder;") @Expression("?.getEffectBlendFactor(NAUSEA, ?)") @ModifyExpressionValue(method = "renderLevel", at = @At("MIXINEXTRAS:EXPRESSION")) private float shouldShowNauseaOverlay(float original) { return minecraft.player.isSpectator() ? 0.0f : original; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc237493/OptionsMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc237493; import dev.isxander.debugify.client.helpers.mc237493.DebugifyTelemetry; import dev.isxander.debugify.client.helpers.mc237493.DebugifyTelemetryAccessor; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.gui.components.Tooltip; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import java.util.Arrays; import net.minecraft.client.OptionInstance; import net.minecraft.client.Options; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-237493", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, modConflicts = "no-telemetry", description = "Telemetry cannot be disabled") @Mixin(Options.class) public abstract class OptionsMixin implements DebugifyTelemetryAccessor { @Shadow public abstract OptionInstance telemetryOptInExtra(); @Unique private final OptionInstance debugifyTelemetry = new OptionInstance<>( "options.telemetry.button", value -> Tooltip.create(value.tooltip()), (component, value) -> value.caption(), new OptionInstance.Enum<>(Arrays.asList(DebugifyTelemetry.values()), DebugifyTelemetry.LEGACY_CODEC), DebugifyTelemetry.OFF, value -> telemetryOptInExtra().set(value == DebugifyTelemetry.ALL) ); @Override public OptionInstance getTelemetryOption() { return debugifyTelemetry; } @Inject(method = "processOptions", at = @At("RETURN")) private void shouldAcceptVanillaTelemetry(Options.FieldAccess access, CallbackInfo ci) { access.process("debugifyTelemetry", getTelemetryOption()); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc237493/TelemetryEventInstanceMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc237493; import com.llamalad7.mixinextras.injector.ModifyReturnValue; import com.mojang.authlib.minecraft.TelemetryEvent; import dev.isxander.debugify.client.helpers.mc237493.DebugifyTelemetry; import dev.isxander.debugify.client.helpers.mc237493.DebugifyTelemetryAccessor; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.Minecraft; import net.minecraft.client.telemetry.TelemetryEventInstance; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-237493", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, modConflicts = "no-telemetry", description = "Telemetry cannot be disabled") @Mixin(TelemetryEventInstance.class) public class TelemetryEventInstanceMixin { @ModifyReturnValue(method = "export", at = @At("RETURN")) private TelemetryEvent preventEvents(TelemetryEvent realEvent) { if (((DebugifyTelemetryAccessor) Minecraft.getInstance().options).getTelemetryOption().get() == DebugifyTelemetry.OFF) { return TelemetryEvent.EMPTY; } return realEvent; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc237493/TelemetryEventWidgetMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc237493; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.client.helpers.mc237493.DebugifyTelemetry; import dev.isxander.debugify.client.helpers.mc237493.DebugifyTelemetryAccessor; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.screens.telemetry.TelemetryEventWidget; import net.minecraft.client.telemetry.TelemetryEventType; import net.minecraft.network.chat.Component; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.List; @BugFix(id = "MC-237493", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, modConflicts = "no-telemetry", description = "Telemetry cannot be disabled") @Mixin(TelemetryEventWidget.class) public class TelemetryEventWidgetMixin { @Shadow @Final private Font font; @ModifyExpressionValue(method = "buildContent", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/telemetry/TelemetryEventType;values()Ljava/util/List;")) private List modifyInUseTelemetry(List inUse) { if (((DebugifyTelemetryAccessor) Minecraft.getInstance().options).getTelemetryOption().get() == DebugifyTelemetry.OFF) return List.of(); return inUse; } @Inject(method = "buildContent", at = @At(value = "INVOKE", target = "Ljava/util/List;sort(Ljava/util/Comparator;)V")) private void addDebugifyContent( CallbackInfoReturnable cir, @Local(name = "content") TelemetryEventWidget.ContentBuilder content ) { if (((DebugifyTelemetryAccessor) Minecraft.getInstance().options).getTelemetryOption().get() == DebugifyTelemetry.OFF) { content.addHeader(this.font, Component.translatable("debugify.mc_237493.header")); content.addLine(this.font, Component.translatable("debugify.mc_237493.line", Component.translatable("options.telemetry.state.none")).withStyle(ChatFormatting.GRAY)); } } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc237493/TelemetryInfoScreenMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc237493; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import dev.isxander.debugify.client.helpers.mc237493.DebugifyTelemetry; import dev.isxander.debugify.client.helpers.mc237493.DebugifyTelemetryAccessor; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.Options; import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.layouts.LayoutElement; import net.minecraft.client.gui.layouts.LinearLayout; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.telemetry.TelemetryEventWidget; import net.minecraft.client.gui.screens.telemetry.TelemetryInfoScreen; import net.minecraft.network.chat.Component; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-237493", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, modConflicts = "no-telemetry", description = "Telemetry cannot be disabled") @Mixin(TelemetryInfoScreen.class) public abstract class TelemetryInfoScreenMixin extends Screen { protected TelemetryInfoScreenMixin(Component title) { super(title); } @Shadow @Final private Options options; @Shadow private TelemetryEventWidget telemetryEventWidget; @Unique private AbstractWidget cycleButton; @Definition(id = "addChild", method = "Lnet/minecraft/client/gui/layouts/LinearLayout;addChild(Lnet/minecraft/client/gui/layouts/LayoutElement;)Lnet/minecraft/client/gui/layouts/LayoutElement;") @Definition(id = "builder", method = "Lnet/minecraft/client/gui/components/Checkbox;builder(Lnet/minecraft/network/chat/Component;Lnet/minecraft/client/gui/Font;)Lnet/minecraft/client/gui/components/Checkbox$Builder;") @Definition(id = "CHECKBOX_OPT_IN", field = "Lnet/minecraft/client/gui/screens/telemetry/TelemetryInfoScreen;CHECKBOX_OPT_IN:Lnet/minecraft/network/chat/Component;") @Expression("?.addChild(builder(CHECKBOX_OPT_IN, ?).?(?).?(?.?.?()).?(?).?())") @WrapOperation(method = "init", at = @At("MIXINEXTRAS:EXPRESSION")) private LayoutElement createTelemetryCheckbox(LinearLayout instance, LayoutElement child, Operation original) { this.cycleButton = instance.addChild(((DebugifyTelemetryAccessor) options).getTelemetryOption().createButton(options, 0, 0, 308, state -> telemetryEventWidget.onOptInChanged(state == DebugifyTelemetry.ALL))); return null; } @Inject(method = "repositionElements", at = @At("TAIL")) private void repositionCycleButton(CallbackInfo ci) { if (this.cycleButton != null) { this.cycleButton.setWidth(308); } } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc242809/DirectJoinServerScreenMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc242809; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.gui.screens.DirectJoinServerScreen; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-242809", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "IP field in the multiplayer menu will not detect the IP if a space is put at the beginning/end of it") @Mixin(DirectJoinServerScreen.class) public class DirectJoinServerScreenMixin { @Definition(id = "ipEdit", field = "Lnet/minecraft/client/gui/screens/DirectJoinServerScreen;ipEdit:Lnet/minecraft/client/gui/components/EditBox;") @Definition(id = "getValue", method = "Lnet/minecraft/client/gui/components/EditBox;getValue()Ljava/lang/String;") @Expression("?.? = @(?.ipEdit.getValue())") @ModifyExpressionValue(method = "onSelect", at = @At("MIXINEXTRAS:EXPRESSION")) private String trimIpSelect(String ip) { return ip.trim(); } @Definition(id = "ipEdit", field = "Lnet/minecraft/client/gui/screens/DirectJoinServerScreen;ipEdit:Lnet/minecraft/client/gui/components/EditBox;") @Definition(id = "setValue", method = "Lnet/minecraft/client/gui/components/EditBox;setValue(Ljava/lang/String;)V") @Expression("this.ipEdit.setValue(@(?))") @ModifyExpressionValue(method = "init", at = @At("MIXINEXTRAS:EXPRESSION")) private String trimIpInit(String ip) { return ip.trim(); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc242809/ManageServerScreenMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc242809; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.gui.screens.ManageServerScreen; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-242809", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "IP field in the multiplayer menu will not detect the IP if a space is put at the beginning/end of it") @Mixin(ManageServerScreen.class) public class ManageServerScreenMixin { @Definition(id = "serverData", field = "Lnet/minecraft/client/gui/screens/ManageServerScreen;serverData:Lnet/minecraft/client/multiplayer/ServerData;") @Definition(id = "ip", field = "Lnet/minecraft/client/multiplayer/ServerData;ip:Ljava/lang/String;") @Definition(id = "ipEdit", field = "Lnet/minecraft/client/gui/screens/ManageServerScreen;ipEdit:Lnet/minecraft/client/gui/components/EditBox;") @Definition(id = "getValue", method = "Lnet/minecraft/client/gui/components/EditBox;getValue()Ljava/lang/String;") @Expression("this.serverData.ip = @(this.ipEdit.getValue())") @ModifyExpressionValue(method = "onAdd", at = @At("MIXINEXTRAS:EXPRESSION")) private String trimIp(String ip) { return ip.trim(); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc251068/WorldSelectionListMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc251068; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.ObjectSelectionList; import net.minecraft.client.gui.screens.ConfirmScreen; import net.minecraft.client.gui.screens.ProgressScreen; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.worldselection.WorldSelectionList; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-251068", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "If you delete your only world, then you are no longer automatically thrown into the menu of creating a new world") @Mixin(WorldSelectionList.class) public abstract class WorldSelectionListMixin extends ObjectSelectionList { public WorldSelectionListMixin(Minecraft minecraft, int i, int j, int k, int l) { super(minecraft, i, j, k, l); } @WrapWithCondition( method = "returnToScreen", at = @At( value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;setScreen(Lnet/minecraft/client/gui/screens/Screen;)V" ) ) private boolean dontShowEmptyWorldList(Minecraft instance, Screen screen) { return (this.minecraft.screen instanceof ProgressScreen || this.minecraft.screen instanceof ConfirmScreen); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc259512/LivingEntityMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc259512; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-259512", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, modConflicts = "eg_fix_horizontal_camera_lag", description = "Increased input delay when riding an entity") @Mixin(LivingEntity.class) public abstract class LivingEntityMixin extends Entity { public LivingEntityMixin(EntityType entityType, Level level) { super(entityType, level); } /** * yHeadRot does not match yRot. yRot is your actual view rotation (the blue line in your debug hitbox), * while yHeadRot is interpolated and lags behind (your visible head rotation) */ @ModifyExpressionValue( method = "getViewYRot", at = @At( value = "FIELD", target = "Lnet/minecraft/world/entity/LivingEntity;yHeadRot:F", opcode = Opcodes.GETFIELD ) ) private float smoothYRot(float original) { return (Entity) this instanceof Player ? this.getYRot() : original; } @ModifyExpressionValue( method = "getViewYRot", at = @At( value = "FIELD", target = "Lnet/minecraft/world/entity/LivingEntity;yHeadRotO:F", opcode = Opcodes.GETFIELD ) ) private float smoothYRot0(float original) { return (Entity) this instanceof Player ? this.yRotO : original; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc267376/CameraMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc267376; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.Camera; import net.minecraft.client.player.LocalPlayer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; @BugFix(id = "MC-267376", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "You can view through blocks on small scales (near plane clipping)") @Mixin(Camera.class) public class CameraMixin { @ModifyArg( method = "update", at = @At( value = "INVOKE", target = "Lnet/minecraft/client/Camera;setupPerspective(FFFFF)V" ), index = 0 ) private float scaleNearClipDistance(float original, @Local(name = "player") LocalPlayer player) { return original * Math.min(player.getScale(), 1F); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc268420/GuiMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc268420; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import com.mojang.blaze3d.pipeline.RenderPipeline; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.resources.Identifier; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-268420", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Cooldown indicator flashes when switching items with high attack speed attribute") @Mixin(Gui.class) public class GuiMixin { @Shadow @Final private Minecraft minecraft; // the FULL sprite never shows anyway so no need to wrap it @WrapWithCondition(method = "extractCrosshair", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiGraphicsExtractor;blitSprite(Lcom/mojang/blaze3d/pipeline/RenderPipeline;Lnet/minecraft/resources/Identifier;IIII)V", ordinal = 2)) private boolean fixAttackIndicatorFlashing(GuiGraphicsExtractor instance, RenderPipeline renderPipeline, Identifier location, int x, int y, int width, int height) { return this.minecraft.player.getAttackStrengthScale(0.0F) * 17F > 0; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc280220/DolphinCarryingItemLayerMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc280220; import com.llamalad7.mixinextras.sugar.Local; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Axis; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.renderer.SubmitNodeCollector; import net.minecraft.client.renderer.entity.layers.DolphinCarryingItemLayer; import net.minecraft.client.renderer.entity.state.DolphinRenderState; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-280220", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "When a Dolphin holds an item, it is rendered upside-down") @Mixin(DolphinCarryingItemLayer.class) public class DolphinCarryingItemLayerMixin { @Inject( method = "submit(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/SubmitNodeCollector;ILnet/minecraft/client/renderer/entity/state/DolphinRenderState;FF)V", at = @At( value = "INVOKE", target = "Lnet/minecraft/client/renderer/item/ItemStackRenderState;submit(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/SubmitNodeCollector;III)V" ) ) private void flipItem(CallbackInfo ci, @Local(argsOnly = true, name = "poseStack") PoseStack poseStack) { poseStack.mulPose(Axis.ZP.rotationDegrees(180F)); poseStack.translate(0F, -0.4F, 0F); // Eyeballed value to make items not float } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc298225/CameraMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc298225; import com.llamalad7.mixinextras.expression.Definition;import com.llamalad7.mixinextras.expression.Expression;import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.injector.ModifyReturnValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.Camera; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-298225", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, modConflicts = "smoothskies", description = "Shapes appear in the end sky with certain distance settings") @Mixin(Camera.class) public class CameraMixin { @Definition(id = "depthFar", field = "Lnet/minecraft/client/Camera;depthFar:F") @Expression("this.depthFar = @(?)") @ModifyExpressionValue(method = "update", at = @At("MIXINEXTRAS:EXPRESSION")) private float fixSkyboxFarplaneClipping(float f) { return Math.max(f, 11 * 16F); // 11 chunks * 16, the minimum cloud render distance for no clipping issues } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc298558/AtmosphericFogEnvironmentMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc298558; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.renderer.fog.environment.AtmosphericFogEnvironment; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-298558", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Rain fog calculation can overshoot while game is unresponsive") @Mixin(AtmosphericFogEnvironment.class) public class AtmosphericFogEnvironmentMixin { /** * The issue stems from the gtDeltaTicks * 0.2, which needs a maximum value of 1. */ @Definition(id = "rainFogMultiplier", field = "Lnet/minecraft/client/renderer/fog/environment/AtmosphericFogEnvironment;rainFogMultiplier:F") @Definition(id = "rainLevel", local = @Local(type = float.class, ordinal = 3)) @Definition(id = "gtDeltaTicks", local = @Local(type = float.class, ordinal = 0)) // `?.` instead of `this.` since the `this` is DUPed making it impossible to target @Expression("?.rainFogMultiplier = ?.rainFogMultiplier + (rainLevel - ?.rainFogMultiplier) * @(gtDeltaTicks) * 0.2") @ModifyExpressionValue(method = "updateRainFogState", at = @At("MIXINEXTRAS:EXPRESSION")) private float clampFog(float original) { // it's impossible to target `gtDeltaTicks * 0.2` since in bytecode // it's `...) * gtDeltaTicks) * 0.2`. so instead just modify `gtDeltaTicks` with min 5, since 5 * 0.2 is 1 return Math.min(5f, original); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc35361/MinecraftMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc35361; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.tutorial.Tutorial; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-35361", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Inventory opening is detected while in Nether Portal") @Mixin(Minecraft.class) public class MinecraftMixin { @Shadow @Nullable public LocalPlayer player; @WrapWithCondition( method = "handleKeybinds", at = @At( value = "INVOKE", target = "Lnet/minecraft/client/tutorial/Tutorial;onOpenInventory()V" ) ) private boolean addNetherPortalCheck(Tutorial instance) { return this.player.portalProcess == null || !this.player.portalProcess.isInsidePortalThisTick(); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc4490/FishingHookRendererMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc4490; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.renderer.entity.FishingHookRenderer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Constant; import org.spongepowered.asm.mixin.injection.ModifyConstant; @BugFix(id = "MC-4490", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Fishing line not attached to fishing rod in third person while crouching") @Mixin(FishingHookRenderer.class) public class FishingHookRendererMixin { @ModifyExpressionValue( method = "getPlayerHandPos", at = @At( value = "CONSTANT", args = "floatValue=-0.1875" ) ) private float renderSneakOffset(float constant) { return -0.2875F; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc46737/GameRendererMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc46737; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.resources.Identifier; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-46737", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Entities' shaders are applied when beginning to spectate them in third person") @Mixin(GameRenderer.class) public class GameRendererMixin { @WrapWithCondition( method = "checkEntityPostEffect", at = @At( value = "INVOKE", target = "Lnet/minecraft/client/renderer/GameRenderer;setPostEffect(Lnet/minecraft/resources/Identifier;)V" ) ) private boolean thirdPersonCheck(GameRenderer renderer, Identifier id) { return Minecraft.getInstance().options.getCameraType().isFirstPerson(); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc46766/MinecraftMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc46766; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.MultiPlayerGameMode; import net.minecraft.world.level.GameType; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-46766", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Breaking particles, sounds, and block cracks can be created in spectator mode") @Mixin(Minecraft.class) public class MinecraftMixin { @Shadow @Nullable public MultiPlayerGameMode gameMode; @ModifyArg( method = "handleKeybinds", at = @At( value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;continueAttack(Z)V" ) ) private boolean shouldContinueAttack(boolean bl) { return bl && gameMode.getPlayerMode() != GameType.SPECTATOR; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc57057/GuardianAttackSoundInstanceMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc57057; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.resources.sounds.AbstractTickableSoundInstance; import net.minecraft.client.resources.sounds.GuardianAttackSoundInstance; import net.minecraft.client.resources.sounds.SoundInstance; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundSource; import net.minecraft.util.RandomSource; import net.minecraft.world.entity.monster.Guardian; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-57057", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Guardian laser attack sound ignores distance") @Mixin(GuardianAttackSoundInstance.class) public abstract class GuardianAttackSoundInstanceMixin extends AbstractTickableSoundInstance { protected GuardianAttackSoundInstanceMixin(SoundEvent soundEvent, SoundSource soundSource, RandomSource randomSource) { super(soundEvent, soundSource, randomSource); } @Inject(method = "", at = @At(value = "TAIL")) private void fixAttenuation(Guardian guardian, CallbackInfo ci) { this.attenuation = SoundInstance.Attenuation.LINEAR; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc577/AbstractContainerScreenMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc577; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.input.MouseButtonEvent; import net.minecraft.network.chat.Component; import net.minecraft.world.inventory.ContainerInput; import net.minecraft.world.inventory.Slot; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @BugFix(id = "MC-577", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Mouse buttons block all inventory controls that are not default") @Mixin(AbstractContainerScreen.class) public abstract class AbstractContainerScreenMixin extends Screen { @Shadow protected abstract void slotClicked(Slot slot, int slotId, int buttonNum, ContainerInput containerInput); protected AbstractContainerScreenMixin(Component title) { super(title); } @ModifyExpressionValue( method = "mouseClicked", at = @At( value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;mouseClicked(Lnet/minecraft/client/input/MouseButtonEvent;Z)Z" ) ) private boolean shouldReturn(boolean original, MouseButtonEvent event) { return original || mouseInventoryClose(event); } @Definition(id = "getHoveredSlot", method = "Lnet/minecraft/client/gui/screens/inventory/AbstractContainerScreen;getHoveredSlot(DD)Lnet/minecraft/world/inventory/Slot;") @Expression("? = this.getHoveredSlot(?, ?)") @Inject( method = "mouseClicked", at = @At( value = "MIXINEXTRAS:EXPRESSION", shift = At.Shift.AFTER ), cancellable = true ) private void dropWithMouse( MouseButtonEvent event, boolean doubleClick, CallbackInfoReturnable cir, @Local(name = "slot") Slot slot ) { if (minecraft.options.keyDrop.matchesMouse(event)) { if (slot == null) return; slotClicked(slot, slot.index, event.hasControlDown() ? 1 : 0, ContainerInput.THROW); cir.setReturnValue(true); } } @Unique private boolean mouseInventoryClose(MouseButtonEvent button) { if (minecraft.options.keyInventory.matchesMouse(button)) { onClose(); return true; } return false; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc59810/MouseHandlerMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc59810; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import dev.isxander.debugify.fixes.OS; import net.minecraft.client.MouseHandler; import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-59810", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, enabled = false, modConflicts = "mcmouser", os = OS.MAC, description = "Cannot break blocks while sprinting (Ctrl+Click = right click on macOS)") @Mixin(MouseHandler.class) public class MouseHandlerMixin { @ModifyExpressionValue( method = "simulateRightClick", at = @At( value = "FIELD", target = "Lnet/minecraft/client/input/InputQuirks;SIMULATE_RIGHT_CLICK_WITH_LONG_LEFT_CLICK:Z", opcode = Opcodes.GETSTATIC ) ) private boolean doRightClickEmulation(boolean isMac) { return false; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc61489/BookEditScreenMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc61489; import com.llamalad7.mixinextras.injector.ModifyReturnValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.BookEditScreen; import net.minecraft.network.chat.Component; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; // Compared to the original patch, we use / 3 here since it seems to line up better. Else, in a windowed screen the Done button appears at the very bottom / slightly off-screen. @BugFix(id = "MC-61489", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, enabled = false, modConflicts = {"fixbookgui", "stendhal", "scribble"}, description = "Book GUI is not vertically centered") @Mixin(BookEditScreen.class) public class BookEditScreenMixin extends Screen { @Shadow @Final public static int IMAGE_HEIGHT; protected BookEditScreenMixin(Component component) { super(component); } @ModifyArg( method = "init", at = @At( value = "INVOKE", target = "Lnet/minecraft/client/gui/components/MultiLineEditBox$Builder;setY(I)Lnet/minecraft/client/gui/components/MultiLineEditBox$Builder;" ) ) private int modifyHeight(int original) { return original + (this.height - IMAGE_HEIGHT) / 3; } @ModifyReturnValue(method = "backgroundTop", at = @At("RETURN")) private int modifyTop(int original) { return original + (this.height - IMAGE_HEIGHT) / 3; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc61489/BookViewScreenMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc61489; import com.llamalad7.mixinextras.injector.ModifyReturnValue; import dev.isxander.debugify.client.utils.ClientUtils; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.BookViewScreen; import net.minecraft.network.chat.Component; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; // Compared to the original patch, we use / 3 here since it seems to line up better. Else, in a windowed screen the Done button appears at the very bottom / slightly off-screen. @BugFix(id = "MC-61489", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, enabled = false, modConflicts = {"fixbookgui", "stendhal", "scribble"}, description = "Book GUI is not vertically centered") @Mixin(BookViewScreen.class) public class BookViewScreenMixin extends Screen { @Shadow @Final protected static int IMAGE_HEIGHT; protected BookViewScreenMixin(Component component) { super(component); } @ModifyReturnValue(method = "backgroundTop", at = @At("RETURN")) private int modifyTop(int original) { return original + (this.height - IMAGE_HEIGHT) / 3; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc79545/ExperienceBarRendererMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc79545; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.gui.contextualbar.ExperienceBarRenderer; import net.minecraft.util.Mth; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-79545", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "The experience bar disappears when too many levels are given to the player") @Mixin(ExperienceBarRenderer.class) public class ExperienceBarRendererMixin { /** * In some cases, this value can wrap-around to negative values * This mixin prevents that. */ @ModifyExpressionValue(method = "extractBackground", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;getXpNeededForNextLevel()I")) private int getNextLevelExperience(int nextLevelExperience) { return Mth.clamp(nextLevelExperience, 0, Integer.MAX_VALUE); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc80859/AbstractContainerScreenMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc80859; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; import java.util.Set; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.world.inventory.Slot; @BugFix(id = "MC-80859", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Starting to drag item stacks over other compatible stacks makes the latter invisible until appearance change (stack size increases)") @Mixin(AbstractContainerScreen.class) public class AbstractContainerScreenMixin { /** * If slots is size 1 then the inner method would run anyway and return so this just ignores the outer * statement and lets it continue to the rendering therefore fixing the bug. */ @WrapOperation( method = "extractSlot", at = @At( value = "INVOKE", target = "Ljava/util/Set;contains(Ljava/lang/Object;)Z" ) ) private boolean stopInvisibleSlots(Set instance, Object slot, Operation original) { if (instance.size() == 1) return false; return original.call(instance, slot); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc90683/ClientPacketListenerMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc90683; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.multiplayer.ClientPacketListener; import org.slf4j.Logger; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-90683", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "\"Received unknown passenger\" - Entities with differing render distances as passengers outputs error") @Mixin(ClientPacketListener.class) public class ClientPacketListenerMixin { @WrapWithCondition( method = "handleSetEntityPassengersPacket", at = @At( value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;)V" ) ) private boolean shouldWarn(Logger logger, String warning) { return false; } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/basic/mc93384/LivingEntityMixin.java ================================================ package dev.isxander.debugify.client.mixins.basic.mc93384; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.level.Level; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; @BugFix(id = "MC-93384", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, description = "Bubbles appear at the feet of drowning mobs") @Mixin(LivingEntity.class) public abstract class LivingEntityMixin extends Entity { public LivingEntityMixin(EntityType type, Level world) { super(type, world); } @ModifyExpressionValue( method = "makeDrownParticles", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;getY()D" ) ) private double addEyeHeightToBubblePos(double footY) { return footY + getEyeHeight(); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/gameplay/mc159163/ClientPacketListenerMixin.java ================================================ package dev.isxander.debugify.client.mixins.gameplay.mc159163; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.Debugify; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientCommonPacketListenerImpl; import net.minecraft.client.multiplayer.ClientPacketListener; import net.minecraft.client.multiplayer.CommonListenerCookie; import net.minecraft.network.Connection; import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.world.entity.Entity; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @BugFix(id = "MC-159163", category = FixCategory.GAMEPLAY, env = BugFix.Env.CLIENT, description = "Quickly pressing the sneak key causes the sneak animation to play twice") @Mixin(ClientPacketListener.class) public abstract class ClientPacketListenerMixin extends ClientCommonPacketListenerImpl implements ClientGamePacketListener { protected ClientPacketListenerMixin(Minecraft client, Connection connection, CommonListenerCookie commonListenerCookie) { super(client, connection, commonListenerCookie); } @Inject( method = "handleSetEntityData", at = @At( value = "INVOKE", target = "Lnet/minecraft/network/syncher/SynchedEntityData;assignValues(Ljava/util/List;)V" ) ) public void removeLocalEntityPose( ClientboundSetEntityDataPacket packet, CallbackInfo info, @Local(name = "entity") Entity entity ) { if (Debugify.isGameplayFixesEnabled() && entity.equals(minecraft.player)) packet.packedItems().removeIf(p -> p.serializer().equals(EntityDataSerializers.POSE)); } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/mixins/gameplay/mc231097/LocalPlayerMixin.java ================================================ package dev.isxander.debugify.client.mixins.gameplay.mc231097; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @BugFix(id = "MC-231097", category = FixCategory.GAMEPLAY, env = BugFix.Env.CLIENT, description = "Holding the \"Use\" button continues to slow down the player even after the used item has been dropped") @Mixin(LocalPlayer.class) public abstract class LocalPlayerMixin { @Shadow @Final protected Minecraft minecraft; @Shadow public abstract boolean isUsingItem(); @Inject( method = "drop", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Inventory;removeFromSelected(Z)Lnet/minecraft/world/item/ItemStack;", shift = At.Shift.AFTER ) ) private void onDropItem(boolean all, CallbackInfoReturnable cir) { if (isUsingItem()) { minecraft.gameMode.releaseUsingItem((LocalPlayer) (Object) this); } } } ================================================ FILE: src/client/java/dev/isxander/debugify/client/utils/ClientUtils.java ================================================ package dev.isxander.debugify.client.utils; import net.minecraft.client.Minecraft; public class ClientUtils { public static boolean isInMultiplayerWorld() { return !Minecraft.getInstance().isLocalServer() && Minecraft.getInstance().level != null; } } ================================================ FILE: src/client/resources/debugify.client.mixins.json ================================================ { "required": true, "package": "dev.isxander.debugify.client.mixins", "compatibilityLevel": "JAVA_25", "injectors": { "defaultRequire": 1 }, "plugin": "dev.isxander.debugify.mixinplugin.MixinPlugin", "mixinextras": { "minVersion": "0.5.3" }, "client": [ "basic.mc105068.LivingEntityMixin", "basic.mc115092.SquidRendererMixin", "basic.mc116379.FishingHookRendererMixin", "basic.mc118740.GuiMixin", "basic.mc118740.LocalPlayerMixin", "basic.mc122477.EditBoxMixin", "basic.mc122477.MinecraftMixin", "basic.mc122627.CommandSuggestionsMixin", "basic.mc127970.ItemInHandRendererMixin", "basic.mc143474.ClientPacketListenerMixin", "basic.mc165305.RenderPipelinesMixin", "basic.mc165381.LocalPlayerMixin", "basic.mc176559.MultiPlayerGameModeMixin", "basic.mc197260.ArmorStandRendererMixin", "basic.mc197260.LivingEntityRendererMixin", "basic.mc210318.BookSignScreenMixin", "basic.mc211561.FishingHookRendererMixin", "basic.mc215531.GuiMixin", "basic.mc217716.GameRendererMixin", "gameplay.mc231097.LocalPlayerMixin", "basic.mc237493.OptionsMixin", "basic.mc237493.TelemetryEventInstanceMixin", "basic.mc237493.TelemetryEventWidgetMixin", "basic.mc237493.TelemetryInfoScreenMixin", "basic.mc242809.DirectJoinServerScreenMixin", "basic.mc242809.ManageServerScreenMixin", "basic.mc251068.WorldSelectionListMixin", "basic.mc267376.CameraMixin", "basic.mc268420.GuiMixin", "basic.mc280220.DolphinCarryingItemLayerMixin", "basic.mc298225.CameraMixin", "basic.mc298558.AtmosphericFogEnvironmentMixin", "basic.mc35361.MinecraftMixin", "basic.mc4490.FishingHookRendererMixin", "basic.mc46737.GameRendererMixin", "basic.mc46766.MinecraftMixin", "basic.mc57057.GuardianAttackSoundInstanceMixin", "basic.mc577.AbstractContainerScreenMixin", "basic.mc59810.MouseHandlerMixin", "basic.mc61489.BookEditScreenMixin", "basic.mc61489.BookViewScreenMixin", "basic.mc79545.ExperienceBarRendererMixin", "basic.mc80859.AbstractContainerScreenMixin", "basic.mc90683.ClientPacketListenerMixin", "basic.mc93384.LivingEntityMixin", "gameplay.mc159163.ClientPacketListenerMixin" ], "mixins": [ "basic.mc118740.PlayerMixin", "basic.mc176559.ItemStackAccessor", "basic.mc188359.CakeBlockMixin", "basic.mc188359.ConsumableMixin", "basic.mc206540.EntityMixin", "basic.mc259512.LivingEntityMixin" ] } ================================================ FILE: src/gametest/java/dev/isxander/debugify/test/DebugifyApiTest.java ================================================ package dev.isxander.debugify.test; import dev.isxander.debugify.api.DebugifyApi; import java.util.Map; import java.util.Set; public class DebugifyApiTest implements DebugifyApi { @Override public String[] getDisabledFixes() { return new String[]{ "MC-577" }; } @Override public Map> getProvidedDisabledFixes() { return Map.of("yet_another_config_lib_v3", Set.of("MC-577")); } } ================================================ FILE: src/gametest/java/dev/isxander/debugify/test/DebugifyTestUtils.java ================================================ package dev.isxander.debugify.test; import dev.isxander.debugify.test.suites.MC8187; import net.minecraft.core.BlockPos; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.network.chat.Component; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.GameType; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import java.util.function.Consumer; import java.util.function.Predicate; /** * Utilities for tests. * * @author Ampflower * @see MC8187 * @since 1.20.1+1.2 **/ public final class DebugifyTestUtils { public static final int TIME_OF_DAY_NOON = 6000; /** * Utility function to force-feed saplings bonemeal. */ public static void bonemealIndefinitely(GameTestHelper ctx, BlockPos pos) { final var player = ctx.makeMockPlayer(GameType.SURVIVAL); player.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(Items.BONE_MEAL, Item.DEFAULT_MAX_STACK_SIZE)); ctx.onEachTick(() -> ctx.useBlock(pos, player)); } /** * Asserts that blocks in a given area are as expected. */ public static void assertBlockFill(GameTestHelper ctx, BlockPos start, BlockPos end, Predicate test, String message) { area(start, end, pos -> ctx.assertBlock(pos, test, block -> Component.literal(message))); } /** * Asserts that blockstates in a given area are as expected. */ public static void assertBlockStateFill(GameTestHelper ctx, BlockPos start, BlockPos end, Predicate test, String message) { area(start, end, pos -> ctx.assertBlockState(pos, test, block -> Component.literal(message))); } /** * Fills the area with the given blockstate. */ public static void fill(GameTestHelper ctx, BlockPos start, BlockPos end, BlockState state) { area(start, end, pos -> ctx.setBlock(pos, state)); } /** * Iterates over the entire box, sending the current position to the consumer. */ private static void area(BlockPos start, BlockPos end, Consumer consumer) { final var pos = new BlockPos.MutableBlockPos(); for (int x = start.getX(); x <= end.getX(); x++) { for (int y = start.getY(); y <= end.getY(); y++) { for (int z = start.getZ(); z <= end.getZ(); z++) { consumer.accept(pos.set(x, y, z)); } } } } } ================================================ FILE: src/gametest/java/dev/isxander/debugify/test/suites/MC100991.java ================================================ package dev.isxander.debugify.test.suites; import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.core.BlockPos; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.FishingHook; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.GameType; public class MC100991 { @GameTest public void statTrackRodKill(GameTestHelper ctx) { Mob targetMob = ctx.spawnWithNoFreeWill(EntityType.CREEPER, new BlockPos(4, 0, 4)); Mob attacker = ctx.spawnWithNoFreeWill(EntityType.HUSK, new BlockPos(1, 0, 1)); ItemStack rodStack = new ItemStack(Items.FISHING_ROD); attacker.setItemInHand(InteractionHand.MAIN_HAND, rodStack); FishingHook hook = ctx.spawn(EntityType.FISHING_BOBBER, targetMob.blockPosition().above(1)); Player mockPlayer = ctx.makeMockPlayer(GameType.CREATIVE); mockPlayer.setItemInHand(InteractionHand.MAIN_HAND, rodStack); mockPlayer.setPos(attacker.position()); hook.setOwner(mockPlayer); ctx.runAfterDelay(20, () -> { // yank entity hook.retrieve(rodStack); ctx.runAfterDelay(5, () -> { System.out.println(targetMob.getCombatTracker().getDeathMessage().getString()); System.out.println(targetMob.getCombatTracker().getDeathMessage()); }); }); } } ================================================ FILE: src/gametest/java/dev/isxander/debugify/test/suites/MC30391.java ================================================ package dev.isxander.debugify.test.suites; import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.core.BlockPos; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; public class MC30391 { @GameTest public void blaze(GameTestHelper ctx) { testWithEntity(ctx, EntityType.BLAZE); } @GameTest public void chicken(GameTestHelper ctx) { testWithEntity(ctx, EntityType.CHICKEN); } @GameTest public void wither(GameTestHelper ctx) { testWithEntity(ctx, EntityType.WITHER); } private void testWithEntity(GameTestHelper ctx, EntityType entityType) { Mob mob = ctx.spawnWithNoFreeWill(entityType, new BlockPos(0, 4, 0)); // TODO: ctx.runAfterDelay(50, ctx::succeed); } } ================================================ FILE: src/gametest/java/dev/isxander/debugify/test/suites/MC72151.java ================================================ package dev.isxander.debugify.test.suites; import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.core.BlockPos; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.network.chat.Component; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.animal.wolf.Wolf; import net.minecraft.world.entity.projectile.Snowball; public class MC72151 { @GameTest public void mc72151(GameTestHelper ctx) { BlockPos wolfPos = new BlockPos(4, 0, 4); Wolf wolf = ctx.spawnWithNoFreeWill(EntityType.WOLF, wolfPos); wolf.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.0); Snowball snowball = ctx.spawn(EntityType.SNOWBALL, 0, 0, 4); double d = wolf.getEyeY() - 1.1F; double e = wolf.getX() - snowball.getX(); double f = d - snowball.getY(); double g = wolf.getZ() - snowball.getZ(); double h = Math.sqrt(e * e + g * g) * 0.2F; snowball.shoot(e, f + h, g, 1.6F, 0f); ctx.succeedIf(() -> ctx.assertTrue(wolf.getHealth() == wolf.getMaxHealth(), Component.literal("Wolf shouldn't be damaged."))); } } ================================================ FILE: src/gametest/java/dev/isxander/debugify/test/suites/MC8187.java ================================================ package dev.isxander.debugify.test.suites; import dev.isxander.debugify.test.DebugifyTestUtils; import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.core.BlockPos; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.network.chat.Component; import net.minecraft.tags.BlockTags; import net.minecraft.world.level.block.*; import net.minecraft.world.level.block.state.BlockState; /** * Dedicated test suite for MC-8187. *

* This is likely well over-engineered with asserting that the test will always work. * * @author Ampflower * @since 1.20.1+1.2 **/ public class MC8187 { private static final String TEMPLATE = "debugify:mc-8187"; // Adjust this if you move the center, as the tests assume this is accurate. private static final int SIZE = 18; // Subtracting one to get NW center. private static final int CENTER = SIZE / 2 - 1; private static final BlockPos CORNER = new BlockPos(CENTER, 1, CENTER); private static final BlockPos START_CORNER = CORNER.above(); private static final BlockPos END_CORNER = CORNER.offset(1, 1, 1); /** * Tests that the tree will grow under random ticks. *

* Side effect: Sets the time to day. */ private static void testTreeRandomTick(GameTestHelper ctx, Block sapling, Block log, BlockPos growCorner, boolean small) { // Ensure that parameters are correct. ctx.assertTrue(sapling instanceof SaplingBlock, Component.literal(sapling + " is not a sapling")); testTreeParamCommon(ctx, sapling, log, growCorner, true); // Setup final BlockState saplingState = sapling.defaultBlockState().setValue(SaplingBlock.STAGE, 1); ctx.onEachTick(() -> ctx.randomTick(growCorner)); testTreeCommon(ctx, saplingState, log, growCorner, small); } /** * Tests that the tree will grow with bonemeal. */ private static void testTreeBonemeal(GameTestHelper ctx, Block sapling, Block log, BlockPos growCorner, boolean small) { // Ensure that parameters are correct. ctx.assertTrue(sapling instanceof SaplingBlock, Component.literal(sapling + " is not a sapling")); testTreeParamCommon(ctx, sapling, log, growCorner, false); // Setup final BlockState saplingState = sapling.defaultBlockState().setValue(SaplingBlock.STAGE, 1); DebugifyTestUtils.bonemealIndefinitely(ctx, growCorner); testTreeCommon(ctx, saplingState, log, growCorner, small); } /** * Tests that the azalea will grow with bonemeal. */ private static void testAzalea(GameTestHelper ctx, Block sapling, Block log, BlockPos growCorner) { // Ensure that parameters are correct. ctx.assertTrue(sapling instanceof AzaleaBlock, Component.literal(sapling + " is not a sapling")); testTreeParamCommon(ctx, sapling, log, growCorner, false); DebugifyTestUtils.bonemealIndefinitely(ctx, growCorner); testTreeCommon(ctx, sapling.defaultBlockState(), log, growCorner, true); } /** * Asserts that the given parameters are correct. *

* This is to catch errors quickly as the input is sensitive to off by 1 errors. */ private static void testTreeParamCommon(GameTestHelper ctx, Block sapling, Block log, BlockPos growCorner, boolean requiresDay) { ctx.assertTrue(log instanceof RotatedPillarBlock, Component.literal(log + " does not appear like a log")); ctx.assertTrue(growCorner.getY() == START_CORNER.getY(), Component.literal("Incorrect Y, got " + growCorner.getY() + ", expected " + START_CORNER.getY())); // Ensure that the structure is correctly set up. assertSuitable(ctx, requiresDay); } /** * Continuously checks whether the tree has grown. */ private static void testTreeCommon(GameTestHelper ctx, BlockState sapling, Block log, BlockPos growCorner, boolean small) { DebugifyTestUtils.fill(ctx, START_CORNER, END_CORNER, sapling); if (small) { ctx.succeedWhen(() -> ctx.assertBlock(growCorner, block -> block == log, block -> Component.literal("Incorrect log, expected " + log))); } else { ctx.succeedWhen(() -> DebugifyTestUtils.assertBlockFill(ctx, START_CORNER, END_CORNER, block -> block == log, "Incorrect log, expected " + log)); } } @GameTest(structure = TEMPLATE, skyAccess = true) public void oak_randomTick_NW(GameTestHelper ctx) { testTreeRandomTick(ctx, Blocks.OAK_SAPLING, Blocks.OAK_LOG, START_CORNER, true); } @GameTest(structure = TEMPLATE, skyAccess = true) public void birch_randomTick_NW(GameTestHelper ctx) { testTreeRandomTick(ctx, Blocks.BIRCH_SAPLING, Blocks.BIRCH_LOG, START_CORNER, true); } @GameTest(structure = TEMPLATE, skyAccess = true) public void spruce_randomTick_NW(GameTestHelper ctx) { testTreeRandomTick(ctx, Blocks.SPRUCE_SAPLING, Blocks.SPRUCE_LOG, START_CORNER, false); } @GameTest(structure = TEMPLATE, skyAccess = true) public void jungle_randomTick_NW(GameTestHelper ctx) { testTreeRandomTick(ctx, Blocks.JUNGLE_SAPLING, Blocks.JUNGLE_LOG, START_CORNER, false); } @GameTest(structure = TEMPLATE, skyAccess = true) public void acacia_randomTick_NW(GameTestHelper ctx) { testTreeRandomTick(ctx, Blocks.ACACIA_SAPLING, Blocks.ACACIA_LOG, START_CORNER, true); } @GameTest(structure = TEMPLATE, skyAccess = true) public void darkOak_randomTick_NW(GameTestHelper ctx) { testTreeRandomTick(ctx, Blocks.DARK_OAK_SAPLING, Blocks.DARK_OAK_LOG, START_CORNER, false); } @GameTest(structure = TEMPLATE, skyAccess = true) public void cherry_randomTick_NW(GameTestHelper ctx) { testTreeRandomTick(ctx, Blocks.CHERRY_SAPLING, Blocks.CHERRY_LOG, START_CORNER, true); } @GameTest(structure = TEMPLATE) public void oak_bonemeal_NW(GameTestHelper ctx) { testTreeBonemeal(ctx, Blocks.OAK_SAPLING, Blocks.OAK_LOG, START_CORNER, true); } @GameTest(structure = TEMPLATE) public void birch_bonemeal_NW(GameTestHelper ctx) { testTreeBonemeal(ctx, Blocks.BIRCH_SAPLING, Blocks.BIRCH_LOG, START_CORNER, true); } @GameTest(structure = TEMPLATE) public void spruce_bonemeal_NW(GameTestHelper ctx) { testTreeBonemeal(ctx, Blocks.SPRUCE_SAPLING, Blocks.SPRUCE_LOG, START_CORNER, false); } @GameTest(structure = TEMPLATE) public void jungle_bonemeal_NW(GameTestHelper ctx) { testTreeBonemeal(ctx, Blocks.JUNGLE_SAPLING, Blocks.JUNGLE_LOG, START_CORNER, false); } @GameTest(structure = TEMPLATE) public void acacia_bonemeal_NW(GameTestHelper ctx) { testTreeBonemeal(ctx, Blocks.ACACIA_SAPLING, Blocks.ACACIA_LOG, START_CORNER, true); } @GameTest(structure = TEMPLATE) public void darkOak_bonemeal_NW(GameTestHelper ctx) { testTreeBonemeal(ctx, Blocks.DARK_OAK_SAPLING, Blocks.DARK_OAK_LOG, START_CORNER, false); } @GameTest(structure = TEMPLATE) public void cherry_bonemeal_NW(GameTestHelper ctx) { testTreeBonemeal(ctx, Blocks.CHERRY_SAPLING, Blocks.CHERRY_LOG, START_CORNER, true); } // The following two needs to be special-cased. @GameTest(structure = TEMPLATE) public void azaleaNW(GameTestHelper ctx) { testAzalea(ctx, Blocks.AZALEA, Blocks.OAK_LOG, START_CORNER); } // @GameTest(template = TEMPLATE) public void mangroveNW(GameTestHelper ctx) { testTreeRandomTick(ctx, Blocks.MANGROVE_PROPAGULE, Blocks.MANGROVE_LOG, START_CORNER, true); } /** * Asserts that the input parameters are suitable for use. */ private static void assertSuitable(GameTestHelper ctx, boolean requiresDay) { // Force it to be day for random-tick-based tests. if (requiresDay) { ctx.setDayTime(DebugifyTestUtils.TIME_OF_DAY_NOON); } // For some reason, + 1 is required. final var pos = CORNER; DebugifyTestUtils.assertBlockStateFill(ctx, pos, pos.offset(1, 0, 1), b -> b.is(BlockTags.DIRT), "Invalid template; not dirt"); DebugifyTestUtils.assertBlockFill(ctx, pos.above(), pos.offset(1, 1, 1), b -> b == Blocks.AIR, "Invalid template; not air"); ctx.assertBlockState(pos.offset(-1, 1, -1), b -> !b.canBeReplaced(), block -> Component.literal("Invalid template; NW block not solid")); } } ================================================ FILE: src/gametest/java/dev/isxander/debugify/test/suites/MC93018.java ================================================ package dev.isxander.debugify.test.suites; import net.fabricmc.fabric.api.gametest.v1.GameTest; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.network.chat.Component; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.animal.wolf.Wolf; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Items; import net.minecraft.world.level.GameType; public class MC93018 { @GameTest public void mc93018(GameTestHelper ctx) { Player player = ctx.makeMockPlayer(GameType.SURVIVAL); player.setItemInHand(InteractionHand.MAIN_HAND, Items.BONE.getDefaultInstance()); ctx.getLevel().addFreshEntity(player); Wolf wolf = ctx.spawn(EntityType.WOLF, 2, 0, 0); wolf.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.0); wolf.mobInteract(player, InteractionHand.MAIN_HAND); ctx.succeedIf(() -> ctx.assertTrue(wolf.getInLoveTime() <= 0, Component.literal("Wolf shouldn't love player"))); } } ================================================ FILE: src/gametest/resources/data/debugify/gametest/structures/mc-8187.snbt ================================================ { DataVersion: 3463, size: [18, 50, 18], data: [ {pos: [8, 0, 8], state: "minecraft:grass_block{snowy:false}"}, {pos: [8, 0, 9], state: "minecraft:grass_block{snowy:false}"}, {pos: [9, 0, 8], state: "minecraft:grass_block{snowy:false}"}, {pos: [9, 0, 9], state: "minecraft:grass_block{snowy:false}"}, {pos: [7, 1, 7], state: "minecraft:stone"}, {pos: [7, 1, 8], state: "minecraft:stone"}, {pos: [7, 1, 9], state: "minecraft:stone"}, {pos: [7, 1, 10], state: "minecraft:stone"}, {pos: [8, 1, 7], state: "minecraft:stone"}, {pos: [8, 1, 10], state: "minecraft:stone"}, {pos: [9, 1, 7], state: "minecraft:stone"}, {pos: [9, 1, 10], state: "minecraft:stone"}, {pos: [10, 1, 7], state: "minecraft:stone"}, {pos: [10, 1, 8], state: "minecraft:stone"}, {pos: [10, 1, 9], state: "minecraft:stone"}, {pos: [10, 1, 10], state: "minecraft:stone"} ], entities: [], palette: [ "minecraft:grass_block{snowy:false}", "minecraft:stone" ] } ================================================ FILE: src/gametest/resources/fabric.mod.json ================================================ { "schemaVersion": 1, "id": "debugify-test", "version": "1.0.0", "name": "Debugify (Game Test)", "license": "LGPLv3", "environment": "*", "icon": "debugify.png", "entrypoints": { "fabric-gametest": [ "dev.isxander.debugify.test.suites.MC72151", "dev.isxander.debugify.test.suites.MC8187", "dev.isxander.debugify.test.suites.MC93018", "dev.isxander.debugify.test.suites.MC30391", "dev.isxander.debugify.test.suites.MC100991" ], "debugify": [ "dev.isxander.debugify.test.DebugifyApiTest" ] }, "depends": { "debugify": "*", "fabric-gametest-api-v1": "*" } } ================================================ FILE: src/main/java/dev/isxander/debugify/Debugify.java ================================================ package dev.isxander.debugify; import dev.isxander.debugify.config.DebugifyConfig; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.error.DebugifyErrorHandler; import net.fabricmc.api.EnvType; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.Version; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spongepowered.asm.mixin.Mixins; import java.util.List; import java.util.Map; public class Debugify { public static final Logger LOGGER = LoggerFactory.getLogger("Debugify"); public static final Version VERSION = FabricLoader.getInstance().getModContainer("debugify").orElseThrow().getMetadata().getVersion(); public static final DebugifyConfig CONFIG = new DebugifyConfig(); /** * Called from mixin plugin to manage * disabled bug fixes */ public static void onPreInitialize() { CONFIG.preload(); Mixins.registerErrorHandlerClass(DebugifyErrorHandler.class.getName()); } public static void onInitialize() { List enabledBugs = CONFIG.getBugFixes().entrySet() .stream() .filter(Map.Entry::getValue) .map(entry -> entry.getKey().bugId()) .toList(); LOGGER.info("Enabled {} bug fixes: {}", enabledBugs.size(), enabledBugs); LOGGER.info("Successfully Debugify'd your game!"); } public static BugFix.Env getEnv() { return FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT ? BugFix.Env.CLIENT : BugFix.Env.SERVER; } public static boolean isGameplayFixesEnabled() { return Debugify.CONFIG.gameplayFixesInMultiplayer; } } ================================================ FILE: src/main/java/dev/isxander/debugify/api/DebugifyApi.java ================================================ package dev.isxander.debugify.api; import java.util.Map; import java.util.Set; public interface DebugifyApi { /** * Returns an array of bug ids (e.g. MC-577) to disable due to this mod */ default String[] getDisabledFixes() { return new String[0]; } /** * Provides a map of mod id to a set of bug ids to disable fixes * due to other mods. */ default Map> getProvidedDisabledFixes() { return Map.of(); } } ================================================ FILE: src/main/java/dev/isxander/debugify/config/DebugifyConfig.java ================================================ package dev.isxander.debugify.config; import dev.isxander.debugify.Debugify; import dev.isxander.debugify.fixes.BugFixData; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import net.fabricmc.loader.api.FabricLoader; import java.nio.file.Files; import java.nio.file.Path; import java.util.*; import java.util.stream.Collectors; public class DebugifyConfig { private final Path configPath = Path.of("config", "debugify.json"); private final Gson gson = new GsonBuilder().setPrettyPrinting().create(); private final Map jsonBugFixes = new HashMap<>(); private final Map bugFixes = new TreeMap<>(); public boolean defaultDisabled = false; public boolean optOutUpdater = false; public boolean gameplayFixesInMultiplayer = false; private boolean preloaded = false; public void registerBugFix(BugFixData bugFix) { if (bugFixes.containsKey(bugFix)) return; boolean enabled = jsonBugFixes.getOrDefault(bugFix.bugId(), bugFix.enabledByDefault() && !defaultDisabled); bugFixes.put(bugFix, enabled); } public void preload() { if (preloaded) return; preloaded = true; if (!Files.exists(configPath)) { if (FabricLoader.getInstance().isModLoaded("yosbr") && Files.exists(configPath.getParent().resolve("yosbr/" + configPath.getFileName().toString()))) { throw new YosbrError(); } return; } Debugify.LOGGER.info("Preloading Debugify"); try { String jsonString = Files.readString(configPath); JsonObject json = gson.fromJson(jsonString, JsonObject.class); if (json.has("opt_out_updater")) { optOutUpdater = json.get("opt_out_updater").getAsBoolean(); } if (json.has("default_disabled")) { defaultDisabled = json.get("default_disabled").getAsBoolean(); } if (json.has("gameplay_fixes_in_multiplayer")) { gameplayFixesInMultiplayer = json.get("gameplay_fixes_in_multiplayer").getAsBoolean(); } Map bugFixes = json.entrySet().stream() .filter((entry) -> entry.getKey().startsWith("MC-") && entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isBoolean()) .map((entry) -> new AbstractMap.SimpleEntry<>(entry.getKey(), entry.getValue().getAsBoolean())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); jsonBugFixes.clear(); jsonBugFixes.putAll(bugFixes); } catch (Exception e) { e.printStackTrace(); } } public void save() { Debugify.LOGGER.info("Saving Debugify"); try { Files.deleteIfExists(configPath); JsonObject json = new JsonObject(); bugFixes.forEach((fix, enabled) -> { if (!defaultDisabled || enabled) json.addProperty(fix.bugId(), enabled); }); json.addProperty("opt_out_updater", optOutUpdater); json.addProperty("gameplay_fixes_in_multiplayer", gameplayFixesInMultiplayer); json.addProperty("default_disabled", defaultDisabled); Files.createFile(configPath); Files.writeString(configPath, gson.toJson(json)); } catch (Exception e) { e.printStackTrace(); } } public boolean isBugFixEnabled(BugFixData bug) { return bugFixes.getOrDefault(bug, false); } public Map getBugFixes() { return bugFixes; } public boolean doesJsonHaveIdenticalKeys() { return jsonBugFixes.keySet().containsAll(bugFixes.keySet().stream().map(BugFixData::bugId).collect(Collectors.toSet())) && jsonBugFixes.size() == bugFixes.size(); } private static class YosbrError extends Error { public YosbrError() { super("Debugify config loaded using YOSBR mod! This doesn't work! Please move 'debugify.json' out of the 'yosbr' folder!"); } } } ================================================ FILE: src/main/java/dev/isxander/debugify/error/CrashReportInjector.java ================================================ package dev.isxander.debugify.error; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Set; /** * Adds details to crash report if Debugify recovered from a mixin application error. * This is needed because in some cases, partial mixin application may lead to runtime crashes, * and crash reports will not include the original mixin application error details that Debugify * logs in {@link DebugifyErrorHandler}. */ public class CrashReportInjector { public static void addDetailsToCrashReport(StringBuilder sb) { Set erroredFixes = DebugifyErrorHandler.getErroredFixes(); if (!erroredFixes.isEmpty()) { sb.append("\n-- Debugify recovered from mixin application errors --\n"); sb.append("Some bug fixes failed to apply, which could have led to this crash.\n"); sb.append("This log does not mean Debugify caused the crash, but it could have.\n\n"); for (var entry : erroredFixes) { sb.append(stringifyErrorEntry(entry)).append("\n"); } } } private static String stringifyErrorEntry(MixinErrorEntry entry) { var stringWriter = new StringWriter(); var printWriter = new PrintWriter(stringWriter); entry.throwable().printStackTrace(printWriter); String stacktrace = stringWriter.toString(); return "%s fix failed to fully apply due to %s during %s\n%s".formatted( entry.fix().bugId(), entry.mixinInfo().getName(), entry.errorStage().name(), stacktrace ); } } ================================================ FILE: src/main/java/dev/isxander/debugify/error/DebugifyErrorHandler.java ================================================ package dev.isxander.debugify.error; import dev.isxander.debugify.Debugify; import dev.isxander.debugify.fixes.BugFixData; import dev.isxander.debugify.mixinplugin.BugFixDataCache; import org.spongepowered.asm.mixin.extensibility.IMixinConfig; import org.spongepowered.asm.mixin.extensibility.IMixinErrorHandler; import org.spongepowered.asm.mixin.extensibility.IMixinInfo; import java.util.Collections; import java.util.HashSet; import java.util.Optional; import java.util.Set; public class DebugifyErrorHandler implements IMixinErrorHandler { private static final Set ERRORED_FIXES = new HashSet<>(); @Override public ErrorAction onPrepareError(IMixinConfig config, Throwable th, IMixinInfo mixin, ErrorAction action) { return handleError(action, mixin, th, ErrorStage.PREPARE); } @Override public ErrorAction onApplyError(String targetClassName, Throwable th, IMixinInfo mixin, ErrorAction action) { return handleError(action, mixin, th, ErrorStage.APPLY); } private ErrorAction handleError(ErrorAction usualAction, IMixinInfo mixin, Throwable th, ErrorStage stage) { Optional bugFix = BugFixDataCache.getIfResolved(mixin.getClassName()); if (bugFix.isEmpty()) return usualAction; BugFixData fix = bugFix.get(); ERRORED_FIXES.add(new MixinErrorEntry(fix, mixin, th, stage)); // no need to add exception here, it's already logged under ErrorAction.WARN Debugify.LOGGER.error("Failed to fully apply bug fix {}, mixin class {} will not be applied! This may cause runtime errors if a partial injection occurs.", fix.bugId(), mixin.getName()); return ErrorAction.WARN; } public static boolean hasErrored(BugFixData fix) { return ERRORED_FIXES.stream().anyMatch(entry -> entry.fix().equals(fix)); } public static Set getErroredFixes() { return Collections.unmodifiableSet(ERRORED_FIXES); } } ================================================ FILE: src/main/java/dev/isxander/debugify/error/ErrorStage.java ================================================ package dev.isxander.debugify.error; public enum ErrorStage { PREPARE, APPLY } ================================================ FILE: src/main/java/dev/isxander/debugify/error/MixinErrorEntry.java ================================================ package dev.isxander.debugify.error; import dev.isxander.debugify.fixes.BugFixData; import org.spongepowered.asm.mixin.extensibility.IMixinInfo; public record MixinErrorEntry(BugFixData fix, IMixinInfo mixinInfo, Throwable throwable, ErrorStage errorStage) { } ================================================ FILE: src/main/java/dev/isxander/debugify/fixes/BugFix.java ================================================ package dev.isxander.debugify.fixes; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface BugFix { String id(); FixCategory category(); Env env(); boolean enabled() default true; String[] modConflicts() default {}; OS os() default OS.UNKNOWN; String description() default ""; enum Env { CLIENT("debugify.env.client"), SERVER("debugify.env.server"); private final String displayName; Env(String displayName) { this.displayName = displayName; } public String getDisplayName() { return displayName; } public String getDescriptionKey() { return getDisplayName() + ".desc"; } } } ================================================ FILE: src/main/java/dev/isxander/debugify/fixes/BugFixData.java ================================================ package dev.isxander.debugify.fixes; import dev.isxander.debugify.mixinplugin.DebugifyDebugFlags; import net.fabricmc.loader.api.FabricLoader; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.stream.Collectors; public record BugFixData(String bugId, FixCategory category, BugFix.Env env, boolean enabledByDefault, List conflicts, OS requiredOs, @Nullable String description) implements Comparable { private static final Map> externalModConflicts = new HashMap<>(); public static void registerApiConflict(String modId, String bugId) { externalModConflicts.computeIfAbsent(bugId, b -> new HashSet<>()).add(modId); } public Set getActiveConflicts() { Set conflicts = conflicts().stream().filter(id -> FabricLoader.getInstance().isModLoaded(id)).collect(Collectors.toSet()); Set apiConflicts = externalModConflicts.get(bugId()); if (apiConflicts != null) conflicts.addAll(apiConflicts); return conflicts; } public boolean satisfiesOSRequirement() { return requiredOs() == OS.UNKNOWN || requiredOs() == OS.getOperatingSystem() || (requiredOs() == OS.LINUX && DebugifyDebugFlags.FORCE_LINUX_FIXES) || (requiredOs() == OS.WINDOWS && DebugifyDebugFlags.FORCE_WINDOWS_FIXES) || (requiredOs() == OS.MAC && DebugifyDebugFlags.FORCE_MACOS_FIXES); } @Override public boolean equals(Object obj) { if (obj instanceof BugFixData bugFixData) return bugFixData.bugId.equals(bugId); return false; } @Override public int compareTo(@NotNull BugFixData o) { if (o.bugId.length() == bugId.length()) { return bugId.compareTo(o.bugId); } return Integer.compare(bugId.length(), o.bugId.length()); } } ================================================ FILE: src/main/java/dev/isxander/debugify/fixes/FixCategory.java ================================================ package dev.isxander.debugify.fixes; public enum FixCategory { BASIC("debugify.basic"), GAMEPLAY("debugify.gameplay"); private final String displayName; FixCategory(String displayName) { this.displayName = displayName; } public String getDisplayName() { return this.displayName; } } ================================================ FILE: src/main/java/dev/isxander/debugify/fixes/OS.java ================================================ package dev.isxander.debugify.fixes; import java.util.Locale; /** * Cannot use {@link net.minecraft.Util.OS} because * this code needs to be run from a Mixin plugin, where you can't access * Minecraft classes. */ public enum OS { WINDOWS("debugify.os.windows"), MAC("debugify.os.macos"), LINUX("debugify.os.linux"), SOLARIS("debugify.os.solaris"), UNKNOWN("debugify.os.unknown"); public static OS getOperatingSystem() { String string = System.getProperty("os.name").toLowerCase(Locale.ROOT); if (string.contains("win")) { return OS.WINDOWS; } else if (string.contains("mac")) { return OS.MAC; } else if (string.contains("solaris")) { return OS.SOLARIS; } else if (string.contains("sunos")) { return OS.SOLARIS; } else if (string.contains("linux")) { return OS.LINUX; } else { return string.contains("unix") ? OS.LINUX : OS.UNKNOWN; } } private final String displayName; OS(String displayName) { this.displayName = displayName; } public String getDisplayName() { return this.displayName; } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixinplugin/BugFixDataCache.java ================================================ package dev.isxander.debugify.mixinplugin; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.BugFixData; import dev.isxander.debugify.fixes.FixCategory; import dev.isxander.debugify.fixes.OS; import org.jetbrains.annotations.Nullable; import org.objectweb.asm.tree.AnnotationNode; import org.objectweb.asm.tree.ClassNode; import org.spongepowered.asm.service.MixinService; import org.spongepowered.asm.util.Annotations; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; public class BugFixDataCache { private static final Map bugFixDataByMixinClass = new HashMap<>(); public static Optional getOrResolve(String mixinClassName) { return Optional.ofNullable( bugFixDataByMixinClass.computeIfAbsent(mixinClassName, BugFixDataCache::resolve) .data() ); } public static Optional getIfResolved(String mixinClassName) { return Optional.ofNullable(bugFixDataByMixinClass.get(mixinClassName)) .flatMap(resolved -> Optional.ofNullable(resolved.data())); } private static ResolvedBugFixData resolve(String mixinClassName) { ClassNode classNode = getClassNode(mixinClassName); if (classNode == null) { return new ResolvedBugFixData(null); } AnnotationNode annotationNode = Annotations.getVisible(classNode, BugFix.class); if (annotationNode == null) { return new ResolvedBugFixData(null); } String id = Annotations.getValue(annotationNode, "id"); FixCategory category = getAnnotationEnumValue(annotationNode, "category", FixCategory.class); BugFix.Env env = getAnnotationEnumValue(annotationNode, "env", BugFix.Env.class); boolean enabledByDefault = Annotations.getValue(annotationNode, "enabled", Boolean.valueOf(true)); List conflicts = Annotations.getValue(annotationNode, "modConflicts", true); OS requiredOS = Annotations.getValue(annotationNode, "os", OS.class, OS.UNKNOWN); String description = Annotations.getValue(annotationNode, "description"); if ("".equals(description)) { description = null; } return new ResolvedBugFixData(new BugFixData(id, category, env, enabledByDefault, conflicts, requiredOS, description)); } private static ClassNode getClassNode(String className) { try { return MixinService.getService().getBytecodeProvider().getClassNode(className); } catch (ClassNotFoundException | IOException e) { return null; } } private static > T getAnnotationEnumValue(AnnotationNode annotation, String key, Class enumClass) { String[] value = Annotations.getValue(annotation, key); return Enum.valueOf(enumClass, value[1]); } record ResolvedBugFixData(@Nullable BugFixData data) {} } ================================================ FILE: src/main/java/dev/isxander/debugify/mixinplugin/DebugifyDebugFlags.java ================================================ package dev.isxander.debugify.mixinplugin; public class DebugifyDebugFlags { public static final boolean FORCE_LINUX_FIXES = boolProp("debugify.forceLinuxFixes"); public static final boolean FORCE_WINDOWS_FIXES = boolProp("debugify.forceWindowsFixes"); public static final boolean FORCE_MACOS_FIXES = boolProp("debugify.forceMacFixes"); private static boolean boolProp(String property) { return Boolean.parseBoolean(System.getProperty(property)); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixinplugin/MixinPlugin.java ================================================ package dev.isxander.debugify.mixinplugin; import dev.isxander.debugify.Debugify; import dev.isxander.debugify.api.DebugifyApi; import dev.isxander.debugify.error.DebugifyErrorHandler; import dev.isxander.debugify.fixes.BugFixData; import net.fabricmc.loader.api.FabricLoader; import org.objectweb.asm.tree.ClassNode; import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; import org.spongepowered.asm.mixin.extensibility.IMixinInfo; import java.util.*; public class MixinPlugin implements IMixinConfigPlugin { @Override public void onLoad(String mixinPackage) { Debugify.onPreInitialize(); var entrypoints = FabricLoader.getInstance().getEntrypointContainers("debugify", DebugifyApi.class); entrypoints.forEach(container -> { DebugifyApi api = container.getEntrypoint(); String containerModId = container.getProvider().getMetadata().getId(); for (String bugId : api.getDisabledFixes()) { BugFixData.registerApiConflict(containerModId, bugId); } api.getProvidedDisabledFixes().forEach((modId, bugs) -> { if (FabricLoader.getInstance().isModLoaded(modId)) { bugs.forEach(bugId -> BugFixData.registerApiConflict(modId, bugId)); } }); }); } @Override public String getRefMapperConfig() { return null; } @Override public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { Optional bugFixOptional = BugFixDataCache.getOrResolve(mixinClassName); if (bugFixOptional.isEmpty()) return true; BugFixData bugFix = bugFixOptional.get(); var multipleMixins = Debugify.CONFIG.getBugFixes().containsKey(bugFix); Debugify.CONFIG.registerBugFix(bugFix); if (DebugifyErrorHandler.hasErrored(bugFix)) { Debugify.LOGGER.warn("Preventing loading of {} mixin, {} because another mixin for the same bug fix failed to apply.", bugFix.bugId(), mixinClassName); return false; } Set conflicts = bugFix.getActiveConflicts(); if (!conflicts.isEmpty()) { if (Debugify.CONFIG.isBugFixEnabled(bugFix) && !multipleMixins) Debugify.LOGGER.warn("Force disabled {} because it's conflicting with: {}", bugFix.bugId(), String.join(", ", conflicts)); return false; } else if (!bugFix.satisfiesOSRequirement()) { if (Debugify.CONFIG.isBugFixEnabled(bugFix) && !multipleMixins) Debugify.LOGGER.warn("Force disabled {} because it only applies to OS: {}", bugFix.bugId(), bugFix.requiredOs().name()); return false; } return Debugify.CONFIG.isBugFixEnabled(bugFix); } @Override public void acceptTargets(Set myTargets, Set otherTargets) {} @Override public List getMixins() { return null; } @Override public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {} @Override public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {} } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc100991/FishingHookMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc100991; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.projectile.FishingHook; import net.minecraft.world.entity.projectile.Projectile; import net.minecraft.world.level.Level; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-100991", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Killing entities with a fishing rod doesn't count as a kill") @Mixin(FishingHook.class) public abstract class FishingHookMixin extends Projectile { public FishingHookMixin(EntityType type, Level level) { super(type, level); } /** * notifies the combat tracker */ @Inject( method = "pullEntity", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;setDeltaMovement(Lnet/minecraft/world/phys/Vec3;)V" ) ) private void onPullEntity(Entity entity, CallbackInfo ci) { if (entity instanceof LivingEntity livingEntity) { livingEntity.getCombatTracker().recordDamage( level().damageSources().thrown((FishingHook)(Object) this, getOwner()), livingEntity.getHealth() ); } } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc119754/FireworkRocketEntityMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc119754; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.projectile.FireworkRocketEntity; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-119754", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Firework boosting on elytra continues in spectator mode") @Mixin(FireworkRocketEntity.class) public class FireworkRocketEntityMixin { @Shadow @Nullable private LivingEntity attachedToEntity; @ModifyExpressionValue( method = "tick", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;isFallFlying()Z" ) ) private boolean shouldFly(boolean elytraFlying) { return elytraFlying && !attachedToEntity.isSpectator(); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc121706/RangedBowAttackGoalMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc121706; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.ai.goal.RangedBowAttackGoal; import net.minecraft.world.entity.monster.Monster; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-121706", env = BugFix.Env.SERVER, category = FixCategory.BASIC, description = "Skeletons and illusioners aren't looking up / down at their target while strafing") @Mixin(RangedBowAttackGoal.class) public abstract class RangedBowAttackGoalMixin { @Shadow @Final private T mob; @Inject( method = "tick", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/monster/Monster;lookAt(Lnet/minecraft/world/entity/Entity;FF)V", shift = At.Shift.AFTER ) ) private void lookAtTarget(CallbackInfo ci) { mob.getLookControl().setLookAt(mob.getTarget(), 30f, 30f); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc121903/MinecraftCommandBlockMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc121903; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.vehicle.minecart.MinecartCommandBlock; import net.minecraft.world.level.storage.ValueInput; import net.minecraft.world.level.storage.ValueOutput; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-121903", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Command block minecarts do not save execution cooldown to NBT") @Mixin(MinecartCommandBlock.class) public class MinecraftCommandBlockMixin { @Shadow private int lastActivated; @Inject(method = "readAdditionalSaveData", at = @At("RETURN")) private void readNbt(ValueInput input, CallbackInfo ci) { input.getInt("LastExecuted").ifPresent(lastExecuted -> { lastActivated = lastExecuted; }); } @Inject(method = "addAdditionalSaveData", at = @At("RETURN")) private void writeNbt(ValueOutput output, CallbackInfo ci) { output.putInt("LastExecuted", lastActivated); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc123450/ItemFrameMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc123450; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.entity.decoration.ItemFrame; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-123450", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Item frames play sounds when the item within them is read from NBT") @Mixin(ItemFrame.class) public class ItemFrameMixin { @WrapWithCondition( method = "setItem(Lnet/minecraft/world/item/ItemStack;Z)V", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/decoration/ItemFrame;playSound(Lnet/minecraft/sounds/SoundEvent;FF)V" ) ) private boolean playSound(ItemFrame instance, SoundEvent soundEvent, float volume, float pitch, @Local(argsOnly = true, name = "updateNeighbours") boolean updateNeighbours) { // the targeted method is only given `updateNeighbours = false` when reading from NBT. // technically, this means mods who want neighbourless updates will no longer play a sound. // ideally, this would be an additional boolean in the method, but we don't have that privilige. return updateNeighbours; } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc129909/ServerPlayerMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc129909; import com.mojang.authlib.GameProfile; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.GameType; import net.minecraft.world.level.Level; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @BugFix(id = "MC-129909", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Players in spectator mode continue to consume foods and liquids shortly after switching game modes") @Mixin(ServerPlayer.class) public abstract class ServerPlayerMixin extends Player { public ServerPlayerMixin(Level world, GameProfile gameProfile) { super(world, gameProfile); } /** * Also fixes * MC-81773, MC-206705 */ @Inject( method = "setGameMode", at = @At( value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;stopRiding()V" ) ) private void onChangeToSpectator(GameType mode, CallbackInfoReturnable cir) { releaseUsingItem(); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc131562/ServerGamePacketListenerImplMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc131562; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.network.chat.Component; import net.minecraft.network.protocol.game.ServerboundSetCommandMinecartPacket; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.network.ServerGamePacketListenerImpl; import net.minecraft.util.StringUtil; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-131562", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Pressing the \"Done\" button in empty command block minecarts prints the message \"Command set: \" in chat") @Mixin(ServerGamePacketListenerImpl.class) public class ServerGamePacketListenerImplMixin { /** * Add a condition to only send the success message if the command is not empty. * This is parity with the command block behaviour. */ @Definition(id = "sendSystemMessage", method = "Lnet/minecraft/server/level/ServerPlayer;sendSystemMessage(Lnet/minecraft/network/chat/Component;)V") @Expression("?.?.sendSystemMessage(?(?, ?))") @WrapWithCondition(method = "handleSetCommandMinecart", at = @At("MIXINEXTRAS:EXPRESSION")) private boolean checkEmptyCommandBeforeMessage(ServerPlayer instance, Component message, @Local(argsOnly = true, name = "packet") ServerboundSetCommandMinecartPacket packet) { return !StringUtil.isNullOrEmpty(packet.getCommand()); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc132878/ArmorStandMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc132878; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.decoration.ArmorStand; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @BugFix(id = "MC-132878", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Armor stands destroyed by explosions/lava/fire don't produce particles") @Mixin(ArmorStand.class) public abstract class ArmorStandMixin { @Shadow protected abstract void showBreakingParticles(); @Inject( method = "hurtServer", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/decoration/ArmorStand;brokenByAnything(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/damagesource/DamageSource;)V", ordinal = 0 ) ) private void breakParticlesExplosion(CallbackInfoReturnable cir) { this.showBreakingParticles(); } @Inject( method = "causeDamage", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/decoration/ArmorStand;brokenByAnything(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/damagesource/DamageSource;)V", ordinal = 0 ) ) private void breakParticlesFire(CallbackInfo ci) { this.showBreakingParticles(); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc133218/ServerPlayerMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc133218; import com.mojang.authlib.GameProfile; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-133218", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Usable items continue to be used on the death screen after dying when the keepInventory gamerule is set to enabled") @Mixin(ServerPlayer.class) public abstract class ServerPlayerMixin extends Player { public ServerPlayerMixin(Level level, GameProfile gameProfile) { super(level, gameProfile); } @Inject(method = "die", at = @At("RETURN")) private void stopUsingItemOnDeath(CallbackInfo ci) { this.stopUsingItem(); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc134110/ChestBlockMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc134110; import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.level.block.ChestBlock; import net.minecraft.world.level.block.Mirror; import net.minecraft.world.level.block.state.BlockState; import org.spongepowered.asm.mixin.Mixin; import static net.minecraft.world.level.block.ChestBlock.TYPE; @BugFix(id = "MC-134110", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Structure mirroring breaking apart double chests") @Mixin(ChestBlock.class) public class ChestBlockMixin { @WrapMethod(method = "mirror") private BlockState fixChestRotations(BlockState state, Mirror mirror, Operation original) { BlockState result = original.call(state, mirror); return mirror == Mirror.NONE ? result : result.setValue(TYPE, result.getValue(TYPE).getOpposite()); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc139041/FishingRodItemMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc139041; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.sounds.SoundSource; import net.minecraft.world.item.FishingRodItem; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; @BugFix(id = "MC-139041", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "The sounds of fishing bobbers aren't controlled by the \"Players\" sound slider") @Mixin(FishingRodItem.class) public class FishingRodItemMixin { @ModifyArg( method = "use", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/level/Level;playSound(Lnet/minecraft/world/entity/Entity;DDDLnet/minecraft/sounds/SoundEvent;Lnet/minecraft/sounds/SoundSource;FF)V" ) ) private SoundSource modifyFishingBobberSounds(SoundSource soundSource) { return SoundSource.PLAYERS; } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc147659/CatSpawnerMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc147659; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.animal.feline.Cat; import net.minecraft.world.entity.npc.CatSpawner; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-147659", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Some witch huts spawn the incorrect cat") @Mixin(CatSpawner.class) public class CatSpawnerMixin { @WrapWithCondition( method = "spawnCat", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/animal/feline/Cat;snapTo(Lnet/minecraft/core/BlockPos;FF)V" ) ) private boolean removeOldCatSnap(Cat instance, BlockPos blockPos, float yaw, float pitch) { return false; } @Inject( method = "spawnCat", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/animal/feline/Cat;finalizeSpawn(Lnet/minecraft/world/level/ServerLevelAccessor;Lnet/minecraft/world/DifficultyInstance;Lnet/minecraft/world/entity/EntitySpawnReason;Lnet/minecraft/world/entity/SpawnGroupData;)Lnet/minecraft/world/entity/SpawnGroupData;" ) ) private void addNewCatSnap(BlockPos spawnPos, ServerLevel level, boolean makePersistent, CallbackInfo ci, @Local(name = "cat") Cat cat) { cat.snapTo(spawnPos, 0, 0); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc153010/FoxMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc153010; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.animal.fox.Fox; import net.minecraft.world.level.gamerules.GameRules; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-153010", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "doMobLoot gamerule doesn't prevent foxes from dropping their items") @Mixin(Fox.class) public class FoxMixin { // gate dropping death loot with gamerule check @ModifyExpressionValue( method = "dropAllDeathLoot", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;isEmpty()Z" ) ) private boolean preventLootDropIfGameruleIsFalse(boolean isEmpty, ServerLevel level) { return isEmpty || !level.getGameRules().get(GameRules.MOB_DROPS); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc155509/PufferfishMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc155509; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.animal.fish.Pufferfish; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-155509", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Dying puffed pufferfish can still sting players") @Mixin(Pufferfish.class) public class PufferfishMixin { @ModifyExpressionValue( method = "playerTouch", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;hurtServer(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/damagesource/DamageSource;F)Z" ) ) private boolean shouldStingPlayer(boolean damaged) { return damaged && ((Pufferfish)(Object) this).isAlive(); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc158900/PlayerListMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc158900; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.server.players.NameAndId; import net.minecraft.server.players.PlayerList; import net.minecraft.server.players.UserBanList; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-158900", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "\"bad packet id 26\" disconnect after first-login after a temporary ban expires") @Mixin(PlayerList.class) public class PlayerListMixin { @WrapOperation( method = "canPlayerLogin", at = @At( value = "INVOKE", target = "Lnet/minecraft/server/players/UserBanList;isBanned(Lnet/minecraft/server/players/NameAndId;)Z" ) ) private boolean removeExpiredBeforeCheck(UserBanList instance, NameAndId user, Operation original) { instance.get(user); // get will remove expired bans return original.call(instance, user); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc159283/DensityFunctionsMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc159283; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.util.Mth; import net.minecraft.world.level.levelgen.DensityFunctions; import net.minecraft.world.level.levelgen.synth.SimplexNoise; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; /** * Taken from Thorium * https://github.com/PotassiumMC/thorium * under LGPLv3 license * * @author NoahvdAa */ @BugFix(id = "MC-159283", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "The End terrain does not generate in multiple rings centered around the world center") @Mixin(DensityFunctions.EndIslandDensityFunction.class) public class DensityFunctionsMixin { /** * Explicitly cast `x` and `z` to long (from int) to prevent integer overflow when squaring. * We use a WrapOperation instead of ModifyArg so we don't do the math twice (one bugged one fixed) */ @Definition(id = "sqrt", method = "Lnet/minecraft/util/Mth;sqrt(F)F") @Definition(id = "sectionX", local = @Local(type = int.class, name = "sectionX", argsOnly = true)) @Definition(id = "sectionZ", local = @Local(type = int.class, name = "sectionZ", argsOnly = true)) @Expression("sqrt((float) (sectionX * sectionX + sectionZ * sectionZ))") @WrapOperation(method = "getHeightValue", at = @At("MIXINEXTRAS:EXPRESSION")) private static float castToLongs(float x, Operation original, SimplexNoise islandNoise, int sectionX, int sectionZ) { return Mth.sqrt((long) sectionX * (long) sectionX + (long) sectionZ * (long) sectionZ); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc160095/CactusBlockMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc160095; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.CactusBlock; import net.minecraft.world.level.block.piston.PistonMovingBlockEntity; import net.minecraft.world.level.block.state.BlockState; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-160095", category = FixCategory.BASIC, env = BugFix.Env.SERVER, modConflicts = "carpet-fixes", description = "Partial blocks break cactus when moved by pistons") @Mixin(CactusBlock.class) public class CactusBlockMixin { @Definition(id = "getBlockState", method = "Lnet/minecraft/world/level/LevelReader;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;") @Definition(id = "pos", local = @Local(type = BlockPos.class, name = "pos", argsOnly = true)) @Definition(id = "relative", method = "Lnet/minecraft/core/BlockPos;relative(Lnet/minecraft/core/Direction;)Lnet/minecraft/core/BlockPos;") @Definition(id = "direction", local = @Local(type = Direction.class, name = "direction")) @Expression("?.getBlockState(pos.relative(direction))") @WrapOperation(method = "canSurvive", at = @At("MIXINEXTRAS:EXPRESSION")) private BlockState replaceBlockState(LevelReader instance, BlockPos blockPos, Operation original) { BlockState state = original.call(instance, blockPos); // If it is a moving piston we check the block its moving not the moving piston block itself. if (state.is(Blocks.MOVING_PISTON) && instance.getBlockEntity(blockPos) instanceof PistonMovingBlockEntity pistonBlock) { return pistonBlock.getMovedState(); } return state; } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc168573/BlocksAttacksMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc168573; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.component.BlocksAttacks; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-168573", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "After breaking a shield, the player's off-hand can't finish using some items") @Mixin(BlocksAttacks.class) public class BlocksAttacksMixin { /** * We need to check if the shield is going to break and only stop using the item after it is broken. * We can't use isBroken here, so instead we check if the next damage will break the blockable, then do the damage call after. */ @WrapOperation( method = "hurtBlockingItem", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;hurtAndBreak(ILnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/entity/EquipmentSlot;)V" ) ) private void fixShieldBreakItemUse( ItemStack instance, int amount, LivingEntity owner, EquipmentSlot slot, Operation original, @Local(argsOnly = true, name = "item") ItemStack item ) { boolean isBroken = item.nextDamageWillBreak(); original.call(instance, amount, owner, slot); if (isBroken) { owner.stopUsingItem(); } } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc170462/MobEffectsMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc170462; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.effect.MobEffectCategory; import net.minecraft.world.effect.MobEffects; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; @BugFix(id = "MC-170462", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Bad Omen is considered a positive effect in potion item tooltips") @Mixin(MobEffects.class) public class MobEffectsMixin { @ModifyArg( method = "", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/effect/BadOmenMobEffect;(Lnet/minecraft/world/effect/MobEffectCategory;I)V" ) ) private static MobEffectCategory badOmenEffectCategory(MobEffectCategory arg) { return MobEffectCategory.HARMFUL; } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc176806/RespawnAnchorBlockMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc176806; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.stats.Stats; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.RespawnAnchorBlock; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @BugFix(id = "MC-176806", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Scoreboard criteria for using glowstone doesn't increase score when charging a respawn anchor") @Mixin(RespawnAnchorBlock.class) public class RespawnAnchorBlockMixin { @Inject( method = "useItemOn", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;consume(ILnet/minecraft/world/entity/LivingEntity;)V" ) ) private void awardGlowstoneStat( CallbackInfoReturnable cir, @Local(argsOnly = true, name = "itemStack") ItemStack itemStack, @Local(argsOnly = true, name = "player") Player player ) { player.awardStat(Stats.ITEM_USED.get(itemStack.getItem())); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc177381/LocateCommandMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc177381; import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.server.commands.LocateCommand; import org.spongepowered.asm.mixin.Mixin; @BugFix(id = "MC-177381", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Game does not count the distance properly if you locate a structure from more than 46340 blocks away") @Mixin(LocateCommand.class) public class LocateCommandMixin { @WrapMethod(method = "dist") private static float distanceHypot(int x1, int z1, int x2, int z2, Operation original) { return (float) Math.hypot(x2 - x1, z2 - z1); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc179072/SwellGoalMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc179072; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.ai.goal.SwellGoal; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-179072", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Creepers do not defuse when switching from Survival to Creative/Spectator") @Mixin(SwellGoal.class) public class SwellGoalMixin { @Shadow private @Nullable LivingEntity target; @ModifyExpressionValue( method = "tick", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/ai/sensing/Sensing;hasLineOfSight(Lnet/minecraft/world/entity/Entity;)Z" ) ) private boolean shouldIgniteCreeper(boolean canSeeTarget) { return canSeeTarget && (target == null || target.canBeSeenAsEnemy()); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc183990/MobMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc183990; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.Mob; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-183990", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Group AI of some mobs breaks when their target dies") @Mixin(Mob.class) public abstract class MobMixin { @Shadow private @Nullable LivingEntity target; @Shadow public abstract void setTarget(@Nullable LivingEntity target); @Inject( method = "baseTick", at = @At( value = "INVOKE", target = "Lnet/minecraft/util/profiling/ProfilerFiller;pop()V" ) ) private void clearTargetIfDead(CallbackInfo ci) { if (target != null && target.isDeadOrDying()) { setTarget(null); } } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc187100/EnderDragonMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc187100; import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.boss.enderdragon.EndCrystal; import net.minecraft.world.entity.boss.enderdragon.EnderDragon; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-187100", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "End crystals try to heal dying Ender dragons") @Mixin(EnderDragon.class) public class EnderDragonMixin { @Shadow public int dragonDeathTime; @Shadow @Nullable public EndCrystal nearestCrystal; @WrapMethod(method = "checkCrystals") private void dontFindNearestCrystalIfDying(Operation original) { if (this.dragonDeathTime > 0) { this.nearestCrystal = null; } else { original.call(); } } @Inject(method = "tickDeath", at = @At("HEAD")) private void clearNearestCrystalOnDeath(CallbackInfo ci) { this.nearestCrystal = null; } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc200418/ZombieVillagerMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc200418; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.animal.chicken.Chicken; import net.minecraft.world.entity.monster.zombie.ZombieVillager; import net.minecraft.world.entity.npc.villager.Villager; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-200418", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Cured baby zombie villagers stay as jockey variant") @Mixin(ZombieVillager.class) public class ZombieVillagerMixin { @Inject(method = "lambda$finishConversion$0", at = @At("RETURN")) private void dismountIfJockey(ServerLevel level, Villager villager, CallbackInfo ci) { if (villager.isPassenger() && villager.getVehicle() instanceof Chicken && villager.isBaby()) { villager.removeVehicle(); } } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc201374/CampfireBlockMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc201374; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.CampfireBlock; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; @BugFix(id = "MC-201374", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Wrong position passed to getCollisionShape from CampfireBlock#isSmokingBlockAt") @Mixin(CampfireBlock.class) public class CampfireBlockMixin { @ModifyArg( method = "isSmokeyPos", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;getCollisionShape(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/phys/shapes/CollisionContext;)Lnet/minecraft/world/phys/shapes/VoxelShape;" ) ) private static BlockPos fixedBlockPos(BlockPos pos, @Local(name = "posToCheck") BlockPos posToCheck) { return posToCheck; } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc202637/FoodPropertiesMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc202637; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.sounds.SoundSource; import net.minecraft.world.food.FoodProperties; import net.minecraft.world.item.component.Consumable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; @BugFix(id = "MC-202637", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Last sound clip of eating will still play when Players volume is set to 0%") @Mixin(FoodProperties.class) public class FoodPropertiesMixin { @Definition(id = "playSound", method = "Lnet/minecraft/world/level/Level;playSound(Lnet/minecraft/world/entity/Entity;DDDLnet/minecraft/sounds/SoundEvent;Lnet/minecraft/sounds/SoundSource;FF)V") @Definition(id = "consumable", local = @Local(type = Consumable.class, name = "consumable", argsOnly = true)) @Definition(id = "sound", method = "Lnet/minecraft/world/item/component/Consumable;sound()Lnet/minecraft/core/Holder;") @Expression("?.playSound(?, ?, ?, ?, (?) consumable.sound().?(), ?, ?, ?)") @ModifyArg(method = "onConsume", at = @At("MIXINEXTRAS:EXPRESSION")) private SoundSource modifyEatSoundSource(SoundSource soundSource) { return SoundSource.PLAYERS; } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc206922/EntityMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc206922; import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LightningBolt; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @BugFix(id = "MC-206922", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Items dropped by entities that are killed by lightning instantly disappear") @Mixin(Entity.class) public class EntityMixin { @Shadow public int tickCount; @WrapMethod(method = "thunderHit") protected void bypassStruckByLightning(ServerLevel level, LightningBolt lightningBolt, Operation operation) { operation.call(level, lightningBolt); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc206922/ItemEntityMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc206922; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.LightningBolt; import net.minecraft.world.entity.item.ItemEntity; import org.spongepowered.asm.mixin.Mixin; @BugFix(id = "MC-206922", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Items dropped by entities that are killed by lightning instantly disappear") @Mixin(ItemEntity.class) public abstract class ItemEntityMixin extends EntityMixin { @Override protected void bypassStruckByLightning(ServerLevel world, LightningBolt lightning, Operation operation) { if (tickCount > 8) { super.bypassStruckByLightning(world, lightning, operation); } } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc215530/ServerPlayerMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc215530; import com.mojang.authlib.GameProfile; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @BugFix(id = "MC-215530", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "The freezing effect isn't immediately removed upon switching into spectator mode") @Mixin(ServerPlayer.class) public abstract class ServerPlayerMixin extends Player { public ServerPlayerMixin(Level world, GameProfile gameProfile) { super(world, gameProfile); } @Inject( method = "setGameMode", at = @At( value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;stopRiding()V" ) ) private void onChangeToSpectator(CallbackInfoReturnable cir) { setTicksFrozen(0); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc221257/ShulkerBulletMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc221257; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.projectile.Projectile; import net.minecraft.world.entity.projectile.ShulkerBullet; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-221257", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Shulker bullets don't produce bubble particles when moving through water") @Mixin(ShulkerBullet.class) public abstract class ShulkerBulletMixin extends Projectile { public ShulkerBulletMixin(EntityType entityType, Level level) { super(entityType, level); } /** * Code taken from {@link net.minecraft.world.entity.projectile.arrow.AbstractArrow} */ @Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/projectile/ShulkerBullet;setPos(Lnet/minecraft/world/phys/Vec3;)V")) private void addMissingBubbleParticles(CallbackInfo ci) { if (this.isInWater()) { Vec3 vec3 = this.position(); Vec3 vec32 = this.getDeltaMovement(); for (int i = 0; i < 4; ++i) { this.level().addParticle(ParticleTypes.BUBBLE, vec3.x - vec32.x * (double) 0.25F, vec3.y - vec32.y * (double) 0.25F, vec3.z - vec32.z * (double) 0.25F, vec32.x, vec32.y, vec32.z); } } } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc223153/BlocksMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc223153; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.SoundType; import net.minecraft.world.level.block.state.BlockBehaviour; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; @BugFix(id = "MC-223153", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Block of Raw Copper uses stone sounds instead of copper sounds") @Mixin(Blocks.class) public class BlocksMixin { @Definition(id = "register", method = "Lnet/minecraft/world/level/block/Blocks;register(Ljava/lang/String;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)Lnet/minecraft/world/level/block/Block;") @Expression("register('raw_copper_block', ?)") @ModifyArg(method = "", at = @At("MIXINEXTRAS:EXPRESSION")) private static BlockBehaviour.Properties addCopperSound(BlockBehaviour.Properties settings) { return settings.sound(SoundType.COPPER); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc224729/ChunkMapMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc224729; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ChunkMap; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ProtoChunk; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; import java.util.function.Predicate; @BugFix(id = "MC-224729", category = FixCategory.BASIC, env = BugFix.Env.SERVER, modConflicts = {"chunksavingfix", "moonrise"}, description = "Partially generated chunks are not saved in some situations") @Mixin(ChunkMap.class) public class ChunkMapMixin { @Definition(id = "filter", method = "Ljava/util/stream/Stream;filter(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;") @Definition(id = "wasAccessibleSinceLastSave", method = "Lnet/minecraft/server/level/ChunkHolder;wasAccessibleSinceLastSave()Z") @Expression("?.filter(::wasAccessibleSinceLastSave)") @ModifyArg(method = "saveAllChunks", at = @At("MIXINEXTRAS:EXPRESSION")) private Predicate alwaysAccessibleFlushSave(Predicate predicate) { return (chunkHolder) -> true; } @ModifyArg(method = "saveAllChunks", at = @At(value = "INVOKE", target = "Ljava/util/stream/Stream;filter(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;", ordinal = 1)) private Predicate saveProtoChunks(Predicate predicate) { return (c) -> predicate.test(c) || c instanceof ProtoChunk; } @ModifyExpressionValue(method = "saveChunkIfNeeded", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ChunkHolder;wasAccessibleSinceLastSave()Z")) private boolean alwaysAccessibleChunkSave(boolean accessible) { return true; } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc226961/ExperienceOrbMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc226961; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.tags.FluidTags; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.ExperienceOrb; import net.minecraft.world.level.Level; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-226961", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Experience Orbs treat flowing lava as a full block") @Mixin(ExperienceOrb.class) public abstract class ExperienceOrbMixin extends Entity { public ExperienceOrbMixin(EntityType entityType, Level level) { super(entityType, level); } @Definition(id = "getFluidState", method = "Lnet/minecraft/world/level/Level;getFluidState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/material/FluidState;") @Definition(id = "is", method = "Lnet/minecraft/world/level/material/FluidState;is(Lnet/minecraft/tags/TagKey;)Z") @Definition(id = "LAVA", field = "Lnet/minecraft/tags/FluidTags;LAVA:Lnet/minecraft/tags/TagKey;") @Expression("?.getFluidState(?).is(LAVA)") @ModifyExpressionValue(method = "tick", at = @At("MIXINEXTRAS:EXPRESSION")) private boolean checkEyeLevel(boolean original) { return this.isEyeInFluid(FluidTags.LAVA); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc227008/EnderManMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc227008; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.monster.EnderMan; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-227008", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Enderman constantly tries to teleport when in a boat or a minecart under daylight") @Mixin(EnderMan.class) public class EnderManMixin { // Target getLightLevelDependentMagicValue so we get an EnderMan instance without needing to cast `this`. As long as this returns <= 0.5F the enderman won't teleport @WrapOperation( method = "customServerAiStep", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/monster/EnderMan;getLightLevelDependentMagicValue()F" ) ) private float checkRiding(EnderMan instance, Operation original) { return instance.isPassenger() ? 0F : original.call(instance); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc227337/ShulkerBulletMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc227337; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvents; import net.minecraft.world.entity.projectile.ShulkerBullet; import net.minecraft.world.phys.EntityHitResult; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-227337", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "When a shulker bullet hits an entity, the explodes sound is not played and particles are not produced") @Mixin(ShulkerBullet.class) public class ShulkerBulletMixin { @Inject( method = "onHitEntity", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/phys/EntityHitResult;getEntity()Lnet/minecraft/world/entity/Entity;" ) ) private void playSoundAndDisplayParticles(EntityHitResult hitResult, CallbackInfo ci) { ShulkerBullet instance = (ShulkerBullet) (Object) this; ((ServerLevel) instance.level()).sendParticles(ParticleTypes.EXPLOSION, instance.getX(), instance.getY(), instance.getZ(), 2, 0.2D, 0.2D, 0.2D, 0.0D); instance.playSound(SoundEvents.SHULKER_BULLET_HIT, 1.0F, 1.0F); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc231743/FlowerPotBlockMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc231743; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.core.BlockPos; import net.minecraft.stats.Stats; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.FlowerPotBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @BugFix(id = "MC-231743", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "\"minecraft.used:minecraft.\" doesn't increase when placing plants into flower pots") @Mixin(FlowerPotBlock.class) public class FlowerPotBlockMixin { @Inject( method = "useItemOn", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;awardStat(Lnet/minecraft/resources/Identifier;)V" ) ) private void onIncrementPottedPlantStat( CallbackInfoReturnable cir, @Local(argsOnly = true, name = "player") Player player, @Local(argsOnly = true, name = "hand") InteractionHand hand ) { player.awardStat(Stats.ITEM_USED.get(player.getItemInHand(hand).getItem())); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc232869/StriderMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc232869; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.Difficulty; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.animal.Animal; import net.minecraft.world.entity.monster.Strider; import net.minecraft.world.level.Level; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-232869", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Adult striders can spawn with saddles in peaceful mode") @Mixin(Strider.class) public abstract class StriderMixin extends Animal { protected StriderMixin(EntityType entityType, Level world) { super(entityType, world); } @Definition(id = "nextInt", method = "Lnet/minecraft/util/RandomSource;nextInt(I)I") @Expression("?.nextInt(30) == 0") @ModifyExpressionValue(method = "finalizeSpawn", at = @At("MIXINEXTRAS:EXPRESSION")) private boolean preventPeacefulJocky(boolean original) { return original && level().getDifficulty() != Difficulty.PEACEFUL; } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc245394/RaidMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc245394; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.sounds.SoundSource; import net.minecraft.world.entity.raid.Raid; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; @BugFix(id = "MC-245394", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "The sounds of raid horns blaring aren't controlled by the correct sound slider") @Mixin(Raid.class) public class RaidMixin { @ModifyArg( method = "playSound", at = @At( value = "INVOKE", target = "Lnet/minecraft/network/protocol/game/ClientboundSoundPacket;(Lnet/minecraft/core/Holder;Lnet/minecraft/sounds/SoundSource;DDDFFJ)V" ) ) private SoundSource modifyRaidSoundSource(SoundSource soundSource) { return SoundSource.HOSTILE; } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc263999/BreakDoorGoalMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc263999; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.llamalad7.mixinextras.sugar.Share; import com.llamalad7.mixinextras.sugar.ref.LocalRef; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.goal.BreakDoorGoal; import net.minecraft.world.entity.ai.goal.DoorInteractGoal; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; /** * removeBlock is called before querying the block state of the door, * which breaks the level event that causes particles */ @BugFix(id = "MC-263999", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Zombies breaking doors do not show break particles") @Mixin(BreakDoorGoal.class) public class BreakDoorGoalMixin extends DoorInteractGoal { public BreakDoorGoalMixin(Mob mob) { super(mob); } // Store the block state before removal @Inject( method = "tick", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/level/Level;removeBlock(Lnet/minecraft/core/BlockPos;Z)Z" ) ) private void storeBlockStatePreRemoval( CallbackInfo ci, @Share("blockState") LocalRef blockStateRef ) { blockStateRef.set(this.mob.level().getBlockState(this.doorPos)); } // Use the stored block state for the level event @Definition(id = "levelEvent", method = "Lnet/minecraft/world/level/Level;levelEvent(ILnet/minecraft/core/BlockPos;I)V") @Definition(id = "getId", method = "Lnet/minecraft/world/level/block/Block;getId(Lnet/minecraft/world/level/block/state/BlockState;)I") @Definition(id = "getBlockState", method = "Lnet/minecraft/world/level/Level;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;") @Definition(id = "doorPos", field = "Lnet/minecraft/world/entity/ai/goal/BreakDoorGoal;doorPos:Lnet/minecraft/core/BlockPos;") @Expression("?.levelEvent(2001, ?, getId(@(?.getBlockState(?.doorPos))))") @WrapOperation(method = "tick", at = @At("MIXINEXTRAS:EXPRESSION")) private BlockState injectCorrectBlockState( Level instance, BlockPos pos, Operation original, @Share("blockState") LocalRef blockStateRef ) { return blockStateRef.get(); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc264285/CreeperMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc264285; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.core.component.DataComponents; import net.minecraft.world.entity.monster.Creeper; import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-264285", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Unbreakable flint and steels are completely consumed when igniting a creeper") @Mixin(Creeper.class) public class CreeperMixin { /** * Igniting a creeper shrinks the stack size by 1 if the item is not damageable. * The intention of this was for consumable items which have no durability (has no max damage tag). * However, items with the unbreakable tag makes them not damageable, so they get consumed incorrectly. *

* The injection point is within a `!` gate, so the return value is true if the stack is not to be shrunk. */ @WrapOperation( method = "mobInteract", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;isDamageableItem()Z" ) ) private boolean shouldNotShrinkStack(ItemStack instance, Operation original) { return instance.has(DataComponents.MAX_DAMAGE); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc264979/SettingsMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc264979; import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.server.dedicated.Settings; import org.spongepowered.asm.mixin.Mixin; import java.nio.file.Files; import java.nio.file.Path; import java.util.Properties; @BugFix(id = "MC-264979", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Fresh installations print NoSuchFileException when attempting to load server.properties") @Mixin(Settings.class) public class SettingsMixin { @WrapMethod(method = "loadFromFile") private static Properties dontLoadMissingFile(Path file, Operation original) { if (Files.notExists(file)) { return new Properties(); } return original.call(file); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc267125/PlayerListMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc267125; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.players.PlayerList; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.List; @BugFix(id = "MC-267125", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Command suggestions for reloadable content are not affected by /reload") @Mixin(PlayerList.class) public abstract class PlayerListMixin { @Shadow @Final private List players; @Shadow public abstract void sendPlayerPermissionLevel(ServerPlayer player); @Inject(method = "reloadResources", at = @At("RETURN")) private void sendCommandSuggestions(CallbackInfo ci) { for (ServerPlayer player : this.players) { this.sendPlayerPermissionLevel(player); } } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc268617/FileUtilMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc268617; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.util.FileUtil; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; @BugFix(id = "MC-268617", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Structures can't be saved if the game directory is named in a certain way") @Mixin(FileUtil.class) public class FileUtilMixin { /** * Updates the valid path RegEx to include more valid file paths. This new filter will properly match all reserved file names, including many undocumented by Microsoft. * This fixes structure blocks for normal installations on old Modrinth instances or certain Linux scenarios such as Flatpak installations. * Can be tested on Windows by naming an instance "com.example". */ @Definition(id = "RESERVED_WINDOWS_FILENAMES", field = "Lnet/minecraft/util/FileUtil;RESERVED_WINDOWS_FILENAMES:Ljava/util/regex/Pattern;") @Definition(id = "compile", method = "Ljava/util/regex/Pattern;compile(Ljava/lang/String;I)Ljava/util/regex/Pattern;") @Expression("RESERVED_WINDOWS_FILENAMES = @(compile(?, ?))") @ModifyArg(method = "", at = @At("MIXINEXTRAS:EXPRESSION")) private static String fixWindowsReservedFilename(String regex) { return ".*\\.|(?:CON|PRN|AUX|NUL|CLOCK\\$|CONIN\\$|CONOUT\\$|(?:COM|LPT)[¹²³0-9])(?:\\..*)?"; } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc271899/StructureTemplateMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc271899; import com.google.common.collect.Maps; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.Shadow; import java.util.List; import java.util.Map; @BugFix(id = "MC-271899", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "StructureTemplate Palette's caches are not thread safe") @Mixin(StructureTemplate.Palette.class) public class StructureTemplateMixin { @Mutable @Shadow @Final private Map> cache = Maps.newConcurrentMap(); } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc272431/EnderDragonMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc272431; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.boss.enderdragon.EnderDragon; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-272431", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Ender Dragon incorrect vertical velocity causes erratic behavior") @Mixin(EnderDragon.class) public class EnderDragonMixin { @Definition(id = "yRotA", field = "Lnet/minecraft/world/entity/boss/enderdragon/EnderDragon;yRotA:F") @Expression("this.yRotA * @(0.01)") @ModifyExpressionValue(method = "aiStep", at = @At("MIXINEXTRAS:EXPRESSION")) private float fixTargetPath(float original) { return 0.1f; } @Definition(id = "setDeltaMovement", method = "Lnet/minecraft/world/entity/boss/enderdragon/EnderDragon;setDeltaMovement(Lnet/minecraft/world/phys/Vec3;)V") @Definition(id = "add", method = "Lnet/minecraft/world/phys/Vec3;add(DDD)Lnet/minecraft/world/phys/Vec3;") @Definition(id = "ydd", local = @Local(type = double.class, name = "ydd")) @Expression("this.setDeltaMovement(?.add(0.0, ydd * @(0.01), 0.0))") @ModifyExpressionValue(method = "aiStep", at = @At("MIXINEXTRAS:EXPRESSION")) private double fixVerticalVelocity(double value) { return 0.1; } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc297837/WaypointTransmitterMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc297837; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.waypoints.WaypointTransmitter; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-297837", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Locator bar shows players above you as being below you when they are high enough") @Mixin(WaypointTransmitter.class) public interface WaypointTransmitterMixin { /** * {@link WaypointTransmitter#isReallyFar(LivingEntity, ServerPlayer)} was being used to determine whether * waypoints should use azimuth distance (far away) or chunk/block distance (close/closer by). *

* The azimuth distance provides only relative yRot, which means the pitch uses the horizon, * not the waypoint itself. *

* Even when the waypoint is in the same chunk as the entity, the azimuth distance was used because it was * over 332 blocks away, just vertically, not horizontally, as I assume it was intended. *

* This mixin fixes the bug by using the block distance instead of the azimuth distance, * by changing the distance calculation to only use horizontal distance. */ @WrapOperation( method = "isReallyFar", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;distanceTo(Lnet/minecraft/world/entity/Entity;)F" ) ) private static float useOnlyHorizontalDistance(LivingEntity entity1, Entity entity2, Operation original) { double xDist = entity1.getX() - entity2.getX(); double zDist = entity1.getZ() - entity2.getZ(); return (float) Math.hypot(xDist, zDist); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc298066/LivingEntityMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc298066; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.level.Level; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-298066", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Directly entering a bed from a mount places the player in the wrong place") @Mixin(LivingEntity.class) public abstract class LivingEntityMixin extends Entity { public LivingEntityMixin(EntityType entityType, Level level) { super(entityType, level); } // This is just a hacky fix to force the player into the correct position @Inject(method = "setPosToBed", at = @At("TAIL")) private void teleportToBed(BlockPos bedPosition, CallbackInfo ci) { this.teleportTo(bedPosition.getX() + 0.5, bedPosition.getY() + 0.6875, bedPosition.getZ() + 0.5); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc30391/LivingEntityMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc30391; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.animal.chicken.Chicken; import net.minecraft.world.entity.boss.wither.WitherBoss; import net.minecraft.world.entity.monster.Blaze; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-30391", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Chickens, blazes and the wither emit particles when landing from a height, despite falling slowly") @Mixin(LivingEntity.class) public class LivingEntityMixin { @ModifyExpressionValue( method = "checkFallDamage", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;isAir()Z" ) ) private boolean shouldntSpawnParticles(boolean isAir) { LivingEntity self = (LivingEntity) (Object) this; return isAir || self instanceof Chicken || self instanceof Blaze || self instanceof WitherBoss; } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc44654/EntityMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc44654; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-44654", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Some entities don't update position to the client when teleported") @Mixin(Entity.class) public abstract class EntityMixin { @Shadow public abstract EntityType getType(); @Shadow public boolean needsSync; /** * Since the update interval is set to infinity, the position will never get updated. * To fix, we mark velocity as dirty via needsSync to force an update. * * We inject precisely here as the target is only called when `!firstTick && isServerLevel`, * since this is where the issue occurs. */ @Inject( method = "setPosRaw", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;isRemoved()Z" ) ) private void forceClientUpdate(CallbackInfo ci) { if (this.getType().updateInterval() == Integer.MAX_VALUE) { this.needsSync = true; } } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc7569/RconConsoleSourceMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc7569; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.network.chat.Component; import net.minecraft.server.rcon.RconConsoleSource; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-7569", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "RCON output has newlines removed") @Mixin(RconConsoleSource.class) public class RconConsoleSourceMixin { @Shadow @Final private StringBuffer buffer; @Inject(method = "sendSystemMessage", at = @At("RETURN")) private void appendNewline(Component message, CallbackInfo ci) { buffer.append(System.lineSeparator()); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc82263/EnderDragonMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc82263; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.boss.enderdragon.EnderDragon; import net.minecraft.world.level.Level; import org.spongepowered.asm.mixin.Mixin; @BugFix(id = "MC-82263", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Ender dragon produces regular hurt sound on final hit") @Mixin(EnderDragon.class) public class EnderDragonMixin extends Mob { protected EnderDragonMixin(EntityType entityType, Level level) { super(entityType, level); } // The death sound plays regardless of what this is set to, it's not set in the target class and instead uses LivingEntity's GENERIC_DEATH @Override protected SoundEvent getDeathSound() { return null; } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc84661/MobEffectsMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc84661; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.effect.MobEffectCategory; import net.minecraft.world.effect.MobEffects; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-84661", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Glowing is considered a positive effect in potion item tooltips") @Mixin(MobEffects.class) public class MobEffectsMixin { @Definition(id = "NEUTRAL", field = "Lnet/minecraft/world/effect/MobEffectCategory;NEUTRAL:Lnet/minecraft/world/effect/MobEffectCategory;") @Expression("new ?(@(NEUTRAL), 745784)") // this colour refers to bad omen effect exclusively @ModifyExpressionValue(method = "", at = @At("MIXINEXTRAS:EXPRESSION")) private static MobEffectCategory badOmenEffectCategory(MobEffectCategory arg) { return MobEffectCategory.HARMFUL; } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc88371/DragonLandingPhaseMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc88371; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.boss.enderdragon.phases.DragonLandingPhase; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-88371", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Ender Dragon flies down in the void when the exit portal is destroyed") @Mixin(DragonLandingPhase.class) public class DragonLandingPhaseMixin { @ModifyExpressionValue( method = "doServerTick", at = @At( value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;getHeightmapPos(Lnet/minecraft/world/level/levelgen/Heightmap$Types;Lnet/minecraft/core/BlockPos;)Lnet/minecraft/core/BlockPos;" ) ) private BlockPos getLandingPos(BlockPos pos) { if (pos.getY() == 0) { // average height of portal return pos.atY(65); } return pos; } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc89146/ChunkAccessMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc89146; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.chunk.ChunkAccess; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.Shadow; import java.util.Map; @BugFix(id = "MC-89146", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Pistons forget update when being reloaded") @Mixin(ChunkAccess.class) public class ChunkAccessMixin { @Shadow @Final @Mutable protected Map blockEntities = new Object2ObjectLinkedOpenHashMap<>(); } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc93018/AnimalMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc93018; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.animal.Animal; import net.minecraft.world.entity.animal.wolf.Wolf; import net.minecraft.world.entity.player.Player; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-93018", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Wild wolves show breeding hearts but do not breed") @Mixin(Animal.class) public class AnimalMixin { /** * Only make wolves love player if they are tamed when fed */ @WrapWithCondition( method = "mobInteract", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/animal/Animal;setInLove(Lnet/minecraft/world/entity/player/Player;)V" ) ) private boolean loveCondition(Animal animal, Player player) { return !(animal instanceof Wolf wolf) || wolf.isTame(); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/basic/mc94054/WallClimberNavigationMixin.java ================================================ package dev.isxander.debugify.mixins.basic.mc94054; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.ai.navigation.WallClimberNavigation; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-94054", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Cave spiders spin around when walking") @Mixin(WallClimberNavigation.class) public class WallClimberNavigationMixin { @ModifyExpressionValue( method = "tick", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/Mob;getBbWidth()F" ) ) private float fixSpiderSpinning(float bbWidth) { return Math.max(bbWidth, 1.0F); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/errorhandler/CrashReportMixin.java ================================================ package dev.isxander.debugify.mixins.errorhandler; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import dev.isxander.debugify.error.CrashReportInjector; import net.minecraft.CrashReport; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(CrashReport.class) public class CrashReportMixin { @Definition(id = "systemReport", field = "Lnet/minecraft/CrashReport;systemReport:Lnet/minecraft/SystemReport;") @Definition(id = "appendToCrashReportString", method = "Lnet/minecraft/SystemReport;appendToCrashReportString(Ljava/lang/StringBuilder;)V") @Expression("this.systemReport.appendToCrashReportString(?)") @Inject(method = "getDetails(Ljava/lang/StringBuilder;)V", at = @At("MIXINEXTRAS:EXPRESSION")) private void appendCrashReport(StringBuilder sb, CallbackInfo ci) { CrashReportInjector.addDetailsToCrashReport(sb); } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/gameplay/mc136249/LivingEntityMixin.java ================================================ package dev.isxander.debugify.mixins.gameplay.mc136249; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.world.entity.LivingEntity; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @BugFix(id = "MC-136249", category = FixCategory.GAMEPLAY, env = BugFix.Env.SERVER, description = "Wearing boots enchanted with depth strider decreases the strength of the riptide enchantment") @Mixin(LivingEntity.class) public abstract class LivingEntityMixin{ @Shadow public abstract boolean isAutoSpinAttack(); @Definition(id = "getAttributeValue", method = "Lnet/minecraft/world/entity/LivingEntity;getAttributeValue(Lnet/minecraft/core/Holder;)D") @Definition(id = "WATER_MOVEMENT_EFFICIENCY", field = "Lnet/minecraft/world/entity/ai/attributes/Attributes;WATER_MOVEMENT_EFFICIENCY:Lnet/minecraft/core/Holder;") @Expression("this.getAttributeValue(WATER_MOVEMENT_EFFICIENCY)") @ModifyExpressionValue(method = "travelInWater", at = @At("MIXINEXTRAS:EXPRESSION")) private double checkRiptide(double original) { return this.isAutoSpinAttack() ? 0 : original; } } ================================================ FILE: src/main/java/dev/isxander/debugify/mixins/gameplay/mc8187/TreeFeatureMixin.java ================================================ /* * Copyright (C) 2023, Ampflower * * This software is subject to the terms of the Zlib License. * If a copy was not distributed with this file, you can obtain one at * https://github.com/Modflower/8187/blob/trunk/LICENSE * * Source: https://github.com/Modflower/8187 * SPDX-License-Identifier: Zlib */ package dev.isxander.debugify.mixins.gameplay.mc8187; import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.Debugify; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; import net.minecraft.core.BlockPos; import net.minecraft.world.level.LevelSimulatedReader; import net.minecraft.world.level.levelgen.feature.TreeFeature; import net.minecraft.world.level.levelgen.feature.configurations.TreeConfiguration; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.Slice; /** * Fixes the offsets for 2x2 saplings at starting height * fixing MC-8187. *

* This code is provided as-is minus differences in mappings by Ampflower. *

* Original mod: {@literal flwr-8187} * (GitHub). * * @author Ampflower * @since 1.20.1+1.2 **/ @BugFix(id = "MC-8187", category = FixCategory.GAMEPLAY, env = BugFix.Env.SERVER, modConflicts = "flwr-8187", description = "Two-by-two arrangements of jungle or spruce saplings cannot grow when there are adjacent blocks located north or west of the sapling formation") @Mixin(TreeFeature.class) public class TreeFeatureMixin { /** * Corrects the starting value if the trunk's minimum size is {@literal 1} * and the starting value is {@literal -1} by returning {@literal 0}. *

* I should note there: This isn't an optimal bugfix as it is possible for poorly implemented 3x3 trees to erroneously check only a 2x2. */ // 2026 Xander: holy moly i just expressionified the hell out of this mixin you're so welcome @Definition(id = "x", local = @Local(type = int.class, name = "x")) @Definition(id = "z", local = @Local(type = int.class, name = "z")) @Definition(id = "r", local = @Local(type = int.class, name = "r")) @Expression({ "x = @(-r)", "z = @(-r)" }) @ModifyExpressionValue(method = "getMaxFreeTreeHeight", at = @At("MIXINEXTRAS:EXPRESSION")) private int fixOffsetNew( int start, @Local(argsOnly = true, name = "maxTreeHeight") int maxTreeHeight, @Local(argsOnly = true, name = "config") TreeConfiguration config ) { // Roughly height == 0 && trunk == 1 if (Debugify.isGameplayFixesEnabled() && start == -1 && config.minimumSize.getSizeAtHeight(maxTreeHeight, 0) == 1) { return 0; } return start; } } ================================================ FILE: src/main/resources/assets/debugify/lang/el_gr.json ================================================ { "debugify.name": "Debugify", "debugify.basic": "Βασικές Διορθώσεις", "debugify.gameplay": "Διορθώσεις Gameplay", "debugify.gameplay.warning": "ΠΡΟΣΟΧΗ: Αυτή η κατηγορία περιέχει διορθώσεις οι οποίες μπορεί να σου δίνουν άδικα πλεονέκτηματα!", "debugify.gameplay.enable_in_multiplayer": "Ενεργοποίηση στο Παιχνίδι Πολλαπλών Παικτών", "debugify.misc": "Διάφορα", "debugify.misc.default_disabled": "Αυτόματη Απενεργοποίηση", "debugify.misc.default_disabled.description": "Απενεργοποιεί τις νεές προσθήκες διορθώσεων.", "debugify.env.client": "Πελάτη", "debugify.env.server": "Διακομιστή" } ================================================ FILE: src/main/resources/assets/debugify/lang/en_us.json ================================================ { "debugify.name": "Debugify", "debugify.basic": "Basic Fixes", "debugify.gameplay": "Gameplay Fixes", "debugify.gameplay.warning": "WARNING: This category contains fixes that may be an unfair advantage!", "debugify.gameplay.enable_in_multiplayer": "Enable In Multiplayer", "debugify.fix.enabled": "Fixed", "debugify.fix.disabled": "Not fixed", "debugify.fix.unavailable": "Unavailable", "debugify.error.conflict": "%s fix is incompatible with the mod '%s'", "debugify.error.os": "%s only applies to %s", "debugify.error.mixin_error": "Failed to load %s, check the log for more information.", "debugify.error.mixin_error.text": "Errored", "debugify.os.windows": "Windows", "debugify.os.macos": "macOS", "debugify.os.linux": "Linux", "debugify.os.solaris": "Solaris", "debugify.misc": "Misc", "debugify.misc.default_disabled": "Default to Disabled", "debugify.misc.default_disabled.description": "Default new bug fixes to be disabled rather than enabled.", "debugify.env.client": "Client", "debugify.env.client.desc": "Fixes that only apply on the client.", "debugify.env.server": "Main", "debugify.env.server.desc": "Fixes that apply to both the client and the server, and common code between them.", "debugify.no_yacl.title": "YetAnotherConfigLib not installed!", "debugify.no_yacl.description": "To configure Debugify using a GUI, you must install %s, this is the library used to make this functionality available. Otherwise, you can configure using the JSON file stored at '%s'.", "debugify.mc_237493.header": "Telemetry Disabled By Debugify", "debugify.mc_237493.line": "You chose '%s' on the telemetry option, so Debugify is preventing any connection with telemetry services from Mojang. This is provided by Debugify for fix MC-237493.", "debugify.mc_237493.tooltip.off": "'%s' completely disables any connection to Mojang telemetry services. (Debugify MC-237493)", "debugify.mc_237493.tooltip.minimal": "'%s' includes only the information Mojang deems required.", "debugify.mc_237493.tooltip.all": "'%s' includes all of minimal and option telemetry.", "debugify.fix_explanation.mc-46503": "Clears shader effects on respawn.", "debugify.fix_explanation.mc-55347": "Clears titles on disconnect.", "debugify.fix_explanation.mc-61489": "Disabled by default because some players or mods might prefer the original book GUI position.", "debugify.fix_explanation.mc-79545": "Clamps the experience level to the integer limit only when rendering.", "debugify.fix_explanation.mc-93384": "Adds the eye height to the particle spawn location.", "debugify.fix_explanation.mc-105068": "Make shield break sound a local sound.", "debugify.fix_explanation.mc-108948": "The issue is that the client does not run the same calculations as the server. When no one is controlling the boat, the client does not run physics on the boat, causing a client de-sync. This fix simply tells the client to run some physics calculations on the boat.", "debugify.fix_explanation.mc-111516": "Modifies a math acos calculation to make sure the result is not more than 1.0.", "debugify.fix_explanation.mc-118740": "Displays the crosshair attack cooldown when performing a right click action.", "debugify.fix_effect.mc-118740": "This also fixes MC-116510: Attack indicator doesn't indicate (most of the time) that breaking instantly-mineable blocks resets your attack", "debugify.fix_explanation.mc-112730": "Prevents beacons and other block entities from being added to the local block entity renderer list if they are already added to the global list.", "debugify.fix_explanation.mc-122477": "Prevents first two keyboard polls after an edit box is initialized, e.g. the chat box.", "debugify.fix_explanation.mc-123739": "Sorts recipe book entries by their identifier.", "debugify.fix_explanation.mc-143474": "Copies over the selected item slot when generating the new local player after respawn.", "debugify.fix_effect.mc-143474": "This also fixes MC-12062: Hotbar selection resets to the far left when exiting the end", "debugify.fix_explanation.mc-159163": "Removes pose data from entity data packet handling.", "debugify.fix_effect.mc-159163": "This will prevent the client from syncing pose data with the server, and purely uses the client to decide the pose.", "debugify.fix_explanation.mc-162253": "Stops a client light update when entering a chunk.", "debugify.fix_explanation.mc-165381": "Cancels destroying block when the client drops an item.", "debugify.fix_explanation.mc-176559": "Does not consider item durability when comparing a change in item when checking if block breaking should reset.", "debugify.fix_explanation.mc-197260": "Overrides the light level passed to the armour stand renderer with a maximum of: the block below the armor stand, bottom of the armor stand, top of the armor stand and the block above of the armor stand.", "debugify.fix_explanation.mc-237493": "Adds an option in the telemetry menu to completely disable telemetry. Telemetry is disabled by overriding all outgoing telemetry events to be an empty telemetry event, which is not sent.", "debugify.fix_explanation.mc-231097": "When dropping an item, the client will send a \"release using item\" packet, if the player is currently using an item.", "debugify.fix_effect.mc-231097": "This can cause very strict anti-cheats, such as Anti-Gaming-Chair, to flag \"invalid packet order\", which may result in a ban.", "debugify.fix_explanation.mc-2025": "Due to floating point inaccuracies, sometimes the hitbox of entities end up being slightly smaller than desired. Then, if this happens before the entities are pushed against each-other, they will intersect with the wall. Then, when the AABB is recalculated on chunk load, they will be determined as inside the wall, where they are then pushed. This fix simply writes an 'AABB' tag to entity NBT data with double-precision hitbox sizes which then get loaded back in.", "debugify.fix_effect.mc-2025": "This fix means loading Debugify for the first time will not fix the issue until the chunks are saved and loaded with Debugify.", "debugify.fix_explanation.mc-7569": "Appends a new line to the end of every system message.", "debugify.fix_explanation.mc-30391": "Adds edge-case checks for chicken, blaze and the wither to fall damage spawn particles to not spawn them.", "debugify.fix_explanation.mc-69216": "Discards fishing hook entity on change to spectator.", "debugify.fix_explanation.mc-72151": "Wolves have a custom function to modify the amount of damage they take, which transforms input damage 0 to 0.5, this fix checks if the damage is 0.5 and changes it back to 0.", "debugify.fix_explanation.mc-88371": "Sets the dragon landing Y position to 65 if the center spawn has been destroyed.", "debugify.fix_explanation.mc-89146": "Provides a strict save order of tile entities, to match the update order which then allows initial update of tile entities to be in the correct order.", "debugify.fix_explanation.mc-93018": "Only initiate breeding if the wolf is tamed.", "debugify.fix_explanation.mc-100991": "Notifies the damage tracker of a thrown fishing hook damaging the entity with 0 damage, like snowballs.", "debugify.fix_explanation.mc-119417": "Stops player from sleeping when they change to spectator.", "debugify.fix_explanation.mc-119754": "Tells firework entities that players are not elytra flying if in spectator.", "debugify.fix_explanation.mc-121706": "Entities with a ranged bow attack goal are forced to look at their target.", "debugify.fix_explanation.mc-121903": "Adds NBT tag 'LastExecuted' to command blocks to save and load their last executed property.", "debugify.fix_explanation.mc-124117": "Sends players packets to update all their effects, their experience and their abilities after cross dimensional teleport.", "debugify.fix_explanation.mc-132878": "Spawns breaking particles when armour stands are hurt.", "debugify.fix_explanation.mc-134110": "Correctly rotates double chests when a structure that is mirrored is placed.", "debugify.fix_explanation.mc-135971": "Overrides CTRL+Q behaviour in crafting slot to repeatedly CTRL+Q until there are no items left in the crafting slot.", "debugify.fix_explanation.mc-155509": "Checks if the pufferfish is alive before attempting to sting the player.", "debugify.fix_explanation.mc-159283": "Casts 32-bit integers to 64-bit equivalents to prevent integer overflow at high X and Z values.", "debugify.fix_effect.mc-159283": "Affects world generation.", "debugify.fix_explanation.mc-160095": "If cacti encounter a piston head, the block that is being moved by the piston is considered instead of the piston.", "debugify.fix_explanation.mc-179072": "Checks if the entity the creeper sees is an enemy before igniting.", "debugify.fix_explanation.mc-183990": "When a mob is ticked, it checks to see if its target is dead, and removes it if so. This fix also applies to a long list of entities that have group attacks, not just silverfish.", "debugify.fix_explanation.mc-193343": "Removes soul speed if player is a spectator.", "debugify.fix_explanation.mc-199467": "Modifies the input to sin and cos functions, which wraps the input from 0 to 2pi. This prevents any integer overflows occurring. Whilst this issue is reportedly an issue of the client, the root cause is in both environments, hence it's located in main.", "debugify.fix_explanation.mc-200418": "Dismounts baby villagers from chickens upon conversion.", "debugify.fix_explanation.mc-206922": "Items with an age less than 9 ticks are not removed from lightning strikes.", "debugify.fix_explanation.mc-215530": "Resets frozen time when the player changes to spectator.", "debugify.fix_explanation.mc-219981": "Sets the zombie's health to its new max health minus whatever damage it has taken.", "debugify.fix_explanation.mc-224729": "Always saves ProtoChunks even if the chunk save predicate returns false.", "debugify.fix_explanation.mc-226961": "Uses XP Orbs' eye height to determine if it is inside lava.", "debugify.fix_effect.mc-226961": "XP Orbs are killed shortly upon touching lava instead of bouncing.", "debugify.fix_explanation.mc-298225": "Fixes skybox getting cut off (i.e. holes/gaps) at low render distances by increasing far plane distance.", "debugify.fix_explanation.mc-268617": "Updates the RegEx filter to include all valid path locations. This allows using structure blocks in certain launchers such as Modrinth or any Linux Flatpak launcher.", "debugify.fix_explanation.mc-272431": "Fixes the dragon's velocity when traveling to path nodes, making it able to properly traverse to its destination and not circle above it.", "debugify.fix_effect.mc-272431": "Prevents zero and one-cycling the dragon as the dragon will no longer slowly perch on the end fountain or above travel nodes.", "debugify.fix_explanation.mc-297837": "Only use horizontal distance when calculating which waypoint transmitter to use, since large distances use azimuthal distance, which guesses pitch via horizon angle.", "debugify.fix_effect.mc-297837": "This allows clients to get exact position of players even when they are far away, but only vertically.", "debugify.fix_explanation.mc-299115": "The owner's reference is converted to an entity on deflection. This conversion fails if the owner is offline." } ================================================ FILE: src/main/resources/assets/debugify/lang/es_ar.json ================================================ { "debugify.name": "Debugify", "debugify.basic": "Arreglos básicos", "debugify.gameplay": "Arreglos de jugabilidad", "debugify.gameplay.warning": "ADVERTENCIA: ¡Esta categoría contiene arreglos que podrían ser una ventaja injusta!", "debugify.gameplay.enable_in_multiplayer": "Habilitar en multijugador", "debugify.fix.enabled": "Arreglado", "debugify.fix.disabled": "No arreglado", "debugify.fix.unavailable": "No disponible", "debugify.error.conflict": "La corrección %s es incompatible con el mod '%s'", "debugify.error.os": "%s solo se aplica a %s", "debugify.error.mixin_error": "Falló la carga de %s, revisá el registro para más información.", "debugify.error.mixin_error.text": "Error", "debugify.os.windows": "Windows", "debugify.os.macos": "macOS", "debugify.os.linux": "Linux", "debugify.os.solaris": "Solaris", "debugify.misc": "Misceláneo", "debugify.misc.default_disabled": "Predeterminado desactivado", "debugify.misc.default_disabled.description": "Por defecto, las nuevas correcciones de errores estarán desactivadas en vez de activadas.", "debugify.env.client": "Cliente", "debugify.env.client.desc": "Arreglos que solo se aplican en el cliente.", "debugify.env.server": "Principal", "debugify.env.server.desc": "Arreglos que se aplican tanto al cliente como al servidor, y al código común entre ambos.", "debugify.no_yacl.title": "¡YetAnotherConfigLib no instalado!", "debugify.no_yacl.description": "Para configurar Debugify desde una interfaz gráfica, necesitás instalar %s. Es la librería que habilita esta funcionalidad. Si no, podés configurarlo manualmente desde el archivo JSON ubicado en '%s'.", "debugify.mc_237493.header": "Telemetría deshabilitada por Debugify", "debugify.mc_237493.line": "Elegiste '%s' en la opción de telemetría, así que Debugify está bloqueando cualquier conexión a servicios de telemetría de Mojang. Esto lo proporciona Debugify para corregir el error MC-237493.", "debugify.mc_237493.tooltip.off": "'%s' desactiva completamente cualquier conexión a los servicios de telemetría de Mojang. (Debugify MC-237493)", "debugify.mc_237493.tooltip.minimal": "'%s' solo incluye la información que Mojang considera necesaria.", "debugify.mc_237493.tooltip.all": "'%s' incluye toda la información mínima y opcional de telemetría.", "debugify.fix_explanation.mc-46503": "Limpia los efectos de sombreado al reaparecer.", "debugify.fix_explanation.mc-55347": "Limpia los títulos al desconectarse.", "debugify.fix_explanation.mc-79545": "Restringe el nivel de experiencia al límite de enteros solamente al renderizar.", "debugify.fix_explanation.mc-93384": "Agrega la altura de los ojos a la ubicación de aparición de partículas.", "debugify.fix_explanation.mc-105068": "Hace que el sonido de ruptura de escudo sea local.", "debugify.fix_explanation.mc-108948": "El cliente no ejecuta los mismos cálculos de física del bote que el servidor. Esta corrección hace que el cliente también realice esos cálculos cuando nadie está controlando el bote.", "debugify.fix_explanation.mc-111516": "Corrige un cálculo matemático de 'acos' para que el resultado no supere 1.0.", "debugify.fix_explanation.mc-118740": "Muestra el cooldown del ataque en la mira al hacer clic derecho.", "debugify.fix_effect.mc-118740": "También corrige MC-116510: El indicador de ataque no muestra (la mayoría de las veces) que romper bloques instantáneos reinicia el ataque.", "debugify.fix_explanation.mc-112730": "Evita que faros y otras entidades de bloque se agreguen a la lista local de renderizado si ya están en la lista global.", "debugify.fix_explanation.mc-122477": "Evita que las dos primeras entradas de teclado afecten después de abrir un cuadro de texto, como el chat.", "debugify.fix_explanation.mc-123739": "Ordena las entradas del libro de recetas por su identificador.", "debugify.fix_explanation.mc-143474": "Copia la ranura de objeto seleccionada al regenerar el jugador tras reaparecer.", "debugify.fix_effect.mc-143474": "También corrige MC-12062: La selección de la barra rápida se reinicia a la izquierda al salir del End.", "debugify.fix_explanation.mc-159163": "Elimina la sincronización de datos de pose del servidor al cliente.", "debugify.fix_effect.mc-159163": "Esto hará que la pose del jugador se determine solamente del lado del cliente.", "debugify.fix_explanation.mc-162253": "Evita una actualización de iluminación del cliente al cargar un chunk.", "debugify.fix_explanation.mc-165381": "Cancela la destrucción de bloques si el jugador tira un objeto.", "debugify.fix_explanation.mc-176559": "Ignora la durabilidad al comparar cambios de objetos durante la ruptura de bloques.", "debugify.fix_explanation.mc-197260": "Corrige la iluminación de las armaduras considerando su entorno inmediato.", "debugify.fix_explanation.mc-237493": "Agrega una opción en el menú de telemetría para desactivar completamente la telemetría.", "debugify.fix_explanation.mc-2025": "Corrige imprecisiones en las hitboxes de entidades escribiendo valores de mayor precisión en los datos NBT.", "debugify.fix_effect.mc-2025": "Esta corrección requiere guardar y volver a cargar los chunks afectados.", "debugify.fix_explanation.mc-7569": "Agrega un salto de línea a cada mensaje del sistema.", "debugify.fix_explanation.mc-30391": "Evita la aparición de partículas de daño para gallinas, blaze y el wither en caídas.", "debugify.fix_explanation.mc-69216": "Descarta el anzuelo si el jugador cambia a espectador.", "debugify.fix_explanation.mc-72151": "Corrige el cálculo de daño recibido por lobos cuando debería ser cero.", "debugify.fix_explanation.mc-88371": "Corrige la altura de aterrizaje del dragón cuando el pilar central fue destruido.", "debugify.fix_explanation.mc-89146": "Fuerza un orden de guardado de entidades de bloque consistente.", "debugify.fix_explanation.mc-93018": "Sólo permite la reproducción de lobos domesticados.", "debugify.fix_explanation.mc-100991": "Corrige el daño cero del anzuelo de pesca registrándolo correctamente.", "debugify.fix_explanation.mc-119417": "Evita que un jugador siga durmiendo si cambia a espectador.", "debugify.fix_explanation.mc-119754": "Corrige el estado de vuelo de elytra para jugadores en espectador.", "debugify.fix_explanation.mc-121706": "Fuerza a entidades con ataque a distancia a mirar a su objetivo.", "debugify.fix_explanation.mc-121903": "Agrega un tag NBT 'LastExecuted' para guardar el último estado de bloques de comando.", "debugify.fix_explanation.mc-124117": "Actualiza los efectos, experiencia y habilidades de un jugador tras una teletransportación entre dimensiones.", "debugify.fix_explanation.mc-132878": "Genera partículas de ruptura cuando dañan a un soporte de armaduras.", "debugify.fix_explanation.mc-134110": "Rota correctamente cofres dobles al colocar estructuras espejadas.", "debugify.fix_explanation.mc-135971": "Mejora el comportamiento de CTRL+Q para vaciar ranuras de crafteo.", "debugify.fix_explanation.mc-155509": "Evita que el pez globo ataque si está muerto.", "debugify.fix_explanation.mc-159283": "Convierte enteros de 32 bits a equivalentes de 64 para evitar desbordamientos numéricos en valores X y Z altos.", "debugify.fix_effect.mc-159283": "Afecta la generación del mundo.", "debugify.fix_explanation.mc-160095": "Corrige la colisión de cactus con cabezas de pistones móviles.", "debugify.fix_explanation.mc-179072": "Los creepers sólo se encienden si ven un enemigo real.", "debugify.fix_explanation.mc-183990": "Corrige que mobs sigan atacando objetivos muertos.", "debugify.fix_explanation.mc-193343": "Elimina el efecto de 'Soul Speed' en modo espectador.", "debugify.fix_explanation.mc-199467": "Corrige posibles desbordamientos enteros al usar funciones seno/coseno.", "debugify.fix_explanation.mc-200418": "Hace que los aldeanos bebés desmonten pollos al convertirse.", "debugify.fix_explanation.mc-206922": "Evita que rayos eliminen ítems con menos de 9 ticks de edad.", "debugify.fix_explanation.mc-215530": "Resetea el congelamiento al cambiar a espectador.", "debugify.fix_explanation.mc-224729": "Siempre guarda los ProtoChunks incluso si el predicado de guardado falla.", "debugify.fix_explanation.mc-298225": "Corrige cortes en el skybox (agujeros) con baja distancia de render, aumentando la distancia del plano lejano.", "debugify.fix_explanation.mc-268617": "Actualiza el filtro RegEx para incluir rutas válidas. Esto permite usar bloques de estructura en launchers como Modrinth o Flatpak en Linux." } ================================================ FILE: src/main/resources/assets/debugify/lang/es_mx.json ================================================ { "debugify.name": "Debugify", "debugify.basic": "Correcciones Básicas", "debugify.gameplay": "Correcciones de Jugabilidad", "debugify.gameplay.warning": "ADVERTENCIA: ¡Esta categoría contiene correcciones que pueden ser una ventaja injusta!", "debugify.gameplay.enable_in_multiplayer": "Habilitar en Multijugador", "debugify.fix.enabled": "Corregido", "debugify.fix.disabled": "No corregido", "debugify.fix.unavailable": "No disponible", "debugify.error.conflict": "La corrección %s es incompatible con el mod '%s'", "debugify.error.os": "%s solo se aplica a %s", "debugify.error.mixin_error": "Error al cargar %s, revisa el registro para obtener más información.", "debugify.error.mixin_error.text": "Con errores", "debugify.os.windows": "Windows", "debugify.os.macos": "macOS", "debugify.os.linux": "Linux", "debugify.os.solaris": "Solaris", "debugify.misc": "Misceláneo", "debugify.misc.default_disabled": "Desactivado por defecto", "debugify.misc.default_disabled.description": "Configura las nuevas correcciones para que estén desactivadas en lugar de activadas.", "debugify.env.client": "Cliente", "debugify.env.client.desc": "Correcciones que solo se aplican en el cliente.", "debugify.env.server": "Principal", "debugify.env.server.desc": "Correcciones que se aplican tanto en el cliente como en el servidor, y código común entre ellos.", "debugify.no_yacl.title": "¡YetAnotherConfigLib no está instalado!", "debugify.no_yacl.description": "Para configurar Debugify utilizando una interfaz gráfica, debes instalar %s, esta es la biblioteca utilizada para hacer esta funcionalidad disponible. De lo contrario, puedes configurarlo utilizando el archivo JSON almacenado en '%s'.", "debugify.mc_237493.header": "Telemetría desactivada por Debugify", "debugify.mc_237493.line": "Seleccionaste '%s' en la opción de telemetría, por lo que Debugify está evitando cualquier conexión con los servicios de telemetría de Mojang. Esto es proporcionado por Debugify para solucionar MC-237493.", "debugify.mc_237493.tooltip.off": "'%s' deshabilita por completo cualquier conexión a los servicios de telemetría de Mojang. (Debugify MC-237493)", "debugify.mc_237493.tooltip.minimal": "'%s' incluye solo la información que Mojang considera necesaria.", "debugify.mc_237493.tooltip.all": "'%s' incluye toda la información de minimal y telemetría opcional.", "debugify.fix_explanation.mc-55347": "Borra los títulos al desconectar.", "debugify.fix_explanation.mc-79545": "Limita el nivel de experiencia al límite entero solo al renderizar.", "debugify.fix_explanation.mc-93384": "Agrega la altura de los ojos a la ubicación de generación de partículas.", "debugify.fix_explanation.mc-108948": "El problema es que el cliente no ejecuta los mismos cálculos que el servidor. Cuando nadie está controlando el bote, el cliente no ejecuta la física en el bote, lo que causa una desincronización del cliente. Esta corrección simplemente le indica al cliente que ejecute algunos cálculos de física en el bote.", "debugify.fix_explanation.mc-111516": "Modifica un cálculo de acos matemático para asegurarse de que el resultado no sea mayor a 1.0", "debugify.fix_explanation.mc-112730": "Evita que los bloques de faros y otras entidades de bloque se agreguen a la lista de renderizado de entidades de bloque local si ya se han agregado a la lista global.", "debugify.fix_explanation.mc-122477": "Evita las dos primeras actualizaciones de teclado después de inicializar un cuadro de edición, por ejemplo, el cuadro de chat.", "debugify.fix_explanation.mc-123739": "Ordena las entradas del libro de recetas por su identificador.", "debugify.fix_explanation.mc-143474": "Copia la ranura de objeto seleccionada al generar el nuevo jugador local después de reaparecer.", "debugify.fix_explanation.mc-159163": "Elimina los datos de postura del manejo de paquetes de datos de entidad.", "debugify.fix_effect.mc-159163": "Esto evitará que el cliente sincronice los datos de postura con el servidor y utiliza únicamente el cliente para decidir la postura.", "debugify.fix_explanation.mc-162253": "Detiene una actualización de luz del cliente al ingresar a un fragmento.", "debugify.fix_explanation.mc-165381": "Cancela la destrucción del bloque cuando el cliente suelta un objeto", "debugify.fix_explanation.mc_176559": "No considera la durabilidad del objeto al comparar un cambio en el objeto al verificar si se debe restablecer la rotura del bloque.", "debugify.fix_explanation.mc-197260": "Anula el nivel de luz pasado al renderizador de soportes de armadura con un máximo de: el bloque debajo del soporte de armadura, la parte inferior del soporte de armadura, la parte superior del soporte de armadura y el bloque encima del soporte de armadura.", "debugify.fix_explanation.mc-237493": "Agrega una opción en el menú de telemetría para desactivar completamente la telemetría. La telemetría se desactiva al anular todos los eventos de telemetría salientes y convertirlos en eventos de telemetría vacíos, que no se envían.", "debugify.fix_explanation.mc-2025": "Debido a imprecisiones de punto flotante, a veces la caja de colisión de las entidades termina siendo ligeramente más pequeña de lo deseado. Entonces, si esto sucede antes de que las entidades se empujen una contra la otra, se intersecarán con la pared. Luego, cuando la AABB se recalcula al cargar el chunk, se determinará que están dentro de la pared, donde entonces se las empuja. Esta corrección simplemente escribe una etiqueta 'AABB' en los datos NBT de la entidad con tamaños de caja de colisión de doble precisión que luego se cargarán nuevamente.", "debugify.fix_effect.mc-2025": "Esta corrección significa que cargar Debugify por primera vez no solucionará el problema hasta que se guarden y carguen los chunks con Debugify.", "debugify.fix_explanation.mc-7569": "Agrega una nueva línea al final de cada mensaje del sistema.", "debugify.fix_explanation.mc-30391": "Agrega verificaciones de casos especiales para partículas de spawn de caída de pollos, blazes y el wither para no generarlas.", "debugify.fix_explanation.mc-69216": "Descarta la entidad de caña de pescar al cambiar al modo espectador.", "debugify.fix_explanation.mc-72151": "Los lobos tienen una función personalizada para modificar la cantidad de daño que reciben, que transforma el daño de entrada de 0 a 0.5, esta corrección verifica si el daño es 0.5 y lo cambia de vuelta a 0.", "debugify.fix_explanation.mc-88371": "Establece la posición Y de aterrizaje del dragón en 65 si el punto central de aparición ha sido destruido.", "debugify.fix_explanation.mc-89146": "Proporciona un orden estricto de guardado de entidades de bloques para que coincida con el orden de actualización, lo que permite que la actualización inicial de las entidades de bloques se realice en el orden correcto.", "debugify.fix_explanation.mc-93018": "Solo inicia el apareamiento si el lobo está domesticado.", "debugify.fix_explanation.mc-100991": "Notifica al rastreador de daños que un anzuelo de pesca lanzado daña a la entidad con 0 de daño, como las bolas de nieve.", "debugify.fix_explanation.mc-119417": "Impide que el jugador duerma cuando cambia a espectador.", "debugify.fix_explanation.mc-119754": "Indica a las entidades de fuegos artificiales que los jugadores no están volando con el elytra si están en modo espectador.", "debugify.fix_explanation.mc-121706": "Obliga a las entidades con un objetivo de ataque a distancia con arco a mirar a su objetivo.", "debugify.fix_explanation.mc-121903": "Agrega la etiqueta NBT 'LastExecuted' a los bloques de comandos para guardar y cargar su última propiedad ejecutada.", "debugify.fix_explanation.mc-124117": "Envía a los jugadores paquetes para actualizar todos sus efectos, su experiencia y sus habilidades después de un teletransporte entre dimensiones.", "debugify.fix_explanation.mc-132878": "Genera partículas de rotura cuando los soportes de armadura son dañados.", "debugify.fix_explanation.mc-135971": "Cambia el comportamiento de CTRL+Q en la ranura de crafteo para repetir CTRL+Q hasta que no queden objetos en la ranura de crafteo.", "debugify.fix_explanation.mc-155509": "Verifica si el pez globo está vivo antes de intentar picar al jugador.", "debugify.fix_explanation.mc-160095": "Si los cactus encuentran una cabeza de pistón, se considera el bloque que está siendo movido por el pistón en lugar del pistón mismo.", "debugify.fix_explanation.mc-179072": "Verifica si la entidad que ve el creeper es un enemigo antes de encenderse.", "debugify.fix_explanation.mc-183990": "Cuando se actualiza una criatura, verifica si su objetivo está muerto y lo elimina en caso afirmativo. Esta corrección también se aplica a una larga lista de entidades que tienen ataques grupales, no solo a los silverfish.", "debugify.fix_explanation.mc-193343": "Elimina la velocidad de alma si el jugador está en modo espectador.", "debugify.fix_explanation.mc-199467": "Modifica la entrada de las funciones sin y cos para que el valor se encuentre en el rango de 0 a 2pi. Esto evita cualquier desbordamiento de enteros. Aunque este problema se informa como un problema del cliente, la causa raíz se encuentra en ambos entornos, por lo que se encuentra en el código principal.", "debugify.fix_explanation.mc-200418": "Desmonta a los aldeanos bebés de los pollos al convertirse.", "debugify.fix_explanation.mc-206922": "Los objetos con una edad menor a 9 ticks no se eliminan por los rayos.", "debugify.fix_explanation.mc-215530": "Restablece el tiempo congelado cuando el jugador cambia a espectador.", "debugify.fix_explanation.mc-224729": "Siempre guarda los ProtoChunks incluso si el predicado de guardado del chunk devuelve falso." } ================================================ FILE: src/main/resources/assets/debugify/lang/fr_fr.json ================================================ { "debugify.name": "Debugify", "debugify.basic": "Corrections de base", "debugify.gameplay": "Corrections du gameplay", "debugify.gameplay.warning": "AVERTISSEMENT : Cette catégorie contient des correctifs qui peuvent constituer un avantage injuste.!", "debugify.gameplay.enable_in_multiplayer": "Activer en multijoueur", "debugify.fix.enabled": "Corrigé", "debugify.fix.disabled": "Non corrigé", "debugify.fix.unavailable": "Indisponible", "debugify.error.conflict": "%s est déjà corrigé par le mod '%s'.", "debugify.error.os": "%s ne s'applique qu'à %s", "debugify.os.windows": "Windows", "debugify.os.macos": "macOS", "debugify.os.linux": "Linux", "debugify.os.solaris": "Solaris", "debugify.misc": "Divers", "debugify.misc.default_disabled": "Valeur par défaut : désactivé", "debugify.misc.default_disabled.description": "Désactive par défaut les nouveaux correctifs de bugs au lieu de les activer.", "debugify.env.client": "Client", "debugify.env.client.desc": "Corrections qui ne s'appliquent qu'au client.", "debugify.env.server": "Principal", "debugify.env.server.desc": "Corrections qui s'appliquent à la fois au client et au serveur, et au code commun entre eux.", "debugify.no_yacl.title": "YetAnotherConfigLib non installé !", "debugify.no_yacl.description": "Pour configurer Debugify à l'aide d'une superposition, vous devez installer %s, qui est la bibliothèque utilisée pour rendre cette fonctionnalité disponible. Sinon, vous pouvez configurer en utilisant le fichier JSON stocké dans '%s'.", "debugify.mc_237493.header": "Télémétrie désactivée par Debugify", "debugify.mc_237493.line": "Vous avez choisi '%s' pour l'option de télémétrie, Debugify empêche donc toute connexion avec les services de télémétrie de Mojang. Cette option est fournie par Debugify pour la correction MC-237493.", "debugify.mc_237493.tooltip.off": "'%s' désactive complètement toute connexion aux services de télémétrie de Mojang. (Debugify MC-237493)", "debugify.mc_237493.tooltip.minimal": "Le fichier \"%s\" ne contient que les informations que Mojang juge nécessaires.", "debugify.mc_237493.tooltip.all": "'%s' inclut toute la télémétrie minimale et optionnelle." } ================================================ FILE: src/main/resources/assets/debugify/lang/it_it.json ================================================ { "debugify.name": "Debugify", "debugify.basic": "Correzioni di base", "debugify.gameplay": "Correzioni di gameplay", "debugify.gameplay.warning": "ATTENZIONE: Questa categoria contiene correzioni che potrebbero rappresentare un vantaggio sleale!", "debugify.gameplay.enable_in_multiplayer": "Abilita in multiplayer", "debugify.fix.enabled": "Corretto", "debugify.fix.disabled": "Non corretto", "debugify.fix.unavailable": "Non disponibile", "debugify.error.conflict": "La correzione %s è incompatibile con la mod '%s'", "debugify.error.os": "%s si applica solo a %s", "debugify.error.mixin_error": "Impossibile caricare %s, controlla il log per ulteriori informazioni.", "debugify.error.mixin_error.text": "Errore", "debugify.os.windows": "Windows", "debugify.os.macos": "macOS", "debugify.os.linux": "Linux", "debugify.os.solaris": "Solaris", "debugify.misc": "Varie", "debugify.misc.default_disabled": "Disabilitato per default", "debugify.misc.default_disabled.description": "Imposta le nuove correzioni di bug come disabilitate anziché abilitate di default.", "debugify.env.client": "Client", "debugify.env.client.desc": "Correzioni che si applicano solo al client.", "debugify.env.server": "Server", "debugify.env.server.desc": "Correzioni che si applicano sia al client che al server, e al codice comune tra di essi.", "debugify.no_yacl.title": "YetAnotherConfigLib non installato!", "debugify.no_yacl.description": "Per configurare Debugify utilizzando un'interfaccia grafica, è necessario installare %s, questa è la libreria utilizzata per rendere disponibile questa funzionalità. Altrimenti, puoi configurare utilizzando il file JSON memorizzato in '%s'.", "debugify.mc_237493.header": "Telemetria disabilitata da Debugify", "debugify.mc_237493.line": "Hai scelto '%s' per l'opzione di telemetria, quindi Debugify sta impedendo qualsiasi connessione con i servizi di telemetria di Mojang. Questo è fornito da Debugify per risolvere MC-237493.", "debugify.mc_237493.tooltip.off": "'%s' disabilita completamente qualsiasi connessione ai servizi di telemetria di Mojang. (Debugify MC-237493)", "debugify.mc_237493.tooltip.minimal": "'%s' include solo le informazioni che Mojang considera necessarie.", "debugify.mc_237493.tooltip.all": "'%s' include tutto ciò che è minimo e l'opzione di telemetria.", "debugify.fix_explanation.mc-55347": "Pulisce i titoli alla disconnessione.", "debugify.fix_explanation.mc-79545": "Limita il livello di esperienza al valore intero solo durante il rendering.", "debugify.fix_explanation.mc-93384": "Aggiunge l'altezza degli occhi alla posizione di generazione delle particelle.", "debugify.fix_explanation.mc-105068": "Rende il suono di rottura dello scudo un suono locale.", "debugify.fix_explanation.mc-108948": "Il problema è che il client non esegue gli stessi calcoli del server. Quando nessuno sta controllando la barca, il client non esegue la fisica sulla barca, causando una desincronizzazione del client. Questa correzione semplicemente dice al client di eseguire alcuni calcoli fisici sulla barca.", "debugify.fix_explanation.mc-111516": "Modifica un calcolo matematico di `acos` per assicurarsi che il risultato non sia superiore a 1.0", "debugify.fix_explanation.mc-112730": "Impede che i beacon e altre entità di blocco vengano aggiunti alla lista del renderer locale delle entità di blocco se sono già stati aggiunti alla lista globale.", "debugify.fix_explanation.mc-122477": "Previene i primi due polling della tastiera dopo che una casella di modifica è stata inizializzata, ad esempio la casella di chat.", "debugify.fix_explanation.mc-123739": "Ordina le voci del ricettario per il loro identificatore.", "debugify.fix_explanation.mc-143474": "Copia lo slot dell'oggetto selezionato quando si genera il nuovo giocatore locale dopo il respawn.", "debugify.fix_explanation.mc-159163": "Rimuove i dati della posa dalla gestione dei pacchetti dei dati delle entità.", "debugify.fix_effect.mc-159163": "Questo impedirà al client di sincronizzare i dati della posa con il server e utilizzerà solo il client per decidere la posa.", "debugify.fix_explanation.mc-162253": "Interrompe un aggiornamento della luce del client quando si entra in un chunk.", "debugify.fix_explanation.mc-165381": "Annulla la distruzione del blocco quando il client lancia un oggetto.", "debugify.fix_explanation.mc_176559": "Non considera la durabilità dell'oggetto quando si confronta un cambiamento dell'oggetto per verificare se la rottura del blocco dovrebbe essere reimpostata.", "debugify.fix_explanation.mc-197260": "Sovrascrive il livello di luce passato al renderer del supporto armature con un massimo di: il blocco sotto il supporto armature, il fondo del supporto armature, la parte superiore del supporto armature e il blocco sopra il supporto armature.", "debugify.fix_explanation.mc-237493": "Aggiunge un'opzione nel menu di telemetria per disabilitare completamente la telemetria. La telemetria è disabilitata sovrascrivendo tutti gli eventi di telemetria in uscita con un evento di telemetria vuoto, che non viene inviato.", "debugify.fix_explanation.mc-2025": "A causa di imprecisioni nei numeri in virgola mobile, a volte la hitbox delle entità risulta leggermente più piccola del desiderato. Se questo accade prima che le entità vengano spostate l'una contro l'altra, esse intersecheranno il muro. Poi, quando l'AABB viene ricalcolato al caricamento del chunk, verranno determinate come dentro il muro, dove vengono quindi spostate. Questa correzione semplicemente aggiunge un tag 'AABB' ai dati NBT dell'entità con dimensioni della hitbox a doppia precisione, che vengono poi ricaricate.", "debugify.fix_effect.mc-2025": "Questa correzione significa che caricare Debugify per la prima volta non risolverà il problema fino a quando i chunk non saranno salvati e ricaricati con Debugify.", "debugify.fix_explanation.mc-7569": "Aggiunge una nuova riga alla fine di ogni messaggio di sistema.", "debugify.fix_explanation.mc-30391": "Aggiunge controlli per casi limite per pollo, blaze e wither per impedire la generazione di particelle di danno da caduta.", "debugify.fix_explanation.mc-69216": "Scarta l'entità del gancio da pesca al cambio in modalità spettatore.", "debugify.fix_explanation.mc-72151": "I lupi hanno una funzione personalizzata per modificare la quantità di danno che ricevono, che trasforma il danno in ingresso da 0 a 0,5; questa correzione controlla se il danno è 0,5 e lo riporta a 0.", "debugify.fix_explanation.mc-88371": "Imposta la posizione Y di atterraggio del drago a 65 se il centro di spawn è stato distrutto.", "debugify.fix_explanation.mc-89146": "Fornisce un ordine di salvataggio rigoroso per le entità di tile, per abbinare l'ordine di aggiornamento, consentendo così l'aggiornamento iniziale delle entità di tile nell'ordine corretto.", "debugify.fix_explanation.mc-93018": "Avvia la riproduzione solo se il lupo è addomesticato.", "debugify.fix_explanation.mc-100991": "Notifica al tracker dei danni di un gancio da pesca lanciato che infligge danno 0 all'entità, come le palle di neve.", "debugify.fix_explanation.mc-119417": "Impedisce al giocatore di dormire quando cambia in modalità spettatore.", "debugify.fix_explanation.mc-119754": "Comunica alle entità dei fuochi d'artificio che i giocatori non stanno volando con l'elytra se sono in modalità spettatore.", "debugify.fix_explanation.mc-121706": "Le entità con un obiettivo di attacco con arco a distanza sono costrette a guardare il loro bersaglio.", "debugify.fix_explanation.mc-121903": "Aggiunge il tag NBT 'LastExecuted' ai blocchi di comando per salvare e caricare la loro proprietà dell'ultimo comando eseguito.", "debugify.fix_explanation.mc-124117": "Invia pacchetti ai giocatori per aggiornare tutti i loro effetti, la loro esperienza e le loro abilità dopo il teletrasporto tra dimensioni.", "debugify.fix_explanation.mc-132878": "Genera particelle di rottura quando i supporti per armature vengono danneggiati.", "debugify.fix_explanation.mc-135971": "Sostituisce il comportamento di CTRL+Q nello slot di crafting per ripetere CTRL+Q fino a quando non ci sono più oggetti nello slot di crafting.", "debugify.fix_explanation.mc-155509": "Controlla se il pesce palla è vivo prima di tentare di pungere il giocatore.", "debugify.fix_explanation.mc-160095": "Se i cactus incontrano una testa di pistone, il blocco che viene spostato dal pistone viene considerato invece del pistone.", "debugify.fix_explanation.mc-179072": "Controlla se l'entità che il creeper vede è un nemico prima di accendersi.", "debugify.fix_explanation.mc-183990": "Quando un mob viene tickato, controlla se il suo bersaglio è morto e lo rimuove se è così. Questa correzione si applica anche a una lunga lista di entità che hanno attacchi di gruppo, non solo ai silverfish.", "debugify.fix_explanation.mc-193343": "Rimuove la velocità dell'anima se il giocatore è in modalità spettatore.", "debugify.fix_explanation.mc-199467": "Modifica l'input delle funzioni seno e coseno, avvolgendo l'input da 0 a 2pi. Questo previene eventuali overflow di interi. Sebbene questo problema venga segnalato come un problema del client, la causa principale si trova in entrambi gli ambienti, quindi è situata in main.", "debugify.fix_explanation.mc-200418": "Smonta i villager baby dai polli al momento della conversione.", "debugify.fix_explanation.mc-206922": "Gli oggetti con un'età inferiore a 9 tick non vengono rimossi dai fulmini.", "debugify.fix_explanation.mc-215530": "Reimposta il tempo congelato quando il giocatore cambia in modalità spettatore.", "debugify.fix_explanation.mc-224729": "Salva sempre i ProtoChunks anche se il predicato di salvataggio del chunk restituisce false." } ================================================ FILE: src/main/resources/assets/debugify/lang/pt_br.json ================================================ { "debugify.name": "Debugify", "debugify.basic": "Correções básicas", "debugify.gameplay": "Correções de jogabilidade", "debugify.gameplay.warning": "AVISO: Esta categoria contém correções que podem ser uma vantagem injusta!", "debugify.gameplay.enable_in_multiplayer": "Ativar no Multiplayer", "debugify.fix.enabled": "consertado", "debugify.fix.disabled": "Não consertado", "debugify.fix.unavailable": "Indisponível", "debugify.error.os": "%s aplica-se apenas a %s", "debugify.os.windows": "Windows", "debugify.os.macos": "macOS", "debugify.os.linux": "Linux", "debugify.os.solaris": "Solaris", "debugify.misc": "Diversos", "debugify.misc.default_disabled": "Padrão para Desativado", "debugify.misc.default_disabled.description": "Novas correções de bug padrão a serem desabilitadas em vez de habilitadas.", "debugify.env.client": "Cliente", "debugify.env.server": "Servidor", "debugify.no_yacl.title": "YetAnotherConfigLib não instalado!", "debugify.no_yacl.description": "Para configurar o Debugify usando uma GUI, você deve instalar o %s, esta é a biblioteca usada para disponibilizar esta funcionalidade. Caso contrário, você pode configurar usando o arquivo JSON armazenado em '%s'." } ================================================ FILE: src/main/resources/assets/debugify/lang/ru_ru.json ================================================ { "debugify.name": "Debugify", "debugify.basic": "Основные исправления", "debugify.gameplay": "Исправления игрового процесса", "debugify.gameplay.warning": "ВНИМАНИЕ: Эта категория содержит исправления, которые могут являться несправедливым преимуществом!", "debugify.gameplay.enable_in_multiplayer": "Включить в сетевой игре", "debugify.fix.enabled": "Исправлено", "debugify.fix.disabled": "Не исправлено", "debugify.fix.unavailable": "Недоступно", "debugify.error.conflict": "Исправление %s несовместимо с модом «%s»", "debugify.error.os": "%s относится только к %s", "debugify.error.mixin_error": "Не удалось загрузить %s, посмотрите логи для получения дополнительной информации.", "debugify.error.mixin_error.text": "Ошибка", "debugify.os.windows": "Windows", "debugify.os.macos": "macOS", "debugify.os.linux": "Linux", "debugify.os.solaris": "Solaris", "debugify.misc": "Разное", "debugify.misc.default_disabled": "Отключать по умолчанию", "debugify.misc.default_disabled.description": "Все новые исправления будут по умолчанию отключены.", "debugify.env.client": "Клиент", "debugify.env.client.desc": "Исправления, применимые только к клиенту.", "debugify.env.server": "Общие", "debugify.env.server.desc": "Исправления, применимые как к клиенту, так и к серверу, а также к общему коду между ними.", "debugify.no_yacl.title": "YetAnotherConfigLib не установлен!", "debugify.no_yacl.description": "Для настройки Debugify через графический интерфейс требуется мод %s - это библиотека, используемая для предоставленияя данной функции. Иначе вы можете отредактировать настройки мода в JSON файле, хранящемся по пути «%s».", "debugify.mc_237493.header": "Телеметрия отключена модом Debugify", "debugify.mc_237493.line": "Вы выбрали «%s» в параметре телеметрии, поэтому Debugify предотвращает любое подключение к службам телеметрии Mojang. Это предусмотрено Debugify для исправления MC-237493.", "debugify.mc_237493.tooltip.off": "«%s» полностью отключает любое подключение к службам телеметрии Mojang. (Debugify MC-237493)", "debugify.mc_237493.tooltip.minimal": "«%s» включает только ту информацию, которую Mojang сочтёт необходимой.", "debugify.mc_237493.tooltip.all": "«%s» включает в себя всю минимальную и дополнительную телеметрию.", "debugify.fix_explanation.mc-55347": "Очищает текст на экране при отключении.", "debugify.fix_explanation.mc-79545": "Ограничивает лимит уровней опыта только при рендере.", "debugify.fix_explanation.mc-93384": "Добавляет к позиции спавна частиц высоту уровня глаз.", "debugify.fix_explanation.mc-108948": "Проблема в том, что клиент не выполняет те же вычисления, что и сервер. Когда лодкой никто не управляет, клиент не запускает физику лодки, что приводит к рассинхронизации. Это исправление просто указывает клиенту выполнить некоторые физические вычисления у лодки.", "debugify.fix_explanation.mc-111516": "Изменяет математический расчет acos, чтобы убедиться, что результат не превышает 1.0.", "debugify.fix_explanation.mc-112730": "Предотвращает добавление маяков и других блоков-сущностей в список рендера локальных блоков-сущностей, если они уже добавлены в общий список.", "debugify.fix_explanation.mc-122477": "Предотвращает первые два ввода с клавиатуры после открытия окна редактирования (например, окно чата).", "debugify.fix_explanation.mc-123739": "Сортирует записи в книге рецептов по их идентификатору.", "debugify.fix_explanation.mc-143474": "Копирует выбранный слот при появлении нового локального игрока после возрождения.", "debugify.fix_explanation.mc-159163": "Удаляет данные о позе из обработки пакетов сущностей.", "debugify.fix_effect.mc-159163": "Это отключит синхронизацию данных о позе клиента с сервером, для определения позы будет использоваться только клиент.", "debugify.fix_explanation.mc-162253": "Останавливает обновление света на клиенте при входе в чанк.", "debugify.fix_explanation.mc-165381": "Отменяет ломание блока, когда клиент выкидывает предмет.", "debugify.fix_explanation.mc-176559": "Не учитывать прочность предмета при сравнении изменения предмета во время проверки на прерывание ломания блока.", "debugify.fix_explanation.mc-197260": "Переопределяет уровень освещения у стойки для брони на максимум для: блока под стойкой, низа и верха стойки, блока над стойкой.", "debugify.fix_explanation.mc-237493": "Добавляет настройку в меню телеметрии для её полного отключения. Телеметрия отключается путем замены всех исходящих событий телеметрии на пустые события, которые не отправляются.", "debugify.fix_explanation.mc-2025": "Иногда хитбоксы сущностей оказываются меньше ожидаемых из-за неточностей с дробным значением. Если это произойдёт до того, как сущности окажутся прижатыми друг к другу, они будут заходить в блок. Затем, когда AABB будет пересчитан при загрузке чанков, они будут определены как находящиеся внутри стены, куда они затем будут помещены. Это исправление просто записывает тег AABB в данные NBT сущности с двойной точностью до размеров хитбокса, который затем загружается обратно.", "debugify.fix_effect.mc-2025": "Это исправление означает, что загрузка Debugify в первый раз не устранит проблему до тех пор, пока чанки не будут сохранены и загружены с помощью Debugify.", "debugify.fix_explanation.mc-7569": "Добавляет новую строку в конец каждого системного сообщения.", "debugify.fix_explanation.mc-30391": "Добавляет дополнительные проверки для курицы, всполоха и визера для предотвращения появления частиц от падения.", "debugify.fix_explanation.mc-69216": "Удаляет сущность крючка удочки при входе в режим наблюдателя.", "debugify.fix_explanation.mc-72151": "У волков есть специальная функция для изменения количества наносимого им урона, которая преобразует входной урон от 0 до 0.5. Это исправление проверяет, равен ли урон 0.5, и изменяет его обратно на 0.", "debugify.fix_explanation.mc-88371": "Устанавливает положение по Y для приземления дракона на 65, если центральный спавн был уничтожен.", "debugify.fix_explanation.mc-89146": "Обеспечивает строгий порядок сохранения тайлов в соответствии с порядком обновления, который затем позволяет выполнять первоначальное обновление тайлов в правильном порядке.", "debugify.fix_explanation.mc-93018": "Размножение начинается только в том случае, если волк приручен.", "debugify.fix_explanation.mc-100991": "Уведомляет систему отслеживания урона о том, что крючок удочки наносит урон, равный 0, как снежки.", "debugify.fix_explanation.mc-119417": "Не дает игроку спать, когда он переключается на режим наблюдателя.", "debugify.fix_explanation.mc-119754": "Сообщает сущностям фейерверка, что игроки не летают на элитрах, если находятся в режиме наблюдателя.", "debugify.fix_explanation.mc-121706": "Существа, нацеленные на дальнюю атаку из лука, вынуждены смотреть на свою цель.", "debugify.fix_explanation.mc-121903": "Добавляет NBT тег LastExecuted к командным блокам для сохранения и загрузки их последнего выполненного свойства.", "debugify.fix_explanation.mc-124117": "Отправляет пакеты игроков для обновления всех их эффектов, опыта и способностей при перемещении между мирами.", "debugify.fix_explanation.mc-132878": "Создает частицы разрушения при нанесении урона стойке для брони.", "debugify.fix_explanation.mc-135971": "Изменяет поведение CTRL+Q в слоте крафта для повторения CTRL+Q до тех пор, пока в слоте для крафта не останется предметов.", "debugify.fix_explanation.mc-155509": "Проверяет, жив ли иглобрюх, прежде чем кольнуть игрока.", "debugify.fix_explanation.mc-160095": "Если кактусы сталкиваются с головкой поршня, то вместо поршня рассматривается блок, который перемещается поршнем.", "debugify.fix_explanation.mc-179072": "Проверяет, является ли существо, которое видит крипер, врагом, прежде чем начать взрываться.", "debugify.fix_explanation.mc-183990": "Когда моб тикает, он проверяет, мертва ли его цель, и удаляет её, если это так. Это исправление также применимо к большому списку сущностей, которые имеют групповые атаки, а не только к чешуйнице.", "debugify.fix_explanation.mc-193343": "Убирает скорость души, если игрок является зрителем.", "debugify.fix_explanation.mc-199467": "Изменяет входные данные для функций sin и cos, которые преобразуют входные данные из 0 в 2pi. Это предотвращает переполнение целых чисел. Хотя, как сообщается, эта проблема связана с клиентом, основная причина находится в обеих средах, следовательно, она находится здесь.", "debugify.fix_explanation.mc-200418": "Сбрасывает детенышей деревенских жителей с куриц при лечении.", "debugify.fix_explanation.mc-206922": "Предметы, возраст которых менее 9 тиков, не удаляются после ударов молнии.", "debugify.fix_explanation.mc-215530": "Сбрасывает заморозку, когда игрок переключается в режим наблюдателя.", "debugify.fix_explanation.mc-224729": "Всегда сохраняет ProtoChunks, даже если не выполняется условие сохранения чанка.", "modmenu.summaryTranslation.debugify": "Исправление багов Майнкрафта с баг-трекера", "modmenu.descriptionTranslation.debugify": "Исправление багов Майнкрафта с баг-трекера\n\nЛицензии:\nj-Tai's TieFix - Использованный код под лицензией LGPLv3\nFlashyReese's Sodium Extra - Использованный код под лицензией LGPLv3\nAmpflower's 2x2 Surronded Saplings Fix - Использованный код под лицензией Zlib" } ================================================ FILE: src/main/resources/assets/debugify/lang/tr_tr.json ================================================ { "debugify.name": "Debugify", "debugify.basic": "Temel Düzeltmeler", "debugify.gameplay": "Oynanış Düzeltmeleri", "debugify.gameplay.warning": "UYARI: Bu kategori, haksız bir avantaj olabilecek düzeltmeler içeriyor!", "debugify.gameplay.enable_in_multiplayer": "Çok Oyunculuda Etkinleştir", "debugify.misc": "Diğer", "debugify.misc.default_disabled": "Varsayılan Olarak Devre Dışı", "debugify.misc.default_disabled.description": "Varsayılan: Etkinleştirmek yerine devre dışı bırakılacak yeni hata düzeltmeleri.", "debugify.env.client": "İstemci", "debugify.env.server": "Sunucu" } ================================================ FILE: src/main/resources/assets/debugify/lang/uk_ua.json ================================================ { "debugify.name": "Debugify", "debugify.basic": "Основні виправлення", "debugify.gameplay": "Виправлення ігроладу", "debugify.gameplay.warning": "УВАГА: Ця категорія містить виправлення, які можуть бути нечесною перевагою!", "debugify.gameplay.enable_in_multiplayer": "Увімкнути в мережевій грі", "debugify.fix.enabled": "Виправлено", "debugify.fix.disabled": "Не виправлено", "debugify.fix.unavailable": "Недоступно", "debugify.error.os": "%s стосується лише %s", "debugify.os.windows": "Windows", "debugify.os.macos": "macOS", "debugify.os.linux": "Linux", "debugify.os.solaris": "Solaris", "debugify.misc": "Різне", "debugify.misc.default_disabled": "За замовчуванням вимкнено", "debugify.misc.default_disabled.description": "Нові виправлення помилок за замовчуванням мають бути вимкнені, а не ввімкнені.", "debugify.env.client": "Клієнт", "debugify.env.server": "Сервер", "debugify.no_yacl.title": "YetAnotherConfigLib не встановлено!", "debugify.no_yacl.description": "Щоб налаштувати Debugify за допомогою інтерфейсу, ви повинні встановити %s. Це бібліотека, яка використовується для надання цієї функції. В іншому разі ви можете налаштувати за допомогою файлу JSON, який зберігається в '%s'." } ================================================ FILE: src/main/resources/assets/debugify/lang/vi_vn.json ================================================ { "debugify.name": "Debugify", "debugify.basic": "Sửa lỗi cơ bản", "debugify.gameplay": "Sửa lỗi trò chơi", "debugify.gameplay.warning": "CẢNH BÁO: Danh mục này chứa các bản sửa lỗi có thể là một lợi thế không công bằng!", "debugify.gameplay.enable_in_multiplayer": "Kích hoạt trong nhiều người chơi", "debugify.fix.enabled": "Đã sửa", "debugify.fix.disabled": "Chưa sửa", "debugify.fix.unavailable": "Không có sẵn", "debugify.error.conflict": "Bản sửa lỗi %s không tương thích với mod '%s'", "debugify.error.os": "%s chỉ áp dụng cho %s", "debugify.error.mixin_error": "Không tải được %s, hãy kiểm tra nhật ký để biết thêm thông tin.", "debugify.error.mixin_error.text": "Bị lỗi", "debugify.os.windows": "Windows", "debugify.os.macos": "macOS", "debugify.os.linux": "Linux", "debugify.os.solaris": "Solaris", "debugify.misc": "Khác", "debugify.misc.default_disabled": "Mặc định là Vô hiệu hóa", "debugify.misc.default_disabled.description": "Các bản sửa lỗi mới mặc định bị vô hiệu hóa thay vì được bật.", "debugify.env.client": "Máy khách", "debugify.env.client.desc": "Các bản sửa lỗi chỉ áp dụng trên máy khách.", "debugify.env.server": "Chính", "debugify.env.server.desc": "Các bản sửa lỗi áp dụng cho cả máy khách và máy chủ cũng như mã chung giữa chúng.", "debugify.no_yacl.title": "YetAnotherConfigLib chưa được cài đặt!", "debugify.no_yacl.description": "Để định cấu hình Debugify bằng GUI, bạn phải cài đặt %s, đây là thư viện được sử dụng để cung cấp chức năng này. Nếu không, bạn có thể định cấu hình bằng cách sử dụng tệp JSON được lưu trữ tại '%s'.", "debugify.mc_237493.header": "Đo từ xa bị vô hiệu hóa bởi Debugify", "debugify.mc_237493.line": "Bạn đã chọn '%s' trên tùy chọn đo từ xa, vì vậy Debugify đang ngăn mọi kết nối với các dịch vụ đo từ xa từ Mojang. Điều này được cung cấp bởi Debugify để sửa lỗi MC-237493.", "debugify.mc_237493.tooltip.off": "'%s' vô hiệu hóa hoàn toàn mọi kết nối với các dịch vụ đo từ xa của Mojang. (Debugify MC-237493)", "debugify.mc_237493.tooltip.minimal": "'%s' chỉ bao gồm thông tin mà Mojang cho là cần thiết.", "debugify.mc_237493.tooltip.all": "'%s' bao gồm tất cả phép đo từ xa tối thiểu và tùy chọn.", "debugify.fix_explanation.mc-55347": "Xóa tiêu đề khi ngắt kết nối.", "debugify.fix_explanation.mc-79545": "Kẹp mức kinh nghiệm vào giới hạn số nguyên chỉ khi kết xuất.", "debugify.fix_explanation.mc-93384": "Thêm chiều cao mắt vào vị trí xuất hiện hạt.", "debugify.fix_explanation.mc-108948": "Vấn đề là máy khách không chạy các tính toán giống như máy chủ. Khi không có ai điều khiển thuyền, máy khách không chạy vật lý trên thuyền, khiến máy khách không đồng bộ hóa. Bản sửa lỗi này chỉ yêu cầu máy khách chạy một số tính toán vật lý trên thuyền.", "debugify.fix_explanation.mc-111516": "Sửa đổi phép tính acos toán học để đảm bảo kết quả không lớn hơn 1.0", "debugify.fix_explanation.mc-112730": "Ngăn không cho đèn hiệu và các thực thể khối khác được thêm vào danh sách trình kết xuất thực thể khối cục bộ nếu chúng đã được thêm vào danh sách chung.", "debugify.fix_explanation.mc-122477": "Ngăn chặn hai cuộc thăm dò bàn phím đầu tiên sau khi hộp chỉnh sửa được khởi tạo, ví dụ: hộp trò chuyện.", "debugify.fix_explanation.mc-123739": "Sắp xếp các mục trong sách công thức theo số nhận dạng của chúng.", "debugify.fix_explanation.mc-143474": "Sao chép vị trí vật phẩm đã chọn khi tạo người chơi cục bộ mới sau khi hồi sinh.", "debugify.fix_explanation.mc-159163": "Loại bỏ dữ liệu tư thế khỏi việc xử lý gói dữ liệu thực thể.", "debugify.fix_effect.mc-159163": "Điều này sẽ ngăn máy khách đồng bộ hóa dữ liệu tư thế với máy chủ và hoàn toàn sử dụng máy khách để quyết định tư thế.", "debugify.fix_explanation.mc-162253": "Dừng cập nhật ánh sáng máy khách khi vào một đoạn khúc.", "debugify.fix_explanation.mc-165381": "Hủy hủy khối khi máy khách đánh rơi vật phẩm", "debugify.fix_explanation.mc_176559": "Không xem xét độ bền của vật phẩm khi so sánh sự thay đổi trong vật phẩm khi kiểm tra xem có nên đặt lại việc phá vỡ khối hay không.", "debugify.fix_explanation.mc-197260": "Ghi đè mức ánh sáng được truyền cho trình kết xuất giá đỡ áo giáp với tối đa: khối bên dưới giá đỡ áo giáp, đáy giá đỡ áo giáp, đỉnh giá đỡ áo giáp và khối bên trên giá đỡ áo giáp.", "debugify.fix_explanation.mc-237493": "Thêm một tùy chọn trong menu đo từ xa để tắt hoàn toàn phép đo từ xa. Đo từ xa bị vô hiệu hóa bằng cách ghi đè tất cả các sự kiện đo từ xa gửi đi thành một sự kiện đo từ xa trống, không được gửi.", "debugify.fix_explanation.mc-2025": "Do sự không chính xác của dấu phẩy động, đôi khi hộp sát thương của các thực thể cuối cùng nhỏ hơn một chút so với mong muốn. Sau đó, nếu điều này xảy ra trước khi các thực thể bị đẩy vào nhau, chúng sẽ giao nhau với bức tường. Sau đó, khi AABB được tính toán lại trên đoạn tải, chúng sẽ được xác định là bên trong tường, nơi chúng được đẩy. Bản sửa lỗi này chỉ cần ghi thẻ 'AABB' vào dữ liệu NBT của thực thể với kích thước hộp đánh chính xác kép, sau đó được tải lại.", "debugify.fix_effect.mc-2025": "Khắc phục sự cố này có nghĩa là tải Debugify lần đầu tiên sẽ không khắc phục được sự cố cho đến khi các khối được lưu và tải bằng Debugify.", "debugify.fix_explanation.mc-7569": "Nối thêm một dòng mới vào cuối mỗi thông báo hệ thống.", "debugify.fix_explanation.mc-30391": "Thêm kiểm tra trường hợp cạnh cho gà, blaze và wither để sát thương rơi sinh ra các hạt để không sinh ra chúng.", "debugify.fix_explanation.mc-69216": "Loại bỏ thực thể móc câu khi đổi thành khán giả.", "debugify.fix_explanation.mc-72151": "Sói có một chức năng tùy chỉnh để sửa đổi lượng sát thương mà chúng nhận, giúp chuyển đổi sát thương đầu vào từ 0 thành 0,5, bản sửa lỗi này kiểm tra xem sát thương có phải là 0,5 hay không và thay đổi về 0.", "debugify.fix_explanation.mc-88371": "Đặt vị trí hạ cánh Y của rồng ender thành 65 nếu trung tâm đã bị phá hủy.", "debugify.fix_explanation.mc-89146": "Cung cấp thứ tự lưu nghiêm ngặt của các thực thể khối xếp, để khớp với thứ tự cập nhật, sau đó cho phép cập nhật ban đầu các thực thể khối xếp theo đúng thứ tự.", "debugify.fix_explanation.mc-93018": "Chỉ bắt đầu sinh sản nếu sói đã được thuần hóa.", "debugify.fix_explanation.mc-100991": "Thông báo cho bộ theo dõi sát thương về một lưỡi câu bị ném ra gây sát thương cho thực thể bằng 0 sát thương, giống như quả cầu tuyết.", "debugify.fix_explanation.mc-119417": "Ngăn người chơi ngủ khi họ chuyển sang chế độ khán giả.", "debugify.fix_explanation.mc-119754": "Nói với các thực thể pháo hoa rằng người chơi không bay elytra nếu ở trong chế độ khán giả", "debugify.fix_explanation.mc-121706": "Các thực thể có mục tiêu tấn công bằng cung tầm xa buộc phải nhìn vào mục tiêu của chúng.", "debugify.fix_explanation.mc-121903": "Thêm thẻ NBT 'LastExecuted' vào các khối lệnh để lưu và tải thuộc tính được thực thi cuối cùng của chúng.", "debugify.fix_explanation.mc-124117": "Gửi cho người chơi các gói để cập nhật tất cả các hiệu ứng, kinh nghiệm và khả năng của họ sau khi dịch chuyển tức thời qua chiều không gian khác.", "debugify.fix_explanation.mc-132878": "Sinh ra các hạt vỡ khi giá đỡ áo giáp bị tổn thương.", "debugify.fix_explanation.mc-135971": "Ghi đè hành vi CTRL+Q trong ô chế tạo thành CTRL+Q liên tục cho đến khi không còn vật phẩm nào trong ô chế tạo.", "debugify.fix_explanation.mc-155509": "Kiểm tra xem cá nóc còn sống hay không trước khi cố gắng chích người chơi.", "debugify.fix_explanation.mc-160095": "Nếu xương rồng gặp đầu pít-tông, khối đang được chuyển động bởi pít-tông được xem xét thay vì chính pít-tông.", "debugify.fix_explanation.mc-179072": "Kiểm tra xem thực thể mà creeper nhìn thấy có phải là kẻ thù hay không trước khi phát nổ.", "debugify.fix_explanation.mc-183990": "Khi một mob được đánh dấu, nó sẽ kiểm tra xem mục tiêu của nó đã chết chưa và loại bỏ nó nếu có. Bản sửa lỗi này cũng áp dụng cho một danh sách dài các thực thể có các cuộc tấn công theo nhóm, không chỉ cá bạc.", "debugify.fix_explanation.mc-193343": "Loại bỏ Tốc độ linh hồn nếu người chơi đang ở chế độ khán giả.", "debugify.fix_explanation.mc-199467": "Sửa đổi đầu vào thành các hàm sin và cos, bao hàm đầu vào từ 0 đến 2pi. Điều này ngăn chặn bất kỳ sự cố tràn số nguyên nào xảy ra. Mặc dù sự cố này được báo cáo là sự cố của máy khách, nhưng nguyên nhân cốt lõi nằm ở cả hai môi trường, do đó, nó nằm trong tệp main.", "debugify.fix_explanation.mc-200418": "Tháo rời dân làng con khỏi gà khi chuyển đổi.", "debugify.fix_explanation.mc-206922": "Các vật phẩm có tuổi đời dưới 9 tick không bị loại bỏ khỏi sét đánh.", "debugify.fix_explanation.mc-215530": "Đặt lại thời gian đóng băng khi người chơi thay đổi thành chế độ khán giả.", "debugify.fix_explanation.mc-224729": "Luôn lưu ProtoChunks ngay cả khi vị từ lưu đoạn mã trả về sai." ================================================ FILE: src/main/resources/assets/debugify/lang/zh_cn.json ================================================ { "debugify.name": "Debugify", "debugify.basic": "基础修复", "debugify.gameplay": "游戏修复", "debugify.gameplay.warning": "警告:此类别包含可能对其他人来说不公平的修复!", "debugify.gameplay.enable_in_multiplayer": "在多人游戏中启用", "debugify.fix.enabled": "已修复", "debugify.fix.disabled": "未修复", "debugify.fix.unavailable": "不可用", "debugify.error.conflict": "‘%s’修复与模组‘%s’不兼容", "debugify.error.os": "%s仅适用于%s", "debugify.os.windows": "Windows", "debugify.os.macos": "macOS", "debugify.os.linux": "Linux", "debugify.os.solaris": "Solaris", "debugify.misc": "杂项", "debugify.misc.default_disabled": "默认为禁用", "debugify.misc.default_disabled.description": "默认禁用新的错误修复,而不是启用。", "debugify.env.client": "客户端", "debugify.env.client.desc": "只适用于客户端的修复。", "debugify.env.server": "主要", "debugify.env.server.desc": "适用于客户端和服务器的修复,以及它们之间的共同代码。", "debugify.no_yacl.title": "未安装 YetAnotherConfigLib!", "debugify.no_yacl.description": "要使用 GUI 配置 Debugify,你必须安装%s,这是用来实现这一功能的前置库。否则,你可以使用存储在「%s」的JSON文件进行配置。", "debugify.mc_237493.header": "遥测已由 Debugify 关闭", "debugify.mc_237493.line": "你在遥测选项上选择了「%s」,所以 Debugify 正在阻止与 Mojang 的遥测服务的任何连接。这是由 Debugify 提供的MC-237493修复。", "debugify.mc_237493.tooltip.off": "「%s」完全禁用了与 Mojang 遥测服务的任何连接。(Debugify MC-237493)", "debugify.mc_237493.tooltip.minimal": "「%s」只包括 Mojang 认为需要的信息。", "debugify.mc_237493.tooltip.all": "「%s」包括所有的最少和可选遥测。" } ================================================ FILE: src/main/resources/assets/debugify/lang/zh_tw.json ================================================ { "debugify.name": "Debugify", "debugify.basic": "基礎修復", "debugify.gameplay": "遊玩修復", "debugify.gameplay.warning": "警告:這個類別中的修復可能導致遊戲不公平性!", "debugify.gameplay.enable_in_multiplayer": "在多人遊戲中啟用", "debugify.fix.enabled": "已修復", "debugify.fix.disabled": "未修復", "debugify.fix.unavailable": "不可用", "debugify.error.conflict": "%s 修復與「%s」模組不相容", "debugify.error.os": "%s 僅適用於 %s", "debugify.error.mixin_error": "%s 載入失敗,檢查記錄檔以取得更多資訊。", "debugify.error.mixin_error.text": "錯誤", "debugify.os.windows": "Windows", "debugify.os.macos": "macOS", "debugify.os.linux": "Linux", "debugify.os.solaris": "Solaris", "debugify.misc": "雜項", "debugify.misc.default_disabled": "預設停用", "debugify.misc.default_disabled.description": "新的錯誤修復將會預設停用。", "debugify.env.client": "用戶端", "debugify.env.client.desc": "修復僅套用於用戶端。", "debugify.env.server": "主要", "debugify.env.server.desc": "修復於用戶端與伺服器端兩者套用,以及它們的通用程式碼。", "debugify.no_yacl.title": "YetAnotherConfigLib 尚未安裝!", "debugify.no_yacl.description": "要透過介面來設定 Debugify,你必須安裝 %s,此函式庫將讓本功能可用。不然你也可以透過編輯儲存在 '%s' 中的 JSON 檔案來設定。", "debugify.mc_237493.header": "Debugify 已停用遙測資料", "debugify.mc_237493.line": "你在遙測資料選項中選擇「%s」,所以 Debugify 將會防止任何來自 Mojang 的遙測資料服務連線。這是由 Debugify 修復的 MC-237493。", "debugify.mc_237493.tooltip.off": "「%s」完全停用任何來自 Mojang 遙測資料服務的連線。(Debugify MC-237493)", "debugify.mc_237493.tooltip.minimal": "「%s」僅包含了 Mojang 認為需要的資訊。", "debugify.mc_237493.tooltip.all": "「%s」包括了所有最小和遙測資料選項。", "debugify.fix_explanation.mc-55347": "在中斷連線時清除遺留字幕。", "debugify.fix_explanation.mc-79545": "在繪製時,將經驗等級限制為整數範圍內。", "debugify.fix_explanation.mc-93384": "將粒子效果生成於眼睛所看的到的高度。", "debugify.fix_explanation.mc-108948": "這個問題在於用戶端未與伺服器執行相同的計算。當沒有任何人在控制船時,用戶端不會對船進行物理計算,因而導致用戶端與伺服器端的非同步情況。這個修復簡單地告訴用戶端,對船執行一些物理計算。", "debugify.fix_explanation.mc-111516": "修改反餘弦數學計算,來確保結果不會大於 1.0。", "debugify.fix_explanation.mc-112730": "如果烽火台和其他方塊已被加入全域清單中,則防止它們被新增到本機方塊實體繪製清單中。", "debugify.fix_explanation.mc-122477": "在初始化編輯區時,防止前兩次的鍵盤輸入。(例如聊天室)", "debugify.fix_explanation.mc-123739": "按照配方的識別碼來排序配方手冊。", "debugify.fix_explanation.mc-143474": "在重生時,複製重生前所在的物品欄位位置。", "debugify.fix_explanation.mc-159163": "從資料封包處理中移除姿勢資料。", "debugify.fix_effect.mc-159163": "這將防止用戶端與伺服器同步姿勢資料,僅讓用戶端決定姿勢。", "debugify.fix_explanation.mc-162253": "在進入另一個區塊時停止用戶端進行照明更新。", "debugify.fix_explanation.mc-165381": "當用戶端丟出物品時,取消破壞方塊。", "debugify.fix_explanation.mc-176559": "在檢查是否重設方塊破壞進度時,不對耐久度的變化進行判斷。", "debugify.fix_explanation.mc-197260": "覆寫繪製光源通過盔甲座的最大值:在盔甲座下方的方塊、盔甲座底部和盔甲座頂部和更上方的方塊。", "debugify.fix_explanation.mc-237493": "在遙測資料收集選單中新增一個選項,能夠完整關閉遙測資料收集。透過覆寫所有傳送的遙測事件為空來停用遙測,這也等於沒有傳送任何東西。", "debugify.fix_explanation.mc-2025": "因為浮點數的不準確性,有的時候實體的碰撞箱會稍微小於預期大小。然後,如果這發生在實體互相推擠彼此時,它們可能會與牆壁交集。然後當 AABB 生物重新在區塊載入時進行計算,它們將會被判斷為在牆壁中,然後被推擠出去。這個修復只是將帶有雙精度浮點數的碰撞箱大小的標籤帶入到 AABB 實體的 NBT 資料中,然後再次被載入回來。", "debugify.fix_effect.mc-2025": "這個修復代表第一次載入 Debugify 將不會修復這個問題,直到區塊被 Debugify 儲存並重新載入。", "debugify.fix_explanation.mc-7569": "對系統的每條訊息結尾附加換行。", "debugify.fix_explanation.mc-30391": "新增對於雞、烈焰使者和凋零的邊緣案例,讓摔落傷害粒子效果不再生成。", "debugify.fix_explanation.mc-69216": "在切換成觀察者模式時捨棄釣竿的魚鉤。", "debugify.fix_explanation.mc-72151": "狼會有自訂函數來編輯修改所受到的傷害,將輸入傷害從 0 轉換為 0.5,這將修復檢查如果傷害為 0.5 時變更為 0。", "debugify.fix_explanation.mc-88371": "若中心的停留點已被摧毀,將把龍的降落點固定在 Y 65。", "debugify.fix_explanation.mc-89146": "提供一種更嚴格的儲存方塊實體的方式,來符合更新順序,這將允許初始化更新方塊實體時有正確的順序。", "debugify.fix_explanation.mc-93018": "只有在狼是已馴服狀態下開始繁殖過程。", "debugify.fix_explanation.mc-100991": "告知傷害追蹤器,拋出釣竿時對實體造成了 0 傷害,就像是雪球一樣。", "debugify.fix_explanation.mc-119417": "防止玩家在睡覺時切換成觀察者模式。", "debugify.fix_explanation.mc-119754": "告訴煙火實體,玩家並不是在觀察者模式中用鞘翅飛行。", "debugify.fix_explanation.mc-121706": "使用遠程弓箭的實體在攻擊時將強制看著目標。", "debugify.fix_explanation.mc-121903": "在指令方塊中新增「LastExecuted」NBT 標籤,以儲存與載入它們最後的執行屬性。", "debugify.fix_explanation.mc-124117": "在跨維度傳送後,向玩家發送封包以更新它們所有的效果、經驗值和能力。", "debugify.fix_explanation.mc-132878": "當盔甲座受到傷害時,正確生成破壞粒子效果。", "debugify.fix_explanation.mc-135971": "覆寫在合成欄中按下 Crtl+Q 的行為,使其重複按 Crtl+Q 直到合成欄沒有剩餘物品。", "debugify.fix_explanation.mc-155509": "在嘗試刺玩家前檢查河豚是否活著。", "debugify.fix_explanation.mc-160095": "如果仙人掌遇到活塞頭,則將考慮被推動的方塊,而不是活塞本身。", "debugify.fix_explanation.mc-179072": "在點燃自己之前檢查實體對於苦力怕來說是否還是敵人。", "debugify.fix_explanation.mc-183990": "當生物被運算時,它將會檢查目標是否死亡,如果是則將其從目標移除。這個修復還套用在一長串群攻的實體,不僅僅是蠹魚。", "debugify.fix_explanation.mc-193343": "當玩家切換至觀察者模式,移除靈魂疾走的移動速度加成。", "debugify.fix_explanation.mc-199467": "修改正弦函數和餘弦函數的輸入函數,使輸入從 0 到 2pi 循環。這可以防止發生任何整數溢出。雖然這個問題被回報於用戶端發生,但根源是兩個環境都有,因此被放在主要部分中。", "debugify.fix_explanation.mc-200418": "讓騎乘在雞上的幼年殭屍村民,在被治療後讓牠取消乘坐。", "debugify.fix_explanation.mc-206922": "存在時間低於 9 刻的物品,不會被雷擊移除掉。", "debugify.fix_explanation.mc-215530": "當玩家切換成觀察者模式時重設冰凍時間。", "debugify.fix_explanation.mc-224729": "無論區塊儲存條件返回是否是 false,始終儲存 ProtoChunks。" } ================================================ FILE: src/main/resources/debugify.mixins.json ================================================ { "required": true, "package": "dev.isxander.debugify.mixins", "compatibilityLevel": "JAVA_25", "injectors": { "defaultRequire": 1 }, "plugin": "dev.isxander.debugify.mixinplugin.MixinPlugin", "mixinextras": { "minVersion": "0.5.3" }, "mixins": [ "basic.mc100991.FishingHookMixin", "basic.mc119754.FireworkRocketEntityMixin", "basic.mc121706.RangedBowAttackGoalMixin", "basic.mc121903.MinecraftCommandBlockMixin", "basic.mc123450.ItemFrameMixin", "basic.mc129909.ServerPlayerMixin", "basic.mc131562.ServerGamePacketListenerImplMixin", "basic.mc132878.ArmorStandMixin", "basic.mc133218.ServerPlayerMixin", "basic.mc134110.ChestBlockMixin", "gameplay.mc136249.LivingEntityMixin", "basic.mc139041.FishingRodItemMixin", "basic.mc147659.CatSpawnerMixin", "basic.mc153010.FoxMixin", "basic.mc155509.PufferfishMixin", "basic.mc158900.PlayerListMixin", "basic.mc159283.DensityFunctionsMixin", "basic.mc160095.CactusBlockMixin", "basic.mc168573.BlocksAttacksMixin", "basic.mc170462.MobEffectsMixin", "basic.mc176806.RespawnAnchorBlockMixin", "basic.mc177381.LocateCommandMixin", "basic.mc179072.SwellGoalMixin", "basic.mc183990.MobMixin", "basic.mc187100.EnderDragonMixin", "basic.mc200418.ZombieVillagerMixin", "basic.mc201374.CampfireBlockMixin", "basic.mc202637.FoodPropertiesMixin", "basic.mc206922.EntityMixin", "basic.mc206922.ItemEntityMixin", "basic.mc215530.ServerPlayerMixin", "basic.mc221257.ShulkerBulletMixin", "basic.mc223153.BlocksMixin", "basic.mc224729.ChunkMapMixin", "basic.mc226961.ExperienceOrbMixin", "basic.mc227008.EnderManMixin", "basic.mc227337.ShulkerBulletMixin", "basic.mc231743.FlowerPotBlockMixin", "basic.mc232869.StriderMixin", "basic.mc245394.RaidMixin", "basic.mc263999.BreakDoorGoalMixin", "basic.mc264285.CreeperMixin", "basic.mc264979.SettingsMixin", "basic.mc267125.PlayerListMixin", "basic.mc268617.FileUtilMixin", "basic.mc271899.StructureTemplateMixin", "basic.mc272431.EnderDragonMixin", "basic.mc297837.WaypointTransmitterMixin", "basic.mc298066.LivingEntityMixin", "basic.mc30391.LivingEntityMixin", "basic.mc44654.EntityMixin", "basic.mc7569.RconConsoleSourceMixin", "basic.mc82263.EnderDragonMixin", "basic.mc84661.MobEffectsMixin", "basic.mc88371.DragonLandingPhaseMixin", "basic.mc89146.ChunkAccessMixin", "basic.mc93018.AnimalMixin", "basic.mc94054.WallClimberNavigationMixin", "errorhandler.CrashReportMixin", "gameplay.mc8187.TreeFeatureMixin" ] } ================================================ FILE: src/main/templates/fabric.mod.json ================================================ { "schemaVersion": 1, "id": "${mod_id}", "version": "${mod_version}", "name": "${mod_name}", "description": "${mod_description}\n\nCredits:\n${mod_credits}", "authors": [ "isXander" ], "contact": { "homepage": "https://isxander.dev", "issues": "https://github.com/isXander/Debugify/issues", "sources": "https://github.com/isXander/Debugify" }, "license": "LGPLv3", "environment": "*", "icon": "debugify.png", "entrypoints": { "main": [ "dev.isxander.debugify.Debugify::onInitialize" ], "client": [ "dev.isxander.debugify.client.DebugifyClient::onInitializeClient" ], "modmenu": [ "dev.isxander.debugify.client.integrations.ModMenuIntegration" ] }, "depends": { "fabricloader": ">=0.18.6", "minecraft": "~26.1", "java": ">=25", "fabric-resource-loader-v0": "*" }, "recommends": { "yet_another_config_lib_v3": "*", "modmenu": "*" }, "custom": { "modmenu": { "links": { "Patched Bugs": "https://github.com/isXander/Debugify/blob/main/PATCHED.md#unpatched-in-vanilla" } } } }