chore(history): squash 100 commit(s) from 2026-09-24
- fix(backend): case-insensitive unique email, revoke PUBLIC schema access, pin Argon2id params - test(backend): assert password length cap boundary (256 ok, 257 rejected) - docs(backend): plan — typed JWT token kinds so refresh/device tokens cannot pass as access tokens - feat(backend): JWT access/refresh token issue and verify - feat(backend): accounts repository (create/find_by_email/find_by_id) - refactor(gui): LoVisualAddonManagerScreen 989→10 файлов addon/ (8.5.2) - docs(backend): plan — fix sqlx::migrate! path in integration tests - feat(backend): POST /auth/register and /auth/login - refactor(settings): SettingsPanelComponent 715→81 + 6 helpers (8.5.2) - docs(backend): plan — harden device flow (single-use codes, bounded store, 404/429) - feat(backend): OAuth device authorization grant for mod login - fix(backend): first confirm wins for device codes - docs(backend): plan — split Task 8 (refactor) and Task 9 (avatars), harden avatar handling - refactor(mixins): LocalPlayerMixin 691→111 + 4 handlers (8.5.2) - refactor(visuals): Trails 687→130 (8.5.2) - refactor(render): ItemBatchRenderer 677->100 (8.5.2) - refactor(visuals): ReimaginedVisual 674→118 + 5 helpers (8.5.2) - refactor(config): ConfigSerializer 668→91 + 4 helpers (8.5.2) - refactor(hud): DynamicIsland 661→158 + 4 helpers (8.5.2) - refactor(render): GlStencilFramebufferSupport 666→169 (8.5.2) - refactor(gui): MenuScreen 669→128 + 4 helpers (8.5.2) - refactor(render): UiStyle 644→170 + 3 helpers (8.5.2) - refactor(gui): ModuleComponent 613→98 + 4 helpers (8.5.2) - refactor(media): MediaSessionService 616→200 + 4 helpers (8.5.2) - refactor(gui): RelationsComponent 661→59 + 4 helpers (8.5.2) - chore(license): strip GPL file headers from all Java sources - refactor(aiming): PointTracker 583→168 + 2 helpers (8.5.2) - refactor(gui): LoVisualProxyManagerScreen 591→132 + 2 helpers (8.5.2) - refactor(visuals): KillEffect 588→96 + 4 helpers (8.5.2) - refactor(render): MeshBuilder +4 helpers (8.5.2) - refactor(visuals): extract WorldParticlesRender helper (8.5.2) - refactor(world): ExplosionDamageUtil 551→116 + 2 helpers (8.5.2) - refactor(visuals): TazikHat 596->179 + Model + Palette in hats/tazik (8.5.2) - chore(license): strip GPL header from remaining 30 files and make strip script variant-aware - refactor(gui): ThemeComponent 561->166 + CardRenderer + ScrollState (8.5.2) - refactor(hud): CustomHotbar 556→178 + Renderer + Selection + SelectionGradient (8.5.2) - refactor(gui): ThemeCardRenderer perf + readability polish - refactor(clickgui): CooldownRulesSetting 596->198 + Editor + DetailRenderer (8.5.2) - refactor(hud): HudNotifier 561->200 + Painter + runtime/HudNotifierRuntime (8.5.2) - refactor(theme): Themes 555->168 + impl/Transition + impl/Blending + impl/ProfileCodec (8.5.2) - refactor(theme): EditableClickGuiTheme 205->185 + JavaDoc (8.5.2) - refactor(theme): ThemeStore 491->128 + store/ThemeStoreJson + store/ThemeStoreIO (8.5.2) - refactor(clickgui): ClickGuiRenderer 604->200 compacted one-line delegators + JavaDoc (8.5.2) - refactor(mainmenu): LoVisualMainMenuScreen 551->161 + impl/Painter + impl/Renderer + impl/TextUtil (8.5.2) - refactor(clickgui): ClickGuiTextEditorState 531->187 + impl/EditorCaret + impl/EditorPainter (8.5.2) - refactor(tab): TabListModel 525->139 + model/Collector + model/Reader + model/Signature + model/TextSplitter (8.5.2) - refactor(backend): shared bearer helper and test helpers, build_app takes Config, validate JWT secret strength - refactor(module): ModuleManager 521->198 + impl/Registrar + impl/Dispatcher (8.5.2) - feat(backend): avatar upload with decode, square crop, PNG re-encode and S3 storage - refactor(clip): ClipFunction 512->146 + impl/Geometry + impl/Debug (8.5.2) - docs(backend): implementation plans for gateway (auth hardening, gRPC, rate limits) and configs-service - refactor(iris-patch): ShaderPatchEngine 499->146 + impl/Repo (8.5.2) - chore(frontend): add router, react-query, fonts and vitest; dev proxy to gateway - refactor(hud): ScriptedListHudPanel 499->158 + panel/Props + panel/Signature (8.5.2) - refactor(hud): BaseHudElement 499->199 + impl/Registry + impl/Namer + impl/Prewarm (8.5.2) - refactor(clickgui): Setting 498->170 + impl/Localization + impl/I18n (8.5.2) - refact(viewmodel): split swing animations into camera/swing package - refact(kineticlyrics): split module into stage, playback and modes - rename(holeesp): module HoleESP -> CrystalHoles - refact(crystalholes): split module into crystal scanner, renderer and safety - refact(addonmanager): split manager into lifecycle, runtime, descriptors and profiles - refact(accountconfig): split config into store, session and value helpers - refactor(render): CustomTextRenderer 229->195, extract glyph-pass into GradientTexts helper - docs(TODO): mark AddonManager split done; close 9.2 refactor gate - refactor(media): LinuxMediaSession 441->148, split reader + track/seek state - refactor(nametags): split NameTags into facade + impl helpers - refactor(clickgui): split MainSettingsComponent into facade + scroll + model - refactor(hud): split CustomBar into facade, model and BarSettings - docs(frontend): implementation plan with design system from the mod theme - feat(frontend): design tokens from the mod theme, fonts and shared UI kit - fix(accounts): run migrations on startup, offload Argon2, validate register input, JSON error shape - docs(gateway): plan note on splitting auth handlers before refresh endpoints - feat(frontend): API client with silent refresh, error descriptions and test helpers - style(mod): group compact one-line bulk query methods in ModuleManager - feat(frontend): session restore, login and registration with client-side validation - refactor(hud): split CustomHealthBar into facade + painter + script renderer - docs(mod): record the 2026-09-24 HUD/settings split wave in TODO phase 8.5 - refactor(rhi): split GlStencilShapeClipBackend into facade + native-state + pass-lifecycle helpers - refactor(rhi): split VulkanRenderStateBridge into facade + MSAA and stencil state helpers - refactor(backtrack): split BacktrackController into facade + model + impl helpers - refactor(svg): split SvgPathParser into facade + arc geometry + command/curve helpers - refactor(mixin): split ClientPacketListenerMixin into hook-only mixin + handlers - refactor(renderer3d): un-nest batch bindings + culling into sibling impl types - refactor(renderwarp): extract static factories + geometry into impl helpers - feat(backend): add common crate with shared JWT, internal gateway contract and accounts proto - refactor(guimixin): move hook bodies into handlers, keep mixin as hooks + shadows - feat(accounts): accept only gateway traffic, read identity from gateway header - refactor(cacheduiscriptruntime): extract engine, hashing and frame stats into impl - refactor(customskyboxrenderer): extract projection, shader passes and sun into impl - refactor(betterchatstoremanager): extract persistence, key/path and hover helpers into impl - feat(accounts): rotating opaque refresh tokens in httpOnly cookie, /auth/refresh and /auth/logout - refactor(targetesp): extract crystal rendering subsystem into impl/TargetEspCrystalRenderer - refactor(betterchathovercache): extract disk codec and lookup indexing into impl/ChatHoverCacheCodec - refactor(microsoftauth): split HTTP transport, device-code and Xbox flows into impl/ - refactor(pvpcooldowns): extract local item-rule engine and defaults into impl/PvpCooldownRules - refactor(lovisual): extract HUD/world render orchestration into HudRender helper - refactor(statuseffectheuristics): extract palette/inference into ParticlePalette and color utils into ParticleColors - refactor(dropesp): extract overlay/label render subsystem into impl/DropEspOverlayRenderer - refactor(proxy): extract SOCKS handshake message builders into ProxyProtocolMessages - refactor(eagleutil): promote EdgeRecovery controller and RecoveryMode to top-level class
This commit is contained in:
parent
9d08fa910a
commit
72bc4c7148
1897 changed files with 36199 additions and 39289 deletions
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.blaze3d;
|
||||
|
||||
import com.mojang.blaze3d.GpuFormat;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.blaze3d;
|
||||
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.blaze3d;
|
||||
|
||||
import net.minecraft.client.renderer.PostChainConfig;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.blaze3d;
|
||||
|
||||
import com.mojang.blaze3d.shaders.ShaderType;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.chat;
|
||||
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.chat;
|
||||
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.chat;
|
||||
|
||||
import net.minecraft.client.gui.components.CommandSuggestions;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.chat;
|
||||
|
||||
import net.minecraft.client.gui.components.CommandSuggestions;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.entity;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.entity;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.entity;
|
||||
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.entity;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.hud;
|
||||
|
||||
import net.minecraft.client.gui.components.BossHealthOverlay;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.hud;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.hud;
|
||||
|
||||
import net.minecraft.client.gui.components.PlayerTabOverlay;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.hud;
|
||||
|
||||
import net.minecraft.client.gui.components.SpriteIconButton;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.inventory;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.inventory;
|
||||
|
||||
import net.minecraft.resources.Identifier;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.inventory;
|
||||
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.inventory;
|
||||
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.misc;
|
||||
|
||||
import net.minecraft.client.player.ClientInput;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.misc;
|
||||
|
||||
import com.mojang.blaze3d.platform.InputConstants;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.misc;
|
||||
|
||||
import com.mojang.authlib.minecraft.UserApiService;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.misc;
|
||||
|
||||
import net.minecraft.client.multiplayer.MultiPlayerGameMode;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.packet;
|
||||
|
||||
import net.minecraft.network.protocol.game.ClientboundExplodePacket;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.packet;
|
||||
|
||||
import net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.packet;
|
||||
|
||||
import net.minecraft.network.protocol.game.ServerboundInteractPacket;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.packet;
|
||||
|
||||
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.projectile;
|
||||
|
||||
import net.minecraft.world.entity.projectile.arrow.AbstractArrow;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.renderer;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.renderer;
|
||||
|
||||
import net.minecraft.client.renderer.entity.EntityRenderer;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.renderer;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.renderer;
|
||||
|
||||
import net.minecraft.client.renderer.rendertype.RenderSetup;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.state;
|
||||
|
||||
import net.minecraft.core.particles.SpellParticleOption;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.state;
|
||||
|
||||
import net.minecraft.world.item.component.Fireworks;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.state;
|
||||
|
||||
import net.minecraft.client.renderer.entity.state.LivingEntityRenderState;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.widget;
|
||||
|
||||
import net.minecraft.client.gui.components.AbstractWidget;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.widget;
|
||||
|
||||
import net.minecraft.client.gui.components.CycleButton;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.widget;
|
||||
|
||||
import net.minecraft.client.gui.components.AbstractSliderButton;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.widget;
|
||||
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.world;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.world;
|
||||
|
||||
import net.minecraft.client.renderer.entity.state.EntityRenderState;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.world;
|
||||
|
||||
import com.mojang.blaze3d.textures.GpuSampler;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.accessors.world;
|
||||
|
||||
import net.minecraft.world.level.Level;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.blaze3d.device;
|
||||
|
||||
import com.mojang.blaze3d.opengl.DirectStateAccess;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.blaze3d.device;
|
||||
|
||||
import com.mojang.blaze3d.GpuFormat;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.blaze3d.device;
|
||||
|
||||
import com.mojang.blaze3d.systems.GpuSurface;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.blaze3d.device;
|
||||
|
||||
import com.mojang.blaze3d.GpuFormat;
|
||||
|
|
@ -32,6 +25,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import dev.loki.lovisual.render.engine.rhi.backend.vulkan.util.VulkanRenderStateBridge;
|
||||
import dev.loki.lovisual.render.engine.rhi.backend.vulkan.util.VulkanPipelineVariantKey;
|
||||
import dev.loki.lovisual.util.logging.DebugLog;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
|
@ -46,7 +40,7 @@ public abstract class VulkanDeviceMixin {
|
|||
private ShaderSource defaultShaderSource;
|
||||
|
||||
@Unique
|
||||
private final Map<VulkanRenderStateBridge.PipelineVariantKey, VulkanRenderPipeline> lovisual$pipelineVariants = new HashMap<>();
|
||||
private final Map<VulkanPipelineVariantKey, VulkanRenderPipeline> lovisual$pipelineVariants = new HashMap<>();
|
||||
|
||||
@Invoker("compilePipeline")
|
||||
protected abstract VulkanRenderPipeline lovisual$compilePipelineVariant(RenderPipeline pipeline, ShaderSource source);
|
||||
|
|
@ -136,7 +130,7 @@ public abstract class VulkanDeviceMixin {
|
|||
CallbackInfoReturnable<VulkanRenderPipeline> cir) {
|
||||
if (!VulkanRenderStateBridge.needsPipelineVariant(pipeline)) return;
|
||||
|
||||
VulkanRenderStateBridge.PipelineVariantKey key = VulkanRenderStateBridge.pipelineVariantKey(pipeline);
|
||||
VulkanPipelineVariantKey key = VulkanRenderStateBridge.pipelineVariantKey(pipeline);
|
||||
VulkanRenderPipeline variant = lovisual$pipelineVariants.get(key);
|
||||
if (variant != null) {
|
||||
cir.setReturnValue(variant);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.blaze3d.encoder;
|
||||
|
||||
import net.minecraft.client.renderer.SubmitNodeCollection;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.blaze3d.encoder;
|
||||
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.blaze3d.encoder;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.blaze3d.pipeline;
|
||||
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.blaze3d.pipeline;
|
||||
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.blaze3d.pipeline;
|
||||
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.blaze3d.pipeline;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.blaze3d.shader;
|
||||
|
||||
import net.minecraft.client.renderer.DynamicUniformStorage;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.blaze3d.shader;
|
||||
|
||||
import com.mojang.blaze3d.opengl.GlStateManager;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.blaze3d.shader;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.blaze3d.texture;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.blaze3d.texture;
|
||||
|
||||
import com.mojang.blaze3d.opengl.GlTexture;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.blaze3d.texture;
|
||||
|
||||
import com.mojang.blaze3d.GpuFormat;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.blaze3d.texture;
|
||||
|
||||
import com.mojang.blaze3d.GpuFormat;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.entity.inventory;
|
||||
|
||||
import net.minecraft.resources.Identifier;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.entity.inventory;
|
||||
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.entity.inventory;
|
||||
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.entity.inventory;
|
||||
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.entity.living;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.entity.living;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.entity.player;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.entity.player;
|
||||
|
||||
import dev.loki.lovisual.features.module.lifecycle.Modules;
|
||||
|
|
|
|||
|
|
@ -1,35 +1,11 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.entity.player;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||
import dev.loki.lovisual.events.Events;
|
||||
import dev.loki.lovisual.events.impl.input.SprintControlEvent;
|
||||
import dev.loki.lovisual.events.impl.movement.MovementInputEvent;
|
||||
import dev.loki.lovisual.events.impl.network.EventPostSync;
|
||||
import dev.loki.lovisual.events.impl.network.EventSync;
|
||||
import dev.loki.lovisual.events.impl.player.PostPlayerUpdateEvent;
|
||||
import dev.loki.lovisual.events.impl.world.EventPushOutOfBlocks;
|
||||
import dev.loki.lovisual.util.combat.rotation.SprintController;
|
||||
import dev.loki.lovisual.util.screen.ClientScreen;
|
||||
import dev.loki.lovisual.mixininterface.entity.ILocalPlayer;
|
||||
import net.minecraft.client.player.ClientInput;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.PortalProcessor;
|
||||
import net.minecraft.world.entity.player.Input;
|
||||
import net.minecraft.world.entity.projectile.throwableitemprojectile.ThrownEnderpearl;
|
||||
import net.minecraft.world.inventory.InventoryMenu;
|
||||
import net.minecraft.world.level.entity.EntityTypeTest;
|
||||
import net.minecraft.world.phys.Vec2;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
|
@ -37,655 +13,92 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import dev.loki.lovisual.features.module.lifecycle.Modules;
|
||||
import dev.loki.lovisual.features.module.modules.visuals.camera.Freecam;
|
||||
import dev.loki.lovisual.mixininterface.entity.ILocalPlayer;
|
||||
import dev.loki.lovisual.mixins.accessors.entity.EntityAccessor;
|
||||
import dev.loki.lovisual.mixins.accessors.misc.InputAccessor;
|
||||
import dev.loki.lovisual.mixins.accessors.entity.LocalPlayerAccessor;
|
||||
import dev.loki.lovisual.util.aiming.rotation.RotationManager;
|
||||
import dev.loki.lovisual.util.aiming.data.Rotation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(LocalPlayer.class)
|
||||
public abstract class LocalPlayerMixin implements ILocalPlayer {
|
||||
|
||||
@Shadow
|
||||
public ClientInput input;
|
||||
@Unique
|
||||
private float lovisual$lastYaw;
|
||||
@Unique
|
||||
private float lovisual$lastPitch;
|
||||
@Unique
|
||||
private double lovisual$rotationPrevX;
|
||||
@Unique
|
||||
private double lovisual$rotationPrevZ;
|
||||
@Unique
|
||||
private float lovisual$rotationPrevBodyYaw;
|
||||
@Unique
|
||||
private boolean lovisual$rotationBodyYawInitialized;
|
||||
@Unique
|
||||
private float freecam$lastHealth = Float.NaN;
|
||||
@Unique
|
||||
private boolean frozen = false;
|
||||
@Unique
|
||||
private Vec3 savedVelocity = Vec3.ZERO;
|
||||
@Unique
|
||||
private double savedX, savedY, savedZ;
|
||||
@Unique
|
||||
private float savedBodyYaw;
|
||||
@Unique
|
||||
private float savedHeadYaw;
|
||||
@Unique
|
||||
private Runnable lovisual$eventPostAction;
|
||||
@Unique
|
||||
private EventSync lovisual$activeSyncEvent;
|
||||
@Unique
|
||||
private boolean lovisual$postUpdateLock = false;
|
||||
@Unique
|
||||
private Input lastInput;
|
||||
@Unique
|
||||
private boolean pendingSpoof = false;
|
||||
@Unique
|
||||
private int boostTicks = 0;
|
||||
@Unique
|
||||
private double boostX = 0, boostZ = 0;
|
||||
@Unique
|
||||
private boolean wasGround = true;
|
||||
@Shadow public ClientInput input;
|
||||
@Shadow protected abstract void sendPosition();
|
||||
|
||||
@Unique
|
||||
private static boolean lovisual$sameInput(Input a, Input b) {
|
||||
if (a == b) return true;
|
||||
if (a == null || b == null) return false;
|
||||
|
||||
return a.forward() == b.forward()
|
||||
&& a.backward() == b.backward()
|
||||
&& a.left() == b.left()
|
||||
&& a.right() == b.right()
|
||||
&& a.jump() == b.jump()
|
||||
&& a.shift() == b.shift()
|
||||
&& a.sprint() == b.sprint();
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static float lovisual$impulse(boolean positive, boolean negative) {
|
||||
if (positive == negative) {
|
||||
return 0.0f;
|
||||
}
|
||||
return positive ? 1.0f : -1.0f;
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static float lovisual$simulateBodyYaw(
|
||||
float yaw,
|
||||
float prevBodyYaw,
|
||||
double prevX,
|
||||
double prevZ,
|
||||
double currentX,
|
||||
double currentZ,
|
||||
float handSwingProgress
|
||||
) {
|
||||
double motionX = currentX - prevX;
|
||||
double motionZ = currentZ - prevZ;
|
||||
float motionSquared = (float) (motionX * motionX + motionZ * motionZ);
|
||||
float bodyYaw = prevBodyYaw;
|
||||
|
||||
if (motionSquared > 0.0025000002F) {
|
||||
float movementYaw = (float) Mth.atan2(motionZ, motionX) * Mth.RAD_TO_DEG - 90.0F;
|
||||
float yawDiff = Math.abs(Mth.wrapDegrees(yaw) - movementYaw);
|
||||
bodyYaw = (yawDiff > 95.0F && yawDiff < 265.0F) ? movementYaw - 180.0F : movementYaw;
|
||||
}
|
||||
|
||||
if (handSwingProgress - 0.2F > 0.0F) {
|
||||
bodyYaw = yaw;
|
||||
}
|
||||
|
||||
float deltaYaw = Mth.wrapDegrees(bodyYaw - prevBodyYaw);
|
||||
bodyYaw = prevBodyYaw + deltaYaw * 0.3F;
|
||||
|
||||
float yawOffsetDiff = Mth.wrapDegrees(yaw - bodyYaw);
|
||||
float maxHeadRotation = 52.0F;
|
||||
if (Math.abs(yawOffsetDiff) > maxHeadRotation) {
|
||||
bodyYaw += yawOffsetDiff - Math.signum(yawOffsetDiff) * maxHeadRotation;
|
||||
}
|
||||
|
||||
return bodyYaw;
|
||||
}
|
||||
@Unique private float lovisual$lastYaw;
|
||||
@Unique private float lovisual$lastPitch;
|
||||
@Unique private final LocalPlayerInputHandler lovisual$inputHandler = new LocalPlayerInputHandler();
|
||||
@Unique private final LocalPlayerRotationHandler lovisual$rotationHandler = new LocalPlayerRotationHandler();
|
||||
@Unique private final LocalPlayerNetworkHandler lovisual$networkHandler = new LocalPlayerNetworkHandler();
|
||||
@Unique private final LocalPlayerMovementHandler lovisual$movementHandler = new LocalPlayerMovementHandler();
|
||||
|
||||
@Inject(method = "tick", at = @At("HEAD"))
|
||||
private void lovisual$cacheLastRotations(CallbackInfo ci) {
|
||||
LocalPlayer self = (LocalPlayer) (Object) this;
|
||||
lovisual$lastYaw = self.getYRot();
|
||||
lovisual$lastPitch = self.getXRot();
|
||||
RotationManager.INSTANCE.runTickLifecycle();
|
||||
if (!lovisual$rotationBodyYawInitialized) {
|
||||
lovisual$rotationPrevX = self.getX();
|
||||
lovisual$rotationPrevZ = self.getZ();
|
||||
lovisual$rotationPrevBodyYaw = self.getVisualRotationYInDegrees();
|
||||
lovisual$rotationBodyYawInitialized = true;
|
||||
}
|
||||
lovisual$rotationHandler.onTickCache((LocalPlayer) (Object) this);
|
||||
}
|
||||
|
||||
@Inject(method = "handlePortalTransitionEffect", at = @At("HEAD"), cancellable = true)
|
||||
private void lovisual$disablePortalNausea(boolean inPortal, CallbackInfo ci) {
|
||||
|
||||
LocalPlayer self = (LocalPlayer) (Object) this;
|
||||
PortalProcessor portalManager = null;
|
||||
if (self instanceof EntityAccessor accessor) {
|
||||
portalManager = accessor.lovisual$getPortalManager();
|
||||
}
|
||||
if (portalManager != null && portalManager.isInsidePortalThisTick()) {
|
||||
if (self instanceof LocalPlayerAccessor accessor) {
|
||||
accessor.lovisual$setNauseaIntensity(0.0f);
|
||||
accessor.lovisual$setLastNauseaIntensity(0.0f);
|
||||
}
|
||||
ci.cancel();
|
||||
}
|
||||
lovisual$movementHandler.onPortalNausea((LocalPlayer) (Object) this, ci);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float lovisual$getLastYaw() {
|
||||
return lovisual$lastYaw;
|
||||
}
|
||||
@Override public float lovisual$getLastYaw() { return lovisual$lastYaw; }
|
||||
@Override public float lovisual$getLastPitch() { return lovisual$lastPitch; }
|
||||
@Override public void lovisual$setLastYaw(float yaw) { lovisual$lastYaw = yaw; }
|
||||
@Override public void lovisual$setLastPitch(float pitch) { lovisual$lastPitch = pitch; }
|
||||
|
||||
@Override
|
||||
public float lovisual$getLastPitch() {
|
||||
return lovisual$lastPitch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lovisual$setLastYaw(float yaw) {
|
||||
this.lovisual$lastYaw = yaw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lovisual$setLastPitch(float pitch) {
|
||||
this.lovisual$lastPitch = pitch;
|
||||
}
|
||||
|
||||
@ModifyExpressionValue(
|
||||
method = "aiStep",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/player/LocalPlayer;canStartSprinting()Z"
|
||||
)
|
||||
)
|
||||
@ModifyExpressionValue(method = "aiStep", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;canStartSprinting()Z"))
|
||||
private boolean lovisual$sprintMovementStart(boolean original) {
|
||||
return lovisual$postSprintControl(original, SprintControlEvent.Source.MOVEMENT_TICK);
|
||||
return lovisual$inputHandler.postSprintControl((LocalPlayer) (Object) this, original, SprintControlEvent.Source.MOVEMENT_TICK);
|
||||
}
|
||||
|
||||
@ModifyExpressionValue(
|
||||
method = "aiStep",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/entity/player/Input;sprint()Z"
|
||||
)
|
||||
)
|
||||
@ModifyExpressionValue(method = "aiStep", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Input;sprint()Z"))
|
||||
private boolean lovisual$sprintMovementInput(boolean original) {
|
||||
return lovisual$postSprintControl(original, SprintControlEvent.Source.MOVEMENT_TICK);
|
||||
return lovisual$inputHandler.postSprintControl((LocalPlayer) (Object) this, original, SprintControlEvent.Source.MOVEMENT_TICK);
|
||||
}
|
||||
|
||||
@ModifyExpressionValue(
|
||||
method = "sendIsSprintingIfNeeded",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/player/LocalPlayer;isSprinting()Z"
|
||||
)
|
||||
)
|
||||
@ModifyExpressionValue(method = "sendIsSprintingIfNeeded", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;isSprinting()Z"))
|
||||
private boolean lovisual$sprintNetwork(boolean original) {
|
||||
if (SprintController.INSTANCE.isSprintBlocked()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return original;
|
||||
return lovisual$networkHandler.shouldBlockSprintNetwork(original);
|
||||
}
|
||||
|
||||
@Unique
|
||||
private boolean lovisual$postSprintControl(boolean original, SprintControlEvent.Source source) {
|
||||
LocalPlayer self = (LocalPlayer) (Object) this;
|
||||
|
||||
if (self.input == null) {
|
||||
return original;
|
||||
}
|
||||
|
||||
if (!Events.BUS.hasListeners(SprintControlEvent.class)) {
|
||||
return original;
|
||||
}
|
||||
|
||||
Vec2 movement = self.input.getMoveVector();
|
||||
SprintControlEvent event = new SprintControlEvent(
|
||||
movement.y,
|
||||
movement.x,
|
||||
original,
|
||||
source
|
||||
);
|
||||
Events.BUS.post(event);
|
||||
return event.shouldSprint();
|
||||
}
|
||||
|
||||
@Inject(method = "modifyInput", at = @At("RETURN"), cancellable = true)
|
||||
private void boostWhenUsing(Vec2 input, CallbackInfoReturnable<Vec2> cir) {
|
||||
// NoStun module removed; no item-use speed boost remains.
|
||||
}
|
||||
|
||||
@Inject(method = "aiStep", at = @At("HEAD"))
|
||||
private void lovisual$elytraFlyVanilla(CallbackInfo ci) {
|
||||
// ElytraFly module removed; no vanilla elytra override remains.
|
||||
}
|
||||
|
||||
@Shadow
|
||||
protected abstract void sendPosition();
|
||||
|
||||
@Inject(method = "applyInput", at = @At("HEAD"), cancellable = true)
|
||||
private void freecam$blockWASD(CallbackInfo ci) {
|
||||
Freecam fc = Modules.get(Freecam.class);
|
||||
if (fc != null && fc.isEnabled() && fc.isCameraInput()) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
private void freecam$blockWASD(CallbackInfo ci) { if (lovisual$inputHandler.shouldBlockWASD()) ci.cancel(); }
|
||||
|
||||
@Inject(
|
||||
method = "aiStep",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/player/ClientInput;tick()V",
|
||||
shift = At.Shift.AFTER
|
||||
)
|
||||
)
|
||||
private void freecam$afterInputTick(CallbackInfo ci) {
|
||||
Freecam fc = Modules.get(Freecam.class);
|
||||
if (fc == null || !fc.isEnabled() || !fc.isCameraInput()) return;
|
||||
@Inject(method = "aiStep", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/ClientInput;tick()V", shift = At.Shift.AFTER))
|
||||
private void freecam$afterInputTick(CallbackInfo ci) { lovisual$inputHandler.handleFreecamAfterInputTick((LocalPlayer) (Object) this); }
|
||||
|
||||
((InputAccessor) this.input).setMovementVector(Vec2.ZERO);
|
||||
@Inject(method = "aiStep", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/ClientInput;tick()V", shift = At.Shift.AFTER))
|
||||
private void lovisual$afterInputTickSprint(CallbackInfo ci) { lovisual$inputHandler.handleAfterInputTickSprint((LocalPlayer) (Object) this); }
|
||||
|
||||
boolean sneak = false;
|
||||
boolean sprint = this.input.keyPresses.sprint();
|
||||
@Redirect(method = "aiStep", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Input;shift()Z", ordinal = 0))
|
||||
private boolean freecam$noFlyDown0(Input in) { return lovisual$inputHandler.redirectShift(in, (LocalPlayer) (Object) this); }
|
||||
|
||||
this.input.keyPresses = new Input(
|
||||
false, false, false, false,
|
||||
false,
|
||||
sneak,
|
||||
sprint
|
||||
);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "aiStep",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/player/ClientInput;tick()V",
|
||||
shift = At.Shift.AFTER
|
||||
)
|
||||
)
|
||||
private void lovisual$afterInputTickSprint(CallbackInfo ci) {
|
||||
if (this.input == null) return;
|
||||
|
||||
Input original = this.input.keyPresses;
|
||||
if (original == null) return;
|
||||
|
||||
Input input = original;
|
||||
|
||||
if (Events.BUS.hasListeners(MovementInputEvent.class)) {
|
||||
MovementInputEvent event = new MovementInputEvent(input);
|
||||
Events.BUS.post(event);
|
||||
|
||||
Input eventInput = event.toPlayerInput();
|
||||
if (!lovisual$sameInput(input, eventInput)) {
|
||||
input = eventInput;
|
||||
}
|
||||
}
|
||||
|
||||
Input transformedInput = lovisual$transformDirection(input);
|
||||
if (!lovisual$sameInput(input, transformedInput)) {
|
||||
input = transformedInput;
|
||||
}
|
||||
|
||||
if (Events.BUS.hasListeners(SprintControlEvent.class)) {
|
||||
float forward = lovisual$impulse(input.forward(), input.backward());
|
||||
float sideways = lovisual$impulse(input.left(), input.right());
|
||||
|
||||
SprintControlEvent event = new SprintControlEvent(
|
||||
forward,
|
||||
sideways,
|
||||
input.sprint(),
|
||||
SprintControlEvent.Source.INPUT
|
||||
);
|
||||
Events.BUS.post(event);
|
||||
|
||||
if (event.shouldSprint() != input.sprint()) {
|
||||
input = new Input(
|
||||
input.forward(),
|
||||
input.backward(),
|
||||
input.left(),
|
||||
input.right(),
|
||||
input.jump(),
|
||||
input.shift(),
|
||||
event.shouldSprint()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!lovisual$sameInput(original, input)) {
|
||||
lovisual$applyPlayerInput(input);
|
||||
}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void lovisual$applyPlayerInput(Input input) {
|
||||
if (this.input == null || input == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
InputAccessor accessor = (InputAccessor) this.input;
|
||||
accessor.setPlayerInput(input);
|
||||
|
||||
float forward = lovisual$impulse(input.forward(), input.backward());
|
||||
float sideways = lovisual$impulse(input.left(), input.right());
|
||||
|
||||
accessor.setMovementVector(new Vec2(sideways, forward).normalized());
|
||||
}
|
||||
|
||||
@Unique
|
||||
private Input lovisual$transformDirection(Input input) {
|
||||
// Free correction now runs at KeyboardInput.tick(), matching the input pipeline.
|
||||
// Keep this post-input hook inert to avoid double-transforming movement input.
|
||||
return input;
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "aiStep",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/entity/player/Input;shift()Z",
|
||||
ordinal = 0
|
||||
)
|
||||
)
|
||||
private boolean freecam$noFlyDown0(Input in) {
|
||||
Freecam fc = Modules.get(Freecam.class);
|
||||
if (fc != null && fc.isEnabled() && fc.isCameraInput()) {
|
||||
LocalPlayer self = (LocalPlayer) (Object) this;
|
||||
if (self.getAbilities().flying) return false;
|
||||
}
|
||||
return in.shift();
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "aiStep",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/entity/player/Input;shift()Z",
|
||||
ordinal = 1
|
||||
),
|
||||
require = 0
|
||||
)
|
||||
private boolean freecam$noFlyDown1(Input in) {
|
||||
Freecam fc = Modules.get(Freecam.class);
|
||||
if (fc != null && fc.isEnabled() && fc.isCameraInput()) {
|
||||
LocalPlayer self = (LocalPlayer) (Object) this;
|
||||
if (self.getAbilities().flying) return false;
|
||||
}
|
||||
return in.shift();
|
||||
}
|
||||
@Redirect(method = "aiStep", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Input;shift()Z", ordinal = 1), require = 0)
|
||||
private boolean freecam$noFlyDown1(Input in) { return lovisual$inputHandler.redirectShift(in, (LocalPlayer) (Object) this); }
|
||||
|
||||
@Inject(method = "hurtTo", at = @At("HEAD"))
|
||||
private void freecam$onUpdateHealth(float newHealth, CallbackInfo ci) {
|
||||
Freecam fc = Modules.get(Freecam.class);
|
||||
|
||||
if (fc == null || !fc.isEnabled() || !fc.disableOnDamage()) {
|
||||
freecam$lastHealth = newHealth;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Float.isNaN(freecam$lastHealth) && newHealth < freecam$lastHealth) {
|
||||
fc.toggle();
|
||||
}
|
||||
|
||||
freecam$lastHealth = newHealth;
|
||||
}
|
||||
|
||||
@Unique
|
||||
private boolean shouldFreezeNow() {
|
||||
Freecam freecam = Modules.get(Freecam.class);
|
||||
return freecam != null && freecam.freezePlayer() && freecam.isCameraInput();
|
||||
}
|
||||
private void freecam$onUpdateHealth(float newHealth, CallbackInfo ci) { lovisual$movementHandler.onHurt(newHealth); }
|
||||
|
||||
@Inject(method = "sendPosition", at = @At("HEAD"), cancellable = true)
|
||||
private void lovisual$eventSync(CallbackInfo ci) {
|
||||
if (!Events.BUS.hasListeners(EventSync.class)) return;
|
||||
lovisual$eventPostAction = null;
|
||||
LocalPlayer self = (LocalPlayer) (Object) this;
|
||||
EventSync event = new EventSync(self.getYRot(), self.getXRot());
|
||||
Events.BUS.post(event);
|
||||
lovisual$activeSyncEvent = event;
|
||||
lovisual$eventPostAction = event.getPostAction();
|
||||
if (event.isCancelled()) {
|
||||
lovisual$activeSyncEvent = null;
|
||||
lovisual$eventPostAction = null;
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
private void lovisual$eventSync(CallbackInfo ci) { lovisual$networkHandler.onSendPositionHead((LocalPlayer) (Object) this, ci); }
|
||||
|
||||
@Inject(method = "sendPosition", at = @At("RETURN"))
|
||||
private void lovisual$eventPostSync(CallbackInfo ci) {
|
||||
if (Events.BUS.hasListeners(EventPostSync.class)) {
|
||||
Events.BUS.post(new EventPostSync());
|
||||
}
|
||||
if (lovisual$eventPostAction != null) {
|
||||
lovisual$eventPostAction.run();
|
||||
lovisual$eventPostAction = null;
|
||||
}
|
||||
lovisual$activeSyncEvent = null;
|
||||
}
|
||||
private void lovisual$eventPostSync(CallbackInfo ci) { lovisual$networkHandler.onSendPositionReturn(); }
|
||||
|
||||
@ModifyExpressionValue(
|
||||
method = "sendPosition",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/player/LocalPlayer;getYRot()F"
|
||||
)
|
||||
)
|
||||
private float lovisual$eventSyncYaw(float original) {
|
||||
lovisual$updateVisualBodyYaw();
|
||||
@ModifyExpressionValue(method = "sendPosition", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;getYRot()F"))
|
||||
private float lovisual$eventSyncYaw(float original) { return lovisual$rotationHandler.resolveSendYaw((LocalPlayer) (Object) this, original, lovisual$networkHandler.getActiveSyncEvent()); }
|
||||
|
||||
EventSync event = lovisual$activeSyncEvent;
|
||||
if (event != null && event.hasRotationOverride()) return event.getYaw();
|
||||
@ModifyExpressionValue(method = "sendPosition", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;getXRot()F"))
|
||||
private float lovisual$eventSyncPitch(float original) { return lovisual$rotationHandler.resolveSendPitch(original, lovisual$networkHandler.getActiveSyncEvent()); }
|
||||
|
||||
Rotation rotation = RotationManager.INSTANCE.getCurrentRotation();
|
||||
return rotation != null ? rotation.yaw() : original;
|
||||
}
|
||||
@ModifyExpressionValue(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;getYRot()F"))
|
||||
private float lovisual$visualTickYaw(float original) { return lovisual$rotationHandler.resolveTickYaw((LocalPlayer) (Object) this, original); }
|
||||
|
||||
@ModifyExpressionValue(
|
||||
method = "sendPosition",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/player/LocalPlayer;getXRot()F"
|
||||
)
|
||||
)
|
||||
private float lovisual$eventSyncPitch(float original) {
|
||||
EventSync event = lovisual$activeSyncEvent;
|
||||
if (event != null && event.hasRotationOverride()) return Mth.clamp(event.getPitch(), -90.0f, 90.0f);
|
||||
@ModifyExpressionValue(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;getXRot()F"))
|
||||
private float lovisual$visualTickPitch(float original) { return lovisual$rotationHandler.resolveTickPitch(original); }
|
||||
|
||||
Rotation rotation = RotationManager.INSTANCE.getCurrentRotation();
|
||||
return rotation != null ? Mth.clamp(rotation.pitch(), -90.0f, 90.0f) : original;
|
||||
}
|
||||
|
||||
@ModifyExpressionValue(
|
||||
method = "tick",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/player/LocalPlayer;getYRot()F"
|
||||
)
|
||||
)
|
||||
private float lovisual$visualTickYaw(float original) {
|
||||
lovisual$updateVisualBodyYaw();
|
||||
|
||||
Rotation rotation = RotationManager.INSTANCE.getCurrentRotation();
|
||||
return rotation != null ? rotation.yaw() : original;
|
||||
}
|
||||
|
||||
@ModifyExpressionValue(
|
||||
method = "tick",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/player/LocalPlayer;getXRot()F"
|
||||
)
|
||||
)
|
||||
private float lovisual$visualTickPitch(float original) {
|
||||
Rotation rotation = RotationManager.INSTANCE.getCurrentRotation();
|
||||
return rotation != null ? Mth.clamp(rotation.pitch(), -90.0f, 90.0f) : original;
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "tick",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/player/LocalPlayer;sendPosition()V",
|
||||
ordinal = 0,
|
||||
shift = At.Shift.AFTER
|
||||
),
|
||||
cancellable = true
|
||||
)
|
||||
private void lovisual$postPlayerUpdate(CallbackInfo ci) {
|
||||
if (!Events.BUS.hasListeners(PostPlayerUpdateEvent.class)) return;
|
||||
if (lovisual$postUpdateLock) return;
|
||||
|
||||
PostPlayerUpdateEvent event = new PostPlayerUpdateEvent();
|
||||
Events.BUS.post(event);
|
||||
|
||||
if (!event.isCancelled()) return;
|
||||
|
||||
ci.cancel();
|
||||
|
||||
int iterations = event.getIterations();
|
||||
if (iterations <= 0) return;
|
||||
|
||||
LocalPlayer self = (LocalPlayer) (Object) this;
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
lovisual$postUpdateLock = true;
|
||||
self.tick();
|
||||
lovisual$postUpdateLock = false;
|
||||
sendPosition();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "sendPosition", at = @At("HEAD"), cancellable = true)
|
||||
private void cancelPackets(CallbackInfo ci) {
|
||||
// Freeze module removed; only Freecam may still freeze movement.
|
||||
}
|
||||
@Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;sendPosition()V", ordinal = 0, shift = At.Shift.AFTER), cancellable = true)
|
||||
private void lovisual$postPlayerUpdate(CallbackInfo ci) { lovisual$networkHandler.onPostPlayerUpdate((LocalPlayer) (Object) this, ci, this::sendPosition); }
|
||||
|
||||
@Inject(method = "aiStep", at = @At("HEAD"), cancellable = true)
|
||||
private void lovisual$freezeTickMovement(CallbackInfo ci) {
|
||||
LocalPlayer p = (LocalPlayer) (Object) this;
|
||||
|
||||
if (!shouldFreezeNow()) {
|
||||
if (frozen) {
|
||||
p.setDeltaMovement(savedVelocity);
|
||||
frozen = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!frozen) {
|
||||
frozen = true;
|
||||
savedX = p.getX();
|
||||
savedY = p.getY();
|
||||
savedZ = p.getZ();
|
||||
savedVelocity = p.getDeltaMovement();
|
||||
|
||||
if (Modules.get(Freecam.class) == null || !Modules.get(Freecam.class).isEnabled()) {
|
||||
savedBodyYaw = p.yBodyRot;
|
||||
savedHeadYaw = p.yHeadRot;
|
||||
}
|
||||
}
|
||||
|
||||
p.setDeltaMovement(Vec3.ZERO);
|
||||
p.absSnapTo(savedX, savedY, savedZ);
|
||||
|
||||
if (Modules.get(Freecam.class) == null || !Modules.get(Freecam.class).isEnabled()) {
|
||||
p.yBodyRot = savedBodyYaw;
|
||||
p.yHeadRot = savedHeadYaw;
|
||||
}
|
||||
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
@Inject(method = "aiStep", at = @At("HEAD"))
|
||||
private void lovisual$noStunTickMovement(CallbackInfo ci) {
|
||||
// NoStun module removed; no hurt-time input override remains.
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void lovisual$updateVisualBodyYaw() {
|
||||
LocalPlayer self = (LocalPlayer) (Object) this;
|
||||
Rotation rotation = RotationManager.INSTANCE.getCurrentRotation();
|
||||
if (rotation == null) {
|
||||
lovisual$rotationPrevX = self.getX();
|
||||
lovisual$rotationPrevZ = self.getZ();
|
||||
lovisual$rotationPrevBodyYaw = self.getVisualRotationYInDegrees();
|
||||
return;
|
||||
}
|
||||
|
||||
float newBodyYaw = lovisual$simulateBodyYaw(
|
||||
rotation.yaw(),
|
||||
lovisual$rotationPrevBodyYaw,
|
||||
lovisual$rotationPrevX,
|
||||
lovisual$rotationPrevZ,
|
||||
self.getX(),
|
||||
self.getZ(),
|
||||
self.attackAnim
|
||||
);
|
||||
|
||||
self.setYBodyRot(newBodyYaw);
|
||||
lovisual$rotationPrevBodyYaw = newBodyYaw;
|
||||
lovisual$rotationPrevX = self.getX();
|
||||
lovisual$rotationPrevZ = self.getZ();
|
||||
}
|
||||
|
||||
@Inject(method = "tick", at = @At("HEAD"))
|
||||
private void detectPearlImpact(CallbackInfo ci) {
|
||||
// NoPush module removed; no pearl-phase spoofing remains.
|
||||
}
|
||||
|
||||
@Inject(method = "sendPosition", at = @At("HEAD"))
|
||||
private void sendSpoofAfterPearl(CallbackInfo ci) {
|
||||
// NoPush module removed; no pearl-phase spoofing remains.
|
||||
}
|
||||
|
||||
@Inject(method = "aiStep", at = @At("TAIL"))
|
||||
private void onCollideBoost(CallbackInfo ci) {
|
||||
// Speed module removed; no entity-collision boost remains.
|
||||
}
|
||||
|
||||
@Inject(method = "aiStep", at = @At("TAIL"))
|
||||
private void omniLongJump(CallbackInfo ci) {
|
||||
// Speed module removed; no jump boost remains.
|
||||
}
|
||||
|
||||
@Inject(method = "modifyInput", at = @At("RETURN"), cancellable = true)
|
||||
private void applyLegitSpeed(Vec2 input, CallbackInfoReturnable<Vec2> cir) {
|
||||
// Speed module removed; no input speed multiplier remains.
|
||||
}
|
||||
|
||||
@Inject(method = "closeContainer", at = @At("HEAD"), cancellable = true)
|
||||
private void lovisual$inventoryMove$deferCloseHandledScreen(CallbackInfo ci) {
|
||||
// InventoryMove module removed; no container close deferral remains.
|
||||
}
|
||||
|
||||
@Inject(method = "closeContainer", at = @At("HEAD"), cancellable = true)
|
||||
private void lovisual$keepInventoryOpen(CallbackInfo ci) {
|
||||
// XCarry module removed; no inventory close suppression remains.
|
||||
}
|
||||
private void lovisual$freezeTickMovement(CallbackInfo ci) { lovisual$movementHandler.onFreezeTick((LocalPlayer) (Object) this, ci); }
|
||||
|
||||
@Inject(method = "moveTowardsClosestSpace", at = @At("HEAD"), cancellable = true)
|
||||
private void lovisual$noPushOutOfBlocks(double x, double z, CallbackInfo ci) {
|
||||
if (!Events.BUS.hasListeners(EventPushOutOfBlocks.class)) return;
|
||||
EventPushOutOfBlocks event = new EventPushOutOfBlocks(x, z);
|
||||
Events.BUS.post(event);
|
||||
if (event.isCancelled()) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
private void lovisual$noPushOutOfBlocks(double x, double z, CallbackInfo ci) { lovisual$movementHandler.onPushOutOfBlocks(x, z, ci); }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.entity.player;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
package dev.loki.lovisual.mixins.entity.player;
|
||||
|
||||
import dev.loki.lovisual.events.Events;
|
||||
import dev.loki.lovisual.events.impl.input.SprintControlEvent;
|
||||
import dev.loki.lovisual.events.impl.movement.MovementInputEvent;
|
||||
import dev.loki.lovisual.features.module.lifecycle.Modules;
|
||||
import dev.loki.lovisual.features.module.modules.visuals.camera.Freecam;
|
||||
import dev.loki.lovisual.mixins.accessors.misc.InputAccessor;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.world.entity.player.Input;
|
||||
import net.minecraft.world.phys.Vec2;
|
||||
|
||||
final class LocalPlayerInputHandler {
|
||||
|
||||
boolean shouldBlockWASD() {
|
||||
Freecam fc = Modules.get(Freecam.class);
|
||||
return fc != null && fc.isEnabled() && fc.isCameraInput();
|
||||
}
|
||||
|
||||
void handleFreecamAfterInputTick(LocalPlayer self) {
|
||||
Freecam fc = Modules.get(Freecam.class);
|
||||
if (fc == null || !fc.isEnabled() || !fc.isCameraInput()) return;
|
||||
if (self.input == null) return;
|
||||
((InputAccessor) self.input).setMovementVector(Vec2.ZERO);
|
||||
boolean sprint = self.input.keyPresses.sprint();
|
||||
self.input.keyPresses = new Input(false, false, false, false, false, false, sprint);
|
||||
}
|
||||
|
||||
void handleAfterInputTickSprint(LocalPlayer self) {
|
||||
if (self.input == null) return;
|
||||
Input original = self.input.keyPresses;
|
||||
if (original == null) return;
|
||||
Input input = original;
|
||||
if (Events.BUS.hasListeners(MovementInputEvent.class)) {
|
||||
MovementInputEvent event = new MovementInputEvent(input);
|
||||
Events.BUS.post(event);
|
||||
Input converted = event.toPlayerInput();
|
||||
if (!sameInput(input, converted)) input = converted;
|
||||
}
|
||||
Input transformed = transformDirection(input);
|
||||
if (!sameInput(input, transformed)) input = transformed;
|
||||
if (Events.BUS.hasListeners(SprintControlEvent.class)) {
|
||||
float forward = impulse(input.forward(), input.backward());
|
||||
float sideways = impulse(input.left(), input.right());
|
||||
SprintControlEvent event = new SprintControlEvent(forward, sideways, input.sprint(), SprintControlEvent.Source.INPUT);
|
||||
Events.BUS.post(event);
|
||||
if (event.shouldSprint() != input.sprint()) {
|
||||
input = new Input(input.forward(), input.backward(), input.left(), input.right(), input.jump(), input.shift(), event.shouldSprint());
|
||||
}
|
||||
}
|
||||
if (!sameInput(original, input)) applyPlayerInput(self, input);
|
||||
}
|
||||
|
||||
void applyPlayerInput(LocalPlayer self, Input input) {
|
||||
if (self.input == null || input == null) return;
|
||||
InputAccessor accessor = (InputAccessor) self.input;
|
||||
accessor.setPlayerInput(input);
|
||||
float forward = impulse(input.forward(), input.backward());
|
||||
float sideways = impulse(input.left(), input.right());
|
||||
accessor.setMovementVector(new Vec2(sideways, forward).normalized());
|
||||
}
|
||||
|
||||
Input transformDirection(Input input) { return input; }
|
||||
|
||||
boolean postSprintControl(LocalPlayer self, boolean original, SprintControlEvent.Source source) {
|
||||
if (self.input == null) return original;
|
||||
if (!Events.BUS.hasListeners(SprintControlEvent.class)) return original;
|
||||
Vec2 movement = self.input.getMoveVector();
|
||||
SprintControlEvent event = new SprintControlEvent(movement.y, movement.x, original, source);
|
||||
Events.BUS.post(event);
|
||||
return event.shouldSprint();
|
||||
}
|
||||
|
||||
boolean redirectShift(Input in, LocalPlayer self) {
|
||||
Freecam fc = Modules.get(Freecam.class);
|
||||
if (fc != null && fc.isEnabled() && fc.isCameraInput() && self.getAbilities().flying) return false;
|
||||
return in.shift();
|
||||
}
|
||||
|
||||
boolean sameInput(Input a, Input b) {
|
||||
if (a == b) return true;
|
||||
if (a == null || b == null) return false;
|
||||
return a.forward() == b.forward() && a.backward() == b.backward() && a.left() == b.left() && a.right() == b.right() && a.jump() == b.jump() && a.shift() == b.shift() && a.sprint() == b.sprint();
|
||||
}
|
||||
|
||||
float impulse(boolean positive, boolean negative) {
|
||||
if (positive == negative) return 0.0f;
|
||||
return positive ? 1.0f : -1.0f;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
package dev.loki.lovisual.mixins.entity.player;
|
||||
|
||||
import dev.loki.lovisual.events.Events;
|
||||
import dev.loki.lovisual.events.impl.world.EventPushOutOfBlocks;
|
||||
import dev.loki.lovisual.features.module.lifecycle.Modules;
|
||||
import dev.loki.lovisual.features.module.modules.visuals.camera.Freecam;
|
||||
import dev.loki.lovisual.mixins.accessors.entity.EntityAccessor;
|
||||
import dev.loki.lovisual.mixins.accessors.entity.LocalPlayerAccessor;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.world.entity.PortalProcessor;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
final class LocalPlayerMovementHandler {
|
||||
|
||||
private float lastHealth = Float.NaN;
|
||||
private boolean frozen;
|
||||
private Vec3 savedVelocity = Vec3.ZERO;
|
||||
private double savedX, savedY, savedZ;
|
||||
private float savedBodyYaw, savedHeadYaw;
|
||||
|
||||
void onPortalNausea(LocalPlayer self, CallbackInfo ci) {
|
||||
PortalProcessor portal = null;
|
||||
if (self instanceof EntityAccessor accessor) portal = accessor.lovisual$getPortalManager();
|
||||
if (portal != null && portal.isInsidePortalThisTick()) {
|
||||
if (self instanceof LocalPlayerAccessor acc) {
|
||||
acc.lovisual$setNauseaIntensity(0.0f);
|
||||
acc.lovisual$setLastNauseaIntensity(0.0f);
|
||||
}
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
void onHurt(float newHealth) {
|
||||
Freecam fc = Modules.get(Freecam.class);
|
||||
if (fc == null || !fc.isEnabled() || !fc.disableOnDamage()) { lastHealth = newHealth; return; }
|
||||
if (!Float.isNaN(lastHealth) && newHealth < lastHealth) fc.toggle();
|
||||
lastHealth = newHealth;
|
||||
}
|
||||
|
||||
void onPushOutOfBlocks(double x, double z, CallbackInfo ci) {
|
||||
if (!Events.BUS.hasListeners(EventPushOutOfBlocks.class)) return;
|
||||
EventPushOutOfBlocks event = new EventPushOutOfBlocks(x, z);
|
||||
Events.BUS.post(event);
|
||||
if (event.isCancelled()) ci.cancel();
|
||||
}
|
||||
|
||||
boolean shouldFreezeNow() {
|
||||
Freecam freecam = Modules.get(Freecam.class);
|
||||
return freecam != null && freecam.freezePlayer() && freecam.isCameraInput();
|
||||
}
|
||||
|
||||
void onFreezeTick(LocalPlayer self, CallbackInfo ci) {
|
||||
if (!shouldFreezeNow()) {
|
||||
if (frozen) { self.setDeltaMovement(savedVelocity); frozen = false; }
|
||||
return;
|
||||
}
|
||||
if (!frozen) {
|
||||
frozen = true;
|
||||
savedX = self.getX(); savedY = self.getY(); savedZ = self.getZ();
|
||||
savedVelocity = self.getDeltaMovement();
|
||||
if (Modules.get(Freecam.class) == null || !Modules.get(Freecam.class).isEnabled()) {
|
||||
savedBodyYaw = self.yBodyRot; savedHeadYaw = self.yHeadRot;
|
||||
}
|
||||
}
|
||||
self.setDeltaMovement(Vec3.ZERO);
|
||||
self.absSnapTo(savedX, savedY, savedZ);
|
||||
if (Modules.get(Freecam.class) == null || !Modules.get(Freecam.class).isEnabled()) {
|
||||
self.yBodyRot = savedBodyYaw; self.yHeadRot = savedHeadYaw;
|
||||
}
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
package dev.loki.lovisual.mixins.entity.player;
|
||||
|
||||
import dev.loki.lovisual.events.Events;
|
||||
import dev.loki.lovisual.events.impl.network.EventPostSync;
|
||||
import dev.loki.lovisual.events.impl.network.EventSync;
|
||||
import dev.loki.lovisual.events.impl.player.PostPlayerUpdateEvent;
|
||||
import dev.loki.lovisual.util.combat.rotation.SprintController;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
final class LocalPlayerNetworkHandler {
|
||||
|
||||
private Runnable eventPostAction;
|
||||
private EventSync activeSyncEvent;
|
||||
private boolean postUpdateLock;
|
||||
|
||||
boolean onSendPositionHead(LocalPlayer self, CallbackInfo ci) {
|
||||
if (!Events.BUS.hasListeners(EventSync.class)) return false;
|
||||
eventPostAction = null;
|
||||
EventSync event = new EventSync(self.getYRot(), self.getXRot());
|
||||
Events.BUS.post(event);
|
||||
activeSyncEvent = event;
|
||||
eventPostAction = event.getPostAction();
|
||||
if (event.isCancelled()) {
|
||||
activeSyncEvent = null;
|
||||
eventPostAction = null;
|
||||
ci.cancel();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void onSendPositionReturn() {
|
||||
if (Events.BUS.hasListeners(EventPostSync.class)) Events.BUS.post(new EventPostSync());
|
||||
if (eventPostAction != null) { eventPostAction.run(); eventPostAction = null; }
|
||||
activeSyncEvent = null;
|
||||
}
|
||||
|
||||
EventSync getActiveSyncEvent() { return activeSyncEvent; }
|
||||
|
||||
boolean onPostPlayerUpdate(LocalPlayer self, CallbackInfo ci, Runnable sendPosition) {
|
||||
if (!Events.BUS.hasListeners(PostPlayerUpdateEvent.class)) return false;
|
||||
if (postUpdateLock) return false;
|
||||
PostPlayerUpdateEvent event = new PostPlayerUpdateEvent();
|
||||
Events.BUS.post(event);
|
||||
if (!event.isCancelled()) return false;
|
||||
ci.cancel();
|
||||
int iterations = event.getIterations();
|
||||
if (iterations <= 0) return true;
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
postUpdateLock = true;
|
||||
self.tick();
|
||||
postUpdateLock = false;
|
||||
sendPosition.run();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean shouldBlockSprintNetwork(boolean original) {
|
||||
if (SprintController.INSTANCE.isSprintBlocked()) return false;
|
||||
return original;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
package dev.loki.lovisual.mixins.entity.player;
|
||||
|
||||
import dev.loki.lovisual.events.impl.network.EventSync;
|
||||
import dev.loki.lovisual.mixininterface.entity.ILocalPlayer;
|
||||
import dev.loki.lovisual.util.aiming.data.Rotation;
|
||||
import dev.loki.lovisual.util.aiming.rotation.RotationManager;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.util.Mth;
|
||||
|
||||
final class LocalPlayerRotationHandler {
|
||||
|
||||
private double rotationPrevX;
|
||||
private double rotationPrevZ;
|
||||
private float rotationPrevBodyYaw;
|
||||
private boolean rotationBodyYawInitialized;
|
||||
|
||||
void onTickCache(LocalPlayer self) {
|
||||
if (self instanceof ILocalPlayer access) {
|
||||
access.lovisual$setLastYaw(self.getYRot());
|
||||
access.lovisual$setLastPitch(self.getXRot());
|
||||
}
|
||||
RotationManager.INSTANCE.runTickLifecycle();
|
||||
if (!rotationBodyYawInitialized) {
|
||||
rotationPrevX = self.getX();
|
||||
rotationPrevZ = self.getZ();
|
||||
rotationPrevBodyYaw = self.getVisualRotationYInDegrees();
|
||||
rotationBodyYawInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
float resolveSendYaw(LocalPlayer self, float original, EventSync active) {
|
||||
updateVisualBodyYaw(self);
|
||||
if (active != null && active.hasRotationOverride()) return active.getYaw();
|
||||
Rotation rotation = RotationManager.INSTANCE.getCurrentRotation();
|
||||
return rotation != null ? rotation.yaw() : original;
|
||||
}
|
||||
|
||||
float resolveSendPitch(float original, EventSync active) {
|
||||
if (active != null && active.hasRotationOverride()) return Mth.clamp(active.getPitch(), -90.0f, 90.0f);
|
||||
Rotation rotation = RotationManager.INSTANCE.getCurrentRotation();
|
||||
return rotation != null ? Mth.clamp(rotation.pitch(), -90.0f, 90.0f) : original;
|
||||
}
|
||||
|
||||
float resolveTickYaw(LocalPlayer self, float original) {
|
||||
updateVisualBodyYaw(self);
|
||||
Rotation rotation = RotationManager.INSTANCE.getCurrentRotation();
|
||||
return rotation != null ? rotation.yaw() : original;
|
||||
}
|
||||
|
||||
float resolveTickPitch(float original) {
|
||||
Rotation rotation = RotationManager.INSTANCE.getCurrentRotation();
|
||||
return rotation != null ? Mth.clamp(rotation.pitch(), -90.0f, 90.0f) : original;
|
||||
}
|
||||
|
||||
void updateVisualBodyYaw(LocalPlayer self) {
|
||||
Rotation rotation = RotationManager.INSTANCE.getCurrentRotation();
|
||||
if (rotation == null) {
|
||||
rotationPrevX = self.getX();
|
||||
rotationPrevZ = self.getZ();
|
||||
rotationPrevBodyYaw = self.getVisualRotationYInDegrees();
|
||||
return;
|
||||
}
|
||||
float newBodyYaw = simulateBodyYaw(rotation.yaw(), rotationPrevBodyYaw, rotationPrevX, rotationPrevZ, self.getX(), self.getZ(), self.attackAnim);
|
||||
self.setYBodyRot(newBodyYaw);
|
||||
rotationPrevBodyYaw = newBodyYaw;
|
||||
rotationPrevX = self.getX();
|
||||
rotationPrevZ = self.getZ();
|
||||
}
|
||||
|
||||
float simulateBodyYaw(float yaw, float prevBodyYaw, double prevX, double prevZ, double currentX, double currentZ, float handSwing) {
|
||||
double motionX = currentX - prevX;
|
||||
double motionZ = currentZ - prevZ;
|
||||
float motionSquared = (float) (motionX * motionX + motionZ * motionZ);
|
||||
float bodyYaw = prevBodyYaw;
|
||||
if (motionSquared > 0.0025000002F) {
|
||||
float movementYaw = (float) Mth.atan2(motionZ, motionX) * Mth.RAD_TO_DEG - 90.0F;
|
||||
float yawDiff = Math.abs(Mth.wrapDegrees(yaw) - movementYaw);
|
||||
bodyYaw = (yawDiff > 95.0F && yawDiff < 265.0F) ? movementYaw - 180.0F : movementYaw;
|
||||
}
|
||||
if (handSwing - 0.2F > 0.0F) bodyYaw = yaw;
|
||||
float deltaYaw = Mth.wrapDegrees(bodyYaw - prevBodyYaw);
|
||||
bodyYaw = prevBodyYaw + deltaYaw * 0.3F;
|
||||
float yawOffsetDiff = Mth.wrapDegrees(yaw - bodyYaw);
|
||||
if (Math.abs(yawOffsetDiff) > 52.0F) bodyYaw += yawOffsetDiff - Math.signum(yawOffsetDiff) * 52.0F;
|
||||
return bodyYaw;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.entity.world;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.entity.world;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.entity.world;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.gui.chat;
|
||||
|
||||
import net.minecraft.client.gui.Font;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.gui.chat;
|
||||
|
||||
import net.minecraft.client.gui.ActiveTextCollector;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.gui.chat;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.gui.core;
|
||||
|
||||
import dev.loki.lovisual.features.module.lifecycle.Modules;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.gui.core;
|
||||
|
||||
import net.minecraft.client.gui.GuiGraphicsExtractor;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.gui.core;
|
||||
|
||||
import dev.loki.lovisual.util.screen.ClientScreen;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.gui.core;
|
||||
|
||||
import net.minecraft.client.gui.components.AbstractWidget;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.gui.multiplayer;
|
||||
|
||||
import dev.loki.lovisual.features.theme.Theme;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.gui.multiplayer;
|
||||
|
||||
import net.minecraft.client.gui.screens.inventory.AbstractRecipeBookScreen;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.gui.screens;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
|
|
@ -25,6 +18,8 @@ import dev.loki.lovisual.features.gui.clickgui.picker.screen.ClickGuiPickerScree
|
|||
import dev.loki.lovisual.features.gui.clickgui.render.ClickGuiRenderer;
|
||||
import dev.loki.lovisual.features.gui.clickgui.screen.ClickGuiScreen;
|
||||
import dev.loki.lovisual.features.gui.hud.nondraggable.impl.bars.CustomBar;
|
||||
import dev.loki.lovisual.features.gui.hud.nondraggable.impl.bars.jump.CustomJumpBarRenderer;
|
||||
import dev.loki.lovisual.features.gui.hud.nondraggable.impl.locator.panel.CustomLocatorRenderer;
|
||||
import dev.loki.lovisual.features.gui.hud.nondraggable.impl.dynamicisland.DynamicIsland;
|
||||
import dev.loki.lovisual.features.module.modules.misc.ClickGui;
|
||||
import dev.loki.lovisual.render.engine.core.system.LoVisualRenderSystem;
|
||||
|
|
@ -43,12 +38,12 @@ public abstract class GuiScreenMixin {
|
|||
|
||||
CustomBar bar = CustomBar.get();
|
||||
if (bar == null || !bar.isHudBarEnabled() || !bar.isHotbarXpBarEnabled()) return;
|
||||
if (CustomBar.shouldUseJumpBar(mc) || !CustomBar.shouldUseLocator(mc, bar)) return;
|
||||
if (CustomJumpBarRenderer.shouldUseJumpBar(mc) || !CustomBar.shouldUseLocator(mc, bar)) return;
|
||||
|
||||
LoVisualRenderSystem.ensureFrameContext();
|
||||
try (RenderPhaseScope ignored = LoVisualRenderSystem.phase(RenderPhase.SCREEN_TOP, "2d:hud:custom_bar_heads")) {
|
||||
Renderer2D.withDeferredLayer(Renderer2D.Deferred2DLayer.AFTER_VANILLA_GUI, () -> {
|
||||
CustomBar.renderLocatorHeads(drawContext, tickCounter, mc);
|
||||
CustomLocatorRenderer.renderLocatorHeads(drawContext, tickCounter, mc);
|
||||
Renderer2D.COLOR.render();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.gui.screens;
|
||||
|
||||
import net.minecraft.client.gui.GuiGraphicsExtractor;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.gui.screens;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.gui.screens;
|
||||
|
||||
import dev.loki.lovisual.util.screen.ClientScreen;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.gui.widgets;
|
||||
|
||||
import dev.loki.lovisual.util.screen.ClientScreen;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.gui.widgets;
|
||||
|
||||
import dev.loki.lovisual.util.screen.ClientScreen;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.gui.widgets;
|
||||
|
||||
import dev.loki.lovisual.util.screen.ClientScreen;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.gui.widgets;
|
||||
|
||||
import dev.loki.lovisual.util.screen.ClientScreen;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.hud;
|
||||
|
||||
import net.minecraft.client.gui.components.DebugScreenOverlay;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.hud;
|
||||
|
||||
import dev.loki.lovisual.util.screen.ClientScreen;
|
||||
|
|
|
|||
|
|
@ -1,67 +1,37 @@
|
|||
/*
|
||||
* This file is part of the LoVisual Client distribution.
|
||||
* Copyright (c) 2026 loki5512344.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3.0.
|
||||
*/
|
||||
|
||||
package dev.loki.lovisual.mixins.hud;
|
||||
|
||||
import net.minecraft.client.DeltaTracker;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphicsExtractor;
|
||||
import net.minecraft.client.gui.Hud;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.ai.attributes.Attribute;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.scores.Objective;
|
||||
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.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import dev.loki.lovisual.events.Events;
|
||||
import dev.loki.lovisual.events.impl.pvp.PvpOverlayEvent;
|
||||
import dev.loki.lovisual.features.gui.hud.draggable.impl.panels.Scoreboard;
|
||||
import dev.loki.lovisual.features.gui.hud.draggable.DraggableHudElementRegistry;
|
||||
import dev.loki.lovisual.features.gui.hud.draggable.impl.status.Potions;
|
||||
import dev.loki.lovisual.features.gui.hud.nondraggable.impl.buttons.SwapTooltip;
|
||||
import dev.loki.lovisual.features.gui.hud.nondraggable.impl.bars.CustomBar;
|
||||
import dev.loki.lovisual.features.gui.hud.nondraggable.impl.bars.CustomHealthBar;
|
||||
import dev.loki.lovisual.features.gui.hud.nondraggable.impl.hotbar.CustomHotbar;
|
||||
import dev.loki.lovisual.features.module.lifecycle.Modules;
|
||||
import dev.loki.lovisual.features.module.modules.misc.protect.MessageFilter;
|
||||
import dev.loki.lovisual.features.module.modules.visuals.player.Crosshair;
|
||||
import dev.loki.lovisual.features.module.modules.visuals.visibility.NoRender;
|
||||
import dev.loki.lovisual.mixininterface.render.IGuiGraphics;
|
||||
import dev.loki.lovisual.render.engine.core.system.LoVisualRenderSystem;
|
||||
import dev.loki.lovisual.render.engine.core.frame.RenderPhase;
|
||||
import dev.loki.lovisual.render.engine.core.frame.RenderPhaseScope;
|
||||
import dev.loki.lovisual.render.engine.core.context.ViewportContext;
|
||||
// import dev.loki.lovisual.render.engine.debug.RenderThread2DDebugRenderer; // disabled: debug probes are manual-only
|
||||
import dev.loki.lovisual.render.engine.renderer.Renderer2D;
|
||||
import dev.loki.lovisual.Lifecycle;
|
||||
import dev.loki.lovisual.util.item.food.IllegalItemUtil;
|
||||
import dev.loki.lovisual.util.item.rarity.RarityColorUtil;
|
||||
import dev.loki.lovisual.util.item.enchant.TopEnchantUtil;
|
||||
import dev.loki.lovisual.util.logging.DebugLog;
|
||||
import dev.loki.lovisual.util.text.format.TextJsonUtil;
|
||||
|
||||
/**
|
||||
* Hooks into vanilla {@link Hud} state extraction. All bodies live in the {@code handlers} package:
|
||||
* overlay toggles ({@link GuiOverlayHandler}), custom bar/hotbar/health rendering
|
||||
* ({@link GuiHudBarHandler}), heart-layout redirects ({@link GuiHealthLayoutHandler}) and held-item
|
||||
* tooltip recoloring ({@link GuiTooltipHandler}).
|
||||
*/
|
||||
@Mixin(Hud.class)
|
||||
public abstract class GuiMixin {
|
||||
|
||||
@Shadow
|
||||
private int toolHighlightTimer;
|
||||
@Shadow
|
||||
private net.minecraft.world.item.ItemStack lastToolHighlight;
|
||||
private ItemStack lastToolHighlight;
|
||||
@Shadow
|
||||
@Final
|
||||
private Minecraft minecraft;
|
||||
|
|
@ -71,359 +41,74 @@ public abstract class GuiMixin {
|
|||
// RenderThread2DDebugRenderer.extractGuiStateProbe(ctx);
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static void lovisual$renderCustomBarOnly(GuiGraphicsExtractor ctx,
|
||||
DeltaTracker tickCounter,
|
||||
Minecraft mc,
|
||||
CustomBar bar) {
|
||||
boolean useJump = CustomBar.shouldUseJumpBar(mc);
|
||||
boolean useLocator = !useJump && CustomBar.shouldUseLocator(mc, bar);
|
||||
boolean drawXp = !useJump && !useLocator;
|
||||
|
||||
LoVisualRenderSystem.ensureFrameContext();
|
||||
try (RenderPhaseScope ignored = LoVisualRenderSystem.phase(RenderPhase.HUD_MAIN, "2d:hud:custom_bar")) {
|
||||
Renderer2D.withDeferredLayer(LOVISUAL$VANILLA_HUD_REPLACEMENT_LAYER, () -> {
|
||||
ViewportContext.beginUnscaled(ctx);
|
||||
Renderer2D.COLOR.begin();
|
||||
if (drawXp) {
|
||||
CustomBar.renderXpBarBackground(Renderer2D.COLOR, mc);
|
||||
}
|
||||
if (useJump) {
|
||||
CustomBar.renderJumpBarBackground(Renderer2D.COLOR, mc);
|
||||
}
|
||||
if (useLocator) {
|
||||
CustomBar.renderLocatorBackground(Renderer2D.COLOR, mc);
|
||||
}
|
||||
Renderer2D.COLOR.render();
|
||||
ViewportContext.end(ctx);
|
||||
|
||||
if (drawXp) {
|
||||
CustomBar.renderXpBarText(ctx, mc);
|
||||
}
|
||||
});
|
||||
lovisual$appendVanillaHudReplacementMarker(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static final Renderer2D.Deferred2DLayer LOVISUAL$VANILLA_HUD_REPLACEMENT_LAYER =
|
||||
Renderer2D.Deferred2DLayer.HUD_AFTER_MISC_OVERLAYS;
|
||||
|
||||
@Unique
|
||||
private static void lovisual$appendVanillaHudReplacementMarker(GuiGraphicsExtractor ctx) {
|
||||
if (!(ctx instanceof IGuiGraphics graphics)) return;
|
||||
ctx.nextStratum();
|
||||
graphics.lovisual$addDeferredHudMarker(LOVISUAL$VANILLA_HUD_REPLACEMENT_LAYER);
|
||||
ctx.nextStratum();
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static int argbFrom(float[] rgba) {
|
||||
if (rgba == null || rgba.length < 3) return 0xFFFFFFFF;
|
||||
float r = rgba[0], g = rgba[1], b = rgba[2];
|
||||
float a = rgba.length > 3 ? rgba[3] : 1f;
|
||||
int ai = (int) (a * 255) & 0xFF;
|
||||
int ri = (int) (r * 255) & 0xFF;
|
||||
int gi = (int) (g * 255) & 0xFF;
|
||||
int bi = (int) (b * 255) & 0xFF;
|
||||
return (ai << 24) | (ri << 16) | (gi << 8) | bi;
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "displayScoreboardSidebar(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/world/scores/Objective;)V",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
@Inject(method = "displayScoreboardSidebar(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/world/scores/Objective;)V", at = @At("HEAD"), cancellable = true)
|
||||
private void lovisual$hideScoreboardSidebar(GuiGraphicsExtractor context, Objective objective, CallbackInfo ci) {
|
||||
|
||||
NoRender noRender = Modules.get(NoRender.class);
|
||||
if ((noRender != null && noRender.hideScoreboard()) || Scoreboard.shouldReplaceVanilla()) {
|
||||
ci.cancel();
|
||||
}
|
||||
GuiOverlayHandler.hideScoreboardSidebar(ci);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "setOverlayMessage(Lnet/minecraft/network/chat/Component;Z)V",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
private void lovisual$filterOverlayMessage(net.minecraft.network.chat.Component message, boolean tinted, CallbackInfo ci) {
|
||||
if (DebugLog.serverOnly()) {
|
||||
if (message == null) {
|
||||
// DebugLog.server("HUD overlay message: tinted=%s raw=null", tinted);
|
||||
} else {
|
||||
String raw = message.getString();
|
||||
String json = TextJsonUtil.toJson(message);
|
||||
// DebugLog.server("HUD overlay message: tinted=%s raw=\"%s\" json=%s", tinted, raw, json);
|
||||
}
|
||||
}
|
||||
if (Events.BUS.hasListeners(PvpOverlayEvent.class)) {
|
||||
Events.BUS.post(new PvpOverlayEvent(message, tinted));
|
||||
}
|
||||
|
||||
MessageFilter messageFilter = Modules.get(MessageFilter.class);
|
||||
if (messageFilter != null && messageFilter.shouldHideHud(message)) {
|
||||
ci.cancel();
|
||||
}
|
||||
@Inject(method = "setOverlayMessage(Lnet/minecraft/network/chat/Component;Z)V", at = @At("HEAD"), cancellable = true)
|
||||
private void lovisual$filterOverlayMessage(Component message, boolean tinted, CallbackInfo ci) {
|
||||
GuiOverlayHandler.filterOverlayMessage(message, tinted, ci);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "extractEffects(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/client/DeltaTracker;)V",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
@Inject(method = "extractEffects(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/client/DeltaTracker;)V", at = @At("HEAD"), cancellable = true)
|
||||
private void lovisual$hideVanillaPotions(GuiGraphicsExtractor context, DeltaTracker tickCounter, CallbackInfo ci) {
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
if (mc == null || mc.player == null) return;
|
||||
if (!DraggableHudElementRegistry.isEnabled(Potions.class)) return;
|
||||
if (mc.player.getActiveEffects().isEmpty()) return;
|
||||
ci.cancel();
|
||||
GuiOverlayHandler.hideVanillaPotions(ci);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "extractCrosshair(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/client/DeltaTracker;)V",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
@Inject(method = "extractCrosshair(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/client/DeltaTracker;)V", at = @At("HEAD"), cancellable = true)
|
||||
private void lovisual$replaceCrosshair(GuiGraphicsExtractor context, DeltaTracker tickCounter, CallbackInfo ci) {
|
||||
|
||||
Crosshair crosshair = Modules.get(Crosshair.class);
|
||||
if (crosshair != null && crosshair.shouldHideVanilla()) {
|
||||
ci.cancel();
|
||||
}
|
||||
GuiOverlayHandler.replaceCrosshair(ci);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "extractVignette(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/world/entity/Entity;)V",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
@Inject(method = "extractVignette(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/world/entity/Entity;)V", at = @At("HEAD"), cancellable = true)
|
||||
private void lovisual$killVignette(GuiGraphicsExtractor context, Entity entity, CallbackInfo ci) {
|
||||
|
||||
// Completely remove vanilla vignette post-processing
|
||||
ci.cancel();
|
||||
GuiOverlayHandler.killVignette(ci);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "extractItemHotbar(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/client/DeltaTracker;)V",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
@Inject(method = "extractItemHotbar(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/client/DeltaTracker;)V", at = @At("HEAD"), cancellable = true)
|
||||
private void lovisual$customHotbar(GuiGraphicsExtractor ctx, DeltaTracker tickCounter, CallbackInfo ci) {
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
if (mc == null || mc.player == null) return;
|
||||
|
||||
CustomHotbar hotbar = CustomHotbar.get();
|
||||
CustomBar bar = CustomBar.get();
|
||||
if (hotbar == null && bar == null) return;
|
||||
|
||||
boolean hotbarEnabled = hotbar != null && hotbar.isHudHotbarEnabled();
|
||||
boolean barEnabled = bar != null && bar.isHudBarEnabled() && bar.isHotbarXpBarEnabled();
|
||||
if (!hotbarEnabled && !barEnabled) return;
|
||||
if (!hotbarEnabled) return;
|
||||
|
||||
boolean useJump = barEnabled && CustomBar.shouldUseJumpBar(mc);
|
||||
boolean useLocator = barEnabled && !useJump && CustomBar.shouldUseLocator(mc, bar);
|
||||
boolean drawXp = barEnabled && !useJump && !useLocator;
|
||||
|
||||
LoVisualRenderSystem.ensureFrameContext();
|
||||
try (RenderPhaseScope ignored = LoVisualRenderSystem.phase(RenderPhase.HUD_MAIN, "2d:hud:custom_hotbar")) {
|
||||
Renderer2D.withDeferredLayer(LOVISUAL$VANILLA_HUD_REPLACEMENT_LAYER, () -> {
|
||||
ViewportContext.beginUnscaled(ctx);
|
||||
Renderer2D.COLOR.begin();
|
||||
if (hotbarEnabled) {
|
||||
CustomHotbar.renderBackground(Renderer2D.COLOR, mc);
|
||||
}
|
||||
if (drawXp) {
|
||||
CustomBar.renderXpBarBackground(Renderer2D.COLOR, mc);
|
||||
}
|
||||
if (barEnabled && useJump) {
|
||||
CustomBar.renderJumpBarBackground(Renderer2D.COLOR, mc);
|
||||
}
|
||||
if (barEnabled && useLocator) {
|
||||
CustomBar.renderLocatorBackground(Renderer2D.COLOR, mc);
|
||||
}
|
||||
Renderer2D.COLOR.render();
|
||||
ViewportContext.end(ctx);
|
||||
|
||||
if (hotbarEnabled) {
|
||||
CustomHotbar.renderItems(ctx, tickCounter, mc);
|
||||
}
|
||||
});
|
||||
lovisual$appendVanillaHudReplacementMarker(ctx);
|
||||
|
||||
if (drawXp) {
|
||||
CustomBar.renderXpBarText(ctx, mc);
|
||||
}
|
||||
if (hotbarEnabled) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
GuiHudBarHandler.renderHotbar(ctx, tickCounter, ci);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "extractItemHotbar(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/client/DeltaTracker;)V",
|
||||
at = @At("TAIL")
|
||||
)
|
||||
@Inject(method = "extractItemHotbar(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/client/DeltaTracker;)V", at = @At("TAIL"))
|
||||
private void lovisual$customBarAfterVanillaHotbar(GuiGraphicsExtractor ctx, DeltaTracker tickCounter, CallbackInfo ci) {
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
if (mc == null || mc.player == null) return;
|
||||
|
||||
CustomHotbar hotbar = CustomHotbar.get();
|
||||
if (hotbar != null && hotbar.isHudHotbarEnabled()) return;
|
||||
|
||||
CustomBar bar = CustomBar.get();
|
||||
if (bar == null || !bar.isHudBarEnabled() || !bar.isHotbarXpBarEnabled()) return;
|
||||
|
||||
lovisual$renderCustomBarOnly(ctx, tickCounter, mc, bar);
|
||||
GuiHudBarHandler.afterVanillaHotbar(ctx, tickCounter);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "extractPortalOverlay(Lnet/minecraft/client/gui/GuiGraphicsExtractor;F)V",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
@Inject(method = "extractPortalOverlay(Lnet/minecraft/client/gui/GuiGraphicsExtractor;F)V", at = @At("HEAD"), cancellable = true)
|
||||
private void lovisual$disableVanillaPortalOverlay(GuiGraphicsExtractor context, float nauseaStrength, CallbackInfo ci) {
|
||||
|
||||
ci.cancel();
|
||||
GuiOverlayHandler.disablePortalOverlay(ci);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "extractSleepOverlay(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/client/DeltaTracker;)V",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
@Inject(method = "extractSleepOverlay(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/client/DeltaTracker;)V", at = @At("HEAD"), cancellable = true)
|
||||
private void lovisual$disableVanillaSleepOverlay(GuiGraphicsExtractor context, DeltaTracker tickCounter, CallbackInfo ci) {
|
||||
|
||||
ci.cancel();
|
||||
GuiOverlayHandler.disableSleepOverlay(ci);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "extractHearts(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/world/entity/player/Player;IIIIFIIIZ)V",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
@Inject(method = "extractHearts(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/world/entity/player/Player;IIIIFIIIZ)V", at = @At("HEAD"), cancellable = true)
|
||||
private void lovisual$renderHealthBar(GuiGraphicsExtractor context,
|
||||
Player player,
|
||||
int x, int y, int lines,
|
||||
int regeneratingHeartIndex, float maxHealth,
|
||||
int lastHealth, int health,
|
||||
int absorption, boolean blinking,
|
||||
CallbackInfo ci) {
|
||||
if (!Lifecycle.canRunHud()) return;
|
||||
if (!(player instanceof LocalPlayer clientPlayer)) return;
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
if (mc == null) return;
|
||||
|
||||
if (!CustomHealthBar.shouldRenderHealthBar(mc, clientPlayer, maxHealth)) return;
|
||||
|
||||
LoVisualRenderSystem.ensureFrameContext();
|
||||
try (RenderPhaseScope ignored = LoVisualRenderSystem.phase(RenderPhase.HUD_MAIN, "2d:hud:custom_health")) {
|
||||
Renderer2D.withDeferredLayer(LOVISUAL$VANILLA_HUD_REPLACEMENT_LAYER, () -> {
|
||||
ViewportContext.beginUnscaled(context);
|
||||
Renderer2D.COLOR.begin();
|
||||
CustomHealthBar.HealthTextInfo textInfo =
|
||||
CustomHealthBar.renderHealthBarBackground(
|
||||
Renderer2D.COLOR,
|
||||
mc,
|
||||
clientPlayer,
|
||||
x,
|
||||
y,
|
||||
maxHealth
|
||||
);
|
||||
CustomHealthBar.renderHealthBarText(textInfo);
|
||||
Renderer2D.COLOR.render();
|
||||
ViewportContext.end(context);
|
||||
});
|
||||
lovisual$appendVanillaHudReplacementMarker(context);
|
||||
ci.cancel();
|
||||
}
|
||||
Player player,
|
||||
int x, int y, int lines,
|
||||
int regeneratingHeartIndex, float maxHealth,
|
||||
int lastHealth, int health,
|
||||
int absorption, boolean blinking,
|
||||
CallbackInfo ci) {
|
||||
GuiHudBarHandler.renderHealth(context, player, x, y, maxHealth, ci);
|
||||
}
|
||||
|
||||
@Inject(method = "extractSelectedItemName", at = @At("HEAD"), cancellable = true)
|
||||
private void lovisual$colorizeHeldItemTooltip(GuiGraphicsExtractor context, CallbackInfo ci) {
|
||||
if (!Lifecycle.canRunHud()) return;
|
||||
SwapTooltip swapTooltip = SwapTooltip.get();
|
||||
if (swapTooltip == null || !swapTooltip.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
if (this.toolHighlightTimer <= 0 || this.lastToolHighlight == null || this.lastToolHighlight.isEmpty()) {
|
||||
SwapTooltip.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
MutableComponent name = Component.empty().append(this.lastToolHighlight.getHoverName());
|
||||
if (this.lastToolHighlight.has(net.minecraft.core.component.DataComponents.CUSTOM_NAME)) {
|
||||
name.withStyle(net.minecraft.ChatFormatting.ITALIC);
|
||||
}
|
||||
|
||||
int illegalColor = IllegalItemUtil.illegalColor();
|
||||
int topColor = TopEnchantUtil.topColor();
|
||||
int rarityColor = argbFrom(RarityColorUtil.INSTANCE.getRarityColor(this.lastToolHighlight));
|
||||
boolean hasIllegal = IllegalItemUtil.isIllegal(this.lastToolHighlight);
|
||||
boolean hasTop = !hasIllegal && TopEnchantUtil.hasTopEnchant(this.lastToolHighlight);
|
||||
int nameColor = hasIllegal ? illegalColor : (hasTop ? topColor : rarityColor);
|
||||
int alpha = (int) ((float) this.toolHighlightTimer * 256.0F / 10.0F);
|
||||
if (alpha > 255) alpha = 255;
|
||||
if (alpha <= 0) {
|
||||
SwapTooltip.clear();
|
||||
return;
|
||||
}
|
||||
float fade = alpha / 255f;
|
||||
int argb = 0xFF000000 | (nameColor & 0x00FFFFFF);
|
||||
SwapTooltip.capture(
|
||||
name.getString(),
|
||||
argb,
|
||||
fade,
|
||||
this.minecraft.gameMode.canHurtPlayer()
|
||||
);
|
||||
ci.cancel();
|
||||
GuiTooltipHandler.colorizeHeldItem(this.toolHighlightTimer, this.lastToolHighlight, this.minecraft, ci);
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "extractPlayerHealth(Lnet/minecraft/client/gui/GuiGraphicsExtractor;)V",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/entity/player/Player;getAbsorptionAmount()F"
|
||||
)
|
||||
)
|
||||
@Redirect(method = "extractPlayerHealth(Lnet/minecraft/client/gui/GuiGraphicsExtractor;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;getAbsorptionAmount()F"))
|
||||
private float lovisual$ignoreAbsorptionForLayout(Player player) {
|
||||
if (!Lifecycle.canRunHud()) {
|
||||
return player.getAbsorptionAmount();
|
||||
}
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
if (mc != null && player instanceof LocalPlayer clientPlayer) {
|
||||
float actualMaxHealth = (float) player.getAttributeValue(Attributes.MAX_HEALTH);
|
||||
if (CustomHealthBar.shouldRenderHealthBar(mc, clientPlayer, actualMaxHealth)) {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
return player.getAbsorptionAmount();
|
||||
return GuiHealthLayoutHandler.ignoreAbsorptionForLayout(player);
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "extractPlayerHealth(Lnet/minecraft/client/gui/GuiGraphicsExtractor;)V",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/entity/player/Player;getAttributeValue(Lnet/minecraft/core/Holder;)D"
|
||||
)
|
||||
)
|
||||
@Redirect(method = "extractPlayerHealth(Lnet/minecraft/client/gui/GuiGraphicsExtractor;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;getAttributeValue(Lnet/minecraft/core/Holder;)D"))
|
||||
private double lovisual$clampMaxHealthForLayout(Player player, Holder<Attribute> attribute) {
|
||||
if (!Lifecycle.canRunHud()) {
|
||||
return player.getAttributes().getValue(attribute);
|
||||
}
|
||||
if (attribute == Attributes.MAX_HEALTH) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
if (mc != null && player instanceof LocalPlayer clientPlayer) {
|
||||
float actualMaxHealth = (float) player.getAttributes().getValue(attribute);
|
||||
if (CustomHealthBar.shouldRenderHealthBar(mc, clientPlayer, actualMaxHealth)) {
|
||||
return 20.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return player.getAttributes().getValue(attribute);
|
||||
return GuiHealthLayoutHandler.clampMaxHealthForLayout(player, attribute);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue