Added and fixed tons of clientside fixes

This commit is contained in:
RaphiMC 2023-11-26 01:05:58 +01:00
parent a50dc89f2f
commit be8c3659bc
No known key found for this signature in database
GPG Key ID: 0F6BB0657A03AC94
53 changed files with 2332 additions and 647 deletions

View File

@ -21,13 +21,13 @@ package de.florianmichael.viafabricplus;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import de.florianmichael.viafabricplus.event.PostGameLoadCallback;
import de.florianmichael.viafabricplus.event.PreLoadCallback;
import de.florianmichael.viafabricplus.fixes.ClientsideFixes;
import de.florianmichael.viafabricplus.fixes.account.BedrockAccountHandler;
import de.florianmichael.viafabricplus.fixes.account.ClassiCubeAccountHandler;
import de.florianmichael.viafabricplus.fixes.classic.CustomClassicProtocolExtensions;
import de.florianmichael.viafabricplus.fixes.classic.screen.ClassicItemSelectionScreen;
import de.florianmichael.viafabricplus.event.PostGameLoadCallback;
import de.florianmichael.viafabricplus.event.PreLoadCallback;
import de.florianmichael.viafabricplus.mappings.CharacterMappings;
import de.florianmichael.viafabricplus.mappings.ItemReleaseVersionMappings;
import de.florianmichael.viafabricplus.mappings.PackFormatsMappings;
@ -53,7 +53,6 @@ import java.io.File;
* - Bedrock scaffolding should be added as soon as ViaBedrock supports block placement (see https://github.com/ViaVersion/ViaFabricPlus/issues/204)
*
* TODO | Movement
* - Cobwebs in <= b1.7.3 are broken (movement has been changed)
* - X/Z Face based jump movement in <= 1.13.2 is broken (https://github.com/ViaVersion/ViaFabricPlus/issues/189)
* - Collision hit boxes has been changed (https://github.com/ViaVersion/ViaFabricPlus/issues/195)
* - Blit-jump is not supported in <= 1.8.9 (https://github.com/ViaVersion/ViaFabricPlus/issues/225)
@ -66,6 +65,12 @@ import java.io.File;
* - Recode config save base to support singleton Jsons
* - Rebase fixes package / change all packages
* - Fix auto detect to not be a huge mess
* - Fix MixinAbstractDonkeyEntity
* - Boats are probably broken. Check entity height offset fix
* - Check TO DO in MixinEntity
* - Sort injection methods in fixes package by version
* - Add setting for revertOnlyPlayerCramming
* - Add setting for MixinLockableContainerBlockEntity
*/
public class ViaFabricPlus {

View File

@ -31,11 +31,11 @@ import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RotationAxis;
public class BoatRenderer_1_8 extends EntityRenderer<BoatEntity> {
public class BoatRenderer1_8 extends EntityRenderer<BoatEntity> {
private static final Identifier TEXTURE = new Identifier("viafabricplus", "textures/boat_1_8.png");
private final BoatModel_1_8 model;
public BoatRenderer_1_8(EntityRendererFactory.Context ctx) {
public BoatRenderer1_8(EntityRendererFactory.Context ctx) {
super(ctx);
shadowRadius = 0.5F;
model = new BoatModel_1_8(ctx.getPart(BoatModel_1_8.MODEL_LAYER));

View File

@ -20,7 +20,10 @@
package de.florianmichael.viafabricplus.fixes;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.entity.*;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityPose;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.boss.dragon.EnderDragonEntity;
import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.entity.mob.*;
@ -141,9 +144,7 @@ public class EntityHeightOffsetsPre1_20_2 {
}
public static double getHeightOffset(final Entity entity) {
if (entity instanceof AllayEntity) {
return ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_4) ? 0 : 0.4;
} else if (entity instanceof ArmorStandEntity armorStandEntity && !armorStandEntity.isMarker()) {
if (entity instanceof ArmorStandEntity armorStandEntity && !armorStandEntity.isMarker()) {
return 0.1;
} else if (entity instanceof EndermiteEntity) {
return 0.1;
@ -153,7 +154,11 @@ public class EntityHeightOffsetsPre1_20_2 {
return !(shulkerEntity.getVehicle() instanceof BoatEntity) && vehicleType != EntityType.MINECART ? 0 : 0.1875 - getMountedHeightOffset(shulkerEntity.getVehicle(), null).y;
} else if (entity instanceof SilverfishEntity) {
return 0.1;
} else if (entity instanceof VexEntity) {
} else if (entity instanceof AllayEntity || entity instanceof VexEntity) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_1tor1_19_2)) {
return 0D;
}
return 0.4;
} else if (entity instanceof ZombifiedPiglinEntity zombifiedPiglinEntity) {
return zombifiedPiglinEntity.isBaby() ? -0.05 : -0.45;

File diff suppressed because it is too large Load Diff

View File

@ -22,29 +22,33 @@ package de.florianmichael.viafabricplus.fixes.tracker;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import java.util.HashMap;
import java.util.Map;
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
public class WolfHealthTracker extends StoredObject {
private final Map<Integer, Float> healthDataMap = new HashMap<>();
private final Int2FloatMap healthDataMap = new Int2FloatOpenHashMap();
public WolfHealthTracker(UserConnection user) {
super(user);
}
public Map<Integer, Float> getHealthDataMap() {
return healthDataMap;
public float getWolfHealth(final int entityId, final float fallback) {
return this.healthDataMap.getOrDefault(entityId, fallback);
}
public void setWolfHealth(final int entityId, final float wolfHealth) {
this.healthDataMap.put(entityId, wolfHealth);
}
public static WolfHealthTracker get() {
final var connection = ProtocolHack.getPlayNetworkUserConnection();
if (connection == null) return null;
WolfHealthTracker tracker = connection.get(WolfHealthTracker.class);
if (!connection.has(WolfHealthTracker.class)) {
connection.put(new WolfHealthTracker(connection));
if (tracker == null) {
connection.put(tracker = new WolfHealthTracker(connection));
}
return connection.get(WolfHealthTracker.class);
return tracker;
}
}

View File

@ -17,25 +17,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
package de.florianmichael.viafabricplus.injection.access;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.item.BrushItem;
import net.minecraft.item.ItemStack;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
public interface IEntity {
@Mixin(BrushItem.class)
public abstract class MixinBrushItem {
boolean viaFabricPlus$isInLoadedChunkAndShouldTick();
@Inject(method = "getMaxUseTime", at = @At("HEAD"), cancellable = true)
private void changeMaxUseTime(ItemStack stack, CallbackInfoReturnable<Integer> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_4)) {
cir.setReturnValue(225);
}
}
void viaFabricPlus$setInLoadedChunkAndShouldTick(final boolean inLoadedChunkAndShouldTick);
}

View File

@ -0,0 +1,30 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD
* Copyright (C) 2023 RK_01/RaphiMC and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.access;
public interface IItemStack {
boolean viaFabricPlus$has1_10ProtocolHackTag();
int viaFabricPlus$get1_10Count();
void viaFabricPlus$set1_10Count(final int count);
}

View File

@ -144,7 +144,7 @@ public abstract class MixinClientConnection extends SimpleChannelInboundHandler<
return instance.channel(channelTypeClass);
}
@Redirect(method = "connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/network/ClientConnection;)Lio/netty/channel/ChannelFuture;", at = @At(value = "INVOKE", target = "Lio/netty/bootstrap/Bootstrap;connect(Ljava/net/InetAddress;I)Lio/netty/channel/ChannelFuture;"))
@Redirect(method = "connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/network/ClientConnection;)Lio/netty/channel/ChannelFuture;", at = @At(value = "INVOKE", target = "Lio/netty/bootstrap/Bootstrap;connect(Ljava/net/InetAddress;I)Lio/netty/channel/ChannelFuture;", remap = false))
private static ChannelFuture useRakNetPingHandlers(Bootstrap instance, InetAddress inetHost, int inetPort, @Local(argsOnly = true) ClientConnection clientConnection, @Local(argsOnly = true) boolean isConnecting) {
if (VersionEnum.bedrockLatest.equals(((IClientConnection) clientConnection).viaFabricPlus$getTargetVersion()) && !isConnecting) {
return instance.register().syncUninterruptibly().channel().bind(new InetSocketAddress(0)).

View File

@ -20,10 +20,11 @@
package de.florianmichael.viafabricplus.injection.mixin.base.integration;
import com.viaversion.viaversion.api.connection.UserConnection;
import de.florianmichael.viafabricplus.settings.impl.GeneralSettings;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import de.florianmichael.viafabricplus.settings.impl.GeneralSettings;
import de.florianmichael.viafabricplus.util.ChatUtil;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.DownloadingTerrainScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;
import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.storage.ClassicProgressStorage;
@ -32,11 +33,10 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@SuppressWarnings("DataFlowIssue")
@Mixin(targets = { "net.minecraft.client.gui.screen.DownloadingTerrainScreen", "net.minecraft.client.gui.screen.ConnectScreen" })
public abstract class MixinDownloadingTerrainScreenAndConnectScreen extends Screen {
@Mixin(DownloadingTerrainScreen.class)
public abstract class MixinDownloadingTerrainScreen extends Screen {
public MixinDownloadingTerrainScreenAndConnectScreen(Text title) {
public MixinDownloadingTerrainScreen(Text title) {
super(title);
}
@ -45,9 +45,6 @@ public abstract class MixinDownloadingTerrainScreenAndConnectScreen extends Scre
if (GeneralSettings.INSTANCE.showClassicLoadingProgressInConnectScreen.getValue()) {
// Check if ViaVersion is translating
final UserConnection connection = ProtocolHack.getPlayNetworkUserConnection();
if (connection == null) {
return;
}
// Check if the client is connecting to a classic server
final ClassicProgressStorage classicProgressStorage = connection.get(ClassicProgressStorage.class);

View File

@ -19,28 +19,29 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import net.raphimc.vialoader.util.VersionEnum;
import com.mojang.authlib.GameProfile;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.mob.HostileEntity;
import net.minecraft.entity.mob.VexEntity;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(VexEntity.class)
public abstract class MixinVexEntity extends HostileEntity {
@Mixin(AbstractClientPlayerEntity.class)
public abstract class MixinAbstractClientPlayerEntity extends PlayerEntity {
public MixinVexEntity(EntityType<? extends HostileEntity> entityType, World world) {
super(entityType, world);
public MixinAbstractClientPlayerEntity(World world, BlockPos pos, float yaw, GameProfile gameProfile) {
super(world, pos, yaw, gameProfile);
}
@Inject(method = "getUnscaledRidingOffset", at = @At("HEAD"), cancellable = true)
private void changeHeightOffset(CallbackInfoReturnable<Double> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_1tor1_19_2)) {
cir.setReturnValue(0.0);
@Inject(method = "isCreative", at = @At("HEAD"), cancellable = true)
private void fixCreativeCheck(CallbackInfoReturnable<Boolean> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
cir.setReturnValue(this.getAbilities().creativeMode);
}
}

View File

@ -1,96 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD
* Copyright (C) 2023 RK_01/RaphiMC and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import net.raphimc.vialoader.util.VersionEnum;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.block.Blocks;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.passive.AbstractDonkeyEntity;
import net.minecraft.entity.passive.AbstractHorseEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(AbstractDonkeyEntity.class)
public abstract class MixinAbstractDonkeyEntity extends AbstractHorseEntity {
@Shadow public abstract boolean hasChest();
@Shadow public abstract void setHasChest(boolean hasChest);
@Shadow protected abstract void playAddChestSound();
public MixinAbstractDonkeyEntity(EntityType<? extends AbstractHorseEntity> entityType, World world) {
super(entityType, world);
}
@Inject(method = "interactMob", at = @At("HEAD"), cancellable = true)
public void fixInteraction(PlayerEntity player, Hand hand, CallbackInfoReturnable<ActionResult> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_1tor1_19_2)) {
ItemStack lv = player.getStackInHand(hand);
if (!this.isBaby()) {
if (this.isTame() && player.shouldCancelInteraction()) {
this.openInventory(player);
cir.setReturnValue(ActionResult.success(this.getWorld().isClient));
}
if (this.hasPassengers()) {
cir.setReturnValue(super.interactMob(player, hand));
}
}
if (!lv.isEmpty()) {
if (this.isBreedingItem(lv)) {
cir.setReturnValue(this.interactHorse(player, lv));
}
if (!this.isTame()) {
this.playAngrySound();
cir.setReturnValue(ActionResult.success(this.getWorld().isClient));
}
if (!this.hasChest() && lv.isOf(Blocks.CHEST.asItem())) {
this.setHasChest(true);
this.playAddChestSound();
if (!player.getAbilities().creativeMode) {
lv.decrement(1);
}
this.onChestedStatusChanged();
cir.setReturnValue(ActionResult.success(this.getWorld().isClient));
}
if (!this.isBaby() && !this.isSaddled() && lv.isOf(Items.SADDLE)) {
this.openInventory(player);
cir.setReturnValue(ActionResult.success(this.getWorld().isClient));
}
}
if (this.isBaby()) {
cir.setReturnValue(super.interactMob(player, hand));
}
this.putPlayerOnBack(player);
cir.setReturnValue(ActionResult.success(this.getWorld().isClient));
}
}
}

View File

@ -19,11 +19,10 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import net.raphimc.vialoader.util.VersionEnum;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.entity.passive.AnimalEntity;
import net.minecraft.world.World;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@ -32,7 +31,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
public abstract class MixinAnimalEntity {
@Redirect(method = "interactMob", at = @At(value = "FIELD", target = "Lnet/minecraft/world/World;isClient:Z"))
private boolean redirectInteractMob(World instance) {
private boolean fixIsClientCheck(World instance) {
return instance.isClient && ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_15);
}

View File

@ -0,0 +1,316 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import de.florianmichael.viafabricplus.fixes.EntityHeightOffsetsPre1_20_2;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.MovementType;
import net.minecraft.entity.vehicle.BoatEntity;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.registry.tag.FluidTags;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(BoatEntity.class)
public abstract class MixinBoatEntity extends Entity {
@Shadow
private double x;
@Shadow
private double y;
@Shadow
private double z;
@Shadow
private double boatYaw;
@Shadow
private double boatPitch;
@Shadow
public abstract int getDamageWobbleTicks();
@Shadow
public abstract void setDamageWobbleTicks(int wobbleTicks);
@Shadow
public abstract float getDamageWobbleStrength();
@Shadow
public abstract void setDamageWobbleStrength(float wobbleStrength);
@Shadow
private BoatEntity.Location location;
@Shadow
public abstract LivingEntity getControllingPassenger();
@Unique
private double speedMultiplier = 0.07D;
@Unique
private int boatInterpolationSteps;
@Unique
private Vec3d boatVelocity = Vec3d.ZERO;
public MixinBoatEntity(EntityType<?> type, World world) {
super(type, world);
}
@Inject(method = "pushAwayFrom", at = @At("HEAD"), cancellable = true)
private void pushAwayFrom1_8(Entity entity, CallbackInfo ci) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
ci.cancel();
super.pushAwayFrom(entity);
}
}
@Inject(method = "updateTrackedPositionAndAngles", at = @At("HEAD"), cancellable = true)
private void updateTrackedPositionAndAngles1_8(double x, double y, double z, float yaw, float pitch, int interpolationSteps, CallbackInfo ci) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
ci.cancel();
if (/*interpolate &&*/ this.hasPassengers() && ProtocolHack.getTargetVersion().isNewerThan(VersionEnum.r1_7_6tor1_7_10)) {
this.prevX = x;
this.prevY = y;
this.prevZ = z;
this.boatInterpolationSteps = 0;
this.setPosition(x, y, z);
this.setRotation(yaw, pitch);
this.setVelocity(Vec3d.ZERO);
this.boatVelocity = Vec3d.ZERO;
} else {
if (!this.hasPassengers()) {
this.boatInterpolationSteps = interpolationSteps + 5;
} else {
if (this.squaredDistanceTo(x, y, z) <= 1) {
return;
}
this.boatInterpolationSteps = 3;
}
this.x = x;
this.y = y;
this.z = z;
this.boatYaw = yaw;
this.boatPitch = pitch;
this.setVelocity(this.boatVelocity);
}
}
}
@Override
public void setVelocityClient(double x, double y, double z) {
super.setVelocityClient(x, y, z);
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
this.boatVelocity = new Vec3d(x, y, z);
}
}
@Inject(method = "tick", at = @At("HEAD"), cancellable = true)
private void tick1_8(CallbackInfo ci) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
ci.cancel();
super.tick();
if (this.getDamageWobbleTicks() > 0) {
this.setDamageWobbleTicks(this.getDamageWobbleTicks() - 1);
}
if (this.getDamageWobbleStrength() > 0) {
this.setDamageWobbleStrength(this.getDamageWobbleStrength() - 1);
}
this.prevX = this.getX();
this.prevY = this.getY();
this.prevZ = this.getZ();
final int yPartitions = 5;
double percentSubmerged = 0;
for (int partitionIndex = 0; partitionIndex < yPartitions; partitionIndex++) {
final double minY = this.getBoundingBox().minY + this.getBoundingBox().getLengthY() * partitionIndex / yPartitions - 0.125;
final double maxY = this.getBoundingBox().minY + this.getBoundingBox().getLengthY() * (partitionIndex + 1) / yPartitions - 0.125;
final Box box = new Box(this.getBoundingBox().minX, minY, this.getBoundingBox().minZ, this.getBoundingBox().maxX, maxY, this.getBoundingBox().maxZ);
if (BlockPos.stream(box).anyMatch(pos -> this.getWorld().getFluidState(pos).isIn(FluidTags.WATER))) {
percentSubmerged += 1.0 / yPartitions;
}
}
final double oldHorizontalSpeed = this.getVelocity().horizontalLength();
if (oldHorizontalSpeed > (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_7_6tor1_7_10) ? 0.2625D : 0.2975D)) {
final double rx = Math.cos(this.getYaw() * Math.PI / 180);
final double rz = Math.sin(this.getYaw() * Math.PI / 180);
for (int i = 0; i < 1 + oldHorizontalSpeed * 60; i++) {
final double dForward = this.random.nextFloat() * 2 - 1;
final double dSideways = (this.random.nextInt(2) * 2 - 1) * 0.7D;
if (this.random.nextBoolean()) {
final double x = this.getX() - rx * dForward * 0.8 + rz * dSideways;
final double z = this.getZ() - rz * dForward * 0.8 - rx * dSideways;
this.getWorld().addParticle(ParticleTypes.SPLASH, x, this.getY() - 0.125D, z, this.getVelocity().x, this.getVelocity().y, this.getVelocity().z);
} else {
final double x = this.getX() + rx + rz * dForward * 0.7;
final double z = this.getZ() + rz - rx * dForward * 0.7;
this.getWorld().addParticle(ParticleTypes.SPLASH, x, this.getY() - 0.125D, z, this.getVelocity().x, this.getVelocity().y, this.getVelocity().z);
}
}
}
if (this.getWorld().isClient && !this.hasPassengers()) {
if (this.boatInterpolationSteps > 0) {
final double newX = this.getX() + (this.x - this.getX()) / this.boatInterpolationSteps;
final double newY = this.getY() + (this.y - this.getY()) / this.boatInterpolationSteps;
final double newZ = this.getZ() + (this.z - this.getZ()) / this.boatInterpolationSteps;
final double newYaw = this.getYaw() + MathHelper.wrapDegrees(this.boatYaw - this.getYaw()) / this.boatInterpolationSteps;
final double newPitch = this.getPitch() + (this.boatPitch - this.getPitch()) / this.boatInterpolationSteps;
this.boatInterpolationSteps--;
this.setPosition(newX, newY, newZ);
this.setRotation((float) newYaw, (float) newPitch);
} else {
this.setPosition(this.getX() + this.getVelocity().x, this.getY() + this.getVelocity().y, this.getZ() + this.getVelocity().z);
if (this.isOnGround()) {
this.setVelocity(this.getVelocity().multiply(0.5D));
}
this.setVelocity(this.getVelocity().multiply(0.99D, 0.95D, 0.99D));
}
} else {
if (percentSubmerged < 1) {
final double normalizedDistanceFromMiddle = percentSubmerged * 2 - 1;
this.setVelocity(this.getVelocity().add(0, 0.04D * normalizedDistanceFromMiddle, 0));
} else {
if (this.getVelocity().y < 0) {
this.setVelocity(this.getVelocity().multiply(1, 0.5D, 1));
}
this.setVelocity(this.getVelocity().add(0, 0.007D, 0));
}
if (this.getControllingPassenger() != null) {
final LivingEntity passenger = this.getControllingPassenger();
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_5_2)) {
final double xAcceleration = passenger.getVelocity().x * this.speedMultiplier;
final double zAcceleration = passenger.getVelocity().z * this.speedMultiplier;
this.setVelocity(this.getVelocity().add(xAcceleration, 0, zAcceleration));
} else if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_6_4)) {
if (passenger.forwardSpeed > 0) {
final double xAcceleration = -Math.sin(passenger.getYaw() * Math.PI / 180) * this.speedMultiplier * 0.05D;
final double zAcceleration = Math.cos(passenger.getYaw() * Math.PI / 180) * this.speedMultiplier * 0.05D;
this.setVelocity(this.getVelocity().add(xAcceleration, 0, zAcceleration));
}
} else {
final float boatAngle = passenger.getYaw() - passenger.sidewaysSpeed * 90F;
final double xAcceleration = -Math.sin(boatAngle * Math.PI / 180) * this.speedMultiplier * passenger.forwardSpeed * 0.05D;
final double zAcceleration = Math.cos(boatAngle * Math.PI / 180) * this.speedMultiplier * passenger.forwardSpeed * 0.05D;
this.setVelocity(this.getVelocity().add(xAcceleration, 0, zAcceleration));
}
}
double newHorizontalSpeed = this.getVelocity().horizontalLength();
if (newHorizontalSpeed > 0.35D) {
final double multiplier = 0.35D / newHorizontalSpeed;
this.setVelocity(this.getVelocity().multiply(multiplier, 1, multiplier));
newHorizontalSpeed = 0.35D;
}
if (newHorizontalSpeed > oldHorizontalSpeed && this.speedMultiplier < 0.35D) {
this.speedMultiplier += (0.35D - this.speedMultiplier) / 35;
if (this.speedMultiplier > 0.35D) {
this.speedMultiplier = 0.35D;
}
} else {
this.speedMultiplier -= (this.speedMultiplier - 0.07D) / 35;
if (this.speedMultiplier < 0.07D) {
this.speedMultiplier = 0.07D;
}
}
if (ProtocolHack.getTargetVersion().isNewerThan(VersionEnum.r1_6_4)) {
for (int i = 0; i < 4; i++) {
final int dx = MathHelper.floor(this.getX() + ((i % 2) - 0.5D) * 0.8D);
//noinspection IntegerDivisionInFloatingPointContext
final int dz = MathHelper.floor(this.getZ() + ((i / 2) - 0.5D) * 0.8D);
for (int ddy = 0; ddy < 2; ddy++) {
final int dy = MathHelper.floor(this.getY()) + ddy;
final BlockPos pos = new BlockPos(dx, dy, dz);
final Block block = this.getWorld().getBlockState(pos).getBlock();
if (block == Blocks.SNOW) {
this.getWorld().setBlockState(pos, Blocks.AIR.getDefaultState());
this.horizontalCollision = false;
} else if (block == Blocks.LILY_PAD) {
this.getWorld().breakBlock(pos, true);
this.horizontalCollision = false;
}
}
}
}
if (this.isOnGround()) {
this.setVelocity(this.getVelocity().multiply(0.5D));
}
this.move(MovementType.SELF, this.getVelocity());
if (!this.horizontalCollision || oldHorizontalSpeed <= 0.2975D) {
this.setVelocity(this.getVelocity().multiply(0.99D, 0.95D, 0.99D));
}
this.setPitch(0);
final double deltaX = this.prevX - this.getX();
final double deltaZ = this.prevZ - this.getZ();
if (deltaX * deltaX + deltaZ * deltaZ > 0.001D) {
final double yawDelta = MathHelper.clamp(MathHelper.wrapDegrees((MathHelper.atan2(deltaZ, deltaX) * 180 / Math.PI) - this.getYaw()), -20, 20);
this.setYaw((float) (this.getYaw() + yawDelta));
}
}
}
}
@Inject(method = "updatePassengerPosition", at = @At(value = "HEAD"), cancellable = true)
private void updatePassengerPosition1_8(Entity passenger, PositionUpdater positionUpdater, CallbackInfo ci) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
final Vec3d newPosition = new Vec3d(EntityHeightOffsetsPre1_20_2.getMountedHeightOffset(this, passenger)).add(this.getPos());
positionUpdater.accept(passenger, newPosition.x, newPosition.y + EntityHeightOffsetsPre1_20_2.getHeightOffset(passenger), newPosition.z);
ci.cancel();
}
}
@Inject(method = "onPassengerLookAround", at = @At("HEAD"), cancellable = true)
private void onPassengerLookAround1_8(Entity passenger, CallbackInfo ci) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
ci.cancel();
super.onPassengerLookAround(passenger);
}
}
@Inject(method = "fall", at = @At("HEAD"), cancellable = true)
private void fall1_8(double heightDifference, boolean onGround, BlockState state, BlockPos landedPosition, CallbackInfo ci) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_6_4)) {
ci.cancel();
super.fall(heightDifference, onGround, state, landedPosition);
} else if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
this.location = BoatEntity.Location.ON_LAND;
}
}
@Inject(method = "canAddPassenger", at = @At("HEAD"), cancellable = true)
private void canAddPassenger1_8(Entity passenger, CallbackInfoReturnable<Boolean> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
cir.setReturnValue(super.canAddPassenger(passenger));
}
}
}

View File

@ -29,8 +29,6 @@ import net.minecraft.world.World;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(CamelEntity.class)
public abstract class MixinCamelEntity extends AbstractHorseEntity {
@ -39,14 +37,6 @@ public abstract class MixinCamelEntity extends AbstractHorseEntity {
super(entityType, world);
}
@Redirect(method = "interactMob", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/passive/CamelEntity;isBaby()Z", ordinal = 0))
private boolean removeBabyCondition(CamelEntity instance) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_4)) {
return false;
}
return instance.isBaby();
}
@Unique
private void viaFabricPlus$clamPassengerYaw(final Entity passenger) {
passenger.setBodyYaw(this.getYaw());
@ -64,7 +54,7 @@ public abstract class MixinCamelEntity extends AbstractHorseEntity {
@Override
public void onPassengerLookAround(Entity passenger) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_20tor1_20_1) && this.getControllingPassenger() != passenger) {
viaFabricPlus$clamPassengerYaw(passenger);
this.viaFabricPlus$clamPassengerYaw(passenger);
}
}
@ -73,7 +63,7 @@ public abstract class MixinCamelEntity extends AbstractHorseEntity {
super.updatePassengerPosition(passenger, positionUpdater);
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_20tor1_20_1)) {
viaFabricPlus$clamPassengerYaw(passenger);
this.viaFabricPlus$clamPassengerYaw(passenger);
}
}

View File

@ -20,25 +20,30 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import com.mojang.authlib.GameProfile;
import de.florianmichael.viafabricplus.fixes.ClientsideFixes;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import de.florianmichael.viafabricplus.injection.access.IClientConnection;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
import de.florianmichael.viafabricplus.settings.impl.VisualSettings;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.input.Input;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.util.Hand;
import net.minecraft.entity.Entity;
import net.minecraft.entity.vehicle.BoatEntity;
import net.minecraft.network.packet.Packet;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.GameMode;
import net.raphimc.vialegacy.protocols.release.protocol1_6_1to1_5_2.Protocol1_6_1to1_5_2;
import net.raphimc.vialegacy.protocols.release.protocol1_6_1to1_5_2.ServerboundPackets1_5_2;
import net.raphimc.vialoader.util.VersionEnum;
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.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@SuppressWarnings("ConstantValue")
@Mixin(value = ClientPlayerEntity.class, priority = 2000)
@ -57,18 +62,20 @@ public abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity
@Shadow
private int ticksSinceLastPositionPacketSent;
@Unique
private boolean viaFabricPlus$areSwingCanceledThisTick = false;
public MixinClientPlayerEntity(ClientWorld world, GameProfile profile) {
super(world, profile);
}
@Shadow protected abstract void sendSprintingPacket();
@Shadow
protected abstract void sendSprintingPacket();
@Shadow
@Final
public ClientPlayNetworkHandler networkHandler;
@Redirect(method = "sendMovementPackets", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/MathHelper;square(D)D"))
private double changeMagnitude(double n) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_18_2)) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_18tor1_18_1)) {
n = 9.0E-4D;
}
@ -88,7 +95,7 @@ public abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity
@Inject(method = "sendMovementPackets", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;hasVehicle()Z"))
private void incrementLastPositionPacketSentCounter(CallbackInfo ci) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
++this.ticksSinceLastPositionPacketSent;
this.ticksSinceLastPositionPacketSent++;
}
}
@ -100,15 +107,6 @@ public abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity
return lastOnGround;
}
@Inject(method = "swingHand", at = @At("HEAD"), cancellable = true)
private void injectSwingHand(Hand hand, CallbackInfo ci) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8) && viaFabricPlus$areSwingCanceledThisTick) {
ci.cancel();
}
viaFabricPlus$areSwingCanceledThisTick = false;
}
@Inject(method = "tickMovement()V",
slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isCamera()Z")),
at = @At(value = "FIELD", target = "Lnet/minecraft/client/input/Input;sneaking:Z", ordinal = 0))
@ -124,20 +122,19 @@ public abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity
@Redirect(method = "tickMovement",
slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isWalking()Z")),
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isSwimming()Z", ordinal = 0))
private boolean redirectIsSneakingWhileSwimming(ClientPlayerEntity _this) {
private boolean redirectIsSneakingWhileSwimming(ClientPlayerEntity instance) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_14_1)) {
return false;
} else {
return _this.isSwimming();
return instance.isSwimming();
}
}
@Redirect(method = "isWalking", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isSubmergedInWater()Z"))
private boolean easierUnderwaterSprinting(ClientPlayerEntity instance) {
@Inject(method = "isWalking", at = @At("HEAD"), cancellable = true)
private void easierUnderwaterSprinting(CallbackInfoReturnable<Boolean> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_14_1)) {
return false;
cir.setReturnValue(((ClientPlayerEntity) (Object) this).input.movementForward >= 0.8);
}
return instance.isSubmergedInWater();
}
@Redirect(method = "tickMovement()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/input/Input;hasForwardMovement()Z", ordinal = 0))
@ -168,8 +165,8 @@ public abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity
@Redirect(method = "autoJump", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/MathHelper;inverseSqrt(F)F"))
private float useFastInverse(float x) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_3)) {
// fast inverse sqrt
x = Float.intBitsToFloat(1597463007 - (Float.floatToIntBits(x) >> 1));
return x * (1.5F - (0.5F * x) * x * x);
}
return MathHelper.inverseSqrt(x);
@ -185,7 +182,7 @@ public abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity
}
@Redirect(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isClimbing()Z"))
private boolean removeLadderCheck(ClientPlayerEntity instance) {
private boolean allowElytraWhenClimbing(ClientPlayerEntity instance) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_15_1)) {
return false;
}
@ -193,7 +190,7 @@ public abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity
}
@Redirect(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;hasVehicle()Z", ordinal = 3))
private boolean removeVehicleCheck(ClientPlayerEntity instance) {
private boolean allowElytraInVehicle(ClientPlayerEntity instance) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_14_4)) {
return false;
}
@ -208,8 +205,16 @@ public abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity
return value;
}
@Redirect(method = "canStartSprinting", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;hasVehicle()Z"))
private boolean removeVehicleCheck(ClientPlayerEntity instance) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_3)) {
return false;
}
return instance.hasVehicle();
}
@Redirect(method = "canStartSprinting", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isFallFlying()Z"))
private boolean removeElytraMovementCheck(ClientPlayerEntity instance) {
private boolean removeFallFlyingCheck(ClientPlayerEntity instance) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_3)) {
return false;
}
@ -217,30 +222,37 @@ public abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity
}
@Redirect(method = "canSprint", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;hasVehicle()Z"))
private boolean removeVehicleCondition(ClientPlayerEntity instance) {
private boolean dontAllowSprintingAsPassenger(ClientPlayerEntity instance) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_1tor1_19_2)) {
return false;
}
return instance.hasVehicle();
}
@Override
public boolean isCreative() {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_7_6tor1_7_10)) {
if (client.interactionManager == null) {
return super.isCreative(); // Fixes https://github.com/ViaVersion/ViaFabricPlus/issues/216
}
return client.interactionManager.getCurrentGameMode() == GameMode.CREATIVE;
@Inject(method = "startRiding", at = @At("RETURN"))
private void setRotationsWhenInBoat(Entity entity, boolean force, CallbackInfoReturnable<Boolean> cir) {
if (cir.getReturnValueZ() && entity instanceof BoatEntity && ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_18tor1_18_1)) {
this.prevYaw = entity.getYaw();
this.setYaw(entity.getYaw());
this.setHeadYaw(entity.getYaw());
}
return super.isCreative();
}
@Override
public int getArmor() {
if (VisualSettings.INSTANCE.emulateArmorHud.isEnabled()) {
return client.player.getInventory().armor.stream().mapToInt(ClientsideFixes::getLegacyArmorPoints).sum();
@Redirect(method = "tick", slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;hasVehicle()Z")), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;sendPacket(Lnet/minecraft/network/packet/Packet;)V", ordinal = 0))
private void modifyPositionPacket(ClientPlayNetworkHandler instance, Packet<?> packet) throws Exception {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_5_2)) {
final PacketWrapper playerPosition = PacketWrapper.create(ServerboundPackets1_5_2.PLAYER_POSITION_AND_ROTATION, ((IClientConnection) this.networkHandler.getConnection()).viaFabricPlus$getUserConnection());
playerPosition.write(Type.DOUBLE, this.getVelocity().x); // x
playerPosition.write(Type.DOUBLE, -999.0D); // y
playerPosition.write(Type.DOUBLE, -999.0D); // stance
playerPosition.write(Type.DOUBLE, this.getVelocity().z); // z
playerPosition.write(Type.FLOAT, this.getYaw()); // yaw
playerPosition.write(Type.FLOAT, this.getPitch()); // pitch
playerPosition.write(Type.BOOLEAN, this.isOnGround()); // onGround
playerPosition.scheduleSendToServer(Protocol1_6_1to1_5_2.class);
return;
}
return super.getArmor();
instance.sendPacket(packet);
}
}

View File

@ -19,8 +19,6 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import net.raphimc.vialoader.util.VersionEnum;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.passive.AnimalEntity;
@ -29,6 +27,7 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.world.World;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -42,7 +41,7 @@ public abstract class MixinCowEntity extends AnimalEntity {
}
@Inject(method = "interactMob", at = @At("HEAD"), cancellable = true)
private void injectInteractMob(PlayerEntity player, Hand hand, CallbackInfoReturnable<ActionResult> cir) {
private void disableMilkingInCreative(PlayerEntity player, Hand hand, CallbackInfoReturnable<ActionResult> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_15_2) && player.getAbilities().creativeMode) {
cir.setReturnValue(super.interactMob(player, hand));
}

View File

@ -19,12 +19,11 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import net.raphimc.vialoader.util.VersionEnum;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.entity.mob.CreeperEntity;
import net.minecraft.sound.SoundEvent;
import net.minecraft.sound.SoundEvents;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@ -33,7 +32,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
public abstract class MixinCreeperEntity {
@Redirect(method = "interactMob", at = @At(value = "FIELD", target = "Lnet/minecraft/sound/SoundEvents;ITEM_FIRECHARGE_USE:Lnet/minecraft/sound/SoundEvent;"))
private SoundEvent fixSound() {
private SoundEvent changeSound() {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_1tor1_19_2)) {
return SoundEvents.ITEM_FLINTANDSTEEL_USE;
}

View File

@ -20,14 +20,14 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import de.florianmichael.viafabricplus.fixes.EntityHeightOffsetsPre1_20_2;
import net.minecraft.entity.EntityDimensions;
import net.raphimc.vialoader.util.VersionEnum;
import de.florianmichael.viafabricplus.injection.access.IEntity;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import it.unimi.dsi.fastutil.objects.Object2DoubleMap;
import net.minecraft.block.BlockState;
import net.minecraft.block.FenceGateBlock;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityDimensions;
import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.FluidState;
import net.minecraft.registry.tag.BlockTags;
@ -37,21 +37,25 @@ import net.minecraft.util.math.Box;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.raphimc.vialoader.util.VersionEnum;
import org.joml.Vector3f;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@SuppressWarnings("ConstantValue")
@Mixin(Entity.class)
public abstract class MixinEntity {
public abstract class MixinEntity implements IEntity {
@Shadow
public World world;
private World world;
@Shadow
protected Object2DoubleMap<TagKey<Fluid>> fluidHeight;
@Shadow
private Vec3d pos;
@ -64,10 +68,14 @@ public abstract class MixinEntity {
@Shadow
public abstract void setVelocity(Vec3d velocity);
@Shadow protected abstract Vector3f getPassengerAttachmentPos(Entity passenger, EntityDimensions dimensions, float scaleFactor);
@Shadow
protected abstract Vector3f getPassengerAttachmentPos(Entity passenger, EntityDimensions dimensions, float scaleFactor);
@Unique
private boolean viaFabricPlus$isInLoadedChunkAndShouldTick;
@ModifyConstant(method = "movementInputToVelocity", constant = @Constant(doubleValue = 1E-7))
private static double injectMovementInputToVelocity(double epsilon) {
private static double fixVelocityEpsilon(double epsilon) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_13_2)) {
return 1E-4;
}
@ -75,7 +83,7 @@ public abstract class MixinEntity {
}
@Inject(method = "getVelocityAffectingPos", at = @At("HEAD"), cancellable = true)
private void replaceAffectingVelocityMagnitude(CallbackInfoReturnable<BlockPos> cir) {
private void modifyVelocityAffectingPos(CallbackInfoReturnable<BlockPos> cir) {
final VersionEnum target = ProtocolHack.getTargetVersion();
if (target.isOlderThanOrEqualTo(VersionEnum.r1_19_4)) {
@ -91,20 +99,19 @@ public abstract class MixinEntity {
}
@Inject(method = "setSwimming", at = @At("HEAD"), cancellable = true)
private void onSetSwimming(boolean swimming, CallbackInfo ci) {
private void cancelSwimming(boolean swimming, CallbackInfo ci) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2) && swimming) {
ci.cancel();
}
}
@SuppressWarnings("deprecation")
@Inject(method = "updateMovementInFluid", at = @At("HEAD"), cancellable = true)
private void modifyFluidMovementBoundingBox(TagKey<Fluid> fluidTag, double d, CallbackInfoReturnable<Boolean> ci) {
private void modifyFluidMovementBoundingBox(TagKey<Fluid> fluidTag, double d, CallbackInfoReturnable<Boolean> cir) {
if (ProtocolHack.getTargetVersion().isNewerThan(VersionEnum.r1_12_2)) {
return;
}
Box box = getBoundingBox().expand(0, -0.4, 0).contract(0.001);
Box box = this.getBoundingBox().expand(0, -0.4, 0).contract(0.001);
int minX = MathHelper.floor(box.minX);
int maxX = MathHelper.ceil(box.maxX);
int minY = MathHelper.floor(box.minY);
@ -112,8 +119,9 @@ public abstract class MixinEntity {
int minZ = MathHelper.floor(box.minZ);
int maxZ = MathHelper.ceil(box.maxZ);
if (!world.isRegionLoaded(minX, minY, minZ, maxX, maxY, maxZ)) {
ci.setReturnValue(false);
if (!this.world.isRegionLoaded(minX, minY, minZ, maxX, maxY, maxZ)) {
cir.setReturnValue(false);
return;
}
double waterHeight = 0;
@ -126,14 +134,14 @@ public abstract class MixinEntity {
for (int y = minY - 1; y < maxY; y++) {
for (int z = minZ; z < maxZ; z++) {
mutable.set(x, y, z);
FluidState state = world.getFluidState(mutable);
FluidState state = this.world.getFluidState(mutable);
if (state.isIn(fluidTag)) {
double height = y + state.getHeight(world, mutable);
double height = y + state.getHeight(this.world, mutable);
if (height >= box.minY - 0.4)
waterHeight = Math.max(height - box.minY + 0.4, waterHeight);
if (y >= minY && maxY >= height) {
foundFluid = true;
pushVec = pushVec.add(state.getVelocity(world, mutable));
pushVec = pushVec.add(state.getVelocity(this.world, mutable));
}
}
}
@ -142,11 +150,11 @@ public abstract class MixinEntity {
if (pushVec.length() > 0) {
pushVec = pushVec.normalize().multiply(0.014);
setVelocity(getVelocity().add(pushVec));
this.setVelocity(this.getVelocity().add(pushVec));
}
this.fluidHeight.put(fluidTag, waterHeight);
ci.setReturnValue(foundFluid);
cir.setReturnValue(foundFluid);
}
@Inject(method = "getTargetingMargin", at = @At("HEAD"), cancellable = true)
@ -157,28 +165,21 @@ public abstract class MixinEntity {
}
@Redirect(method = {"setYaw", "setPitch"}, at = @At(value = "INVOKE", target = "Ljava/lang/Float;isFinite(F)Z"))
private boolean modifyIsFinite(float f) {
return Float.isFinite(f) || ((Object) this instanceof ClientPlayerEntity && ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2));
private boolean allowInfiniteValues(float f) {
return Float.isFinite(f) || ((Object) this instanceof ClientPlayerEntity && ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_4tor1_16_5));
}
@ModifyConstant(method = "checkBlockCollision", constant = @Constant(doubleValue = 1.0E-7))
private double changeBlockCollisionConstant(double constant) {
private double fixBlockCollisionMargin(double constant) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_1tor1_19_2)) {
return 0.001;
return 1E-3;
}
return constant;
}
@Redirect(method = "move", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;onLanding()V"))
private void revertOnLanding(Entity instance) {
if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_19)) {
instance.onLanding();
}
}
@Inject(method = "getPosWithYOffset", at = @At("HEAD"), cancellable = true)
private void changeLogic(float offset, CallbackInfoReturnable<BlockPos> cir) {
private void modifyPosWithYOffset(float offset, CallbackInfoReturnable<BlockPos> cir) {
final VersionEnum target = ProtocolHack.getTargetVersion();
if (target.isOlderThanOrEqualTo(VersionEnum.r1_19_4)) {
int i = MathHelper.floor(this.pos.x);
@ -186,10 +187,11 @@ public abstract class MixinEntity {
int k = MathHelper.floor(this.pos.z);
BlockPos blockPos = new BlockPos(i, j, k);
if (this.world.getBlockState(blockPos).isAir()) {
BlockPos blockPos2 = blockPos.down();
BlockState blockState = this.world.getBlockState(blockPos2);
BlockPos downPos = blockPos.down();
BlockState blockState = this.world.getBlockState(downPos);
if (blockState.isIn(BlockTags.FENCES) || blockState.isIn(BlockTags.WALLS) || blockState.getBlock() instanceof FenceGateBlock) {
cir.setReturnValue(blockPos2);
cir.setReturnValue(downPos);
return;
}
}
@ -198,14 +200,14 @@ public abstract class MixinEntity {
}
@Inject(method = "getRidingOffset", at = @At("HEAD"), cancellable = true)
private void replaceRidingOffset(Entity vehicle, CallbackInfoReturnable<Float> cir) {
private void getRidingOffset1_20_1(Entity vehicle, CallbackInfoReturnable<Float> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_20tor1_20_1)) {
cir.setReturnValue((float) EntityHeightOffsetsPre1_20_2.getHeightOffset((Entity) (Object) this));
}
}
@Redirect(method = "getPassengerRidingPos", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getPassengerAttachmentPos(Lnet/minecraft/entity/Entity;Lnet/minecraft/entity/EntityDimensions;F)Lorg/joml/Vector3f;"))
private Vector3f revertStaticRidingOffsetCalculation(Entity instance, Entity passenger, EntityDimensions dimensions, float scaleFactor) {
private Vector3f getPassengerRidingPos1_20_1(Entity instance, Entity passenger, EntityDimensions dimensions, float scaleFactor) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_20tor1_20_1)) {
return EntityHeightOffsetsPre1_20_2.getMountedHeightOffset(instance, passenger);
}
@ -213,4 +215,14 @@ public abstract class MixinEntity {
return getPassengerAttachmentPos(passenger, dimensions, scaleFactor);
}
@Override
public boolean viaFabricPlus$isInLoadedChunkAndShouldTick() {
return this.viaFabricPlus$isInLoadedChunkAndShouldTick || !ProtocolHack.getTargetVersion().isBetweenInclusive(VersionEnum.r1_9, VersionEnum.r1_16_4tor1_16_5) /* || TODO: Add setting to force this*/;
}
@Override
public void viaFabricPlus$setInLoadedChunkAndShouldTick(final boolean inLoadedChunkAndShouldTick) {
this.viaFabricPlus$isInLoadedChunkAndShouldTick = inLoadedChunkAndShouldTick;
}
}

View File

@ -1,43 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD
* Copyright (C) 2023 RK_01/RaphiMC and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import net.raphimc.vialoader.util.VersionEnum;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.predicate.entity.EntityPredicates;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(EntityPredicates.class)
public abstract class MixinEntityPredicates {
@SuppressWarnings("target")
@Redirect(method = "method_5915(Lnet/minecraft/entity/Entity;Lnet/minecraft/scoreboard/AbstractTeam;Lnet/minecraft/scoreboard/AbstractTeam$CollisionRule;Lnet/minecraft/entity/Entity;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;isMainPlayer()Z"))
private static boolean makeMainPlayerUnpushable(PlayerEntity player) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
return false;
}
return player.isMainPlayer();
}
}

View File

@ -19,9 +19,8 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import de.florianmichael.viafabricplus.fixes.BoatRenderer_1_8;
import de.florianmichael.viafabricplus.fixes.BoatRenderer1_8;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import de.florianmichael.viafabricplus.settings.impl.ExperimentalSettings;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.render.entity.EntityRenderer;
import net.minecraft.client.render.entity.EntityRendererFactory;
@ -41,19 +40,19 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
public abstract class MixinEntityRenderDispatcher {
@Unique
private BoatRenderer_1_8 viaFabricPlus$boatRenderer;
private BoatRenderer1_8 viaFabricPlus$boatRenderer;
@SuppressWarnings("unchecked")
@Inject(method = "getRenderer", at = @At("HEAD"), cancellable = true)
private <T extends Entity> void onGetRenderer(T entity, CallbackInfoReturnable<EntityRenderer<? super T>> ci) {
if (ExperimentalSettings.INSTANCE.emulateBoatMovement.getValue() && ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8) && entity instanceof BoatEntity) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8) && entity instanceof BoatEntity) {
ci.setReturnValue((EntityRenderer<? super T>) viaFabricPlus$boatRenderer);
}
}
@Inject(method = "reload", at = @At("TAIL"), locals = LocalCapture.CAPTURE_FAILHARD)
private void onReload(ResourceManager manager, CallbackInfo ci, EntityRendererFactory.Context context) {
viaFabricPlus$boatRenderer = new BoatRenderer_1_8(context);
viaFabricPlus$boatRenderer = new BoatRenderer1_8(context);
}
}

View File

@ -19,14 +19,15 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import com.llamalad7.mixinextras.injector.WrapWithCondition;
import de.florianmichael.viafabricplus.settings.impl.ExperimentalSettings;
import de.florianmichael.viafabricplus.fixes.EntityHeightOffsetsPre1_20_2;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import de.florianmichael.viafabricplus.settings.impl.ExperimentalSettings;
import net.minecraft.block.BlockState;
import net.minecraft.block.TrapdoorBlock;
import net.minecraft.entity.*;
import net.minecraft.entity.mob.SkeletonHorseEntity;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluid;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
@ -42,28 +43,17 @@ import org.joml.Vector3f;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Optional;
@SuppressWarnings("ConstantValue")
@Mixin(LivingEntity.class)
public abstract class MixinLivingEntity extends Entity {
@Shadow
protected boolean jumping;
public MixinLivingEntity(EntityType<?> type, World world) {
super(type, world);
}
@Inject(method = "getPreferredEquipmentSlot", at = @At("HEAD"), cancellable = true)
private static void removeShieldSlotPreference(ItemStack stack, CallbackInfoReturnable<EquipmentSlot> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_9_3tor1_9_4) && stack.isOf(Items.SHIELD)) {
cir.setReturnValue(EquipmentSlot.MAINHAND);
}
}
@Shadow
protected abstract float getBaseMovementSpeedMultiplier();
@ -73,6 +63,30 @@ public abstract class MixinLivingEntity extends Entity {
@Shadow
protected abstract boolean canEnterTrapdoor(BlockPos pos, BlockState state);
@Shadow
public abstract boolean hasStatusEffect(StatusEffect effect);
@Shadow
private int jumpingCooldown;
public MixinLivingEntity(EntityType<?> type, World world) {
super(type, world);
}
@Inject(method = "<init>", at = @At("RETURN"))
private void modify1_7StepHeight(EntityType<? extends LivingEntity> type, World world, CallbackInfo ci) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_7_6tor1_7_10)) {
this.setStepHeight(0.5F);
}
}
@Inject(method = "getPreferredEquipmentSlot", at = @At("HEAD"), cancellable = true)
private static void removeShieldSlotPreference(ItemStack stack, CallbackInfoReturnable<EquipmentSlot> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_9_3tor1_9_4) && stack.isOf(Items.SHIELD)) {
cir.setReturnValue(EquipmentSlot.MAINHAND);
}
}
@Redirect(method = "applyMovementInput", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/LivingEntity;jumping:Z"))
private boolean disableJumpOnLadder(LivingEntity self) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_13_2)) {
@ -85,12 +99,21 @@ public abstract class MixinLivingEntity extends Entity {
@Redirect(method = "travel",
slice = @Slice(from = @At(value = "FIELD", target = "Lnet/minecraft/entity/effect/StatusEffects;DOLPHINS_GRACE:Lnet/minecraft/entity/effect/StatusEffect;")),
at = @At(value = "FIELD", target = "Lnet/minecraft/entity/LivingEntity;horizontalCollision:Z", ordinal = 0))
private boolean disableClimbing(LivingEntity self) {
private boolean disableClimbing(LivingEntity instance) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_13_2)) {
return false;
}
return horizontalCollision;
return instance.horizontalCollision;
}
@Redirect(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;isLogicalSideForUpdatingMovement()Z"))
private boolean allowPlayerToBeMovedByEntityPackets(LivingEntity instance) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_3) || ProtocolHack.getTargetVersion().equals(VersionEnum.bedrockLatest)) {
return instance.getControllingPassenger() instanceof PlayerEntity player ? player.isMainPlayer() : !instance.getWorld().isClient;
}
return instance.isLogicalSideForUpdatingMovement();
}
@ModifyVariable(method = "applyFluidMovingSpeed", ordinal = 0, at = @At("HEAD"), argsOnly = true)
@ -102,19 +125,21 @@ public abstract class MixinLivingEntity extends Entity {
return movingDown;
}
@WrapWithCondition(method = "tickMovement",
slice = @Slice(from = @At(value = "FIELD", target = "Lnet/minecraft/entity/effect/StatusEffects;LEVITATION:Lnet/minecraft/entity/effect/StatusEffect;", ordinal = 0)),
at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;onLanding()V", ordinal = 0))
private boolean dontResetLevitationFallDistance(LivingEntity instance) {
return ProtocolHack.getTargetVersion().isNewerThan(VersionEnum.r1_12_2);
@Redirect(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;onLanding()V"))
private void dontResetLevitationFallDistance(LivingEntity instance) {
if (!this.hasStatusEffect(StatusEffects.SLOW_FALLING) && ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2)) {
return;
}
instance.onLanding();
}
@Redirect(method = "travel", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;isSprinting()Z", ordinal = 0))
private boolean modifySwimSprintSpeed(LivingEntity self) {
private boolean modifySwimSprintSpeed(LivingEntity instance) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2)) {
return false;
}
return self.isSprinting();
return instance.isSprinting();
}
@Redirect(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;getFluidHeight(Lnet/minecraft/registry/tag/TagKey;)D"))
@ -129,7 +154,7 @@ public abstract class MixinLivingEntity extends Entity {
@Inject(method = "applyFluidMovingSpeed", at = @At("HEAD"), cancellable = true)
private void modifySwimSprintFallSpeed(double gravity, boolean movingDown, Vec3d velocity, CallbackInfoReturnable<Vec3d> ci) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2) && !hasNoGravity()) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2) && !this.hasNoGravity()) {
ci.setReturnValue(new Vec3d(velocity.x, velocity.y - 0.02, velocity.z));
}
}
@ -143,27 +168,30 @@ public abstract class MixinLivingEntity extends Entity {
}
@Inject(method = "canEnterTrapdoor", at = @At("HEAD"), cancellable = true)
private void onCanEnterTrapdoor(CallbackInfoReturnable<Boolean> ci) {
private void disableCrawling(CallbackInfoReturnable<Boolean> ci) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
ci.setReturnValue(false);
}
}
@ModifyConstant(method = "travel", constant = @Constant(floatValue = 0.9F))
private float changeEntitySpeed(float constant) {
private float modifySwimFriction(float constant) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2)) {
//noinspection ConstantConditions
if ((Entity) this instanceof SkeletonHorseEntity) {
return this.getBaseMovementSpeedMultiplier(); // 0.96F
}
return 0.8F;
return this.getBaseMovementSpeedMultiplier();
}
return constant;
}
@Redirect(method = "travel", at = @At(value = "INVOKE", target = "Ljava/lang/Math;cos(D)D"))
@Inject(method = "tickMovement", at = @At("HEAD"))
private void removeJumpDelay1_0(CallbackInfo ci) {
if (ProtocolHack.getTargetVersion().isOlderThan(VersionEnum.r1_0_0tor1_0_1)) {
this.jumpingCooldown = 0;
}
}
@Redirect(method = "travel", at = @At(value = "INVOKE", target = "Ljava/lang/Math;cos(D)D", remap = false))
private double fixCosTable(double a) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_18_2)) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_18tor1_18_1)) {
return MathHelper.cos((float) a);
}
return Math.cos(a);
@ -171,20 +199,20 @@ public abstract class MixinLivingEntity extends Entity {
@Redirect(method = "travel", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;getFluidHeight(Lnet/minecraft/registry/tag/TagKey;)D"))
private double fixLavaMovement(LivingEntity instance, TagKey<Fluid> tagKey) {
double height = instance.getFluidHeight(tagKey);
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_15_2)) {
height += getSwimHeight() + 4;
return Double.MAX_VALUE;
}
return height;
return instance.getFluidHeight(tagKey);
}
@ModifyConstant(method = "isBlocking", constant = @Constant(intValue = 5))
private int shieldBlockCounter(int constant) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
return 0;
@Redirect(method = "travel", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;isChunkLoaded(Lnet/minecraft/util/math/BlockPos;)Z"))
private boolean modify1_13LoadedCheck(World instance, BlockPos blockPos) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_13_2)) {
return this.getWorld().isChunkLoaded(blockPos) && instance.getChunkManager().isChunkLoaded(blockPos.getX() >> 4, blockPos.getZ() >> 4);
} else {
return this.getWorld().isChunkLoaded(blockPos);
}
return constant;
}
@Redirect(method = "tickCramming", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;isClient()Z"))
@ -211,14 +239,14 @@ public abstract class MixinLivingEntity extends Entity {
}
@Inject(method = "getRidingOffset", at = @At("HEAD"), cancellable = true)
private void replaceRidingOffset(Entity vehicle, CallbackInfoReturnable<Float> cir) {
private void getRidingOffset1_20_1(Entity vehicle, CallbackInfoReturnable<Float> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_20tor1_20_1)) {
cir.setReturnValue((float) EntityHeightOffsetsPre1_20_2.getHeightOffset(this));
}
}
@Redirect(method = "getPassengerRidingPos", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;getPassengerAttachmentPos(Lnet/minecraft/entity/Entity;Lnet/minecraft/entity/EntityDimensions;F)Lorg/joml/Vector3f;"))
private Vector3f revertStaticRidingOffsetCalculation(LivingEntity instance, Entity entity, EntityDimensions entityDimensions, float v) {
private Vector3f getPassengerRidingPos1_20_1(LivingEntity instance, Entity entity, EntityDimensions entityDimensions, float v) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_20tor1_20_1)) {
return EntityHeightOffsetsPre1_20_2.getMountedHeightOffset(instance, entity);
}

View File

@ -20,12 +20,11 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import com.mojang.authlib.GameProfile;
import net.raphimc.vialoader.util.VersionEnum;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.network.OtherClientPlayerEntity;
import net.minecraft.client.world.ClientWorld;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -39,7 +38,7 @@ public abstract class MixinOtherClientPlayerEntity extends AbstractClientPlayerE
}
@Inject(method = "updatePose", at = @At("HEAD"))
private void dontUpdatePose(CallbackInfo ci) {
private void onUpdatePose(CallbackInfo ci) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_13_2)) {
super.updatePose();
}

View File

@ -1,46 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD
* Copyright (C) 2023 RK_01/RaphiMC and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import net.raphimc.vialoader.util.VersionEnum;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityPose;
import net.minecraft.entity.mob.PiglinEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(PiglinEntity.class)
public abstract class MixinPiglinEntity {
@Shadow public abstract boolean isBaby();
@Inject(method = "getActiveEyeHeight", at = @At("HEAD"), cancellable = true)
private void changeEyeHeight(EntityPose pose, EntityDimensions dimensions, CallbackInfoReturnable<Float> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_1tor1_19_2)) {
cir.setReturnValue(this.isBaby() ? 0.93F : 1.74F);
}
}
}

View File

@ -21,23 +21,26 @@ package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import de.florianmichael.viafabricplus.settings.impl.VisualSettings;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityPose;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.block.BlockState;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.*;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectUtil;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.entity.player.PlayerAbilities;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ElytraItem;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.registry.tag.FluidTags;
import net.minecraft.sound.SoundEvent;
import net.minecraft.util.Hand;
import net.minecraft.util.Identifier;
import net.minecraft.world.World;
import net.raphimc.vialoader.util.VersionEnum;
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.*;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@ -46,15 +49,24 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(PlayerEntity.class)
public abstract class MixinPlayerEntity extends LivingEntity {
@Shadow
@Final
private PlayerAbilities abilities;
@Shadow
public abstract boolean canHarvest(BlockState state);
@Shadow
@Final
private PlayerInventory inventory;
@Unique
private static final EntityDimensions viaFabricPlus$sneaking_dimensions_v1_13_2 = EntityDimensions.changing(0.6f, 1.65f);
@Unique
private static final SoundEvent viaFabricPlus$random_hurt = SoundEvent.of(new Identifier("viafabricplus", "random.hurt"));
@Shadow
@Final
private PlayerAbilities abilities;
@Unique
public boolean viaFabricPlus$isSprinting;
protected MixinPlayerEntity(EntityType<? extends LivingEntity> entityType, World world) {
super(entityType, world);
@ -63,39 +75,38 @@ public abstract class MixinPlayerEntity extends LivingEntity {
@Inject(method = "updatePose", at = @At("HEAD"), cancellable = true)
private void onUpdatePose(CallbackInfo ci) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_13_2)) {
EntityPose pose;
if (isFallFlying())
final EntityPose pose;
if (this.isFallFlying()) {
pose = EntityPose.FALL_FLYING;
else if (isSleeping())
} else if (this.isSleeping()) {
pose = EntityPose.SLEEPING;
else if (isSwimming())
} else if (this.isSwimming()) {
pose = EntityPose.SWIMMING;
else if (isUsingRiptide())
} else if (this.isUsingRiptide()) {
pose = EntityPose.SPIN_ATTACK;
else if (isSneaking() && !abilities.flying)
} else if (this.isSneaking() && !this.abilities.flying) {
pose = EntityPose.CROUCHING;
else
} else {
pose = EntityPose.STANDING;
}
this.setPose(pose);
ci.cancel();
}
}
@Inject(method = "getDimensions", at = @At("HEAD"), cancellable = true)
private void onGetDimensions(EntityPose pose, CallbackInfoReturnable<EntityDimensions> ci) {
private void modifyDimensions(EntityPose pose, CallbackInfoReturnable<EntityDimensions> cir) {
if (pose == EntityPose.CROUCHING) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
ci.setReturnValue(PlayerEntity.STANDING_DIMENSIONS);
} else if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_13_2) || ProtocolHack.getTargetVersion() == VersionEnum.bedrockLatest) {
ci.setReturnValue(viaFabricPlus$sneaking_dimensions_v1_13_2);
cir.setReturnValue(PlayerEntity.STANDING_DIMENSIONS);
} else if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_13_2)) {
cir.setReturnValue(viaFabricPlus$sneaking_dimensions_v1_13_2);
}
}
}
@Inject(method = "getAttackCooldownProgress", at = @At("HEAD"), cancellable = true)
private void injectGetAttackCooldownProgress(CallbackInfoReturnable<Float> ci) {
private void removeAttackCooldown(CallbackInfoReturnable<Float> ci) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
ci.setReturnValue(1f);
}
@ -124,28 +135,102 @@ public abstract class MixinPlayerEntity extends LivingEntity {
instance.swingHand(hand);
}
@Unique
public boolean viaFabricPlus$isSprinting;
@Inject(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;setMovementSpeed(F)V"))
private void trackOldField(CallbackInfo ci) {
private void storeSprintingState(CallbackInfo ci) {
viaFabricPlus$isSprinting = this.isSprinting();
}
@Redirect(method = "getOffGroundSpeed", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;isSprinting()Z"))
private boolean useOldField(PlayerEntity instance) {
private boolean useLastSprintingState(PlayerEntity instance) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_3)) {
return viaFabricPlus$isSprinting;
}
return instance.isSprinting();
}
@Redirect(method = "checkFallFlying", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;hasStatusEffect(Lnet/minecraft/entity/effect/StatusEffect;)Z"))
private boolean allowElytraWhenLevitating(PlayerEntity instance, StatusEffect statusEffect) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_15_2)) {
return false;
}
return instance.hasStatusEffect(statusEffect);
}
@Inject(method = "checkFallFlying", at = @At("HEAD"), cancellable = true)
private void makeElytraMovementServerside(CallbackInfoReturnable<Boolean> cir) {
// Elytra movement was serverside in <= 1.14.4 and got moved to the client in 1.15
if ((Object) this instanceof ClientPlayerEntity && ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_14_4)) {
cir.setReturnValue(!this.isOnGround() && this.getVelocity().y < 0.0 && !isFallFlying());
private void replaceFallFlyingCondition(CallbackInfoReturnable<Boolean> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_14_4)) {
if (!this.isOnGround() && this.getVelocity().y < 0D && !this.isFallFlying()) {
final ItemStack itemStack = this.getEquippedStack(EquipmentSlot.CHEST);
if (itemStack.isOf(Items.ELYTRA) && ElytraItem.isUsable(itemStack)) {
cir.setReturnValue(true);
return;
}
}
cir.setReturnValue(false);
}
}
@Redirect(method = "adjustMovementForSneaking", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;getStepHeight()F"))
private float modifyStepHeight1_10(PlayerEntity instance) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_10)) {
return 1.0F;
}
return instance.getStepHeight();
}
/**
* @author RK_01
* @reason ProtocolHack block break speed changes
*/
@Overwrite
public float getBlockBreakingSpeed(BlockState block) {
float f = this.inventory.getBlockBreakingSpeed(block);
final ItemStack itemStack = this.getMainHandStack();
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_4_4tor1_4_5)) {
int i = EnchantmentHelper.getEfficiency(this);
if (i > 0 && this.canHarvest(block)) f += (float) (i * i + 1);
} else {
if (f > 1F || ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_4_6tor1_4_7)) {
int i = EnchantmentHelper.getEfficiency(this);
if (i > 0 && !itemStack.isEmpty()) {
final float f1 = (i * i + 1);
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_7_6tor1_7_10)) {
if (f <= 1.0 && !this.canHarvest(block)) f += f1 * 0.08F;
else f += f1;
} else {
f += f1;
}
}
}
}
if (StatusEffectUtil.hasHaste(this)) {
f *= 1.0F + (float) (StatusEffectUtil.getHasteAmplifier(this) + 1) * 0.2F;
}
if (this.hasStatusEffect(StatusEffects.MINING_FATIGUE)) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_7_6tor1_7_10)) {
f *= 1.0F - (float) (this.getStatusEffect(StatusEffects.MINING_FATIGUE).getAmplifier() + 1) * 0.2F;
if (f < 0) f = 0;
} else {
f *= switch (this.getStatusEffect(StatusEffects.MINING_FATIGUE).getAmplifier()) {
case 0 -> 0.3F;
case 1 -> 0.09F;
case 2 -> 0.0027F;
default -> 8.1E-4F;
};
}
}
if (this.isSubmergedIn(FluidTags.WATER) && !EnchantmentHelper.hasAquaAffinity(this)) {
f /= 5.0F;
}
if (!this.isOnGround()) {
f /= 5F;
}
return f;
}
}

View File

@ -17,15 +17,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import net.raphimc.vialoader.util.VersionEnum;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.render.entity.PlayerEntityRenderer;
import net.minecraft.entity.EntityPose;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -35,18 +35,27 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(PlayerEntityRenderer.class)
public abstract class MixinPlayerEntityRenderer {
@Inject(method = "getPositionOffset*", at = @At("RETURN"), cancellable = true)
private void injectGetPositionOffset(AbstractClientPlayerEntity player, float delta, CallbackInfoReturnable<Vec3d> ci) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_13_2)) {
if (player.getSleepingDirection() != null) {
ci.setReturnValue(ci.getReturnValue().subtract(player.getSleepingDirection().getOffsetX() * 0.4, 0, player.getSleepingDirection().getOffsetZ() * 0.4));
@Inject(method = "getPositionOffset(Lnet/minecraft/client/network/AbstractClientPlayerEntity;F)Lnet/minecraft/util/math/Vec3d;", at = @At("RETURN"), cancellable = true)
private void modifySleepingOffset(AbstractClientPlayerEntity player, float delta, CallbackInfoReturnable<Vec3d> cir) {
if (player.getPose() == EntityPose.SLEEPING) {
final Direction sleepingDir = player.getSleepingDirection();
if (sleepingDir != null) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_13_2)) {
cir.setReturnValue(cir.getReturnValue().subtract(sleepingDir.getOffsetX() * 0.4, 0, sleepingDir.getOffsetZ() * 0.4));
}
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.b1_5tob1_5_2)) {
cir.setReturnValue(cir.getReturnValue().subtract(sleepingDir.getOffsetX() * 0.1, 0, sleepingDir.getOffsetZ() * 0.1));
}
if (ProtocolHack.getTargetVersion().isBetweenInclusive(VersionEnum.b1_6tob1_6_6, VersionEnum.r1_7_6tor1_7_10)) {
cir.setReturnValue(cir.getReturnValue().subtract(0, 0.3F, 0));
}
}
}
}
@Redirect(method = "getPositionOffset(Lnet/minecraft/client/network/AbstractClientPlayerEntity;F)Lnet/minecraft/util/math/Vec3d;",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/AbstractClientPlayerEntity;isInSneakingPose()Z"))
private boolean redirectGetPositionOffset(AbstractClientPlayerEntity player) {
private boolean disableSneakPositionOffset(AbstractClientPlayerEntity player) {
return (ProtocolHack.getTargetVersion().isNewerThan(VersionEnum.r1_11_1to1_11_2)) && player.isInSneakingPose();
}

View File

@ -0,0 +1,28 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.mob.SkeletonHorseEntity;
import net.minecraft.entity.passive.AbstractHorseEntity;
import net.minecraft.world.World;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(SkeletonHorseEntity.class)
public abstract class MixinSkeletonHorseEntity extends AbstractHorseEntity {
protected MixinSkeletonHorseEntity(EntityType<? extends AbstractHorseEntity> entityType, World world) {
super(entityType, world);
}
@Inject(method = "getBaseMovementSpeedMultiplier", at = @At("HEAD"), cancellable = true)
private void modifyBaseMovementSpeedMultiplier(CallbackInfoReturnable<Float> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2)) {
cir.setReturnValue(super.getBaseMovementSpeedMultiplier());
}
}
}

View File

@ -19,11 +19,10 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import net.raphimc.vialoader.util.VersionEnum;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.entity.passive.SquidEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -33,7 +32,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
public abstract class MixinSquidEntity {
@Inject(method = "canBeLeashedBy", at = @At("HEAD"), cancellable = true)
private void injectCanBeLeashedBy(PlayerEntity player, CallbackInfoReturnable<Boolean> cir) {
private void cancelLeashing(PlayerEntity player, CallbackInfoReturnable<Boolean> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_4tor1_16_5)) {
cir.setReturnValue(false);
}

View File

@ -19,26 +19,87 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import net.raphimc.vialoader.util.VersionEnum;
import de.florianmichael.viafabricplus.fixes.tracker.WolfHealthTracker;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.mob.Angerable;
import net.minecraft.entity.passive.TameableEntity;
import net.minecraft.entity.passive.WolfEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.DyeItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.util.ActionResult;
import net.minecraft.util.DyeColor;
import net.minecraft.util.Hand;
import net.minecraft.world.World;
import net.raphimc.vialoader.util.VersionEnum;
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.CallbackInfoReturnable;
@SuppressWarnings("DataFlowIssue")
@Mixin(WolfEntity.class)
public abstract class MixinWolfEntity {
public abstract class MixinWolfEntity extends TameableEntity implements Angerable {
@Shadow
public abstract DyeColor getCollarColor();
@Shadow
public abstract void setCollarColor(DyeColor color);
protected MixinWolfEntity(EntityType<? extends TameableEntity> entityType, World world) {
super(entityType, world);
}
@Inject(method = "interactMob", at = @At("HEAD"), cancellable = true)
private void fixWolfInteract(PlayerEntity player, Hand hand, CallbackInfoReturnable<ActionResult> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_14_4)) {
final ItemStack itemStack = player.getStackInHand(hand);
final Item item = itemStack.getItem();
if (this.isTamed()) {
if (item.isFood()) {
if (item.getFoodComponent().isMeat() && this.getWolfHealth() < 20.0F) {
if (!player.getAbilities().creativeMode) itemStack.decrement(1);
this.heal((float) item.getFoodComponent().getHunger());
cir.setReturnValue(ActionResult.SUCCESS);
return;
}
} else if (item instanceof DyeItem dyeItem) {
final DyeColor dyeColor = dyeItem.getColor();
if (dyeColor != this.getCollarColor()) {
this.setCollarColor(dyeColor);
if (!player.getAbilities().creativeMode) itemStack.decrement(1);
cir.setReturnValue(ActionResult.SUCCESS);
return;
}
}
} else if (item == Items.BONE && !this.hasAngerTime()) {
if (!player.getAbilities().creativeMode) itemStack.decrement(1);
cir.setReturnValue(ActionResult.SUCCESS);
return;
}
cir.setReturnValue(super.interactMob(player, hand));
}
}
@Redirect(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/passive/WolfEntity;getHealth()F"))
private float rewriteHealth(WolfEntity instance) {
float health = instance.getHealth();
private float fixWolfHealth(WolfEntity instance) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_14_4)) {
return WolfHealthTracker.get().getHealthDataMap().getOrDefault(instance.getId(), health);
return this.getWolfHealth();
}
return health;
return instance.getHealth();
}
@Unique
private float getWolfHealth() {
return WolfHealthTracker.get().getWolfHealth(this.getId(), this.getHealth());
}
}

View File

@ -19,12 +19,11 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.input;
import net.raphimc.vialoader.util.VersionEnum;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.input.Input;
import net.minecraft.client.input.KeyboardInput;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
@ -33,7 +32,7 @@ import org.spongepowered.asm.mixin.injection.ModifyVariable;
public abstract class MixinKeyboardInput extends Input {
@ModifyVariable(method = "tick", at = @At(value = "LOAD", ordinal = 0), argsOnly = true)
private boolean injectTick(boolean slowDown) {
private boolean changeSneakSlowdownCondition(boolean slowDown) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_13_2)) {
return this.sneaking;
} else if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_14_4)) {

View File

@ -0,0 +1,27 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ArmorItem;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.world.World;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ArmorItem.class)
public abstract class MixinArmorItem {
@Inject(method = "use", at = @At("HEAD"), cancellable = true)
private void disableRightClick(World world, PlayerEntity user, Hand hand, CallbackInfoReturnable<TypedActionResult<ItemStack>> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_4_6tor1_4_7)) {
cir.setReturnValue(new TypedActionResult<>(ActionResult.FAIL, user.getStackInHand(hand)));
}
}
}

View File

@ -19,25 +19,65 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import net.raphimc.vialoader.util.VersionEnum;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.google.common.collect.ImmutableSet;
import de.florianmichael.viafabricplus.fixes.Material1_19_4;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.item.AxeItem;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.item.*;
import net.minecraft.registry.tag.TagKey;
import net.minecraft.util.ActionResult;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Set;
@Mixin(AxeItem.class)
public abstract class MixinAxeItem {
public abstract class MixinAxeItem extends MiningToolItem {
@Unique
private static final Set<Block> _b1_8_1_EFFECTIVE_BLOCKS = ImmutableSet.of(Blocks.OAK_PLANKS, Blocks.BOOKSHELF, Blocks.OAK_LOG, Blocks.CHEST);
@Unique
private static final Set<Block> _r1_16_5_EFFECTIVE_BLOCKS = ImmutableSet.of(Blocks.LADDER, Blocks.SCAFFOLDING, Blocks.OAK_BUTTON, Blocks.SPRUCE_BUTTON, Blocks.BIRCH_BUTTON, Blocks.JUNGLE_BUTTON, Blocks.DARK_OAK_BUTTON, Blocks.ACACIA_BUTTON, Blocks.CRIMSON_BUTTON, Blocks.WARPED_BUTTON);
@Unique
private static final Set<Material1_19_4> _r1_16_5_EFFECTIVE_MATERIALS = ImmutableSet.of(Material1_19_4.WOOD, Material1_19_4.NETHER_WOOD, Material1_19_4.PLANT, Material1_19_4.REPLACEABLE_PLANT, Material1_19_4.BAMBOO, Material1_19_4.GOURD);
public MixinAxeItem(float attackDamage, float attackSpeed, ToolMaterial material, TagKey<Block> effectiveBlocks, Settings settings) {
super(attackDamage, attackSpeed, material, effectiveBlocks, settings);
}
@Inject(method = "useOnBlock", at = @At("HEAD"), cancellable = true)
private void alwaysPassInteraction(ItemUsageContext context, CallbackInfoReturnable<ActionResult> cir) {
private void disableUse(ItemUsageContext context, CallbackInfoReturnable<ActionResult> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2)) {
cir.setReturnValue(ActionResult.PASS);
}
}
@Override
public boolean isSuitableFor(BlockState state) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_4tor1_16_5)) {
return false;
}
return super.isSuitableFor(state);
}
@Override
public float getMiningSpeedMultiplier(ItemStack stack, BlockState state) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.b1_8tob1_8_1)) {
return _b1_8_1_EFFECTIVE_BLOCKS.contains(state.getBlock()) ? this.miningSpeed : 1.0F;
} else if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_4tor1_16_5)) {
return _r1_16_5_EFFECTIVE_MATERIALS.contains(Material1_19_4.getMaterial(state)) ? this.miningSpeed : _r1_16_5_EFFECTIVE_BLOCKS.contains(state.getBlock()) ? this.miningSpeed : 1.0F;
}
return super.getMiningSpeedMultiplier(stack, state);
}
}

View File

@ -19,8 +19,6 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import net.raphimc.vialoader.util.VersionEnum;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@ -32,6 +30,7 @@ import net.minecraft.item.ItemPlacementContext;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -41,7 +40,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
public abstract class MixinBlockItem {
@Inject(method = "canPlace", at = @At("HEAD"), cancellable = true)
private void injectCanPlace(ItemPlacementContext context, BlockState state, CallbackInfoReturnable<Boolean> ci) {
private void checkChestPlacement(ItemPlacementContext context, BlockState state, CallbackInfoReturnable<Boolean> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2)) {
Block block = state.getBlock();
if (block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST) {
@ -52,12 +51,12 @@ public abstract class MixinBlockItem {
BlockState otherState = world.getBlockState(pos.offset(dir));
if (otherState.getBlock() == block) {
if (foundAdjChest) {
ci.setReturnValue(false);
cir.setReturnValue(false);
return;
}
foundAdjChest = true;
if (otherState.get(ChestBlock.CHEST_TYPE) != ChestType.SINGLE) {
ci.setReturnValue(false);
cir.setReturnValue(false);
return;
}
}

View File

@ -0,0 +1,48 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BowItem;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.UseAction;
import net.minecraft.world.World;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(BowItem.class)
public abstract class MixinBowItem {
@Inject(method = "getMaxUseTime", at = @At("HEAD"), cancellable = true)
private void makeInstantUsable(CallbackInfoReturnable<Integer> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.b1_7tob1_7_3)) {
cir.setReturnValue(0);
}
}
@Inject(method = "getUseAction", at = @At("HEAD"), cancellable = true)
private void makeInstantUsable2(CallbackInfoReturnable<UseAction> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.b1_7tob1_7_3)) {
cir.setReturnValue(UseAction.NONE);
}
}
@Inject(method = "use", at = @At("HEAD"), cancellable = true)
private void makeInstantUsable(World world, PlayerEntity user, Hand hand, CallbackInfoReturnable<TypedActionResult<ItemStack>> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.b1_7tob1_7_3)) {
final ItemStack stack = user.getStackInHand(hand);
final ItemStack arrowStack = user.getProjectileType(stack);
if (arrowStack.isEmpty()) {
cir.setReturnValue(TypedActionResult.fail(stack));
} else {
arrowStack.decrement(1);
cir.setReturnValue(TypedActionResult.pass(stack));
}
}
}
}

View File

@ -17,12 +17,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.client.font.TextRenderer;
import de.florianmichael.viafabricplus.injection.access.IItemStack;
import net.minecraft.client.gui.DrawContext;
import net.raphimc.vialoader.util.VersionEnum;
import net.minecraft.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@ -30,14 +29,20 @@ import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(DrawContext.class)
public abstract class MixinDrawContext {
@Redirect(method = "drawItemInSlot(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawText(Lnet/minecraft/client/font/TextRenderer;Ljava/lang/String;IIIZ)I"))
private int recolor(DrawContext instance, TextRenderer textRenderer, String text, int x, int y, int color, boolean shadow) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_10) && text.startsWith("-")) {
color = -43213; // red
@Redirect(method = "drawItemInSlot(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getCount()I"))
private int handleNegativeItemCount(ItemStack instance) {
if (((IItemStack) (Object) instance).viaFabricPlus$has1_10ProtocolHackTag()) {
return ((IItemStack) (Object) instance).viaFabricPlus$get1_10Count();
}
return instance.getCount();
}
return instance.drawText(textRenderer, text, x, y, color, shadow);
@Redirect(method = "drawItemInSlot(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V", at = @At(value = "INVOKE", target = "Ljava/lang/String;valueOf(I)Ljava/lang/String;", remap = false))
private String makeTextRed(int count) {
if (count <= 0) {
return "§c" + count;
}
return String.valueOf(count);
}
}

View File

@ -19,8 +19,6 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import net.raphimc.vialoader.util.VersionEnum;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.EnderPearlItem;
@ -28,6 +26,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.world.World;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -37,7 +36,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
public abstract class MixinEnderPearlItem {
@Inject(method = "use", at = @At("HEAD"), cancellable = true)
private void injectUse(World world, PlayerEntity user, Hand hand, CallbackInfoReturnable<TypedActionResult<ItemStack>> ci) {
private void removeCreativeModeEnderPearl(World world, PlayerEntity user, Hand hand, CallbackInfoReturnable<TypedActionResult<ItemStack>> ci) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8) && user.getAbilities().creativeMode) {
ci.setReturnValue(TypedActionResult.pass(user.getStackInHand(hand)));
}

View File

@ -20,35 +20,25 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Equipment;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.world.World;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(Equipment.class)
public interface MixinEquipment {
@Redirect(method = "equipAndSwap", at = @At(value = "INVOKE", target = "Lnet/minecraft/enchantment/EnchantmentHelper;hasBindingCurse(Lnet/minecraft/item/ItemStack;)Z"))
default boolean removeBindingCurseCondition(ItemStack stack) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_3)) {
return false;
}
return EnchantmentHelper.hasBindingCurse(stack);
}
@Redirect(method = "equipAndSwap", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;areEqual(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ItemStack;)Z"))
default boolean simplifyCondition(ItemStack left, ItemStack right) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_3)) {
return !right.isEmpty();
}
return ItemStack.areEqual(left, right);
}
@Redirect(method = "equipAndSwap", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;isCreative()Z"))
default boolean removeCreativeCondition(PlayerEntity instance) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_20tor1_20_1)) {
@ -56,4 +46,18 @@ public interface MixinEquipment {
}
return instance.isCreative();
}
@Inject(method = "equipAndSwap", at = @At("HEAD"), cancellable = true)
private void cancelArmorSwap(Item item, World world, PlayerEntity user, Hand hand, CallbackInfoReturnable<TypedActionResult<ItemStack>> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_3)) {
final ItemStack heldItem = user.getStackInHand(hand);
final EquipmentSlot targetSlot = MobEntity.getPreferredEquipmentSlot(heldItem);
final ItemStack targetItem = user.getEquippedStack(targetSlot);
if (!targetItem.isEmpty()) {
cir.setReturnValue(TypedActionResult.fail(heldItem));
}
}
}
}

View File

@ -19,17 +19,17 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import de.florianmichael.viafabricplus.settings.impl.VisualSettings;
import net.minecraft.util.Arm;
import net.raphimc.vialoader.util.VersionEnum;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import de.florianmichael.viafabricplus.settings.impl.VisualSettings;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.item.HeldItemRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Arm;
import net.minecraft.util.Hand;
import net.minecraft.util.math.RotationAxis;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;

View File

@ -73,11 +73,11 @@ public abstract class MixinHoeItem extends MiningToolItem {
public float getMiningSpeedMultiplier(ItemStack stack, BlockState state) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_15_2)) {
return 1.0F;
}
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_4tor1_16_5)) {
} else if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_4tor1_16_5)) {
return viaFabricPlus$EFFECTIVE_BLOCKS_1165.contains(state.getBlock()) ? this.miningSpeed : 1.0F;
} else {
return super.getMiningSpeedMultiplier(stack, state);
}
return super.getMiningSpeedMultiplier(stack, state);
}
}

View File

@ -27,14 +27,21 @@ import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(Item.class)
public abstract class MixinItem {
@Shadow @Final private int maxDamage;
@Shadow
@Final
private int maxDamage;
@Redirect(method = { "getMaxDamage", "isDamageable", "getItemBarStep", "getItemBarColor" }, at = @At(value = "FIELD", target = "Lnet/minecraft/item/Item;maxDamage:I"))
@Shadow
public abstract boolean isFood();
@Redirect(method = {"getMaxDamage", "isDamageable", "getItemBarStep", "getItemBarColor"}, at = @At(value = "FIELD", target = "Lnet/minecraft/item/Item;maxDamage:I"))
private int changeCrossbowDamage(Item instance) {
if (instance instanceof CrossbowItem && ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_17_1)) {
return 326;
@ -42,4 +49,19 @@ public abstract class MixinItem {
return maxDamage;
}
@Inject(method = "getMaxCount", at = @At("HEAD"), cancellable = true)
private void dontStackFood(CallbackInfoReturnable<Integer> cir) {
if (this.isFood() && ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.b1_7tob1_7_3)) {
cir.setReturnValue(1);
}
}
@Redirect(method = {"use", "finishUsing", "getUseAction", "getMaxUseTime"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;isFood()Z"))
private boolean makeFoodInstantConsumable(Item instance) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.b1_7tob1_7_3)) {
return false;
}
return instance.isFood();
}
}

View File

@ -37,11 +37,14 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ItemGroups.class)
public abstract class MixinItemGroups {
@Shadow @Nullable private static ItemGroup.@Nullable DisplayContext displayContext;
@Shadow
@Nullable
private static ItemGroup.@Nullable DisplayContext displayContext;
@Shadow
private static void updateEntries(ItemGroup.DisplayContext displayContext) {
}
@Unique
private static VersionEnum viaFabricPlus$version;

View File

@ -19,27 +19,36 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import net.raphimc.vialoader.util.VersionEnum;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.fixes.Material1_19_4;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ItemPlacementContext.class)
public abstract class MixinItemPlacementContext {
public abstract class MixinItemPlacementContext extends ItemUsageContext {
public MixinItemPlacementContext(PlayerEntity player, Hand hand, BlockHitResult hit) {
super(player, hand, hit);
}
@Inject(method = "getPlayerLookDirection", at = @At("HEAD"), cancellable = true)
private void injectGetPlayerLookDirection(CallbackInfoReturnable<Direction> ci) {
private void get112LookDirection(CallbackInfoReturnable<Direction> cir) {
final ItemPlacementContext self = (ItemPlacementContext) (Object) this;
final PlayerEntity player = self.getPlayer();
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2) && player != null) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2)) {
final BlockPos placementPos = self.getBlockPos();
final double blockPosCenterFactor = ProtocolHack.getTargetVersion().isNewerThan(VersionEnum.r1_10) ? 0.5 : 0;
@ -47,17 +56,24 @@ public abstract class MixinItemPlacementContext {
final double eyeY = player.getY() + player.getEyeHeight(player.getPose());
if (eyeY - placementPos.getY() > 2) {
ci.setReturnValue(Direction.DOWN);
cir.setReturnValue(Direction.DOWN);
return;
}
if (placementPos.getY() - eyeY > 0) {
ci.setReturnValue(Direction.UP);
cir.setReturnValue(Direction.UP);
return;
}
}
ci.setReturnValue(player.getHorizontalFacing());
cir.setReturnValue(player.getHorizontalFacing());
}
}
@Inject(method = "canPlace", at = @At("RETURN"), cancellable = true)
private void anvilOverride(CallbackInfoReturnable<Boolean> cir) {
if (!cir.getReturnValueZ() && ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2)) {
cir.setReturnValue(Material1_19_4.getMaterial(this.getWorld().getBlockState(this.getBlockPos())).equals(Material1_19_4.DECORATION) && Block.getBlockFromItem(this.getStack().getItem()).equals(Blocks.ANVIL));
}
}

View File

@ -37,7 +37,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ItemRenderer.class)
public abstract class MixinItemRenderer {
@Shadow @Final private ItemModels models;
@Shadow
@Final
private ItemModels models;
@Inject(method = "getModel", at = @At("HEAD"), cancellable = true)
private void removeModel(ItemStack stack, World world, LivingEntity entity, int seed, CallbackInfoReturnable<BakedModel> cir) {

View File

@ -21,18 +21,15 @@ package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import de.florianmichael.viafabricplus.injection.access.IItemStack;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.*;
import net.raphimc.vialoader.util.VersionEnum;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
@ -42,39 +39,21 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.OptionalDouble;
@Mixin(value = ItemStack.class, priority = 1)
public abstract class MixinItemStack {
public abstract class MixinItemStack implements IItemStack {
@Shadow
public abstract Item getItem();
@Shadow @Final public static ItemStack EMPTY;
@Unique
private boolean viaFabricPlus$has1_10ProtocolHackTag;
@Shadow private int count;
@Shadow @Final @Deprecated private @Nullable Item item;
@Inject(method = "isEmpty", at = @At("HEAD"), cancellable = true)
private void dontRecalculateState(CallbackInfoReturnable<Boolean> cir) {
if (MinecraftClient.getInstance() != null && ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_10)) {
final ItemStack self = (ItemStack) (Object) this;
cir.setReturnValue(self == EMPTY || this.item == null || this.item == Items.AIR || count == 0);
}
}
@Inject(method = "getMiningSpeedMultiplier", at = @At("RETURN"), cancellable = true)
private void modifyMiningSpeedMultiplier(BlockState state, CallbackInfoReturnable<Float> ci) {
final Item toolItem = ((ItemStack) (Object) this).getItem();
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_15_2) && toolItem instanceof HoeItem) {
ci.setReturnValue(1F);
}
}
@Unique
private int viaFabricPlus$1_10_count;
@Redirect(method = "getTooltip",
slice = @Slice(from = @At(value = "FIELD", target = "Lnet/minecraft/entity/attribute/EntityAttributes;GENERIC_ATTACK_DAMAGE:Lnet/minecraft/entity/attribute/EntityAttribute;", ordinal = 0)),
at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;getAttributeBaseValue(Lnet/minecraft/entity/attribute/EntityAttribute;)D", ordinal = 0))
private double redirectGetTooltip(PlayerEntity player, EntityAttribute attribute) {
private double fixDamageCalculation(PlayerEntity player, EntityAttribute attribute) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
return 0;
} else {
@ -91,7 +70,7 @@ public abstract class MixinItemStack {
modifiers.removeAll(EntityAttributes.GENERIC_ATTACK_DAMAGE);
OptionalDouble defaultAttackDamage = viaFabricPlus$getDefaultAttackDamage(getItem());
if (defaultAttackDamage.isPresent()) {
modifiers.put(EntityAttributes.GENERIC_ATTACK_DAMAGE, new EntityAttributeModifier(Item.ATTACK_DAMAGE_MODIFIER_ID, "Weapon Modifier", defaultAttackDamage.getAsDouble(), EntityAttributeModifier.Operation.ADDITION));
modifiers.put(EntityAttributes.GENERIC_ATTACK_DAMAGE, new EntityAttributeModifier(Item.ATTACK_DAMAGE_MODIFIER_ID, "Tool modifier", defaultAttackDamage.getAsDouble(), EntityAttributeModifier.Operation.ADDITION));
}
modifiers.removeAll(EntityAttributes.GENERIC_ATTACK_SPEED);
modifiers.removeAll(EntityAttributes.GENERIC_ARMOR);
@ -99,20 +78,18 @@ public abstract class MixinItemStack {
return modifiers;
}
@Inject(method = "copy", at = @At("RETURN"))
private void copyProtocolHackData(CallbackInfoReturnable<ItemStack> cir) {
final IItemStack mixinItemStack = (IItemStack) (Object) cir.getReturnValue();
if (this.viaFabricPlus$has1_10ProtocolHackTag) {
mixinItemStack.viaFabricPlus$set1_10Count(this.viaFabricPlus$1_10_count);
}
}
@Unique
private OptionalDouble viaFabricPlus$getDefaultAttackDamage(Item item) {
if (item instanceof ToolItem) {
ToolMaterial material = ((ToolItem) item).getMaterial();
int materialBonus;
if (material == ToolMaterials.STONE) {
materialBonus = 1;
} else if (material == ToolMaterials.IRON) {
materialBonus = 2;
} else if (material == ToolMaterials.DIAMOND) {
materialBonus = 3;
} else {
materialBonus = 0;
}
if (item instanceof ToolItem toolItem) {
final float materialBonus = toolItem.getMaterial().getAttackDamage();
if (item instanceof SwordItem) {
return OptionalDouble.of(4 + materialBonus);
} else if (item instanceof PickaxeItem) {
@ -127,4 +104,20 @@ public abstract class MixinItemStack {
return OptionalDouble.empty();
}
@Override
public boolean viaFabricPlus$has1_10ProtocolHackTag() {
return this.viaFabricPlus$has1_10ProtocolHackTag;
}
@Override
public int viaFabricPlus$get1_10Count() {
return this.viaFabricPlus$1_10_count;
}
@Override
public void viaFabricPlus$set1_10Count(final int count) {
this.viaFabricPlus$has1_10ProtocolHackTag = true;
this.viaFabricPlus$1_10_count = count;
}
}

View File

@ -1,45 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD
* Copyright (C) 2023 RK_01/RaphiMC and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import net.raphimc.vialoader.util.VersionEnum;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.block.BlockState;
import net.minecraft.item.HoeItem;
import net.minecraft.item.ItemStack;
import net.minecraft.item.MiningToolItem;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(MiningToolItem.class)
public abstract class MixinMiningToolItem {
@Inject(method = "getMiningSpeedMultiplier", at = @At("RETURN"), cancellable = true)
private void changeHoeEffectiveBlocks(ItemStack stack, BlockState state, CallbackInfoReturnable<Float> cir) {
//noinspection ConstantValue
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_15_2) && (Object) this instanceof HoeItem) {
cir.setReturnValue(1.0F);
}
}
}

View File

@ -0,0 +1,41 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ShearsItem;
import net.minecraft.registry.tag.BlockTags;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ShearsItem.class)
public abstract class MixinShearsItem extends Item {
public MixinShearsItem(Settings settings) {
super(settings);
}
@Inject(method = "isSuitableFor", at = @At("HEAD"), cancellable = true)
private void changeEffectiveBlocks(BlockState state, CallbackInfoReturnable<Boolean> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.b1_8tob1_8_1)) {
cir.setReturnValue(state.isOf(Blocks.COBWEB));
}
}
@Inject(method = "getMiningSpeedMultiplier", at = @At("HEAD"), cancellable = true)
private void changeMiningSpeed(ItemStack stack, BlockState state, CallbackInfoReturnable<Float> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_4tor1_16_5)) {
if (!state.isOf(Blocks.COBWEB) && !state.isIn(BlockTags.LEAVES)) {
cir.setReturnValue(state.isIn(BlockTags.WOOL) ? 5.0F : super.getMiningSpeedMultiplier(stack, state));
} else {
cir.setReturnValue(15.0F);
}
}
}
}

View File

@ -19,29 +19,59 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import net.raphimc.vialoader.util.VersionEnum;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.google.common.collect.ImmutableSet;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.item.ShovelItem;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.item.*;
import net.minecraft.registry.tag.TagKey;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.Slice;
import java.util.Map;
import java.util.Set;
@Mixin(ShovelItem.class)
public abstract class MixinShovelItem {
public abstract class MixinShovelItem extends MiningToolItem {
@Redirect(method = "useOnBlock",
at = @At(value = "INVOKE", target = "Ljava/util/Map;get(Ljava/lang/Object;)Ljava/lang/Object;", ordinal = 0),
slice = @Slice(from = @At(value = "FIELD", target = "Lnet/minecraft/item/ShovelItem;PATH_STATES:Ljava/util/Map;")))
private Object redirectUseOnBlock(Map<Object, Object> map, Object grassBlock) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
return null;
} else {
return map.get(grassBlock);
@Unique
private static final Set<Block> _b1_8_1_EFFECTIVE_BLOCKS = ImmutableSet.of(Blocks.GRASS_BLOCK, Blocks.DIRT, Blocks.SAND, Blocks.GRAVEL, Blocks.SNOW, Blocks.SNOW_BLOCK, Blocks.CLAY, Blocks.FARMLAND);
@Unique
private static final Set<Block> _r1_16_5_EFFECTIVE_BLOCKS = ImmutableSet.of(Blocks.CLAY, Blocks.DIRT, Blocks.COARSE_DIRT, Blocks.PODZOL, Blocks.FARMLAND, Blocks.GRASS_BLOCK, Blocks.GRAVEL, Blocks.MYCELIUM, Blocks.SAND, Blocks.RED_SAND, Blocks.SNOW_BLOCK, Blocks.SNOW, Blocks.SOUL_SAND, Blocks.DIRT_PATH, Blocks.WHITE_CONCRETE_POWDER, Blocks.ORANGE_CONCRETE_POWDER, Blocks.MAGENTA_CONCRETE_POWDER, Blocks.LIGHT_BLUE_CONCRETE_POWDER, Blocks.YELLOW_CONCRETE_POWDER, Blocks.LIME_CONCRETE_POWDER, Blocks.PINK_CONCRETE_POWDER, Blocks.GRAY_CONCRETE_POWDER, Blocks.LIGHT_GRAY_CONCRETE_POWDER, Blocks.CYAN_CONCRETE_POWDER, Blocks.PURPLE_CONCRETE_POWDER, Blocks.BLUE_CONCRETE_POWDER, Blocks.BROWN_CONCRETE_POWDER, Blocks.GREEN_CONCRETE_POWDER, Blocks.RED_CONCRETE_POWDER, Blocks.BLACK_CONCRETE_POWDER, Blocks.SOUL_SOIL);
protected MixinShovelItem(float attackDamage, float attackSpeed, ToolMaterial material, TagKey<Block> effectiveBlocks, Item.Settings settings) {
super(attackDamage, attackSpeed, material, effectiveBlocks, settings);
}
@Redirect(method = "useOnBlock", slice = @Slice(from = @At(value = "FIELD", target = "Lnet/minecraft/item/ShovelItem;PATH_STATES:Ljava/util/Map;")), at = @At(value = "INVOKE", target = "Ljava/util/Map;get(Ljava/lang/Object;)Ljava/lang/Object;", ordinal = 0, remap = false))
private Object disablePathAction(Map<Object, Object> instance, Object grassBlock) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) return null;
return instance.get(grassBlock);
}
@Override
public boolean isSuitableFor(BlockState state) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_4tor1_16_5)) {
return state.isOf(Blocks.SNOW) || state.isOf(Blocks.SNOW_BLOCK);
}
return super.isSuitableFor(state);
}
@Override
public float getMiningSpeedMultiplier(ItemStack stack, BlockState state) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.b1_8tob1_8_1)) {
return _b1_8_1_EFFECTIVE_BLOCKS.contains(state.getBlock()) ? this.miningSpeed : 1.0F;
} else if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_4tor1_16_5)) {
return _r1_16_5_EFFECTIVE_BLOCKS.contains(state.getBlock()) ? this.miningSpeed : 1.0F;
}
return super.getMiningSpeedMultiplier(stack, state);
}
}

View File

@ -19,9 +19,9 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import net.raphimc.vialoader.util.VersionEnum;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.SwordItem;
@ -31,7 +31,11 @@ import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.UseAction;
import net.minecraft.world.World;
import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(SwordItem.class)
public abstract class MixinSwordItem extends ToolItem {
@ -42,7 +46,7 @@ public abstract class MixinSwordItem extends ToolItem {
@Override
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
if (ProtocolHack.getTargetVersion().isBetweenInclusive(VersionEnum.b1_8tob1_8_1, VersionEnum.r1_8)) {
ItemStack itemStack = user.getStackInHand(hand);
user.setCurrentHand(hand);
return TypedActionResult.consume(itemStack);
@ -60,10 +64,17 @@ public abstract class MixinSwordItem extends ToolItem {
@Override
public int getMaxUseTime(ItemStack stack) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
if (ProtocolHack.getTargetVersion().isBetweenInclusive(VersionEnum.b1_8tob1_8_1, VersionEnum.r1_8)) {
return 72000;
}
return super.getMaxUseTime(stack);
}
@Inject(method = "getMiningSpeedMultiplier", at = @At("HEAD"), cancellable = true)
private void changeMiningSpeed(ItemStack stack, BlockState state, CallbackInfoReturnable<Float> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.b1_8tob1_8_1)) {
cir.setReturnValue(state.isOf(Blocks.COBWEB) ? 15.0F : 1.5F);
}
}
}

View File

@ -37,7 +37,7 @@ public abstract class MixinScreen {
@Shadow @Nullable protected MinecraftClient client;
@Inject(method = "handleTextClick", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;error(Ljava/lang/String;Ljava/lang/Object;)V", shift = At.Shift.BEFORE, ordinal = 1), cancellable = true)
@Inject(method = "handleTextClick", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;error(Ljava/lang/String;Ljava/lang/Object;)V", shift = At.Shift.BEFORE, ordinal = 1, remap = false), cancellable = true)
private void allowRunCommandAction(Style style, CallbackInfoReturnable<Boolean> cir) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19)) {
this.client.player.networkHandler.sendChatMessage(SharedConstants.stripInvalidChars(style.getClickEvent().getValue()));

View File

@ -34,7 +34,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.List;
@SuppressWarnings("DataFlowIssue")
@Mixin(MetadataRewriter1_15To1_14_4.class)
public abstract class MixinMetadataRewriter1_15To1_14_4 extends EntityRewriter<ClientboundPackets1_14_4, Protocol1_15To1_14_4> {
@ -44,7 +43,7 @@ public abstract class MixinMetadataRewriter1_15To1_14_4 extends EntityRewriter<C
@Inject(method = "handleMetadata", at = @At(value = "INVOKE", target = "Ljava/util/List;remove(Ljava/lang/Object;)Z", shift = At.Shift.BEFORE), remap = false)
private void trackHealth(int entityId, EntityType type, Metadata metadata, List<Metadata> metadatas, UserConnection connection, CallbackInfo ci) {
WolfHealthTracker.get().getHealthDataMap().put(entityId, (Float) metadata.getValue());
WolfHealthTracker.get().setWolfHealth(entityId, metadata.value());
}
}

View File

@ -178,7 +178,7 @@ public class ProtocolHack {
return ((IClientConnection) handler.getConnection()).viaFabricPlus$getUserConnection();
}
return null;
throw new IllegalStateException("The player is not connected to a server");
}
/**

View File

@ -28,7 +28,6 @@ public class ExperimentalSettings extends SettingGroup {
public final BooleanSetting fixChunkBorders = new BooleanSetting(this, Text.translatable("experimental.viafabricplus.chunkborderfix"), true);
public final BooleanSetting waterMovementEdgeDetection = new BooleanSetting(this, Text.translatable("experimental.viafabricplus.watermovement"), true);
public final BooleanSetting emulateBoatMovement = new BooleanSetting(this, Text.translatable("experimental.viafabricplus.boatmovement"), false);
public ExperimentalSettings() {
super(Text.translatable("settings.viafabricplus.experimental"));

View File

@ -11,13 +11,14 @@
"base.connect.MixinClientLoginNetworkHandler",
"base.integration.MixinAddServerScreen",
"base.integration.MixinDebugHud",
"base.integration.MixinDownloadingTerrainScreenAndConnectScreen",
"base.integration.MixinDownloadingTerrainScreen",
"base.integration.MixinMinecraftClient",
"base.integration.MixinMultiplayerScreen",
"base.integration.MixinMultiplayerServerListPinger_1",
"base.integration.MixinMultiplayerServerListWidget_ServerEntry",
"base.per_server_version.MixinConnectScreen_1",
"base.per_server_version.MixinMultiplayerServerListPinger",
"base.per_server_version.MixinPerformanceLog",
"base.per_server_version.MixinServerInfo",
"compat.classic4j.MixinCCAuthenticationResponse",
"compat.classic4j.MixinTextFieldWidget",
@ -27,11 +28,9 @@
"fixes.authlib.MixinKeyPairResponse",
"fixes.authlib.MixinYggdrasilUserApiService",
"fixes.minecraft.MixinClientPlayerInteractionManager",
"fixes.minecraft.MixinDrawContext",
"fixes.minecraft.MixinFontStorage",
"fixes.minecraft.MixinMinecraftClient",
"fixes.minecraft.MixinPendingUpdateManager",
"fixes.minecraft.MixinPlayerEntityRenderer",
"fixes.minecraft.MixinPlayerListEntry",
"fixes.minecraft.MixinPlayerPublicKey_PublicKeyData",
"fixes.minecraft.MixinProfileKeysImpl",
@ -45,24 +44,31 @@
"fixes.minecraft.block.MixinBambooBlock",
"fixes.minecraft.block.MixinBedBlock",
"fixes.minecraft.block.MixinBrewingStandBlock",
"fixes.minecraft.block.MixinCarpetBlock",
"fixes.minecraft.block.MixinCauldronBlock",
"fixes.minecraft.block.MixinChestBlock",
"fixes.minecraft.block.MixinCropBlock",
"fixes.minecraft.block.MixinEnderChestBlock",
"fixes.minecraft.block.MixinEndPortalBlock",
"fixes.minecraft.block.MixinEndPortalFrameBlock",
"fixes.minecraft.block.MixinFarmlandBlock",
"fixes.minecraft.block.MixinFenceBlock",
"fixes.minecraft.block.MixinFenceGateBlock",
"fixes.minecraft.block.MixinFireBlock",
"fixes.minecraft.block.MixinFlowerbedBlock",
"fixes.minecraft.block.MixinFlowerPotBlock",
"fixes.minecraft.block.MixinHopperBlock",
"fixes.minecraft.block.MixinLadderBlock",
"fixes.minecraft.block.MixinLeavesBlock",
"fixes.minecraft.block.MixinLilyPadBlock",
"fixes.minecraft.block.MixinNoteBlock",
"fixes.minecraft.block.MixinPaneBlock",
"fixes.minecraft.block.MixinPistonBlock",
"fixes.minecraft.block.MixinPistonHeadBlock",
"fixes.minecraft.block.MixinSnowBlock",
"fixes.minecraft.block.MixinSoulSandBlock",
"fixes.minecraft.block.MixinWallBlock",
"fixes.minecraft.entity.MixinAbstractClientPlayerEntity",
"fixes.minecraft.entity.MixinAbstractDonkeyEntity",
"fixes.minecraft.entity.MixinAnimalEntity",
"fixes.minecraft.entity.MixinBipedEntityModel",
@ -81,6 +87,7 @@
"fixes.minecraft.entity.MixinOtherClientPlayerEntity",
"fixes.minecraft.entity.MixinPiglinEntity",
"fixes.minecraft.entity.MixinPlayerEntity",
"fixes.minecraft.entity.MixinPlayerEntityRenderer",
"fixes.minecraft.entity.MixinSquidEntity",
"fixes.minecraft.entity.MixinVexEntity",
"fixes.minecraft.entity.MixinWolfEntity",
@ -89,6 +96,7 @@
"fixes.minecraft.item.MixinAxeItem",
"fixes.minecraft.item.MixinBlockItem",
"fixes.minecraft.item.MixinBrushItem",
"fixes.minecraft.item.MixinDrawContext",
"fixes.minecraft.item.MixinEnderPearlItem",
"fixes.minecraft.item.MixinEquipment",
"fixes.minecraft.item.MixinFireworkRocketItem",
@ -167,12 +175,10 @@
"defaultRequire": 1
},
"mixins": [
"base.per_server_version.MixinPerformanceLog",
"fixes.minecraft.block.MixinCarpetBlock",
"fixes.minecraft.block.MixinEnderChestBlock",
"fixes.minecraft.block.MixinFenceGateBlock",
"fixes.minecraft.block.MixinLeavesBlock",
"fixes.minecraft.block.MixinNoteBlock",
"fixes.minecraft.block.MixinPistonBlock"
"fixes.minecraft.entity.MixinBoatEntity",
"fixes.minecraft.entity.MixinSkeletonHorseEntity",
"fixes.minecraft.item.MixinArmorItem",
"fixes.minecraft.item.MixinBowItem",
"fixes.minecraft.item.MixinShearsItem"
]
}