Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Tablist buffering #98

Merged
merged 4 commits into from
Aug 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Shared/src/main/java/dev/tr7zw/exordium/access/TablistAccess.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package dev.tr7zw.exordium.access;

import dev.tr7zw.exordium.util.BufferedComponent;
import net.minecraft.world.scores.Objective;
import net.minecraft.world.scores.Scoreboard;

public interface TablistAccess {
public void updateState(Scoreboard scoreboard, Objective objective);
public BufferedComponent getBufferedComponent();
}
1 change: 1 addition & 0 deletions Shared/src/main/java/dev/tr7zw/exordium/config/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class Config {
public ComponentSettings experienceSettings = new ComponentSettings(true, 5);
public ComponentSettings healthSettings = new ComponentSettings(true, 20);
public ComponentSettings scoreboardSettings = new ComponentSettings(true, 5);
public ComponentSettings tablistSettings = new ComponentSettings(true, 20);

public class ComponentSettings {
public boolean enabled = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public void initialize() {
addSettings(options, config.hotbarSettings, "hotbar");
addSettings(options, config.experienceSettings, "experience");
addSettings(options, config.scoreboardSettings, "scoreboard");
addSettings(options, config.tablistSettings, "tablist");

getOptions().addSmall(options.toArray(new OptionInstance[0]));

Expand Down
19 changes: 19 additions & 0 deletions Shared/src/main/java/dev/tr7zw/exordium/mixin/GuiMixin.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package dev.tr7zw.exordium.mixin;

import dev.tr7zw.exordium.access.TablistAccess;
import net.minecraft.client.gui.components.PlayerTabOverlay;
import net.minecraft.world.scores.Objective;
import net.minecraft.world.scores.Scoreboard;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
Expand All @@ -18,6 +22,8 @@ public class GuiMixin {

@Shadow
private ChatComponent chat;
@Shadow
private PlayerTabOverlay tabList;

@WrapOperation(method = "render", at = {
@At(value = "INVOKE", target = "Lnet/minecraft/client/gui/components/ChatComponent;render(Lnet/minecraft/client/gui/GuiGraphics;III)V"),
Expand All @@ -31,5 +37,18 @@ private void renderChatWrapper(ChatComponent instance, GuiGraphics guiGraphics,
}
bufferedComponent.renderEnd();
}

@WrapOperation(method = "render", at = {
@At(value = "INVOKE", target = "Lnet/minecraft/client/gui/components/PlayerTabOverlay;render(Lnet/minecraft/client/gui/GuiGraphics;ILnet/minecraft/world/scores/Scoreboard;Lnet/minecraft/world/scores/Objective;)V"),
})
private void renderTablistWrapper(PlayerTabOverlay instance, GuiGraphics guiGraphics, int screenWidth, Scoreboard scoreboard, Objective objective2, final Operation<Void> operation) {
TablistAccess tablistAccess = (TablistAccess) tabList;
tablistAccess.updateState(scoreboard, objective2);
BufferedComponent bufferedComponent = tablistAccess.getBufferedComponent();
if(!bufferedComponent.render()) {
operation.call(instance, guiGraphics, screenWidth, scoreboard, objective2);
}
bufferedComponent.renderEnd();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package dev.tr7zw.exordium.mixin;

import dev.tr7zw.exordium.ExordiumModBase;
import dev.tr7zw.exordium.access.TablistAccess;
import dev.tr7zw.exordium.util.BufferedComponent;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.PlayerInfo;
import net.minecraft.network.chat.Component;
import net.minecraft.world.scores.Objective;
import net.minecraft.world.scores.Score;
import net.minecraft.world.scores.Scoreboard;
import org.spongepowered.asm.mixin.Mixin;
import net.minecraft.client.gui.components.PlayerTabOverlay;
import org.spongepowered.asm.mixin.Shadow;

import java.util.List;

@Mixin(PlayerTabOverlay.class)
public abstract class PlayerTabOverlayMixin implements TablistAccess {
@Shadow
private Minecraft minecraft;
private int playerInfoHash = 0;
private int headerHash = 0;
private int footerHash = 0;
private int scoreboardHash = 0;
private int objectiveHash = 0;
@Shadow
private Component header;
@Shadow
private Component footer;
private Objective lastTrackedObjective;
private boolean outdated;
private BufferedComponent bufferedComponent = new BufferedComponent(true, ExordiumModBase.instance.config.tablistSettings) {

@Override
public boolean needsRender() {
return outdated;
}

@Override
public void captureState() {
playerInfoHash = fastGetPlayerInfoListHashCode(getPlayerInfos());
headerHash = header == null ? 0 : header.getString().hashCode();
footerHash = footer == null ? 0 : footer.getString().hashCode();
}
};

public void updateState(Scoreboard scoreboard, Objective objective) {
boolean scoreboardOrObjectiveChange = scoreboardOrObjectiveChanged(scoreboard, objective);
int newHeaderHash = header == null ? 0 : header.getString().hashCode();
int newFooterHash = footer == null ? 0 : footer.getString().hashCode();
outdated = playerInfoHash != fastGetPlayerInfoListHashCode(getPlayerInfos()) || headerHash != newHeaderHash || footerHash != newFooterHash || scoreboardOrObjectiveChange;
}

public boolean scoreboardOrObjectiveChanged(Scoreboard scoreboard, Objective objective) {
if (objective == null && lastTrackedObjective == null) return false;

int scoreboardHashCode = 1;
for (Score score : scoreboard.getPlayerScores(objective))
scoreboardHashCode = 31 * scoreboardHashCode + (score == null ? 0 : score.getScore());

int newObjectiveHashCode = objective == null ? 0 : objective.getName().hashCode();
if (scoreboardHashCode == scoreboardHash && newObjectiveHashCode == objectiveHash) return false;
scoreboardHash = scoreboardHashCode;
objectiveHash = newObjectiveHashCode;
lastTrackedObjective = objective;
return true;
}

public int fastGetPlayerInfoListHashCode(List<PlayerInfo> playerInfos) {
int hashCode = 1;
for (PlayerInfo playerInfo : playerInfos) {
int combinedHashes = 0;
if (playerInfo == null) {
hashCode *= 31;
continue;
}
combinedHashes += playerInfo.getProfile().getId().hashCode();
combinedHashes += playerInfo.getTabListDisplayName() == null ? 0 : playerInfo.getTabListDisplayName().getString().hashCode();
combinedHashes += playerInfo.getSkinLocation().hashCode();
hashCode = 31 * hashCode + combinedHashes;
}
return hashCode;
}

public BufferedComponent getBufferedComponent() {
return bufferedComponent;
}

@Shadow
public abstract List<PlayerInfo> getPlayerInfos();
}
10 changes: 9 additions & 1 deletion Shared/src/main/resources/assets/exordium/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,13 @@
"text.exordium.setting.scoreboard.forceblend": "Force Scoreboard Blend",
"text.exordium.setting.scoreboard.forceblend.tooltip": "Force on texture blending for the scoreboard. Might fix some issues with other mods.",
"text.exordium.setting.scoreboard.forceupdates": "Force Scoreboard Updates",
"text.exordium.setting.scoreboard.forceupdates.tooltip": "Force the scoreboard to update every frame(keeping in mind the fps limit). Might fix some issues with other mods."
"text.exordium.setting.scoreboard.forceupdates.tooltip": "Force the scoreboard to update every frame(keeping in mind the fps limit). Might fix some issues with other mods.",
"text.exordium.setting.tablist.enabled": "Buffer Tablist",
"text.exordium.setting.tablist.fps": "Buffer Tablist Max. FPS",
"text.exordium.setting.tablist.fps.tooltip": "The maximum framerate for the tablist",
"text.exordium.setting.tablist.enabled.tooltip": "Enable/Disable buffering the tablist",
"text.exordium.setting.tablist.forceblend": "Force Tablist Blend",
"text.exordium.setting.tablist.forceblend.tooltip": "Force on texture blending for the tablist. Might fix some issues with other mods.",
"text.exordium.setting.tablist.forceupdates": "Force Tablist Updates",
"text.exordium.setting.tablist.forceupdates.tooltip": "Force the tablist to update every frame(keeping in mind the fps limit). Might fix some issues with other mods."
}
3 changes: 2 additions & 1 deletion Shared/src/main/resources/exordium.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"GuiHealthMixin",
"ScoreboardMixin",
"GuiMixin",
"GameRendererMixin"
"GameRendererMixin",
"PlayerTabOverlayMixin"
],
"injectors": {
"defaultRequire": 1
Expand Down