Skip to content

Commit

Permalink
Attribute rewriters
Browse files Browse the repository at this point in the history
  • Loading branch information
SamB440 committed Jul 1, 2024
1 parent 2df7c68 commit 16a90bb
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -445,24 +445,14 @@ private void check(PositionUpdate update) {
wasChecked = true;

// Depth strider was added in 1.8
final boolean hasAttributes = player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_21);
if (hasAttributes && PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_21)) {
if (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_8)) {
player.depthStriderLevel = (float) player.compensatedEntities.getSelf().getAttribute(Attributes.GENERIC_WATER_MOVEMENT_EFFICIENCY).get();
} else {
if (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_8)) {
player.depthStriderLevel = EnchantmentHelper.getMaximumEnchantLevel(player.getInventory(), EnchantmentTypes.DEPTH_STRIDER, PacketEvents.getAPI().getServerManager().getVersion().toClientVersion());
if (hasAttributes && PacketEvents.getAPI().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_21)) {
// This is what via does
player.depthStriderLevel /= 3.0;
}
} else {
player.depthStriderLevel = 0;
}
player.depthStriderLevel = 0;
}

if (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_19)) {
ItemStack leggings = player.getInventory().getLeggings();
player.sneakingSpeedMultiplier = GrimMath.clampFloat(0.3F + (leggings.getEnchantmentLevel(EnchantmentTypes.SWIFT_SNEAK, player.getClientVersion()) * 0.15F), 0f, 1f);
player.sneakingSpeedMultiplier = (float) player.compensatedEntities.getSelf().getAttribute(Attributes.PLAYER_SNEAKING_SPEED).get();
} else {
player.sneakingSpeedMultiplier = 0.3F;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,16 +341,10 @@ public void livingEntityTravel() {
player.depthStriderLevel *= 0.5F;
}

if (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_21)) {
if (player.depthStriderLevel > 0.0F) {
swimFriction += (0.54600006F - swimFriction) * player.depthStriderLevel;
swimSpeed += (player.speed - swimSpeed) * player.depthStriderLevel;
}
} else {
if (player.depthStriderLevel > 0.0F) {
swimFriction += (0.54600006F - swimFriction) * player.depthStriderLevel / 3.0F;
swimSpeed += (player.speed - swimSpeed) * player.depthStriderLevel / 3.0F;
}
if (player.depthStriderLevel > 0.0F) {
final float divisor = player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_21) ? 1.0F : 3.0F;
swimFriction += (0.54600006F - swimFriction) * player.depthStriderLevel / divisor;
swimSpeed += (player.speed - swimSpeed) * player.depthStriderLevel / divisor;
}

if (player.compensatedEntities.getDolphinsGraceAmplifier() != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
package ac.grim.grimac.utils.data.attribute;

import ac.grim.grimac.player.GrimPlayer;
import ac.grim.grimac.utils.math.GrimMath;
import com.github.retrooper.packetevents.protocol.attribute.Attribute;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes;

import java.util.List;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;

import static ac.grim.grimac.utils.latency.CompensatedEntities.SPRINTING_MODIFIER_UUID;

public final class ValuedAttribute {

private static final Function<Double, Double> DEFAULT_GET_REWRITE = Function.identity();

private final Attribute attribute;
// Attribute limits defined by https://minecraft.wiki/w/Attribute
// These seem to be clamped on the client, but not the server
Expand All @@ -20,6 +27,11 @@ public final class ValuedAttribute {
private final double defaultValue;
private double value;

// BiFunction of <Old, New, Output>
// This allows us to rewrite the value based on client & server version
private BiFunction<Double, Double, Double> rewriteFunction;
private Function<Double, Double> getRewriteFunction;

private ValuedAttribute(Attribute attribute, double defaultValue, double min, double max) {
if (defaultValue < min || defaultValue > max) {
throw new IllegalArgumentException("Default value must be between min and max!");
Expand All @@ -30,12 +42,39 @@ private ValuedAttribute(Attribute attribute, double defaultValue, double min, do
this.value = defaultValue;
this.min = min;
this.max = max;
this.getRewriteFunction = DEFAULT_GET_REWRITE;
}

public static ValuedAttribute ranged(Attribute attribute, double defaultValue, double min, double max) {
return new ValuedAttribute(attribute, defaultValue, min, max);
}

public ValuedAttribute withRewriter(BiFunction<Double, Double, Double> rewriteFunction) {
this.rewriteFunction = rewriteFunction;
return this;
}

/**
* Creates a rewriter that prevents the value from ever being modified unless the player meets the required version.
* @param player the player
* @param requiredVersion the required version for the attribute
* @return this instance for chaining
*/
public ValuedAttribute versionedRewriter(GrimPlayer player, ClientVersion requiredVersion) {
withRewriter((oldValue, newValue) -> {
if (player.getClientVersion().isOlderThan(requiredVersion)) {
return oldValue;
}
return newValue;
});
return this;
}

public ValuedAttribute withGetRewriter(Function<Double, Double> getRewriteFunction) {
this.getRewriteFunction = getRewriteFunction;
return this;
}

public Attribute attribute() {
return attribute;
}
Expand All @@ -45,7 +84,7 @@ public void reset() {
}

public double get() {
return value;
return getRewriteFunction.apply(this.value);
}

public void override(double value) {
Expand Down Expand Up @@ -84,7 +123,16 @@ public double with(WrapperPlayServerUpdateAttributes.Property property) {
d1 *= 1.0D + attributemodifier.getAmount();
}

double newValue = GrimMath.clampFloat((float) d1, (float) min, (float) max);
if (rewriteFunction != null) {
newValue = rewriteFunction.apply(this.value, newValue);
}

if (newValue < min || newValue > max) {
throw new IllegalArgumentException("New value must be between min and max!");
}

this.lastProperty = property;
return this.value = GrimMath.clampFloat((float) d1, (float) min, (float) max);
return this.value = newValue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
import ac.grim.grimac.player.GrimPlayer;
import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox;
import ac.grim.grimac.utils.data.attribute.ValuedAttribute;
import ac.grim.grimac.utils.inventory.EnchantmentHelper;
import ac.grim.grimac.utils.math.GrimMath;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentTypes;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.player.GameMode;
import com.github.retrooper.packetevents.protocol.potion.PotionType;
Expand Down Expand Up @@ -44,12 +47,53 @@ public PacketEntitySelf(GrimPlayer player) {
final ValuedAttribute movementSpeed = ValuedAttribute.ranged(Attributes.GENERIC_MOVEMENT_SPEED, 0.1f, 0, 1024);
movementSpeed.with(new WrapperPlayServerUpdateAttributes.Property("MOVEMENT_SPEED", 0.1f, new ArrayList<>()));
attributeMap.put(Attributes.GENERIC_MOVEMENT_SPEED, movementSpeed);
attributeMap.put(Attributes.GENERIC_JUMP_STRENGTH, ValuedAttribute.ranged(Attributes.GENERIC_JUMP_STRENGTH, 0.42f, 0, 32));
attributeMap.put(Attributes.PLAYER_BLOCK_BREAK_SPEED, ValuedAttribute.ranged(Attributes.PLAYER_BLOCK_BREAK_SPEED, 1.0, 0, 1024));
attributeMap.put(Attributes.PLAYER_ENTITY_INTERACTION_RANGE, ValuedAttribute.ranged(Attributes.PLAYER_ENTITY_INTERACTION_RANGE, 3, 0, 64));
attributeMap.put(Attributes.PLAYER_BLOCK_INTERACTION_RANGE, ValuedAttribute.ranged(Attributes.PLAYER_BLOCK_INTERACTION_RANGE, 4.5, 0, 64));
attributeMap.put(Attributes.GENERIC_WATER_MOVEMENT_EFFICIENCY, ValuedAttribute.ranged(Attributes.GENERIC_WATER_MOVEMENT_EFFICIENCY, 0, 0, 1));
attributeMap.put(Attributes.PLAYER_SNEAKING_SPEED, ValuedAttribute.ranged(Attributes.PLAYER_SNEAKING_SPEED, 0.3, 0, 1));
attributeMap.put(Attributes.GENERIC_JUMP_STRENGTH, ValuedAttribute.ranged(Attributes.GENERIC_JUMP_STRENGTH, 0.42f, 0, 32)
.versionedRewriter(player, ClientVersion.V_1_20_5));
attributeMap.put(Attributes.PLAYER_BLOCK_BREAK_SPEED, ValuedAttribute.ranged(Attributes.PLAYER_BLOCK_BREAK_SPEED, 1.0, 0, 1024)
.versionedRewriter(player, ClientVersion.V_1_20_5));
attributeMap.put(Attributes.PLAYER_ENTITY_INTERACTION_RANGE, ValuedAttribute.ranged(Attributes.PLAYER_ENTITY_INTERACTION_RANGE, 3, 0, 64)
.versionedRewriter(player, ClientVersion.V_1_20_5));
attributeMap.put(Attributes.PLAYER_BLOCK_INTERACTION_RANGE, ValuedAttribute.ranged(Attributes.PLAYER_BLOCK_INTERACTION_RANGE, 4.5, 0, 64)
.versionedRewriter(player, ClientVersion.V_1_20_5));
attributeMap.put(Attributes.GENERIC_WATER_MOVEMENT_EFFICIENCY, ValuedAttribute.ranged(Attributes.GENERIC_WATER_MOVEMENT_EFFICIENCY, 0, 0, 1)
.withGetRewriter(value -> {
// On clients < 1.21, use depth strider enchant level always
final double depthStrider = EnchantmentHelper.getMaximumEnchantLevel(player.getInventory(), EnchantmentTypes.DEPTH_STRIDER, PacketEvents.getAPI().getServerManager().getVersion().toClientVersion());
if (depthStrider == 0) {
return 0d;
}

if (player.getClientVersion().isOlderThan(ClientVersion.V_1_21)) {
return depthStrider;
}

// Server is older than 1.21, but player is on 1.21+ so return depth strider value / 3 to simulate via
// https://github.com/ViaVersion/ViaVersion/blob/dc503cd613f5cf00a6f11b78e52b1a76a42acf91/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/storage/EfficiencyAttributeStorage.java#L34
if (PacketEvents.getAPI().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_21)) {
return depthStrider / 3;
}

// We are on a version that fully supports this value!
return value;
})
.versionedRewriter(player, ClientVersion.V_1_21));
attributeMap.put(Attributes.PLAYER_SNEAKING_SPEED, ValuedAttribute.ranged(Attributes.PLAYER_SNEAKING_SPEED, 0.3, 0, 1)
.withGetRewriter(value -> {
final int swiftSneak = player.getInventory().getLeggings().getEnchantmentLevel(EnchantmentTypes.SWIFT_SNEAK, player.getClientVersion());
final double clamped = GrimMath.clampFloat(0.3F + (swiftSneak * 0.15F), 0f, 1f);
if (player.getClientVersion().isOlderThan(ClientVersion.V_1_21)) {
return clamped;
}

// https://github.com/ViaVersion/ViaVersion/blob/dc503cd613f5cf00a6f11b78e52b1a76a42acf91/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/storage/EfficiencyAttributeStorage.java#L32
if (PacketEvents.getAPI().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_21)) {
return clamped;
}

// We are on a version that fully supports this value!
return value;
})
.versionedRewriter(player, ClientVersion.V_1_21));
}

public PacketEntitySelf(GrimPlayer player, PacketEntitySelf old) {
Expand Down

0 comments on commit 16a90bb

Please sign in to comment.