Skip to content

Commit

Permalink
Fixes #6
Browse files Browse the repository at this point in the history
  • Loading branch information
samolego committed Jun 15, 2021
1 parent a50d53f commit 3b3cf20
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 9 deletions.
6 changes: 6 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ repositories {
maven {
url 'https://jitpack.io'
}
maven {
name = "TomTheGeek-repo"
url = "https://maven.tomthegeek.ml/releases/"
}
}

def ENV = System.getenv()
Expand All @@ -37,6 +41,8 @@ dependencies {
// LuckPerms
modImplementation 'me.lucko:fabric-permissions-api:0.1-SNAPSHOT'

// WDMNF
modRuntime("com.github.tom_the_geek:wdmnf:1.0.0+mc.1.17")
//modRuntime "com.github.CaffeineMC:hydrogen-fabric:mc1.16.5-v0.2.0"
//modRuntime "com.github.astei:lazydfu:0.1.2"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@

@Mixin(EntityTrackerUpdateS2CPacket.class)
public interface EntityTrackerUpdateS2CPacketAccessor {
@Accessor("id")
int getId();

@Accessor("trackedValues")
List<DataTracker.Entry<?>> getTrackedValues();

@Mutable
@Accessor("trackedValues")
void setTrackedValues(List<DataTracker.Entry<?>> trackedValues);

@Accessor("id")
int getId();

@Mutable
@Accessor("id")
void setId(int id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.data.DataTracker;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.Packet;
import net.minecraft.network.packet.s2c.play.EntityTrackerUpdateS2CPacket;
import net.minecraft.server.network.ServerPlayNetworkHandler;
Expand All @@ -15,12 +16,15 @@
import net.minecraft.text.TranslatableText;
import net.minecraft.util.registry.Registry;
import org.samo_lego.healthcare.healthbar.HealthbarPreferences;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
Expand All @@ -31,33 +35,55 @@
public class ServerPlayNetworkHandlerMixin_HealthTag {
@Shadow public ServerPlayerEntity player;

@Shadow @Final public ClientConnection connection;

/**
* Dummy handler used for creating modified
* packets with health.
* This is used instead of real entity datatracker since
* we don't want its values to get marked
* as non-dirty upon sending the fake packet.
*/
@Unique
private final DataTracker healthcare$dummyTracker = new DataTracker(null);

/**
* Gets the current packet being sent and modifies
* it accordingly to player's preferences in the packet is
* an {@link EntityTrackerUpdateS2CPacket}.
*
* @param packet packet being sent
* @param listener
* @param ci
*/
@Inject(
method = "sendPacket(Lnet/minecraft/network/Packet;Lio/netty/util/concurrent/GenericFutureListener;)V",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/network/ClientConnection;send(Lnet/minecraft/network/Packet;Lio/netty/util/concurrent/GenericFutureListener;)V"
)
),
cancellable = true
)
private void onPacketSend(Packet<?> packet, GenericFutureListener<? extends Future<? super Void>> listener, CallbackInfo ci) {
if(packet instanceof EntityTrackerUpdateS2CPacket) {
List<DataTracker.Entry<?>> trackedValues = ((EntityTrackerUpdateS2CPacketAccessor) packet).getTrackedValues();

Entity entity = this.player.getServerWorld().getEntityById(((EntityTrackerUpdateS2CPacketAccessor) packet).getId());
int id = ((EntityTrackerUpdateS2CPacketAccessor) packet).getId();
Entity entity = this.player.getServerWorld().getEntityById(id);

if(
entity instanceof LivingEntity &&
entity instanceof LivingEntity living &&
((HealthbarPreferences) this.player).isEnabled() &&
!(entity instanceof PlayerEntity) &&
!config.blacklistedEntities.contains(Registry.ENTITY_TYPE.getId(entity.getType()).toString())
) {
List<DataTracker.Entry<?>> trackedValues = new ArrayList<>(((EntityTrackerUpdateS2CPacketAccessor) packet).getTrackedValues());

// Removing current custom name
trackedValues.removeIf(value -> value.getData().getId() == 2);

// Ensure name is visible only if mob is not too far away
boolean visible = (entity.distanceTo(player) < config.activationRange || entity.isCustomNameVisible()) && ((HealthbarPreferences) player).isAlwaysVisible();
DataTracker.Entry<Boolean> visibleTag = new DataTracker.Entry<>(EntityAccessor.getNAME_VISIBLE(), visible);

LivingEntity living = (LivingEntity) entity;
float health = living.getHealth();
float maxHealth = living.getMaxHealth();

Expand All @@ -68,7 +94,17 @@ private void onPacketSend(Packet<?> packet, GenericFutureListener<? extends Futu
DataTracker.Entry<Optional<Text>> healthTag = new DataTracker.Entry<>(EntityAccessor.getCUSTOM_NAME(), Optional.of(name.append(" ").append(healthbar)));

Collections.addAll(trackedValues, visibleTag, healthTag);
((EntityTrackerUpdateS2CPacketAccessor) packet).setTrackedValues(trackedValues);

// Create a new packet in order to not mess with other network handlers
// since same packet object is sent to every player
EntityTrackerUpdateS2CPacket trackerUpdatePacket = new EntityTrackerUpdateS2CPacket(id, this.healthcare$dummyTracker, false);
EntityTrackerUpdateS2CPacketAccessor accessor = (EntityTrackerUpdateS2CPacketAccessor) trackerUpdatePacket;

accessor.setId(id);
accessor.setTrackedValues(trackedValues);

this.connection.send(trackerUpdatePacket, listener);
ci.cancel(); // cancel the original packet going out
}
}
}
Expand Down

0 comments on commit 3b3cf20

Please sign in to comment.